summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2012-02-05 11:21:29 -0500
committerAnthony G. Basile <blueness@gentoo.org>2012-02-05 11:21:29 -0500
commitcb29449ba86b1b7d605c9b24417178739547505b (patch)
treeb2a00706a601f9aadd0e3f4e0e3574de2524ccca
parentGrsec/PaX: 2.2.2-2.6.32.55-201201272054 + 2.2.2-3.2.2-201201272014 (diff)
downloadhardened-patchset-cb29449ba86b1b7d605c9b24417178739547505b.tar.gz
hardened-patchset-cb29449ba86b1b7d605c9b24417178739547505b.tar.bz2
hardened-patchset-cb29449ba86b1b7d605c9b24417178739547505b.zip
Grsec/PaX: 2.2.2-2.6.32.56-201202032051 + 2.2.2-3.2.4-201202032052
-rw-r--r--2.6.32/0000_README6
-rw-r--r--2.6.32/1055_linux-2.6.32.56.patch716
-rw-r--r--2.6.32/4420_grsecurity-2.2.2-2.6.32.56-201202032051.patch (renamed from 2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch)620
-rw-r--r--2.6.32/4425_grsec-pax-without-grsec.patch6
-rw-r--r--2.6.32/4430_grsec-kconfig-default-gids.patch14
-rw-r--r--2.6.32/4435_grsec-kconfig-gentoo.patch4
-rw-r--r--2.6.32/4437-grsec-kconfig-proc-user.patch4
-rw-r--r--2.6.32/4440_selinux-avc_audit-log-curr_ip.patch2
-rw-r--r--3.2.2/1001_linux-3.2.2.patch6552
-rw-r--r--3.2.4/0000_README (renamed from 3.2.2/0000_README)10
-rw-r--r--3.2.4/1002_linux-3.2.3.patch3760
-rw-r--r--3.2.4/1003_linux-3.2.4.patch40
-rw-r--r--3.2.4/4420_grsecurity-2.2.2-3.2.4-201202032052.patch (renamed from 3.2.2/4420_grsecurity-2.2.2-3.2.2-201201272014.patch)996
-rw-r--r--3.2.4/4421_grsec-remove-localversion-grsec.patch (renamed from 3.2.2/4421_grsec-remove-localversion-grsec.patch)0
-rw-r--r--3.2.4/4422_grsec-mute-warnings.patch (renamed from 3.2.2/4422_grsec-mute-warnings.patch)0
-rw-r--r--3.2.4/4423_grsec-remove-protected-paths.patch (renamed from 3.2.2/4423_grsec-remove-protected-paths.patch)0
-rw-r--r--3.2.4/4425_grsec-pax-without-grsec.patch (renamed from 3.2.2/4425_grsec-pax-without-grsec.patch)0
-rw-r--r--3.2.4/4430_grsec-kconfig-default-gids.patch (renamed from 3.2.2/4430_grsec-kconfig-default-gids.patch)12
-rw-r--r--3.2.4/4435_grsec-kconfig-gentoo.patch (renamed from 3.2.2/4435_grsec-kconfig-gentoo.patch)2
-rw-r--r--3.2.4/4437-grsec-kconfig-proc-user.patch (renamed from 3.2.2/4437-grsec-kconfig-proc-user.patch)0
-rw-r--r--3.2.4/4440_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.2/4440_selinux-avc_audit-log-curr_ip.patch)2
-rw-r--r--3.2.4/4445_disable-compat_vdso.patch (renamed from 3.2.2/4445_disable-compat_vdso.patch)0
22 files changed, 5254 insertions, 7492 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README
index c4e9b3d..f0c7190 100644
--- a/2.6.32/0000_README
+++ b/2.6.32/0000_README
@@ -14,7 +14,11 @@ Patch: 1054_linux-2.6.32.55.patch
From: http://www.kernel.org
Desc: Linux 2.6.32.55
-Patch: 4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch
+Patch: 1055_linux-2.6.32.56.patch
+From: http://www.kernel.org
+Desc: Linux 2.6.32.56
+
+Patch: 4420_grsecurity-2.2.2-2.6.32.56-201202032051.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/2.6.32/1055_linux-2.6.32.56.patch b/2.6.32/1055_linux-2.6.32.56.patch
new file mode 100644
index 0000000..53aba88
--- /dev/null
+++ b/2.6.32/1055_linux-2.6.32.56.patch
@@ -0,0 +1,716 @@
+diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
+index 114ee29..2be0a97 100644
+--- a/block/scsi_ioctl.c
++++ b/block/scsi_ioctl.c
+@@ -24,6 +24,7 @@
+ #include <linux/capability.h>
+ #include <linux/completion.h>
+ #include <linux/cdrom.h>
++#include <linux/ratelimit.h>
+ #include <linux/slab.h>
+ #include <linux/times.h>
+ #include <asm/uaccess.h>
+@@ -689,9 +690,53 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
+ }
+ EXPORT_SYMBOL(scsi_cmd_ioctl);
+
++int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
++{
++ if (bd && bd == bd->bd_contains)
++ return 0;
++
++ /* Actually none of these is particularly useful on a partition,
++ * but they are safe.
++ */
++ switch (cmd) {
++ case SCSI_IOCTL_GET_IDLUN:
++ case SCSI_IOCTL_GET_BUS_NUMBER:
++ case SCSI_IOCTL_GET_PCI:
++ case SCSI_IOCTL_PROBE_HOST:
++ case SG_GET_VERSION_NUM:
++ case SG_SET_TIMEOUT:
++ case SG_GET_TIMEOUT:
++ case SG_GET_RESERVED_SIZE:
++ case SG_SET_RESERVED_SIZE:
++ case SG_EMULATED_HOST:
++ return 0;
++ case CDROM_GET_CAPABILITY:
++ /* Keep this until we remove the printk below. udev sends it
++ * and we do not want to spam dmesg about it. CD-ROMs do
++ * not have partitions, so we get here only for disks.
++ */
++ return -ENOTTY;
++ default:
++ break;
++ }
++
++ /* In particular, rule out all resets and host-specific ioctls. */
++ printk_ratelimited(KERN_WARNING
++ "%s: sending ioctl %x to a partition!\n", current->comm, cmd);
++
++ return capable(CAP_SYS_RAWIO) ? 0 : -ENOTTY;
++}
++EXPORT_SYMBOL(scsi_verify_blk_ioctl);
++
+ int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
+ unsigned int cmd, void __user *arg)
+ {
++ int ret;
++
++ ret = scsi_verify_blk_ioctl(bd, cmd);
++ if (ret < 0)
++ return ret;
++
+ return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
+ }
+ EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
+diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
+index 9ed9f60..88f160b 100644
+--- a/crypto/sha512_generic.c
++++ b/crypto/sha512_generic.c
+@@ -21,8 +21,6 @@
+ #include <linux/percpu.h>
+ #include <asm/byteorder.h>
+
+-static DEFINE_PER_CPU(u64[80], msg_schedule);
+-
+ static inline u64 Ch(u64 x, u64 y, u64 z)
+ {
+ return z ^ (x & (y ^ z));
+@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+
+ static inline void BLEND_OP(int I, u64 *W)
+ {
+- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
++ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
+ }
+
+ static void
+@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input)
+ u64 a, b, c, d, e, f, g, h, t1, t2;
+
+ int i;
+- u64 *W = get_cpu_var(msg_schedule);
++ u64 W[16];
+
+ /* load the input */
+ for (i = 0; i < 16; i++)
+ LOAD_OP(i, W, input);
+
+- for (i = 16; i < 80; i++) {
+- BLEND_OP(i, W);
+- }
+-
+ /* 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];
+
+- /* now iterate */
+- for (i=0; i<80; i+=8) {
+- 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;
+- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+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+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+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+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+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+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+7];
+- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
++#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);
+ }
+
+ state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input)
+
+ /* erase our data */
+ a = b = c = d = e = f = g = h = t1 = t2 = 0;
+- memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
+- put_cpu_var(msg_schedule);
+ }
+
+ static int
+diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
+index 932b5aa..d676d49 100644
+--- a/drivers/gpu/drm/drm_auth.c
++++ b/drivers/gpu/drm/drm_auth.c
+@@ -102,7 +102,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv,
+ * Searches and unlinks the entry in drm_device::magiclist with the magic
+ * number hash key, while holding the drm_device::struct_mutex lock.
+ */
+-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
++int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+ {
+ struct drm_magic_entry *pt;
+ struct drm_hash_item *hash;
+@@ -137,6 +137,8 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+ * If there is a magic number in drm_file::magic then use it, otherwise
+ * searches an unique non-zero magic number and add it associating it with \p
+ * file_priv.
++ * This ioctl needs protection by the drm_global_mutex, which protects
++ * struct drm_file::magic and struct drm_magic_entry::priv.
+ */
+ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ {
+@@ -174,6 +176,8 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ * \return zero if authentication successed, or a negative number otherwise.
+ *
+ * Checks if \p file_priv is associated with the magic number passed in \arg.
++ * This ioctl needs protection by the drm_global_mutex, which protects
++ * struct drm_file::magic and struct drm_magic_entry::priv.
+ */
+ int drm_authmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
+index ba14553..519161e 100644
+--- a/drivers/gpu/drm/drm_fops.c
++++ b/drivers/gpu/drm/drm_fops.c
+@@ -449,6 +449,11 @@ int drm_release(struct inode *inode, struct file *filp)
+ (long)old_encode_dev(file_priv->minor->device),
+ dev->open_count);
+
++ /* Release any auth tokens that might point to this file_priv,
++ (do that under the drm_global_mutex) */
++ if (file_priv->magic)
++ (void) drm_remove_magic(file_priv->master, file_priv->magic);
++
+ /* if the master has gone away we can't do anything with the lock */
+ if (file_priv->minor->master)
+ drm_master_release(dev, filp);
+diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
+index 525a00b..15645ab 100644
+--- a/drivers/hwmon/f71805f.c
++++ b/drivers/hwmon/f71805f.c
+@@ -281,11 +281,11 @@ static inline long temp_from_reg(u8 reg)
+
+ static inline u8 temp_to_reg(long val)
+ {
+- if (val < 0)
+- val = 0;
+- else if (val > 1000 * 0xff)
+- val = 0xff;
+- return ((val + 500) / 1000);
++ if (val <= 0)
++ return 0;
++ if (val >= 1000 * 0xff)
++ return 0xff;
++ return (val + 500) / 1000;
+ }
+
+ /*
+diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
+index 2040507..740785e 100644
+--- a/drivers/hwmon/sht15.c
++++ b/drivers/hwmon/sht15.c
+@@ -515,7 +515,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb,
+
+ static int __devinit sht15_probe(struct platform_device *pdev)
+ {
+- int ret = 0;
++ int ret;
+ struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+
+ if (!data) {
+@@ -532,6 +532,7 @@ static int __devinit sht15_probe(struct platform_device *pdev)
+ init_waitqueue_head(&data->wait_queue);
+
+ if (pdev->dev.platform_data == NULL) {
++ ret = -EINVAL;
+ dev_err(&pdev->dev, "no platform data supplied");
+ goto err_free_data;
+ }
+diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
+index 82f7d6e..7ab302d 100644
+--- a/drivers/md/dm-linear.c
++++ b/drivers/md/dm-linear.c
+@@ -116,7 +116,17 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
+ unsigned long arg)
+ {
+ struct linear_c *lc = (struct linear_c *) ti->private;
+- return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg);
++ struct dm_dev *dev = lc->dev;
++ int r = 0;
++
++ /*
++ * Only pass ioctls through if the device sizes match exactly.
++ */
++ if (lc->start ||
++ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
++ r = scsi_verify_blk_ioctl(NULL, cmd);
++
++ return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
+ }
+
+ static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index b03cd39..4ec5fe2 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -1464,6 +1464,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
+
+ spin_unlock_irqrestore(&m->lock, flags);
+
++ /*
++ * Only pass ioctls through if the device sizes match exactly.
++ */
++ if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
++ r = scsi_verify_blk_ioctl(NULL, cmd);
++
+ return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+ }
+
+diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
+index 68d800f..705a589 100644
+--- a/drivers/mmc/host/mmci.c
++++ b/drivers/mmc/host/mmci.c
+@@ -232,12 +232,8 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
+ }
+
+ if (!cmd->data || cmd->error) {
+- if (host->data) {
+- /* Terminate the DMA transfer */
+- if (dma_inprogress(host))
+- mmci_dma_data_error(host);
++ if (host->data)
+ mmci_stop_data(host);
+- }
+ mmci_request_end(host, cmd->mrq);
+ } else if (!(cmd->data->flags & MMC_DATA_READ)) {
+ mmci_start_data(host, cmd->data);
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index 2dd1b73..a5b55fe 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -817,6 +817,10 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
+ SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
+ disk->disk_name, cmd));
+
++ error = scsi_verify_blk_ioctl(bdev, cmd);
++ if (error < 0)
++ return error;
++
+ /*
+ * If we are in the middle of error recovery, don't let anyone
+ * else try and use this device. Also, if error recovery fails, it
+@@ -996,6 +1000,11 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+ {
+ struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device;
++ int ret;
++
++ ret = scsi_verify_blk_ioctl(bdev, cmd);
++ if (ret < 0)
++ return -ENOIOCTLCMD;
+
+ /*
+ * If we are in the middle of error recovery, don't let anyone
+@@ -1007,8 +1016,6 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
+ return -ENODEV;
+
+ if (sdev->host->hostt->compat_ioctl) {
+- int ret;
+-
+ ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
+
+ return ret;
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index 696ca75f..d71514b 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -458,7 +458,9 @@ retry:
+ for (i = 0; i < desc->length - cntr; i++)
+ desc->ubuf[i] = desc->ubuf[i + cntr];
+
++ spin_lock_irq(&desc->iuspin);
+ desc->length -= cntr;
++ spin_unlock_irq(&desc->iuspin);
+ /* in case we had outstanding data */
+ if (!desc->length)
+ clear_bit(WDM_READ, &desc->flags);
+diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
+index cd8726c..6bc0bf3 100644
+--- a/drivers/usb/misc/usbsevseg.c
++++ b/drivers/usb/misc/usbsevseg.c
+@@ -24,7 +24,7 @@
+
+ #define VENDOR_ID 0x0fc5
+ #define PRODUCT_ID 0x1227
+-#define MAXLEN 6
++#define MAXLEN 8
+
+ /* table of devices that work with this driver */
+ static struct usb_device_id id_table[] = {
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 8dcaf42..bb16725 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -140,6 +140,7 @@ static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
++ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
+ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
+ { } /* Terminating Entry */
+ };
+@@ -360,8 +361,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port,
+ * Quantises the baud rate as per AN205 Table 1
+ */
+ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
+- if (baud <= 56) baud = 0;
+- else if (baud <= 300) baud = 300;
++ if (baud <= 300)
++ baud = 300;
+ else if (baud <= 600) baud = 600;
+ else if (baud <= 1200) baud = 1200;
+ else if (baud <= 1800) baud = 1800;
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 5ce2cb9..85d630e 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -798,6 +798,7 @@ static struct usb_device_id id_table_combined [] = {
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) },
+ { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+ { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+@@ -806,6 +807,8 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID),
++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
+@@ -842,6 +845,7 @@ static struct usb_device_id id_table_combined [] = {
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
++ { USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
+ { }, /* Optional parameter entry */
+ { } /* Terminating entry */
+ };
+@@ -1351,8 +1355,7 @@ static int set_serial_info(struct tty_struct *tty,
+ goto check_and_exit;
+ }
+
+- if ((new_serial.baud_base != priv->baud_base) &&
+- (new_serial.baud_base < 9600)) {
++ if (new_serial.baud_base != priv->baud_base) {
+ unlock_kernel();
+ return -EINVAL;
+ }
+@@ -1865,6 +1868,7 @@ static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
+
+ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
+ { /* ftdi_open */
++ struct ktermios dummy;
+ struct usb_device *dev = port->serial->dev;
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+@@ -1892,8 +1896,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
+ This is same behaviour as serial.c/rs_open() - Kuba */
+
+ /* ftdi_set_termios will send usb control messages */
+- if (tty)
+- ftdi_set_termios(tty, port, tty->termios);
++ if (tty) {
++ memset(&dummy, 0, sizeof(dummy));
++ ftdi_set_termios(tty, port, &dummy);
++ }
+
+ /* Not throttled */
+ spin_lock_irqsave(&port->lock, flags);
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 8ce1bcb..212fc41 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -38,6 +38,13 @@
+ /* www.candapter.com Ewert Energy Systems CANdapter device */
+ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
+
++/*
++ * Texas Instruments XDS100v2 JTAG / BeagleBone A3
++ * http://processors.wiki.ti.com/index.php/XDS100
++ * http://beagleboard.org/bone
++ */
++#define TI_XDS100V2_PID 0xa6d0
++
+ #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */
+
+ /* US Interface Navigator (http://www.usinterface.com/) */
+@@ -524,6 +531,12 @@
+ #define ADI_GNICEPLUS_PID 0xF001
+
+ /*
++ * Hornby Elite
++ */
++#define HORNBY_VID 0x04D8
++#define HORNBY_ELITE_PID 0x000A
++
++/*
+ * RATOC REX-USB60F
+ */
+ #define RATOC_VENDOR_ID 0x0584
+@@ -1173,3 +1186,9 @@
+ */
+ /* TagTracer MIFARE*/
+ #define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0
++
++/*
++ * Rainforest Automation
++ */
++/* ZigBee controller */
++#define FTDI_RF_R106 0x8A28
+diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
+index fbdbac5..14d51e6 100644
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2664,15 +2664,7 @@ cleanup:
+
+ static void edge_disconnect(struct usb_serial *serial)
+ {
+- int i;
+- struct edgeport_port *edge_port;
+-
+ dbg("%s", __func__);
+-
+- for (i = 0; i < serial->num_ports; ++i) {
+- edge_port = usb_get_serial_port_data(serial->port[i]);
+- edge_remove_sysfs_attrs(edge_port->port);
+- }
+ }
+
+ static void edge_release(struct usb_serial *serial)
+@@ -2927,6 +2919,7 @@ static struct usb_serial_driver edgeport_1port_device = {
+ .disconnect = edge_disconnect,
+ .release = edge_release,
+ .port_probe = edge_create_sysfs_attrs,
++ .port_remove = edge_remove_sysfs_attrs,
+ .ioctl = edge_ioctl,
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+@@ -2957,6 +2950,7 @@ static struct usb_serial_driver edgeport_2port_device = {
+ .disconnect = edge_disconnect,
+ .release = edge_release,
+ .port_probe = edge_create_sysfs_attrs,
++ .port_remove = edge_remove_sysfs_attrs,
+ .ioctl = edge_ioctl,
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
+index 443947f..7a5f1ac 100644
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -1609,7 +1609,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
+ rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
+ if (rc) {
+ printk(KERN_DEBUG "Valid eCryptfs headers not found in "
+- "file header region or xattr region\n");
++ "file header region or xattr region, inode %lu\n",
++ ecryptfs_inode->i_ino);
+ rc = -EINVAL;
+ goto out;
+ }
+@@ -1618,7 +1619,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
+ ECRYPTFS_DONT_VALIDATE_HEADER_SIZE);
+ if (rc) {
+ printk(KERN_DEBUG "Valid eCryptfs headers not found in "
+- "file xattr region either\n");
++ "file xattr region either, inode %lu\n",
++ ecryptfs_inode->i_ino);
+ rc = -EINVAL;
+ }
+ if (crypt_stat->mount_crypt_stat->flags
+@@ -1629,7 +1631,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
+ "crypto metadata only in the extended attribute "
+ "region, but eCryptfs was mounted without "
+ "xattr support enabled. eCryptfs will not treat "
+- "this like an encrypted file.\n");
++ "this like an encrypted file, inode %lu\n",
++ ecryptfs_inode->i_ino);
+ rc = -EINVAL;
+ }
+ }
+diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
+index 4ec8f61..c4b0bc5 100644
+--- a/fs/ecryptfs/miscdev.c
++++ b/fs/ecryptfs/miscdev.c
+@@ -408,11 +408,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
+ ssize_t sz = 0;
+ char *data;
+ uid_t euid = current_euid();
++ unsigned char packet_size_peek[3];
+ int rc;
+
+- if (count == 0)
++ if (count == 0) {
+ goto out;
++ } else if (count == (1 + 4)) {
++ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
++ goto memdup;
++ } else if (count < (1 + 4 + 1)
++ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
++ printk(KERN_WARNING "%s: Acceptable packet size range is "
++ "[%d-%lu], but amount of data written is [%zu].",
++ __func__, (1 + 4 + 1),
++ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
++ return -EINVAL;
++ }
++
++ if (copy_from_user(packet_size_peek, (buf + 1 + 4),
++ sizeof(packet_size_peek))) {
++ printk(KERN_WARNING "%s: Error while inspecting packet size\n",
++ __func__);
++ return -EFAULT;
++ }
++
++ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
++ &packet_size_length);
++ if (rc) {
++ printk(KERN_WARNING "%s: Error parsing packet length; "
++ "rc = [%d]\n", __func__, rc);
++ return rc;
++ }
++
++ if ((1 + 4 + packet_size_length + packet_size) != count) {
++ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
++ packet_size);
++ return -EINVAL;
++ }
+
++memdup:
+ data = memdup_user(buf, count);
+ if (IS_ERR(data)) {
+ printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
+@@ -434,23 +470,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
+ }
+ memcpy(&counter_nbo, &data[i], 4);
+ seq = be32_to_cpu(counter_nbo);
+- i += 4;
+- rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
+- &packet_size_length);
+- if (rc) {
+- printk(KERN_WARNING "%s: Error parsing packet length; "
+- "rc = [%d]\n", __func__, rc);
+- goto out_free;
+- }
+- i += packet_size_length;
+- if ((1 + 4 + packet_size_length + packet_size) != count) {
+- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
+- " + packet_size([%zd]))([%zd]) != "
+- "count([%zd]). Invalid packet format.\n",
+- __func__, packet_size_length, packet_size,
+- (1 + packet_size_length + packet_size), count);
+- goto out_free;
+- }
++ i += 4 + packet_size_length;
+ rc = ecryptfs_miscdev_response(&data[i], packet_size,
+ euid, current_user_ns(),
+ task_pid(current), seq);
+diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
+index 0cc4faf..6b78546 100644
+--- a/fs/ecryptfs/read_write.c
++++ b/fs/ecryptfs/read_write.c
+@@ -136,6 +136,11 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
+ size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
+ size_t total_remaining_bytes = ((offset + size) - pos);
+
++ if (fatal_signal_pending(current)) {
++ rc = -EINTR;
++ break;
++ }
++
+ if (num_bytes > total_remaining_bytes)
+ num_bytes = total_remaining_bytes;
+ if (pos < offset) {
+@@ -197,15 +202,19 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
+ }
+ pos += num_bytes;
+ }
+- if ((offset + size) > ecryptfs_file_size) {
+- i_size_write(ecryptfs_inode, (offset + size));
++ if (pos > ecryptfs_file_size) {
++ i_size_write(ecryptfs_inode, pos);
+ if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
+- rc = ecryptfs_write_inode_size_to_metadata(
++ int rc2;
++
++ rc2 = ecryptfs_write_inode_size_to_metadata(
+ ecryptfs_inode);
+- if (rc) {
++ if (rc2) {
+ printk(KERN_ERR "Problem with "
+ "ecryptfs_write_inode_size_to_metadata; "
+- "rc = [%d]\n", rc);
++ "rc = [%d]\n", rc2);
++ if (!rc)
++ rc = rc2;
+ goto out;
+ }
+ }
+diff --git a/include/drm/drmP.h b/include/drm/drmP.h
+index 66713c6..ebab6a6 100644
+--- a/include/drm/drmP.h
++++ b/include/drm/drmP.h
+@@ -1221,6 +1221,7 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_authmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
++extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);
+
+ /* Cache management (drm_cache.c) */
+ void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 63070ad..5eb6cb0 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -777,6 +777,7 @@ extern void blk_plug_device(struct request_queue *);
+ extern void blk_plug_device_unlocked(struct request_queue *);
+ extern int blk_remove_plug(struct request_queue *);
+ extern void blk_recount_segments(struct request_queue *, struct bio *);
++extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
+ extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
+ unsigned int, void __user *);
+ extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
diff --git a/2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch b/2.6.32/4420_grsecurity-2.2.2-2.6.32.56-201202032051.patch
index 4b8b2b0..c0e9b3a 100644
--- a/2.6.32/4420_grsecurity-2.2.2-2.6.32.55-201201272054.patch
+++ b/2.6.32/4420_grsecurity-2.2.2-2.6.32.56-201202032051.patch
@@ -185,7 +185,7 @@ index c840e7d..f4c451c 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 64d4fc6..3b32f7f 100644
+index 81ad738..cbdaeb0 100644
--- a/Makefile
+++ b/Makefile
@@ -221,8 +221,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -13949,10 +13949,18 @@ index ef3cd31..9d2f6ab 100644
.store = store,
};
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
-index 5c0e653..1e82c7c 100644
+index 5c0e653..0882b0a 100644
--- a/arch/x86/kernel/cpu/mcheck/p5.c
+++ b/arch/x86/kernel/cpu/mcheck/p5.c
-@@ -50,7 +50,9 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+@@ -12,6 +12,7 @@
+ #include <asm/system.h>
+ #include <asm/mce.h>
+ #include <asm/msr.h>
++#include <asm/pgtable.h>
+
+ /* By default disabled */
+ int mce_p5_enabled __read_mostly;
+@@ -50,7 +51,9 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
if (!cpu_has(c, X86_FEATURE_MCE))
return;
@@ -13963,10 +13971,18 @@ index 5c0e653..1e82c7c 100644
wmb();
diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c
-index 54060f5..e6ba93d 100644
+index 54060f5..c1a7577 100644
--- a/arch/x86/kernel/cpu/mcheck/winchip.c
+++ b/arch/x86/kernel/cpu/mcheck/winchip.c
-@@ -24,7 +24,9 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c)
+@@ -11,6 +11,7 @@
+ #include <asm/system.h>
+ #include <asm/mce.h>
+ #include <asm/msr.h>
++#include <asm/pgtable.h>
+
+ /* Machine check handler for WinChip C6: */
+ static void winchip_machine_check(struct pt_regs *regs, long error_code)
+@@ -24,7 +25,9 @@ void winchip_mcheck_init(struct cpuinfo_x86 *c)
{
u32 lo, hi;
@@ -25343,7 +25359,7 @@ index 84e236c..69bd3f6 100644
return (void *)vaddr;
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
-index 2feb9bd..3646202 100644
+index 2feb9bd..ab91e7b 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -41,8 +41,8 @@ int page_is_ram(unsigned long pagenr)
@@ -25373,7 +25389,17 @@ index 2feb9bd..3646202 100644
return NULL;
WARN_ON_ONCE(is_ram);
}
-@@ -407,7 +404,7 @@ static int __init early_ioremap_debug_setup(char *str)
+@@ -378,6 +375,9 @@ void *xlate_dev_mem_ptr(unsigned long phys)
+
+ /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
+ if (page_is_ram(start >> PAGE_SHIFT))
++#ifdef CONFIG_HIGHMEM
++ if ((start >> PAGE_SHIFT) < max_low_pfn)
++#endif
+ return __va(phys);
+
+ addr = (void __force *)ioremap_default(start, PAGE_SIZE);
+@@ -407,7 +407,7 @@ static int __init early_ioremap_debug_setup(char *str)
early_param("early_ioremap_debug", early_ioremap_debug_setup);
static __initdata int after_paging_init;
@@ -25382,7 +25408,7 @@ index 2feb9bd..3646202 100644
static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
{
-@@ -439,8 +436,7 @@ void __init early_ioremap_init(void)
+@@ -439,8 +439,7 @@ void __init early_ioremap_init(void)
slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
@@ -27300,18 +27326,10 @@ index a847046..75a1746 100644
.store = elv_attr_store,
};
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
-index 114ee29..d0efa50 100644
+index 2be0a97..bded3fd 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
-@@ -24,6 +24,7 @@
- #include <linux/capability.h>
- #include <linux/completion.h>
- #include <linux/cdrom.h>
-+#include <linux/ratelimit.h>
- #include <linux/slab.h>
- #include <linux/times.h>
- #include <asm/uaccess.h>
-@@ -220,8 +221,20 @@ EXPORT_SYMBOL(blk_verify_command);
+@@ -221,8 +221,20 @@ EXPORT_SYMBOL(blk_verify_command);
static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
struct sg_io_hdr *hdr, fmode_t mode)
{
@@ -27333,7 +27351,7 @@ index 114ee29..d0efa50 100644
if (blk_verify_command(rq->cmd, mode & FMODE_WRITE))
return -EPERM;
-@@ -430,6 +443,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
+@@ -431,6 +443,8 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
int err;
unsigned int in_len, out_len, bytes, opcode, cmdlen;
char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
@@ -27342,7 +27360,7 @@ index 114ee29..d0efa50 100644
if (!sic)
return -EINVAL;
-@@ -463,9 +478,18 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
+@@ -464,9 +478,18 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
*/
err = -EFAULT;
rq->cmd_len = cmdlen;
@@ -27362,61 +27380,6 @@ index 114ee29..d0efa50 100644
if (in_len && copy_from_user(buffer, sic->data + cmdlen, in_len))
goto error;
-@@ -689,9 +713,54 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
- }
- EXPORT_SYMBOL(scsi_cmd_ioctl);
-
-+int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
-+{
-+ if (bd && bd == bd->bd_contains)
-+ return 0;
-+
-+ /* Actually none of these is particularly useful on a partition,
-+ * but they are safe.
-+ */
-+ switch (cmd) {
-+ case SCSI_IOCTL_GET_IDLUN:
-+ case SCSI_IOCTL_GET_BUS_NUMBER:
-+ case SCSI_IOCTL_GET_PCI:
-+ case SCSI_IOCTL_PROBE_HOST:
-+ case SG_GET_VERSION_NUM:
-+ case SG_SET_TIMEOUT:
-+ case SG_GET_TIMEOUT:
-+ case SG_GET_RESERVED_SIZE:
-+ case SG_SET_RESERVED_SIZE:
-+ case SG_EMULATED_HOST:
-+ return 0;
-+ case CDROM_GET_CAPABILITY:
-+ /* Keep this until we remove the printk below. udev sends it
-+ * and we do not want to spam dmesg about it. CD-ROMs do
-+ * not have partitions, so we get here only for disks.
-+ */
-+ return -ENOIOCTLCMD;
-+ default:
-+ break;
-+ }
-+
-+ /* In particular, rule out all resets and host-specific ioctls. */
-+ if (printk_ratelimit())
-+ printk(KERN_WARNING "%s: sending ioctl %x to a partition!\n",
-+ current->comm, cmd);
-+
-+ return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD;
-+}
-+EXPORT_SYMBOL(scsi_verify_blk_ioctl);
-+
- int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
- unsigned int cmd, void __user *arg)
- {
-+ int ret;
-+
-+ ret = scsi_verify_blk_ioctl(bd, cmd);
-+ if (ret < 0)
-+ return ret;
-+
- return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
- }
- EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 3533582..f143117 100644
--- a/crypto/cryptd.c
@@ -27473,109 +27436,6 @@ index b651a55..023297d 100644
/* Copy key, add padding */
for (i = 0; i < keylen; ++i)
-diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
-index 9ed9f60..88f160b 100644
---- a/crypto/sha512_generic.c
-+++ b/crypto/sha512_generic.c
-@@ -21,8 +21,6 @@
- #include <linux/percpu.h>
- #include <asm/byteorder.h>
-
--static DEFINE_PER_CPU(u64[80], msg_schedule);
--
- static inline u64 Ch(u64 x, u64 y, u64 z)
- {
- return z ^ (x & (y ^ z));
-@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
-
- static inline void BLEND_OP(int I, u64 *W)
- {
-- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
-+ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
- }
-
- static void
-@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input)
- u64 a, b, c, d, e, f, g, h, t1, t2;
-
- int i;
-- u64 *W = get_cpu_var(msg_schedule);
-+ u64 W[16];
-
- /* load the input */
- for (i = 0; i < 16; i++)
- LOAD_OP(i, W, input);
-
-- for (i = 16; i < 80; i++) {
-- BLEND_OP(i, W);
-- }
--
- /* 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];
-
-- /* now iterate */
-- for (i=0; i<80; i+=8) {
-- 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;
-- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+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+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+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+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+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+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+7];
-- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
-+#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);
- }
-
- state[0] += a; state[1] += b; state[2] += c; state[3] += d;
-@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input)
-
- /* erase our data */
- a = b = c = d = e = f = g = h = t1 = t2 = 0;
-- memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
-- put_cpu_var(msg_schedule);
- }
-
- static int
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 0d2cdb8..d8de48d 100644
--- a/drivers/acpi/acpi_pad.c
@@ -31876,9 +31736,18 @@ index bf2170f..ce8cab9 100644
acpi_os_unmap_memory(virt, len);
return 0;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
-index 123cedf..137edef 100644
+index 123cedf..6664cb4 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
+@@ -146,7 +146,7 @@ static int tty_open(struct inode *, struct file *);
+ static int tty_release(struct inode *, struct file *);
+ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+ #ifdef CONFIG_COMPAT
+-static long tty_compat_ioctl(struct file *file, unsigned int cmd,
++long tty_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
+ #else
+ #define tty_compat_ioctl NULL
@@ -1774,6 +1774,7 @@ got_driver:
if (IS_ERR(tty)) {
@@ -32792,7 +32661,7 @@ index 0e27d98..dec8768 100644
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
-index ba14553..182d0bb 100644
+index 519161e..98c840c 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -66,7 +66,7 @@ static int drm_setup(struct drm_device * dev)
@@ -32832,9 +32701,9 @@ index ba14553..182d0bb 100644
- dev->open_count);
+ local_read(&dev->open_count));
- /* if the master has gone away we can't do anything with the lock */
- if (file_priv->minor->master)
-@@ -524,9 +524,9 @@ int drm_release(struct inode *inode, struct file *filp)
+ /* Release any auth tokens that might point to this file_priv,
+ (do that under the drm_global_mutex) */
+@@ -529,9 +529,9 @@ int drm_release(struct inode *inode, struct file *filp)
* End inline drm_release
*/
@@ -34105,7 +33974,7 @@ index 7cdd76f..fe0efdf 100644
int ycalib; /* calibrated null value for y */
int zcalib; /* calibrated null value for z */
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
-index 2040507..706ec1e 100644
+index 740785e..5a5c6c6 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -112,7 +112,7 @@ struct sht15_data {
@@ -41626,42 +41495,6 @@ index 21a045e..ec89e03 100644
dev_set_name(&rport->dev, "port-%d:%d", shost->host_no, id);
transport_setup_device(&rport->dev);
-diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
-index 2dd1b73..fd8145f 100644
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -817,6 +817,10 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
- SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
- disk->disk_name, cmd));
-
-+ error = scsi_verify_blk_ioctl(bdev, cmd);
-+ if (error < 0)
-+ return error;
-+
- /*
- * If we are in the middle of error recovery, don't let anyone
- * else try and use this device. Also, if error recovery fails, it
-@@ -996,6 +1000,11 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
- {
- struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device;
-+ int ret;
-+
-+ ret = scsi_verify_blk_ioctl(bdev, cmd);
-+ if (ret < 0)
-+ return ret;
-
- /*
- * If we are in the middle of error recovery, don't let anyone
-@@ -1007,8 +1016,6 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
- return -ENODEV;
-
- if (sdev->host->hostt->compat_ioctl) {
-- int ret;
--
- ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
-
- return ret;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 040f751..98a5ed2 100644
--- a/drivers/scsi/sg.c
@@ -48429,6 +48262,22 @@ index 44c0aea..2529092 100644
dcache_init();
inode_init();
+diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
+index 39c6ee8..dcee0f1 100644
+--- a/fs/debugfs/inode.c
++++ b/fs/debugfs/inode.c
+@@ -269,7 +269,11 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
+ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
+ {
+ return debugfs_create_file(name,
++#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
++ S_IFDIR | S_IRWXU,
++#else
+ S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
++#endif
+ parent, NULL, NULL);
+ }
+ EXPORT_SYMBOL_GPL(debugfs_create_dir);
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index c010ecf..a8d8c59 100644
--- a/fs/dlm/lockspace.c
@@ -48443,7 +48292,7 @@ index c010ecf..a8d8c59 100644
.store = dlm_attr_store,
};
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
-index 443947f..a871402 100644
+index 7a5f1ac..205b034 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -418,17 +418,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
@@ -48497,20 +48346,20 @@ index 443947f..a871402 100644
rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
(extent_offset
* crypt_stat->extent_size),
-@@ -569,6 +539,7 @@ static int ecryptfs_decrypt_extent(struct page *page,
+@@ -569,16 +539,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
goto out;
}
rc = 0;
-+<<<<<<< HEAD
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; "
- "rc = [%d]\n", (extent_base + extent_offset),
-@@ -579,6 +550,8 @@ static int ecryptfs_decrypt_extent(struct page *page,
- + (extent_offset
- * crypt_stat->extent_size)), 8);
- }
-+=======
-+>>>>>>> 58ded24... eCryptfs: Fix oops when printing debug info in extent crypto functions
+- if (unlikely(ecryptfs_verbosity > 0)) {
+- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; "
+- "rc = [%d]\n", (extent_base + extent_offset),
+- rc);
+- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+- "decryption:\n");
+- ecryptfs_dump_hex((char *)(page_address(page)
+- + (extent_offset
+- * crypt_stat->extent_size)), 8);
+- }
out:
return rc;
}
@@ -48536,89 +48385,11 @@ index 88ba4d4..073f003 100644
set_fs(old_fs);
if (rc < 0)
goto out_free;
-diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
-index 4ec8f61..c4b0bc5 100644
---- a/fs/ecryptfs/miscdev.c
-+++ b/fs/ecryptfs/miscdev.c
-@@ -408,11 +408,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
- ssize_t sz = 0;
- char *data;
- uid_t euid = current_euid();
-+ unsigned char packet_size_peek[3];
- int rc;
-
-- if (count == 0)
-+ if (count == 0) {
- goto out;
-+ } else if (count == (1 + 4)) {
-+ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
-+ goto memdup;
-+ } else if (count < (1 + 4 + 1)
-+ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
-+ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
-+ printk(KERN_WARNING "%s: Acceptable packet size range is "
-+ "[%d-%lu], but amount of data written is [%zu].",
-+ __func__, (1 + 4 + 1),
-+ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
-+ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
-+ return -EINVAL;
-+ }
-
-+ if (copy_from_user(packet_size_peek, (buf + 1 + 4),
-+ sizeof(packet_size_peek))) {
-+ printk(KERN_WARNING "%s: Error while inspecting packet size\n",
-+ __func__);
-+ return -EFAULT;
-+ }
-+
-+ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
-+ &packet_size_length);
-+ if (rc) {
-+ printk(KERN_WARNING "%s: Error parsing packet length; "
-+ "rc = [%d]\n", __func__, rc);
-+ return rc;
-+ }
-+
-+ if ((1 + 4 + packet_size_length + packet_size) != count) {
-+ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
-+ packet_size);
-+ return -EINVAL;
-+ }
-+
-+memdup:
- data = memdup_user(buf, count);
- if (IS_ERR(data)) {
- printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
-@@ -434,23 +470,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
- }
- memcpy(&counter_nbo, &data[i], 4);
- seq = be32_to_cpu(counter_nbo);
-- i += 4;
-- rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
-- &packet_size_length);
-- if (rc) {
-- printk(KERN_WARNING "%s: Error parsing packet length; "
-- "rc = [%d]\n", __func__, rc);
-- goto out_free;
-- }
-- i += packet_size_length;
-- if ((1 + 4 + packet_size_length + packet_size) != count) {
-- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
-- " + packet_size([%zd]))([%zd]) != "
-- "count([%zd]). Invalid packet format.\n",
-- __func__, packet_size_length, packet_size,
-- (1 + packet_size_length + packet_size), count);
-- goto out_free;
-- }
-+ i += 4 + packet_size_length;
- rc = ecryptfs_miscdev_response(&data[i], packet_size,
- euid, current_user_ns(),
- task_pid(current), seq);
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
-index 0cc4faf..0404659 100644
+index 6b78546..7ba3260 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
-@@ -134,13 +134,18 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
+@@ -134,7 +134,12 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
@@ -48630,7 +48401,9 @@ index 0cc4faf..0404659 100644
+ break;
+ }
- if (num_bytes > total_remaining_bytes)
+ if (fatal_signal_pending(current)) {
+ rc = -EINTR;
+@@ -145,7 +150,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
num_bytes = total_remaining_bytes;
if (pos < offset) {
/* remaining zeros to write, up to destination offset */
@@ -48639,31 +48412,6 @@ index 0cc4faf..0404659 100644
if (num_bytes > total_remaining_zeros)
num_bytes = total_remaining_zeros;
-@@ -197,15 +202,19 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
- }
- pos += num_bytes;
- }
-- if ((offset + size) > ecryptfs_file_size) {
-- i_size_write(ecryptfs_inode, (offset + size));
-+ if (pos > ecryptfs_file_size) {
-+ i_size_write(ecryptfs_inode, pos);
- if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
-- rc = ecryptfs_write_inode_size_to_metadata(
-+ int rc2;
-+
-+ rc2 = ecryptfs_write_inode_size_to_metadata(
- ecryptfs_inode);
-- if (rc) {
-+ if (rc2) {
- printk(KERN_ERR "Problem with "
- "ecryptfs_write_inode_size_to_metadata; "
-- "rc = [%d]\n", rc);
-+ "rc = [%d]\n", rc2);
-+ if (!rc)
-+ rc = rc2;
- goto out;
- }
- }
diff --git a/fs/exec.c b/fs/exec.c
index 86fafc6..5033350 100644
--- a/fs/exec.c
@@ -54633,6 +54381,29 @@ index bb92b7c..5aa72b0 100644
ret = -EAGAIN;
pipe_unlock(ipipe);
+diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
+index e020183..18d64b4 100644
+--- a/fs/sysfs/dir.c
++++ b/fs/sysfs/dir.c
+@@ -678,6 +678,18 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
+ struct sysfs_dirent *sd;
+ int rc;
+
++#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
++ const char *parent_name = parent_sd->s_name;
++
++ mode = S_IFDIR | S_IRWXU;
++
++ if ((!strcmp(parent_name, "") && (!strcmp(name, "devices") || !strcmp(name, "fs"))) ||
++ (!strcmp(parent_name, "devices") && !strcmp(name, "system")) ||
++ (!strcmp(parent_name, "fs") && (!strcmp(name, "selinux") || !strcmp(name, "fuse"))) ||
++ (!strcmp(parent_name, "system") && !strcmp(name, "cpu")))
++ mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
++#endif
++
+ /* allocate */
+ sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
+ if (!sd)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 7118a38..70af853 100644
--- a/fs/sysfs/file.c
@@ -54718,22 +54489,6 @@ index 7118a38..70af853 100644
wake_up_interruptible(&od->poll);
}
-diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
-index 4974995..c26609c 100644
---- a/fs/sysfs/mount.c
-+++ b/fs/sysfs/mount.c
-@@ -36,7 +36,11 @@ struct sysfs_dirent sysfs_root = {
- .s_name = "",
- .s_count = ATOMIC_INIT(1),
- .s_flags = SYSFS_DIR,
-+#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
-+ .s_mode = S_IFDIR | S_IRWXU,
-+#else
- .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-+#endif
- .s_ino = 1,
- };
-
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c5081ad..342ea86 100644
--- a/fs/sysfs/symlink.c
@@ -55023,10 +54778,10 @@ index 8f32f50..b6a41e8 100644
link[pathlen] = '\0';
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..883b00b
+index 0000000..8cac8cb
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1064 @@
+@@ -0,0 +1,1068 @@
+#
+# grecurity configuration
+#
@@ -55496,15 +55251,19 @@ index 0000000..883b00b
+ depends on SYSFS
+ help
+ If you say Y here, sysfs (the pseudo-filesystem mounted at /sys) and
-+ any filesystem normally mounted under it (e.g. debugfs) will only
-+ be accessible by root. These filesystems generally provide access
++ any filesystem normally mounted under it (e.g. debugfs) will be
++ mostly accessible only by root. These filesystems generally provide access
+ to hardware and debug information that isn't appropriate for unprivileged
+ users of the system. Sysfs and debugfs have also become a large source
+ of new vulnerabilities, ranging from infoleaks to local compromise.
+ There has been very little oversight with an eye toward security involved
+ in adding new exporters of information to these filesystems, so their
+ use is discouraged.
-+ This option is equivalent to a chmod 0700 of the mount paths.
++ For reasons of compatibility, a few directories have been whitelisted
++ for access by non-root users:
++ /sys/fs/selinux
++ /sys/fs/fuse
++ /sys/devices/system/cpu
+
+config GRKERNSEC_ROFS
+ bool "Runtime read-only mount protection"
@@ -64946,10 +64705,10 @@ index 0000000..0dc13c3
+EXPORT_SYMBOL(gr_log_timechange);
diff --git a/grsecurity/grsec_tpe.c b/grsecurity/grsec_tpe.c
new file mode 100644
-index 0000000..4a78774
+index 0000000..a35ba33
--- /dev/null
+++ b/grsecurity/grsec_tpe.c
-@@ -0,0 +1,39 @@
+@@ -0,0 +1,73 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/file.h>
@@ -64964,25 +64723,59 @@ index 0000000..4a78774
+#ifdef CONFIG_GRKERNSEC
+ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
+ const struct cred *cred = current_cred();
++ char *msg = NULL;
++ char *msg2 = NULL;
++
++ // never restrict root
++ if (!cred->uid)
++ return 1;
+
-+ if (cred->uid && ((grsec_enable_tpe &&
++ if (grsec_enable_tpe) {
+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
-+ ((grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid)) ||
-+ (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid)))
++ if (grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid))
++ msg = "not being in trusted group";
++ else if (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid))
++ msg = "being in untrusted group";
+#else
-+ in_group_p(grsec_tpe_gid)
++ if (in_group_p(grsec_tpe_gid))
++ msg = "being in untrusted group";
+#endif
-+ ) || gr_acl_tpe_check()) &&
-+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
-+ (inode->i_mode & S_IWOTH))))) {
-+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
++ }
++ if (!msg && gr_acl_tpe_check())
++ msg = "being in untrusted role";
++
++ // not in any affected group/role
++ if (!msg)
++ goto next_check;
++
++ if (inode->i_uid)
++ msg2 = "file in non-root-owned directory";
++ else if (inode->i_mode & S_IWOTH)
++ msg2 = "file in world-writable directory";
++ else if (inode->i_mode & S_IWGRP)
++ msg2 = "file in group-writable directory";
++
++ if (msg && msg2) {
++ char fullmsg[64] = {0};
++ snprintf(fullmsg, sizeof(fullmsg)-1, "%s and %s", msg, msg2);
++ gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, fullmsg, file->f_path.dentry, file->f_path.mnt);
+ return 0;
+ }
++ msg = NULL;
++next_check:
+#ifdef CONFIG_GRKERNSEC_TPE_ALL
-+ if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
-+ ((inode->i_uid && (inode->i_uid != cred->uid)) ||
-+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
-+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
++ if (!grsec_enable_tpe || !grsec_enable_tpe_all)
++ return 1;
++
++ if (inode->i_uid && (inode->i_uid != cred->uid))
++ msg = "directory not owned by user";
++ else if (inode->i_mode & S_IWOTH)
++ msg = "file in world-writable directory";
++ else if (inode->i_mode & S_IWGRP)
++ msg = "file in group-writable directory";
++
++ if (msg) {
++ gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, msg, file->f_path.dentry, file->f_path.mnt);
+ return 0;
+ }
+#endif
@@ -65755,7 +65548,7 @@ index b6e818f..21aa58a 100644
/**
* PERCPU - define output section for percpu area, simple version
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 66713c6..98c0460 100644
+index ebab6a6..351dba1 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -71,6 +71,7 @@
@@ -65942,18 +65735,10 @@ index a3d802e..482f69c 100644
int hasvdso;
};
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
-index 63070ad..a2906d2 100644
+index 5eb6cb0..a2906d2 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
-@@ -777,6 +777,7 @@ extern void blk_plug_device(struct request_queue *);
- extern void blk_plug_device_unlocked(struct request_queue *);
- extern int blk_remove_plug(struct request_queue *);
- extern void blk_recount_segments(struct request_queue *, struct bio *);
-+extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
- extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
- unsigned int, void __user *);
- extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
-@@ -1280,7 +1281,7 @@ struct block_device_operations {
+@@ -1281,7 +1281,7 @@ struct block_device_operations {
int (*revalidate_disk) (struct gendisk *);
int (*getgeo)(struct block_device *, struct hd_geometry *);
struct module *owner;
@@ -67354,7 +67139,7 @@ index 0000000..3826b91
+#endif
diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
new file mode 100644
-index 0000000..dfb15ef
+index 0000000..b3347e2
--- /dev/null
+++ b/include/linux/grmsg.h
@@ -0,0 +1,109 @@
@@ -67392,7 +67177,7 @@ index 0000000..dfb15ef
+#define GR_UNSAFESHARE_EXEC_ACL_MSG "denied exec with cloned fs of %.950s by "
+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
-+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
++#define GR_EXEC_TPE_MSG "denied untrusted exec (due to %.64s) of %.950s by "
+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
+#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
@@ -75211,7 +74996,7 @@ index 04a0252..580c512 100644
struct tasklet_struct *list;
diff --git a/kernel/sys.c b/kernel/sys.c
-index e9512b1..f07185f 100644
+index e9512b1..8a10cb3 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -133,6 +133,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error)
@@ -75333,7 +75118,29 @@ index e9512b1..f07185f 100644
if (capable(CAP_SETUID)) {
new->suid = new->uid = uid;
if (uid != old->uid) {
-@@ -732,6 +761,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+@@ -721,9 +750,18 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+
+ retval = -EPERM;
+ if (!capable(CAP_SETUID)) {
+- if (ruid != (uid_t) -1 && ruid != old->uid &&
+- ruid != old->euid && ruid != old->suid)
+- goto error;
++ // if RBAC is enabled, require CAP_SETUID to change
++ // uid to euid (from a suid binary, for instance)
++ // this is a hardening of normal permissions, not
++ // weakening
++ if (gr_acl_is_enabled()) {
++ if (ruid != (uid_t) -1 && ruid != old->uid)
++ goto error;
++ } else {
++ if (ruid != (uid_t) -1 && ruid != old->uid &&
++ ruid != old->euid && ruid != old->suid)
++ goto error;
++ }
+ if (euid != (uid_t) -1 && euid != old->uid &&
+ euid != old->euid && euid != old->suid)
+ goto error;
+@@ -732,6 +770,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
goto error;
}
@@ -75343,7 +75150,29 @@ index e9512b1..f07185f 100644
if (ruid != (uid_t) -1) {
new->uid = ruid;
if (ruid != old->uid) {
-@@ -800,6 +832,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+@@ -789,9 +830,18 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+
+ retval = -EPERM;
+ if (!capable(CAP_SETGID)) {
+- if (rgid != (gid_t) -1 && rgid != old->gid &&
+- rgid != old->egid && rgid != old->sgid)
+- goto error;
++ // if RBAC is enabled, require CAP_SETGID to change
++ // gid to egid (from a sgid binary, for instance)
++ // this is a hardening of normal permissions, not
++ // weakening
++ if (gr_acl_is_enabled()) {
++ if (rgid != (gid_t) -1 && rgid != old->gid)
++ goto error;
++ } else {
++ if (rgid != (gid_t) -1 && rgid != old->gid &&
++ rgid != old->egid && rgid != old->sgid)
++ goto error;
++ }
+ if (egid != (gid_t) -1 && egid != old->gid &&
+ egid != old->egid && egid != old->sgid)
+ goto error;
+@@ -800,6 +850,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
goto error;
}
@@ -75353,7 +75182,7 @@ index e9512b1..f07185f 100644
if (rgid != (gid_t) -1)
new->gid = rgid;
if (egid != (gid_t) -1)
-@@ -849,6 +884,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
+@@ -849,6 +902,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS) < 0)
goto error;
@@ -75363,7 +75192,7 @@ index e9512b1..f07185f 100644
if (uid == old->uid || uid == old->euid ||
uid == old->suid || uid == old->fsuid ||
capable(CAP_SETUID)) {
-@@ -889,6 +927,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
+@@ -889,6 +945,9 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
if (gid == old->gid || gid == old->egid ||
gid == old->sgid || gid == old->fsgid ||
capable(CAP_SETGID)) {
@@ -75373,7 +75202,7 @@ index e9512b1..f07185f 100644
if (gid != old_fsgid) {
new->fsgid = gid;
goto change_okay;
-@@ -1454,7 +1495,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
+@@ -1454,7 +1513,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
error = get_dumpable(me->mm);
break;
case PR_SET_DUMPABLE:
@@ -84589,10 +84418,10 @@ index d52f7a0..269eb1b 100755
rm -f tags
xtags ctags
diff --git a/security/Kconfig b/security/Kconfig
-index fb363cd..0524cf3 100644
+index fb363cd..886ace4 100644
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -4,6 +4,625 @@
+@@ -4,6 +4,626 @@
menu "Security options"
@@ -85100,6 +84929,7 @@ index fb363cd..0524cf3 100644
+
+config PAX_MEMORY_SANITIZE
+ bool "Sanitize all freed memory"
++ depends on !HIBERNATION
+ help
+ By saying Y here the kernel will erase memory pages as soon as they
+ are freed. This in turn reduces the lifetime of data stored in the
@@ -85218,7 +85048,7 @@ index fb363cd..0524cf3 100644
config KEYS
bool "Enable access key retention support"
help
-@@ -146,7 +765,7 @@ config INTEL_TXT
+@@ -146,7 +766,7 @@ config INTEL_TXT
config LSM_MMAP_MIN_ADDR
int "Low address space for LSM to protect from user allocation"
depends on SECURITY && SECURITY_SELINUX
diff --git a/2.6.32/4425_grsec-pax-without-grsec.patch b/2.6.32/4425_grsec-pax-without-grsec.patch
index bbb8671..0f87dc1 100644
--- a/2.6.32/4425_grsec-pax-without-grsec.patch
+++ b/2.6.32/4425_grsec-pax-without-grsec.patch
@@ -36,7 +36,7 @@ diff -Naur a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
diff -Naur a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c 2011-04-17 18:15:55.000000000 -0400
+++ b/fs/exec.c 2011-04-17 18:29:40.000000000 -0400
-@@ -1807,9 +1807,11 @@
+@@ -1812,9 +1812,11 @@
}
up_read(&mm->mmap_sem);
}
@@ -48,7 +48,7 @@ diff -Naur a/fs/exec.c b/fs/exec.c
printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
"PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
-@@ -1824,10 +1826,12 @@
+@@ -1829,10 +1831,12 @@
#ifdef CONFIG_PAX_REFCOUNT
void pax_report_refcount_overflow(struct pt_regs *regs)
{
@@ -61,7 +61,7 @@ diff -Naur a/fs/exec.c b/fs/exec.c
printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
current->comm, task_pid_nr(current), current_uid(), current_euid());
print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
-@@ -1887,10 +1891,12 @@
+@@ -1892,10 +1896,12 @@
NORET_TYPE void pax_report_usercopy(const void *ptr, unsigned long len, bool to, const char *type)
{
diff --git a/2.6.32/4430_grsec-kconfig-default-gids.patch b/2.6.32/4430_grsec-kconfig-default-gids.patch
index 2cd1c5a..763d845 100644
--- a/2.6.32/4430_grsec-kconfig-default-gids.patch
+++ b/2.6.32/4430_grsec-kconfig-default-gids.patch
@@ -12,7 +12,7 @@ from shooting themselves in the foot.
diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
--- a/grsecurity/Kconfig 2011-12-12 15:11:47.000000000 -0500
+++ b/grsecurity/Kconfig 2011-12-12 15:13:17.000000000 -0500
-@@ -431,7 +431,7 @@
+@@ -433,7 +433,7 @@
config GRKERNSEC_PROC_GID
int "GID for special group"
depends on GRKERNSEC_PROC_USERGROUP
@@ -21,7 +21,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
config GRKERNSEC_PROC_ADD
bool "Additional restrictions"
-@@ -655,7 +655,7 @@
+@@ -661,7 +661,7 @@
config GRKERNSEC_AUDIT_GID
int "GID for auditing"
depends on GRKERNSEC_AUDIT_GROUP
@@ -30,7 +30,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
config GRKERNSEC_EXECLOG
bool "Exec logging"
-@@ -833,7 +833,7 @@
+@@ -865,7 +865,7 @@
config GRKERNSEC_TPE_GID
int "GID for untrusted users"
depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
@@ -39,7 +39,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Setting this GID determines what group TPE restrictions will be
*enabled* for. If the sysctl option is enabled, a sysctl option
-@@ -842,7 +842,7 @@
+@@ -874,7 +874,7 @@
config GRKERNSEC_TPE_GID
int "GID for trusted users"
depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
@@ -48,7 +48,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Setting this GID determines what group TPE restrictions will be
*disabled* for. If the sysctl option is enabled, a sysctl option
-@@ -915,7 +915,7 @@
+@@ -947,7 +947,7 @@
config GRKERNSEC_SOCKET_ALL_GID
int "GID to deny all sockets for"
depends on GRKERNSEC_SOCKET_ALL
@@ -57,7 +57,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Here you can choose the GID to disable socket access for. Remember to
add the users you want socket access disabled for to the GID
-@@ -936,7 +936,7 @@
+@@ -968,7 +968,7 @@
config GRKERNSEC_SOCKET_CLIENT_GID
int "GID to deny client sockets for"
depends on GRKERNSEC_SOCKET_CLIENT
@@ -66,7 +66,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Here you can choose the GID to disable client socket access for.
Remember to add the users you want client socket access disabled for to
-@@ -954,7 +954,7 @@
+@@ -986,7 +986,7 @@
config GRKERNSEC_SOCKET_SERVER_GID
int "GID to deny server sockets for"
depends on GRKERNSEC_SOCKET_SERVER
diff --git a/2.6.32/4435_grsec-kconfig-gentoo.patch b/2.6.32/4435_grsec-kconfig-gentoo.patch
index 7c9be0d..b7e7322 100644
--- a/2.6.32/4435_grsec-kconfig-gentoo.patch
+++ b/2.6.32/4435_grsec-kconfig-gentoo.patch
@@ -27,7 +27,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
config GRKERNSEC_LOW
bool "Low"
-@@ -190,6 +190,259 @@
+@@ -192,6 +192,259 @@
- Restricted sysfs/debugfs
- Active kernel exploit response
@@ -341,7 +341,7 @@ diff -Naur a/security/Kconfig b/security/Kconfig
default ""
config PAX_KERNEXEC_MODULE_TEXT
-@@ -553,8 +554,9 @@
+@@ -554,8 +555,9 @@
config PAX_MEMORY_UDEREF
bool "Prevent invalid userland pointer dereference"
diff --git a/2.6.32/4437-grsec-kconfig-proc-user.patch b/2.6.32/4437-grsec-kconfig-proc-user.patch
index d84eb57..ca88ef7 100644
--- a/2.6.32/4437-grsec-kconfig-proc-user.patch
+++ b/2.6.32/4437-grsec-kconfig-proc-user.patch
@@ -6,7 +6,7 @@ in a different way to avoid bug #366019. This patch should eventually go upstre
diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
--- a/grsecurity/Kconfig 2011-06-29 07:46:02.000000000 -0400
+++ b/grsecurity/Kconfig 2011-06-29 07:47:20.000000000 -0400
-@@ -665,7 +665,7 @@
+@@ -667,7 +667,7 @@
config GRKERNSEC_PROC_USER
bool "Restrict /proc to user only"
@@ -15,7 +15,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
If you say Y here, non-root users will only be able to view their own
processes, and restricts them from viewing network-related information,
-@@ -673,7 +673,7 @@
+@@ -675,7 +675,7 @@
config GRKERNSEC_PROC_USERGROUP
bool "Allow special group"
diff --git a/2.6.32/4440_selinux-avc_audit-log-curr_ip.patch b/2.6.32/4440_selinux-avc_audit-log-curr_ip.patch
index 5bbfa24..0873c15 100644
--- a/2.6.32/4440_selinux-avc_audit-log-curr_ip.patch
+++ b/2.6.32/4440_selinux-avc_audit-log-curr_ip.patch
@@ -28,7 +28,7 @@ Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org>
diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
--- a/grsecurity/Kconfig 2011-04-17 18:47:02.000000000 -0400
+++ b/grsecurity/Kconfig 2011-04-17 18:51:15.000000000 -0400
-@@ -1264,6 +1264,27 @@
+@@ -1296,6 +1296,27 @@
menu "Logging Options"
depends on GRKERNSEC
diff --git a/3.2.2/1001_linux-3.2.2.patch b/3.2.2/1001_linux-3.2.2.patch
deleted file mode 100644
index ec16cce..0000000
--- a/3.2.2/1001_linux-3.2.2.patch
+++ /dev/null
@@ -1,6552 +0,0 @@
-diff --git a/Makefile b/Makefile
-index c5edffa..2f684da 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 3
- PATCHLEVEL = 2
--SUBLEVEL = 1
-+SUBLEVEL = 2
- EXTRAVERSION =
- NAME = Saber-toothed Squirrel
-
-diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
-index bfb4d01..5207035 100644
---- a/arch/ia64/kernel/acpi.c
-+++ b/arch/ia64/kernel/acpi.c
-@@ -429,22 +429,24 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];
- static struct acpi_table_slit __initdata *slit_table;
- cpumask_t early_cpu_possible_map = CPU_MASK_NONE;
-
--static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
-+static int __init
-+get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
- {
- int pxm;
-
- pxm = pa->proximity_domain_lo;
-- if (ia64_platform_is("sn2"))
-+ if (ia64_platform_is("sn2") || acpi_srat_revision >= 2)
- pxm += pa->proximity_domain_hi[0] << 8;
- return pxm;
- }
-
--static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
-+static int __init
-+get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
- {
- int pxm;
-
- pxm = ma->proximity_domain;
-- if (!ia64_platform_is("sn2"))
-+ if (!ia64_platform_is("sn2") && acpi_srat_revision <= 1)
- pxm &= 0xff;
-
- return pxm;
-diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S
-index 577abba..83bb960 100644
---- a/arch/score/kernel/entry.S
-+++ b/arch/score/kernel/entry.S
-@@ -408,7 +408,7 @@ ENTRY(handle_sys)
- sw r9, [r0, PT_EPC]
-
- cmpi.c r27, __NR_syscalls # check syscall number
-- bgtu illegal_syscall
-+ bgeu illegal_syscall
-
- slli r8, r27, 2 # get syscall routine
- la r11, sys_call_table
-diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
-index 8e41071..49ad773 100644
---- a/arch/x86/include/asm/amd_nb.h
-+++ b/arch/x86/include/asm/amd_nb.h
-@@ -1,6 +1,7 @@
- #ifndef _ASM_X86_AMD_NB_H
- #define _ASM_X86_AMD_NB_H
-
-+#include <linux/ioport.h>
- #include <linux/pci.h>
-
- struct amd_nb_bus_dev_range {
-@@ -13,6 +14,7 @@ extern const struct pci_device_id amd_nb_misc_ids[];
- extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
-
- extern bool early_is_amd_nb(u32 value);
-+extern struct resource *amd_get_mmconfig_range(struct resource *res);
- extern int amd_cache_northbridges(void);
- extern void amd_flush_garts(void);
- extern int amd_numa_init(void);
-diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
-index 8e862aa..1b82f7e 100644
---- a/arch/x86/include/asm/uv/uv_bau.h
-+++ b/arch/x86/include/asm/uv/uv_bau.h
-@@ -65,7 +65,7 @@
- * UV2: Bit 19 selects between
- * (0): 10 microsecond timebase and
- * (1): 80 microseconds
-- * we're using 655us, similar to UV1: 65 units of 10us
-+ * we're using 560us, similar to UV1: 65 units of 10us
- */
- #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL)
- #define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL)
-@@ -167,6 +167,7 @@
- #define FLUSH_RETRY_TIMEOUT 2
- #define FLUSH_GIVEUP 3
- #define FLUSH_COMPLETE 4
-+#define FLUSH_RETRY_BUSYBUG 5
-
- /*
- * tuning the action when the numalink network is extremely delayed
-@@ -235,10 +236,10 @@ struct bau_msg_payload {
-
-
- /*
-- * Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
-+ * UV1 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
- * see table 4.2.3.0.1 in broacast_assist spec.
- */
--struct bau_msg_header {
-+struct uv1_bau_msg_header {
- unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */
- /* bits 5:0 */
- unsigned int base_dest_nasid:15; /* nasid of the first bit */
-@@ -318,19 +319,87 @@ struct bau_msg_header {
- };
-
- /*
-+ * UV2 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
-+ * see figure 9-2 of harp_sys.pdf
-+ */
-+struct uv2_bau_msg_header {
-+ unsigned int base_dest_nasid:15; /* nasid of the first bit */
-+ /* bits 14:0 */ /* in uvhub map */
-+ unsigned int dest_subnodeid:5; /* must be 0x10, for the LB */
-+ /* bits 19:15 */
-+ unsigned int rsvd_1:1; /* must be zero */
-+ /* bit 20 */
-+ /* Address bits 59:21 */
-+ /* bits 25:2 of address (44:21) are payload */
-+ /* these next 24 bits become bytes 12-14 of msg */
-+ /* bits 28:21 land in byte 12 */
-+ unsigned int replied_to:1; /* sent as 0 by the source to
-+ byte 12 */
-+ /* bit 21 */
-+ unsigned int msg_type:3; /* software type of the
-+ message */
-+ /* bits 24:22 */
-+ unsigned int canceled:1; /* message canceled, resource
-+ is to be freed*/
-+ /* bit 25 */
-+ unsigned int payload_1:3; /* not currently used */
-+ /* bits 28:26 */
-+
-+ /* bits 36:29 land in byte 13 */
-+ unsigned int payload_2a:3; /* not currently used */
-+ unsigned int payload_2b:5; /* not currently used */
-+ /* bits 36:29 */
-+
-+ /* bits 44:37 land in byte 14 */
-+ unsigned int payload_3:8; /* not currently used */
-+ /* bits 44:37 */
-+
-+ unsigned int rsvd_2:7; /* reserved */
-+ /* bits 51:45 */
-+ unsigned int swack_flag:1; /* software acknowledge flag */
-+ /* bit 52 */
-+ unsigned int rsvd_3a:3; /* must be zero */
-+ unsigned int rsvd_3b:8; /* must be zero */
-+ unsigned int rsvd_3c:8; /* must be zero */
-+ unsigned int rsvd_3d:3; /* must be zero */
-+ /* bits 74:53 */
-+ unsigned int fairness:3; /* usually zero */
-+ /* bits 77:75 */
-+
-+ unsigned int sequence:16; /* message sequence number */
-+ /* bits 93:78 Suppl_A */
-+ unsigned int chaining:1; /* next descriptor is part of
-+ this activation*/
-+ /* bit 94 */
-+ unsigned int multilevel:1; /* multi-level multicast
-+ format */
-+ /* bit 95 */
-+ unsigned int rsvd_4:24; /* ordered / source node /
-+ source subnode / aging
-+ must be zero */
-+ /* bits 119:96 */
-+ unsigned int command:8; /* message type */
-+ /* bits 127:120 */
-+};
-+
-+/*
- * The activation descriptor:
- * The format of the message to send, plus all accompanying control
- * Should be 64 bytes
- */
- struct bau_desc {
-- struct pnmask distribution;
-+ struct pnmask distribution;
- /*
- * message template, consisting of header and payload:
- */
-- struct bau_msg_header header;
-- struct bau_msg_payload payload;
-+ union bau_msg_header {
-+ struct uv1_bau_msg_header uv1_hdr;
-+ struct uv2_bau_msg_header uv2_hdr;
-+ } header;
-+
-+ struct bau_msg_payload payload;
- };
--/*
-+/* UV1:
- * -payload-- ---------header------
- * bytes 0-11 bits 41-56 bits 58-81
- * A B (2) C (3)
-@@ -340,6 +409,16 @@ struct bau_desc {
- * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector)
- * ------------payload queue-----------
- */
-+/* UV2:
-+ * -payload-- ---------header------
-+ * bytes 0-11 bits 70-78 bits 21-44
-+ * A B (2) C (3)
-+ *
-+ * A/B/C are moved to:
-+ * A C B
-+ * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector)
-+ * ------------payload queue-----------
-+ */
-
- /*
- * The payload queue on the destination side is an array of these.
-@@ -385,7 +464,6 @@ struct bau_pq_entry {
- struct msg_desc {
- struct bau_pq_entry *msg;
- int msg_slot;
-- int swack_slot;
- struct bau_pq_entry *queue_first;
- struct bau_pq_entry *queue_last;
- };
-@@ -439,6 +517,9 @@ struct ptc_stats {
- unsigned long s_retry_messages; /* retry broadcasts */
- unsigned long s_bau_reenabled; /* for bau enable/disable */
- unsigned long s_bau_disabled; /* for bau enable/disable */
-+ unsigned long s_uv2_wars; /* uv2 workaround, perm. busy */
-+ unsigned long s_uv2_wars_hw; /* uv2 workaround, hiwater */
-+ unsigned long s_uv2_war_waits; /* uv2 workaround, long waits */
- /* destination statistics */
- unsigned long d_alltlb; /* times all tlb's on this
- cpu were flushed */
-@@ -511,9 +592,12 @@ struct bau_control {
- short osnode;
- short uvhub_cpu;
- short uvhub;
-+ short uvhub_version;
- short cpus_in_socket;
- short cpus_in_uvhub;
- short partition_base_pnode;
-+ short using_desc; /* an index, like uvhub_cpu */
-+ unsigned int inuse_map;
- unsigned short message_number;
- unsigned short uvhub_quiesce;
- short socket_acknowledge_count[DEST_Q_SIZE];
-@@ -531,6 +615,7 @@ struct bau_control {
- int cong_response_us;
- int cong_reps;
- int cong_period;
-+ unsigned long clocks_per_100_usec;
- cycles_t period_time;
- long period_requests;
- struct hub_and_pnode *thp;
-@@ -591,6 +676,11 @@ static inline void write_mmr_sw_ack(unsigned long mr)
- uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
- }
-
-+static inline void write_gmmr_sw_ack(int pnode, unsigned long mr)
-+{
-+ write_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
-+}
-+
- static inline unsigned long read_mmr_sw_ack(void)
- {
- return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
-diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
-index 4c39baa..bae1efe 100644
---- a/arch/x86/kernel/amd_nb.c
-+++ b/arch/x86/kernel/amd_nb.c
-@@ -119,6 +119,37 @@ bool __init early_is_amd_nb(u32 device)
- return false;
- }
-
-+struct resource *amd_get_mmconfig_range(struct resource *res)
-+{
-+ u32 address;
-+ u64 base, msr;
-+ unsigned segn_busn_bits;
-+
-+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
-+ return NULL;
-+
-+ /* assume all cpus from fam10h have mmconfig */
-+ if (boot_cpu_data.x86 < 0x10)
-+ return NULL;
-+
-+ address = MSR_FAM10H_MMIO_CONF_BASE;
-+ rdmsrl(address, msr);
-+
-+ /* mmconfig is not enabled */
-+ if (!(msr & FAM10H_MMIO_CONF_ENABLE))
-+ return NULL;
-+
-+ base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
-+
-+ segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
-+ FAM10H_MMIO_CONF_BUSRANGE_MASK;
-+
-+ res->flags = IORESOURCE_MEM;
-+ res->start = base;
-+ res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
-+ return res;
-+}
-+
- int amd_get_subcaches(int cpu)
- {
- struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
-diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
-index 9d59bba..79b05b8 100644
---- a/arch/x86/kernel/apic/x2apic_uv_x.c
-+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
-@@ -769,7 +769,12 @@ void __init uv_system_init(void)
- for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
- uv_possible_blades +=
- hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8));
-- printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades());
-+
-+ /* uv_num_possible_blades() is really the hub count */
-+ printk(KERN_INFO "UV: Found %d blades, %d hubs\n",
-+ is_uv1_hub() ? uv_num_possible_blades() :
-+ (uv_num_possible_blades() + 1) / 2,
-+ uv_num_possible_blades());
-
- bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades();
- uv_blade_info = kzalloc(bytes, GFP_KERNEL);
-diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
-index 4b5ba85..845df68 100644
---- a/arch/x86/mm/mmap.c
-+++ b/arch/x86/mm/mmap.c
-@@ -75,9 +75,9 @@ static unsigned long mmap_rnd(void)
- */
- if (current->flags & PF_RANDOMIZE) {
- if (mmap_is_ia32())
-- rnd = (long)get_random_int() % (1<<8);
-+ rnd = get_random_int() % (1<<8);
- else
-- rnd = (long)(get_random_int() % (1<<28));
-+ rnd = get_random_int() % (1<<28);
- }
- return rnd << PAGE_SHIFT;
- }
-diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c
-index 81dbfde..7efd0c6 100644
---- a/arch/x86/mm/srat.c
-+++ b/arch/x86/mm/srat.c
-@@ -104,6 +104,8 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
- if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
- return;
- pxm = pa->proximity_domain_lo;
-+ if (acpi_srat_revision >= 2)
-+ pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8;
- node = setup_node(pxm);
- if (node < 0) {
- printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
-@@ -155,6 +157,8 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
- start = ma->base_address;
- end = start + ma->length;
- pxm = ma->proximity_domain;
-+ if (acpi_srat_revision <= 1)
-+ pxm &= 0xff;
- node = setup_node(pxm);
- if (node < 0) {
- printk(KERN_ERR "SRAT: Too many proximity domains.\n");
-diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
-index 6b8759f..d24d3da 100644
---- a/arch/x86/pci/Makefile
-+++ b/arch/x86/pci/Makefile
-@@ -18,8 +18,9 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
- obj-$(CONFIG_X86_MRST) += mrst.o
-
- obj-y += common.o early.o
--obj-y += amd_bus.o bus_numa.o
-+obj-y += bus_numa.o
-
-+obj-$(CONFIG_AMD_NB) += amd_bus.o
- obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
-
- ifeq ($(CONFIG_PCI_DEBUG),y)
-diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
-index 404f21a..f8348ab 100644
---- a/arch/x86/pci/acpi.c
-+++ b/arch/x86/pci/acpi.c
-@@ -149,7 +149,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
- struct acpi_resource_address64 addr;
- acpi_status status;
- unsigned long flags;
-- u64 start, end;
-+ u64 start, orig_end, end;
-
- status = resource_to_addr(acpi_res, &addr);
- if (!ACPI_SUCCESS(status))
-@@ -165,7 +165,21 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
- return AE_OK;
-
- start = addr.minimum + addr.translation_offset;
-- end = addr.maximum + addr.translation_offset;
-+ orig_end = end = addr.maximum + addr.translation_offset;
-+
-+ /* Exclude non-addressable range or non-addressable portion of range */
-+ end = min(end, (u64)iomem_resource.end);
-+ if (end <= start) {
-+ dev_info(&info->bridge->dev,
-+ "host bridge window [%#llx-%#llx] "
-+ "(ignored, not CPU addressable)\n", start, orig_end);
-+ return AE_OK;
-+ } else if (orig_end != end) {
-+ dev_info(&info->bridge->dev,
-+ "host bridge window [%#llx-%#llx] "
-+ "([%#llx-%#llx] ignored, not CPU addressable)\n",
-+ start, orig_end, end + 1, orig_end);
-+ }
-
- res = &info->res[info->res_num];
- res->name = info->name;
-diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
-index 026e493..385a940 100644
---- a/arch/x86/pci/amd_bus.c
-+++ b/arch/x86/pci/amd_bus.c
-@@ -30,34 +30,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
- { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
- };
-
--static u64 __initdata fam10h_mmconf_start;
--static u64 __initdata fam10h_mmconf_end;
--static void __init get_pci_mmcfg_amd_fam10h_range(void)
--{
-- u32 address;
-- u64 base, msr;
-- unsigned segn_busn_bits;
--
-- /* assume all cpus from fam10h have mmconf */
-- if (boot_cpu_data.x86 < 0x10)
-- return;
--
-- address = MSR_FAM10H_MMIO_CONF_BASE;
-- rdmsrl(address, msr);
--
-- /* mmconfig is not enable */
-- if (!(msr & FAM10H_MMIO_CONF_ENABLE))
-- return;
--
-- base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
--
-- segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
-- FAM10H_MMIO_CONF_BUSRANGE_MASK;
--
-- fam10h_mmconf_start = base;
-- fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
--}
--
- #define RANGE_NUM 16
-
- /**
-@@ -85,6 +57,9 @@ static int __init early_fill_mp_bus_info(void)
- u64 val;
- u32 address;
- bool found;
-+ struct resource fam10h_mmconf_res, *fam10h_mmconf;
-+ u64 fam10h_mmconf_start;
-+ u64 fam10h_mmconf_end;
-
- if (!early_pci_allowed())
- return -1;
-@@ -211,12 +186,17 @@ static int __init early_fill_mp_bus_info(void)
- subtract_range(range, RANGE_NUM, 0, end);
-
- /* get mmconfig */
-- get_pci_mmcfg_amd_fam10h_range();
-+ fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res);
- /* need to take out mmconf range */
-- if (fam10h_mmconf_end) {
-- printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
-+ if (fam10h_mmconf) {
-+ printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf);
-+ fam10h_mmconf_start = fam10h_mmconf->start;
-+ fam10h_mmconf_end = fam10h_mmconf->end;
- subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
- fam10h_mmconf_end + 1);
-+ } else {
-+ fam10h_mmconf_start = 0;
-+ fam10h_mmconf_end = 0;
- }
-
- /* mmio resource */
-diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
-index 5b55219..9010ca7 100644
---- a/arch/x86/platform/uv/tlb_uv.c
-+++ b/arch/x86/platform/uv/tlb_uv.c
-@@ -157,13 +157,14 @@ static int __init uvhub_to_first_apicid(int uvhub)
- * clear of the Timeout bit (as well) will free the resource. No reply will
- * be sent (the hardware will only do one reply per message).
- */
--static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp)
-+static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp,
-+ int do_acknowledge)
- {
- unsigned long dw;
- struct bau_pq_entry *msg;
-
- msg = mdp->msg;
-- if (!msg->canceled) {
-+ if (!msg->canceled && do_acknowledge) {
- dw = (msg->swack_vec << UV_SW_ACK_NPENDING) | msg->swack_vec;
- write_mmr_sw_ack(dw);
- }
-@@ -212,8 +213,8 @@ static void bau_process_retry_msg(struct msg_desc *mdp,
- if (mmr & (msg_res << UV_SW_ACK_NPENDING)) {
- unsigned long mr;
- /*
-- * is the resource timed out?
-- * make everyone ignore the cancelled message.
-+ * Is the resource timed out?
-+ * Make everyone ignore the cancelled message.
- */
- msg2->canceled = 1;
- stat->d_canceled++;
-@@ -231,8 +232,8 @@ static void bau_process_retry_msg(struct msg_desc *mdp,
- * Do all the things a cpu should do for a TLB shootdown message.
- * Other cpu's may come here at the same time for this message.
- */
--static void bau_process_message(struct msg_desc *mdp,
-- struct bau_control *bcp)
-+static void bau_process_message(struct msg_desc *mdp, struct bau_control *bcp,
-+ int do_acknowledge)
- {
- short socket_ack_count = 0;
- short *sp;
-@@ -284,8 +285,9 @@ static void bau_process_message(struct msg_desc *mdp,
- if (msg_ack_count == bcp->cpus_in_uvhub) {
- /*
- * All cpus in uvhub saw it; reply
-+ * (unless we are in the UV2 workaround)
- */
-- reply_to_message(mdp, bcp);
-+ reply_to_message(mdp, bcp, do_acknowledge);
- }
- }
-
-@@ -491,27 +493,138 @@ static int uv1_wait_completion(struct bau_desc *bau_desc,
- /*
- * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register.
- */
--static unsigned long uv2_read_status(unsigned long offset, int rshft, int cpu)
-+static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc)
- {
- unsigned long descriptor_status;
- unsigned long descriptor_status2;
-
- descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK);
-- descriptor_status2 = (read_mmr_uv2_status() >> cpu) & 0x1UL;
-+ descriptor_status2 = (read_mmr_uv2_status() >> desc) & 0x1UL;
- descriptor_status = (descriptor_status << 1) | descriptor_status2;
- return descriptor_status;
- }
-
-+/*
-+ * Return whether the status of the descriptor that is normally used for this
-+ * cpu (the one indexed by its hub-relative cpu number) is busy.
-+ * The status of the original 32 descriptors is always reflected in the 64
-+ * bits of UVH_LB_BAU_SB_ACTIVATION_STATUS_0.
-+ * The bit provided by the activation_status_2 register is irrelevant to
-+ * the status if it is only being tested for busy or not busy.
-+ */
-+int normal_busy(struct bau_control *bcp)
-+{
-+ int cpu = bcp->uvhub_cpu;
-+ int mmr_offset;
-+ int right_shift;
-+
-+ mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
-+ right_shift = cpu * UV_ACT_STATUS_SIZE;
-+ return (((((read_lmmr(mmr_offset) >> right_shift) &
-+ UV_ACT_STATUS_MASK)) << 1) == UV2H_DESC_BUSY);
-+}
-+
-+/*
-+ * Entered when a bau descriptor has gone into a permanent busy wait because
-+ * of a hardware bug.
-+ * Workaround the bug.
-+ */
-+int handle_uv2_busy(struct bau_control *bcp)
-+{
-+ int busy_one = bcp->using_desc;
-+ int normal = bcp->uvhub_cpu;
-+ int selected = -1;
-+ int i;
-+ unsigned long descriptor_status;
-+ unsigned long status;
-+ int mmr_offset;
-+ struct bau_desc *bau_desc_old;
-+ struct bau_desc *bau_desc_new;
-+ struct bau_control *hmaster = bcp->uvhub_master;
-+ struct ptc_stats *stat = bcp->statp;
-+ cycles_t ttm;
-+
-+ stat->s_uv2_wars++;
-+ spin_lock(&hmaster->uvhub_lock);
-+ /* try for the original first */
-+ if (busy_one != normal) {
-+ if (!normal_busy(bcp))
-+ selected = normal;
-+ }
-+ if (selected < 0) {
-+ /* can't use the normal, select an alternate */
-+ mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
-+ descriptor_status = read_lmmr(mmr_offset);
-+
-+ /* scan available descriptors 32-63 */
-+ for (i = 0; i < UV_CPUS_PER_AS; i++) {
-+ if ((hmaster->inuse_map & (1 << i)) == 0) {
-+ status = ((descriptor_status >>
-+ (i * UV_ACT_STATUS_SIZE)) &
-+ UV_ACT_STATUS_MASK) << 1;
-+ if (status != UV2H_DESC_BUSY) {
-+ selected = i + UV_CPUS_PER_AS;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+
-+ if (busy_one != normal)
-+ /* mark the busy alternate as not in-use */
-+ hmaster->inuse_map &= ~(1 << (busy_one - UV_CPUS_PER_AS));
-+
-+ if (selected >= 0) {
-+ /* switch to the selected descriptor */
-+ if (selected != normal) {
-+ /* set the selected alternate as in-use */
-+ hmaster->inuse_map |=
-+ (1 << (selected - UV_CPUS_PER_AS));
-+ if (selected > stat->s_uv2_wars_hw)
-+ stat->s_uv2_wars_hw = selected;
-+ }
-+ bau_desc_old = bcp->descriptor_base;
-+ bau_desc_old += (ITEMS_PER_DESC * busy_one);
-+ bcp->using_desc = selected;
-+ bau_desc_new = bcp->descriptor_base;
-+ bau_desc_new += (ITEMS_PER_DESC * selected);
-+ *bau_desc_new = *bau_desc_old;
-+ } else {
-+ /*
-+ * All are busy. Wait for the normal one for this cpu to
-+ * free up.
-+ */
-+ stat->s_uv2_war_waits++;
-+ spin_unlock(&hmaster->uvhub_lock);
-+ ttm = get_cycles();
-+ do {
-+ cpu_relax();
-+ } while (normal_busy(bcp));
-+ spin_lock(&hmaster->uvhub_lock);
-+ /* switch to the original descriptor */
-+ bcp->using_desc = normal;
-+ bau_desc_old = bcp->descriptor_base;
-+ bau_desc_old += (ITEMS_PER_DESC * bcp->using_desc);
-+ bcp->using_desc = (ITEMS_PER_DESC * normal);
-+ bau_desc_new = bcp->descriptor_base;
-+ bau_desc_new += (ITEMS_PER_DESC * normal);
-+ *bau_desc_new = *bau_desc_old; /* copy the entire descriptor */
-+ }
-+ spin_unlock(&hmaster->uvhub_lock);
-+ return FLUSH_RETRY_BUSYBUG;
-+}
-+
- static int uv2_wait_completion(struct bau_desc *bau_desc,
- unsigned long mmr_offset, int right_shift,
- struct bau_control *bcp, long try)
- {
- unsigned long descriptor_stat;
- cycles_t ttm;
-- int cpu = bcp->uvhub_cpu;
-+ int desc = bcp->using_desc;
-+ long busy_reps = 0;
- struct ptc_stats *stat = bcp->statp;
-
-- descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu);
-+ descriptor_stat = uv2_read_status(mmr_offset, right_shift, desc);
-
- /* spin on the status MMR, waiting for it to go idle */
- while (descriptor_stat != UV2H_DESC_IDLE) {
-@@ -542,12 +655,23 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
- bcp->conseccompletes = 0;
- return FLUSH_RETRY_TIMEOUT;
- } else {
-+ busy_reps++;
-+ if (busy_reps > 1000000) {
-+ /* not to hammer on the clock */
-+ busy_reps = 0;
-+ ttm = get_cycles();
-+ if ((ttm - bcp->send_message) >
-+ (bcp->clocks_per_100_usec)) {
-+ return handle_uv2_busy(bcp);
-+ }
-+ }
- /*
- * descriptor_stat is still BUSY
- */
- cpu_relax();
- }
-- descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu);
-+ descriptor_stat = uv2_read_status(mmr_offset, right_shift,
-+ desc);
- }
- bcp->conseccompletes++;
- return FLUSH_COMPLETE;
-@@ -563,17 +687,17 @@ static int wait_completion(struct bau_desc *bau_desc,
- {
- int right_shift;
- unsigned long mmr_offset;
-- int cpu = bcp->uvhub_cpu;
-+ int desc = bcp->using_desc;
-
-- if (cpu < UV_CPUS_PER_AS) {
-+ if (desc < UV_CPUS_PER_AS) {
- mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
-- right_shift = cpu * UV_ACT_STATUS_SIZE;
-+ right_shift = desc * UV_ACT_STATUS_SIZE;
- } else {
- mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
-- right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
-+ right_shift = ((desc - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
- }
-
-- if (is_uv1_hub())
-+ if (bcp->uvhub_version == 1)
- return uv1_wait_completion(bau_desc, mmr_offset, right_shift,
- bcp, try);
- else
-@@ -752,19 +876,22 @@ static void handle_cmplt(int completion_status, struct bau_desc *bau_desc,
- * Returns 1 if it gives up entirely and the original cpu mask is to be
- * returned to the kernel.
- */
--int uv_flush_send_and_wait(struct bau_desc *bau_desc,
-- struct cpumask *flush_mask, struct bau_control *bcp)
-+int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp)
- {
- int seq_number = 0;
- int completion_stat = 0;
-+ int uv1 = 0;
- long try = 0;
- unsigned long index;
- cycles_t time1;
- cycles_t time2;
- struct ptc_stats *stat = bcp->statp;
- struct bau_control *hmaster = bcp->uvhub_master;
-+ struct uv1_bau_msg_header *uv1_hdr = NULL;
-+ struct uv2_bau_msg_header *uv2_hdr = NULL;
-+ struct bau_desc *bau_desc;
-
-- if (is_uv1_hub())
-+ if (bcp->uvhub_version == 1)
- uv1_throttle(hmaster, stat);
-
- while (hmaster->uvhub_quiesce)
-@@ -772,22 +899,39 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
-
- time1 = get_cycles();
- do {
-- if (try == 0) {
-- bau_desc->header.msg_type = MSG_REGULAR;
-+ bau_desc = bcp->descriptor_base;
-+ bau_desc += (ITEMS_PER_DESC * bcp->using_desc);
-+ if (bcp->uvhub_version == 1) {
-+ uv1 = 1;
-+ uv1_hdr = &bau_desc->header.uv1_hdr;
-+ } else
-+ uv2_hdr = &bau_desc->header.uv2_hdr;
-+ if ((try == 0) || (completion_stat == FLUSH_RETRY_BUSYBUG)) {
-+ if (uv1)
-+ uv1_hdr->msg_type = MSG_REGULAR;
-+ else
-+ uv2_hdr->msg_type = MSG_REGULAR;
- seq_number = bcp->message_number++;
- } else {
-- bau_desc->header.msg_type = MSG_RETRY;
-+ if (uv1)
-+ uv1_hdr->msg_type = MSG_RETRY;
-+ else
-+ uv2_hdr->msg_type = MSG_RETRY;
- stat->s_retry_messages++;
- }
-
-- bau_desc->header.sequence = seq_number;
-- index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu;
-+ if (uv1)
-+ uv1_hdr->sequence = seq_number;
-+ else
-+ uv2_hdr->sequence = seq_number;
-+ index = (1UL << AS_PUSH_SHIFT) | bcp->using_desc;
- bcp->send_message = get_cycles();
-
- write_mmr_activation(index);
-
- try++;
- completion_stat = wait_completion(bau_desc, bcp, try);
-+ /* UV2: wait_completion() may change the bcp->using_desc */
-
- handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat);
-
-@@ -798,6 +942,7 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
- }
- cpu_relax();
- } while ((completion_stat == FLUSH_RETRY_PLUGGED) ||
-+ (completion_stat == FLUSH_RETRY_BUSYBUG) ||
- (completion_stat == FLUSH_RETRY_TIMEOUT));
-
- time2 = get_cycles();
-@@ -812,6 +957,7 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
- record_send_stats(time1, time2, bcp, stat, completion_stat, try);
-
- if (completion_stat == FLUSH_GIVEUP)
-+ /* FLUSH_GIVEUP will fall back to using IPI's for tlb flush */
- return 1;
- return 0;
- }
-@@ -967,7 +1113,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
- stat->s_ntargself++;
-
- bau_desc = bcp->descriptor_base;
-- bau_desc += ITEMS_PER_DESC * bcp->uvhub_cpu;
-+ bau_desc += (ITEMS_PER_DESC * bcp->using_desc);
- bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
- if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes))
- return NULL;
-@@ -980,13 +1126,86 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
- * uv_flush_send_and_wait returns 0 if all cpu's were messaged,
- * or 1 if it gave up and the original cpumask should be returned.
- */
-- if (!uv_flush_send_and_wait(bau_desc, flush_mask, bcp))
-+ if (!uv_flush_send_and_wait(flush_mask, bcp))
- return NULL;
- else
- return cpumask;
- }
-
- /*
-+ * Search the message queue for any 'other' message with the same software
-+ * acknowledge resource bit vector.
-+ */
-+struct bau_pq_entry *find_another_by_swack(struct bau_pq_entry *msg,
-+ struct bau_control *bcp, unsigned char swack_vec)
-+{
-+ struct bau_pq_entry *msg_next = msg + 1;
-+
-+ if (msg_next > bcp->queue_last)
-+ msg_next = bcp->queue_first;
-+ while ((msg_next->swack_vec != 0) && (msg_next != msg)) {
-+ if (msg_next->swack_vec == swack_vec)
-+ return msg_next;
-+ msg_next++;
-+ if (msg_next > bcp->queue_last)
-+ msg_next = bcp->queue_first;
-+ }
-+ return NULL;
-+}
-+
-+/*
-+ * UV2 needs to work around a bug in which an arriving message has not
-+ * set a bit in the UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE register.
-+ * Such a message must be ignored.
-+ */
-+void process_uv2_message(struct msg_desc *mdp, struct bau_control *bcp)
-+{
-+ unsigned long mmr_image;
-+ unsigned char swack_vec;
-+ struct bau_pq_entry *msg = mdp->msg;
-+ struct bau_pq_entry *other_msg;
-+
-+ mmr_image = read_mmr_sw_ack();
-+ swack_vec = msg->swack_vec;
-+
-+ if ((swack_vec & mmr_image) == 0) {
-+ /*
-+ * This message was assigned a swack resource, but no
-+ * reserved acknowlegment is pending.
-+ * The bug has prevented this message from setting the MMR.
-+ * And no other message has used the same sw_ack resource.
-+ * Do the requested shootdown but do not reply to the msg.
-+ * (the 0 means make no acknowledge)
-+ */
-+ bau_process_message(mdp, bcp, 0);
-+ return;
-+ }
-+
-+ /*
-+ * Some message has set the MMR 'pending' bit; it might have been
-+ * another message. Look for that message.
-+ */
-+ other_msg = find_another_by_swack(msg, bcp, msg->swack_vec);
-+ if (other_msg) {
-+ /* There is another. Do not ack the current one. */
-+ bau_process_message(mdp, bcp, 0);
-+ /*
-+ * Let the natural processing of that message acknowledge
-+ * it. Don't get the processing of sw_ack's out of order.
-+ */
-+ return;
-+ }
-+
-+ /*
-+ * There is no other message using this sw_ack, so it is safe to
-+ * acknowledge it.
-+ */
-+ bau_process_message(mdp, bcp, 1);
-+
-+ return;
-+}
-+
-+/*
- * The BAU message interrupt comes here. (registered by set_intr_gate)
- * See entry_64.S
- *
-@@ -1022,9 +1241,11 @@ void uv_bau_message_interrupt(struct pt_regs *regs)
- count++;
-
- msgdesc.msg_slot = msg - msgdesc.queue_first;
-- msgdesc.swack_slot = ffs(msg->swack_vec) - 1;
- msgdesc.msg = msg;
-- bau_process_message(&msgdesc, bcp);
-+ if (bcp->uvhub_version == 2)
-+ process_uv2_message(&msgdesc, bcp);
-+ else
-+ bau_process_message(&msgdesc, bcp, 1);
-
- msg++;
- if (msg > msgdesc.queue_last)
-@@ -1083,7 +1304,7 @@ static void __init enable_timeouts(void)
- */
- mmr_image |= (1L << SOFTACK_MSHIFT);
- if (is_uv2_hub()) {
-- mmr_image |= (1L << UV2_LEG_SHFT);
-+ mmr_image &= ~(1L << UV2_LEG_SHFT);
- mmr_image |= (1L << UV2_EXT_SHFT);
- }
- write_mmr_misc_control(pnode, mmr_image);
-@@ -1142,7 +1363,7 @@ static int ptc_seq_show(struct seq_file *file, void *data)
- seq_printf(file,
- "all one mult none retry canc nocan reset rcan ");
- seq_printf(file,
-- "disable enable\n");
-+ "disable enable wars warshw warwaits\n");
- }
- if (cpu < num_possible_cpus() && cpu_online(cpu)) {
- stat = &per_cpu(ptcstats, cpu);
-@@ -1173,8 +1394,10 @@ static int ptc_seq_show(struct seq_file *file, void *data)
- stat->d_nomsg, stat->d_retries, stat->d_canceled,
- stat->d_nocanceled, stat->d_resets,
- stat->d_rcanceled);
-- seq_printf(file, "%ld %ld\n",
-- stat->s_bau_disabled, stat->s_bau_reenabled);
-+ seq_printf(file, "%ld %ld %ld %ld %ld\n",
-+ stat->s_bau_disabled, stat->s_bau_reenabled,
-+ stat->s_uv2_wars, stat->s_uv2_wars_hw,
-+ stat->s_uv2_war_waits);
- }
- return 0;
- }
-@@ -1432,12 +1655,15 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
- {
- int i;
- int cpu;
-+ int uv1 = 0;
- unsigned long gpa;
- unsigned long m;
- unsigned long n;
- size_t dsize;
- struct bau_desc *bau_desc;
- struct bau_desc *bd2;
-+ struct uv1_bau_msg_header *uv1_hdr;
-+ struct uv2_bau_msg_header *uv2_hdr;
- struct bau_control *bcp;
-
- /*
-@@ -1451,6 +1677,8 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
- gpa = uv_gpa(bau_desc);
- n = uv_gpa_to_gnode(gpa);
- m = uv_gpa_to_offset(gpa);
-+ if (is_uv1_hub())
-+ uv1 = 1;
-
- /* the 14-bit pnode */
- write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m));
-@@ -1461,21 +1689,33 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
- */
- for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) {
- memset(bd2, 0, sizeof(struct bau_desc));
-- bd2->header.swack_flag = 1;
-- /*
-- * The base_dest_nasid set in the message header is the nasid
-- * of the first uvhub in the partition. The bit map will
-- * indicate destination pnode numbers relative to that base.
-- * They may not be consecutive if nasid striding is being used.
-- */
-- bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode);
-- bd2->header.dest_subnodeid = UV_LB_SUBNODEID;
-- bd2->header.command = UV_NET_ENDPOINT_INTD;
-- bd2->header.int_both = 1;
-- /*
-- * all others need to be set to zero:
-- * fairness chaining multilevel count replied_to
-- */
-+ if (uv1) {
-+ uv1_hdr = &bd2->header.uv1_hdr;
-+ uv1_hdr->swack_flag = 1;
-+ /*
-+ * The base_dest_nasid set in the message header
-+ * is the nasid of the first uvhub in the partition.
-+ * The bit map will indicate destination pnode numbers
-+ * relative to that base. They may not be consecutive
-+ * if nasid striding is being used.
-+ */
-+ uv1_hdr->base_dest_nasid =
-+ UV_PNODE_TO_NASID(base_pnode);
-+ uv1_hdr->dest_subnodeid = UV_LB_SUBNODEID;
-+ uv1_hdr->command = UV_NET_ENDPOINT_INTD;
-+ uv1_hdr->int_both = 1;
-+ /*
-+ * all others need to be set to zero:
-+ * fairness chaining multilevel count replied_to
-+ */
-+ } else {
-+ uv2_hdr = &bd2->header.uv2_hdr;
-+ uv2_hdr->swack_flag = 1;
-+ uv2_hdr->base_dest_nasid =
-+ UV_PNODE_TO_NASID(base_pnode);
-+ uv2_hdr->dest_subnodeid = UV_LB_SUBNODEID;
-+ uv2_hdr->command = UV_NET_ENDPOINT_INTD;
-+ }
- }
- for_each_present_cpu(cpu) {
- if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu)))
-@@ -1531,6 +1771,7 @@ static void pq_init(int node, int pnode)
- write_mmr_payload_first(pnode, pn_first);
- write_mmr_payload_tail(pnode, first);
- write_mmr_payload_last(pnode, last);
-+ write_gmmr_sw_ack(pnode, 0xffffUL);
-
- /* in effect, all msg_type's are set to MSG_NOOP */
- memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE);
-@@ -1584,14 +1825,14 @@ static int calculate_destination_timeout(void)
- ts_ns = base * mult1 * mult2;
- ret = ts_ns / 1000;
- } else {
-- /* 4 bits 0/1 for 10/80us, 3 bits of multiplier */
-- mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL);
-+ /* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */
-+ mmr_image = uv_read_local_mmr(UVH_LB_BAU_MISC_CONTROL);
- mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT;
- if (mmr_image & (1L << UV2_ACK_UNITS_SHFT))
-- mult1 = 80;
-+ base = 80;
- else
-- mult1 = 10;
-- base = mmr_image & UV2_ACK_MASK;
-+ base = 10;
-+ mult1 = mmr_image & UV2_ACK_MASK;
- ret = mult1 * base;
- }
- return ret;
-@@ -1618,6 +1859,7 @@ static void __init init_per_cpu_tunables(void)
- bcp->cong_response_us = congested_respns_us;
- bcp->cong_reps = congested_reps;
- bcp->cong_period = congested_period;
-+ bcp->clocks_per_100_usec = usec_2_cycles(100);
- }
- }
-
-@@ -1728,8 +1970,17 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
- bcp->cpus_in_socket = sdp->num_cpus;
- bcp->socket_master = *smasterp;
- bcp->uvhub = bdp->uvhub;
-+ if (is_uv1_hub())
-+ bcp->uvhub_version = 1;
-+ else if (is_uv2_hub())
-+ bcp->uvhub_version = 2;
-+ else {
-+ printk(KERN_EMERG "uvhub version not 1 or 2\n");
-+ return 1;
-+ }
- bcp->uvhub_master = *hmasterp;
- bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id;
-+ bcp->using_desc = bcp->uvhub_cpu;
- if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
- printk(KERN_EMERG "%d cpus per uvhub invalid\n",
- bcp->uvhub_cpu);
-@@ -1845,6 +2096,8 @@ static int __init uv_bau_init(void)
- uv_base_pnode = uv_blade_to_pnode(uvhub);
- }
-
-+ enable_timeouts();
-+
- if (init_per_cpu(nuvhubs, uv_base_pnode)) {
- nobau = 1;
- return 0;
-@@ -1855,7 +2108,6 @@ static int __init uv_bau_init(void)
- if (uv_blade_nr_possible_cpus(uvhub))
- init_uvhub(uvhub, vector, uv_base_pnode);
-
-- enable_timeouts();
- alloc_intr_gate(vector, uv_bau_message_intr1);
-
- for_each_possible_blade(uvhub) {
-@@ -1867,7 +2119,8 @@ static int __init uv_bau_init(void)
- val = 1L << 63;
- write_gmmr_activation(pnode, val);
- mmr = 1; /* should be 1 to broadcast to both sockets */
-- write_mmr_data_broadcast(pnode, mmr);
-+ if (!is_uv1_hub())
-+ write_mmr_data_broadcast(pnode, mmr);
- }
- }
-
-diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
-index fbdf0d8..688be8a 100644
---- a/block/scsi_ioctl.c
-+++ b/block/scsi_ioctl.c
-@@ -24,6 +24,7 @@
- #include <linux/capability.h>
- #include <linux/completion.h>
- #include <linux/cdrom.h>
-+#include <linux/ratelimit.h>
- #include <linux/slab.h>
- #include <linux/times.h>
- #include <asm/uaccess.h>
-@@ -690,6 +691,57 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
- }
- EXPORT_SYMBOL(scsi_cmd_ioctl);
-
-+int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
-+{
-+ if (bd && bd == bd->bd_contains)
-+ return 0;
-+
-+ /* Actually none of these is particularly useful on a partition,
-+ * but they are safe.
-+ */
-+ switch (cmd) {
-+ case SCSI_IOCTL_GET_IDLUN:
-+ case SCSI_IOCTL_GET_BUS_NUMBER:
-+ case SCSI_IOCTL_GET_PCI:
-+ case SCSI_IOCTL_PROBE_HOST:
-+ case SG_GET_VERSION_NUM:
-+ case SG_SET_TIMEOUT:
-+ case SG_GET_TIMEOUT:
-+ case SG_GET_RESERVED_SIZE:
-+ case SG_SET_RESERVED_SIZE:
-+ case SG_EMULATED_HOST:
-+ return 0;
-+ case CDROM_GET_CAPABILITY:
-+ /* Keep this until we remove the printk below. udev sends it
-+ * and we do not want to spam dmesg about it. CD-ROMs do
-+ * not have partitions, so we get here only for disks.
-+ */
-+ return -ENOTTY;
-+ default:
-+ break;
-+ }
-+
-+ /* In particular, rule out all resets and host-specific ioctls. */
-+ printk_ratelimited(KERN_WARNING
-+ "%s: sending ioctl %x to a partition!\n", current->comm, cmd);
-+
-+ return capable(CAP_SYS_RAWIO) ? 0 : -ENOTTY;
-+}
-+EXPORT_SYMBOL(scsi_verify_blk_ioctl);
-+
-+int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
-+ unsigned int cmd, void __user *arg)
-+{
-+ int ret;
-+
-+ ret = scsi_verify_blk_ioctl(bd, cmd);
-+ if (ret < 0)
-+ return ret;
-+
-+ return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
-+}
-+EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
-+
- static int __init blk_scsi_ioctl_init(void)
- {
- blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
-diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c
-index 8c7b997..42163d8 100644
---- a/drivers/acpi/acpica/dsargs.c
-+++ b/drivers/acpi/acpica/dsargs.c
-@@ -387,5 +387,29 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
- status = acpi_ds_execute_arguments(node, node->parent,
- extra_desc->extra.aml_length,
- extra_desc->extra.aml_start);
-+ if (ACPI_FAILURE(status)) {
-+ return_ACPI_STATUS(status);
-+ }
-+
-+ /* Validate the region address/length via the host OS */
-+
-+ status = acpi_os_validate_address(obj_desc->region.space_id,
-+ obj_desc->region.address,
-+ (acpi_size) obj_desc->region.length,
-+ acpi_ut_get_node_name(node));
-+
-+ if (ACPI_FAILURE(status)) {
-+ /*
-+ * Invalid address/length. We will emit an error message and mark
-+ * the region as invalid, so that it will cause an additional error if
-+ * it is ever used. Then return AE_OK.
-+ */
-+ ACPI_EXCEPTION((AE_INFO, status,
-+ "During address validation of OpRegion [%4.4s]",
-+ node->name.ascii));
-+ obj_desc->common.flags |= AOPOBJ_INVALID;
-+ status = AE_OK;
-+ }
-+
- return_ACPI_STATUS(status);
- }
-diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
-index 3b5c318..e56f3be 100644
---- a/drivers/acpi/numa.c
-+++ b/drivers/acpi/numa.c
-@@ -45,6 +45,8 @@ static int pxm_to_node_map[MAX_PXM_DOMAINS]
- static int node_to_pxm_map[MAX_NUMNODES]
- = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
-
-+unsigned char acpi_srat_revision __initdata;
-+
- int pxm_to_node(int pxm)
- {
- if (pxm < 0)
-@@ -255,9 +257,13 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header,
-
- static int __init acpi_parse_srat(struct acpi_table_header *table)
- {
-+ struct acpi_table_srat *srat;
- if (!table)
- return -EINVAL;
-
-+ srat = (struct acpi_table_srat *)table;
-+ acpi_srat_revision = srat->header.revision;
-+
- /* Real work done in acpi_table_parse_srat below. */
-
- return 0;
-diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
-index 3a0428e..c850de4 100644
---- a/drivers/acpi/processor_core.c
-+++ b/drivers/acpi/processor_core.c
-@@ -173,8 +173,30 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
- apic_id = map_mat_entry(handle, type, acpi_id);
- if (apic_id == -1)
- apic_id = map_madt_entry(type, acpi_id);
-- if (apic_id == -1)
-- return apic_id;
-+ if (apic_id == -1) {
-+ /*
-+ * On UP processor, there is no _MAT or MADT table.
-+ * So above apic_id is always set to -1.
-+ *
-+ * BIOS may define multiple CPU handles even for UP processor.
-+ * For example,
-+ *
-+ * Scope (_PR)
-+ * {
-+ * Processor (CPU0, 0x00, 0x00000410, 0x06) {}
-+ * Processor (CPU1, 0x01, 0x00000410, 0x06) {}
-+ * Processor (CPU2, 0x02, 0x00000410, 0x06) {}
-+ * Processor (CPU3, 0x03, 0x00000410, 0x06) {}
-+ * }
-+ *
-+ * Ignores apic_id and always return 0 for CPU0's handle.
-+ * Return -1 for other CPU's handle.
-+ */
-+ if (acpi_id == 0)
-+ return acpi_id;
-+ else
-+ return apic_id;
-+ }
-
- #ifdef CONFIG_SMP
- for_each_possible_cpu(i) {
-diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
-index 990f5a8..48e06be 100644
---- a/drivers/bcma/host_pci.c
-+++ b/drivers/bcma/host_pci.c
-@@ -227,11 +227,14 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
- #ifdef CONFIG_PM
- static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
- {
-+ struct bcma_bus *bus = pci_get_drvdata(dev);
-+
- /* Host specific */
- pci_save_state(dev);
- pci_disable_device(dev);
- pci_set_power_state(dev, pci_choose_state(dev, state));
-
-+ bus->mapped_core = NULL;
- return 0;
- }
-
-diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
-index 587cce5..b0f553b 100644
---- a/drivers/block/cciss.c
-+++ b/drivers/block/cciss.c
-@@ -1735,7 +1735,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
- case CCISS_BIG_PASSTHRU:
- return cciss_bigpassthru(h, argp);
-
-- /* scsi_cmd_ioctl handles these, below, though some are not */
-+ /* scsi_cmd_blk_ioctl handles these, below, though some are not */
- /* very meaningful for cciss. SG_IO is the main one people want. */
-
- case SG_GET_VERSION_NUM:
-@@ -1746,9 +1746,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
- case SG_EMULATED_HOST:
- case SG_IO:
- case SCSI_IOCTL_SEND_COMMAND:
-- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
-+ return scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
-
-- /* scsi_cmd_ioctl would normally handle these, below, but */
-+ /* scsi_cmd_blk_ioctl would normally handle these, below, but */
- /* they aren't a good fit for cciss, as CD-ROMs are */
- /* not supported, and we don't have any bus/target/lun */
- /* which we present to the kernel. */
-diff --git a/drivers/block/ub.c b/drivers/block/ub.c
-index 0e376d4..7333b9e 100644
---- a/drivers/block/ub.c
-+++ b/drivers/block/ub.c
-@@ -1744,12 +1744,11 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode)
- static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
- {
-- struct gendisk *disk = bdev->bd_disk;
- void __user *usermem = (void __user *) arg;
- int ret;
-
- mutex_lock(&ub_mutex);
-- ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem);
-+ ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, usermem);
- mutex_unlock(&ub_mutex);
-
- return ret;
-diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
-index 4d0b70a..e46f2f7 100644
---- a/drivers/block/virtio_blk.c
-+++ b/drivers/block/virtio_blk.c
-@@ -243,8 +243,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
- if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
- return -ENOTTY;
-
-- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
-- (void __user *)data);
-+ return scsi_cmd_blk_ioctl(bdev, mode, cmd,
-+ (void __user *)data);
- }
-
- /* We provide getgeo only to please some old bootloader/partitioning tools */
-diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
-index f997c27..cedb231 100644
---- a/drivers/cdrom/cdrom.c
-+++ b/drivers/cdrom/cdrom.c
-@@ -2747,12 +2747,11 @@ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
- {
- void __user *argp = (void __user *)arg;
- int ret;
-- struct gendisk *disk = bdev->bd_disk;
-
- /*
- * Try the generic SCSI command ioctl's first.
- */
-- ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
-+ ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
- if (ret != -ENOTTY)
- return ret;
-
-diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
-index bfc08f6..31b0d1a 100644
---- a/drivers/gpu/drm/radeon/r100.c
-+++ b/drivers/gpu/drm/radeon/r100.c
-@@ -2177,6 +2177,7 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev)
- void r100_bm_disable(struct radeon_device *rdev)
- {
- u32 tmp;
-+ u16 tmp16;
-
- /* disable bus mastering */
- tmp = RREG32(R_000030_BUS_CNTL);
-@@ -2187,8 +2188,8 @@ void r100_bm_disable(struct radeon_device *rdev)
- WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
- tmp = RREG32(RADEON_BUS_CNTL);
- mdelay(1);
-- pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
-- pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
-+ pci_read_config_word(rdev->pdev, 0x4, &tmp16);
-+ pci_write_config_word(rdev->pdev, 0x4, tmp16 & 0xFFFB);
- mdelay(1);
- }
-
-diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
-index f5ac7e7..c45d921 100644
---- a/drivers/gpu/drm/radeon/r600_hdmi.c
-+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
-@@ -196,6 +196,13 @@ static void r600_hdmi_videoinfoframe(
- frame[0xD] = (right_bar >> 8);
-
- r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
-+ /* Our header values (type, version, length) should be alright, Intel
-+ * is using the same. Checksum function also seems to be OK, it works
-+ * fine for audio infoframe. However calculated value is always lower
-+ * by 2 in comparison to fglrx. It breaks displaying anything in case
-+ * of TVs that strictly check the checksum. Hack it manually here to
-+ * workaround this issue. */
-+ frame[0x0] += 2;
-
- WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
- frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
-diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
-index c4d00a1..9b39145 100644
---- a/drivers/gpu/drm/radeon/radeon_device.c
-+++ b/drivers/gpu/drm/radeon/radeon_device.c
-@@ -224,8 +224,11 @@ int radeon_wb_init(struct radeon_device *rdev)
- if (radeon_no_wb == 1)
- rdev->wb.enabled = false;
- else {
-- /* often unreliable on AGP */
- if (rdev->flags & RADEON_IS_AGP) {
-+ /* often unreliable on AGP */
-+ rdev->wb.enabled = false;
-+ } else if (rdev->family < CHIP_R300) {
-+ /* often unreliable on pre-r300 */
- rdev->wb.enabled = false;
- } else {
- rdev->wb.enabled = true;
-diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
-index b1053d6..c259e21 100644
---- a/drivers/gpu/drm/radeon/rs600.c
-+++ b/drivers/gpu/drm/radeon/rs600.c
-@@ -324,10 +324,10 @@ void rs600_hpd_fini(struct radeon_device *rdev)
-
- void rs600_bm_disable(struct radeon_device *rdev)
- {
-- u32 tmp;
-+ u16 tmp;
-
- /* disable bus mastering */
-- pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
-+ pci_read_config_word(rdev->pdev, 0x4, &tmp);
- pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
- mdelay(1);
- }
-diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
-index 22a4a05..d21f6d0 100644
---- a/drivers/hid/Kconfig
-+++ b/drivers/hid/Kconfig
-@@ -335,6 +335,7 @@ config HID_MULTITOUCH
- Say Y here if you have one of the following devices:
- - 3M PCT touch screens
- - ActionStar dual touch panels
-+ - Atmel panels
- - Cando dual touch panels
- - Chunghwa panels
- - CVTouch panels
-@@ -355,6 +356,7 @@ config HID_MULTITOUCH
- - Touch International Panels
- - Unitec Panels
- - XAT optical touch panels
-+ - Xiroku optical touch panels
-
- If unsure, say N.
-
-@@ -620,6 +622,7 @@ config HID_WIIMOTE
- depends on BT_HIDP
- depends on LEDS_CLASS
- select POWER_SUPPLY
-+ select INPUT_FF_MEMLESS
- ---help---
- Support for the Nintendo Wii Remote bluetooth device.
-
-diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
-index af35384..bb656d8 100644
---- a/drivers/hid/hid-core.c
-+++ b/drivers/hid/hid-core.c
-@@ -362,7 +362,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
-
- case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
- parser->global.report_size = item_udata(item);
-- if (parser->global.report_size > 32) {
-+ if (parser->global.report_size > 96) {
- dbg_hid("invalid report_size %d\n",
- parser->global.report_size);
- return -1;
-@@ -1404,11 +1404,13 @@ static const struct hid_device_id hid_have_special_driver[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
- { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
-- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
-- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
-- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
-- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
-- { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
- { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) },
- { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
-@@ -1423,6 +1425,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) },
- { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
-@@ -1549,6 +1552,15 @@ static const struct hid_device_id hid_have_special_driver[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
- { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX1) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX1) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR1) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_SPX2) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_MPX2) },
-+ { HID_USB_DEVICE(USB_VENDOR_ID_XIROKU, USB_DEVICE_ID_XIROKU_CSR2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
- { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
-diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
-index 4a441a6..00cabb3 100644
---- a/drivers/hid/hid-ids.h
-+++ b/drivers/hid/hid-ids.h
-@@ -21,6 +21,7 @@
- #define USB_VENDOR_ID_3M 0x0596
- #define USB_DEVICE_ID_3M1968 0x0500
- #define USB_DEVICE_ID_3M2256 0x0502
-+#define USB_DEVICE_ID_3M3266 0x0506
-
- #define USB_VENDOR_ID_A4TECH 0x09da
- #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
-@@ -145,6 +146,9 @@
- #define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
- #define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208
-
-+#define USB_VENDOR_ID_ATMEL 0x03eb
-+#define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c
-+
- #define USB_VENDOR_ID_AVERMEDIA 0x07ca
- #define USB_DEVICE_ID_AVER_FM_MR800 0xb800
-
-@@ -230,11 +234,14 @@
-
- #define USB_VENDOR_ID_DWAV 0x0eef
- #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
--#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
--#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c
--#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2 0x72a1
--#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3 0x480e
--#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4 0x726b
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302
-+#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001
-
- #define USB_VENDOR_ID_ELECOM 0x056e
- #define USB_DEVICE_ID_ELECOM_BM084 0x0061
-@@ -356,6 +363,9 @@
- #define USB_VENDOR_ID_HANVON 0x20b3
- #define USB_DEVICE_ID_HANVON_MULTITOUCH 0x0a18
-
-+#define USB_VENDOR_ID_HANVON_ALT 0x22ed
-+#define USB_DEVICE_ID_HANVON_ALT_MULTITOUCH 0x1010
-+
- #define USB_VENDOR_ID_HAPP 0x078b
- #define USB_DEVICE_ID_UGCI_DRIVING 0x0010
- #define USB_DEVICE_ID_UGCI_FLYING 0x0020
-@@ -707,6 +717,17 @@
- #define USB_VENDOR_ID_XAT 0x2505
- #define USB_DEVICE_ID_XAT_CSR 0x0220
-
-+#define USB_VENDOR_ID_XIROKU 0x1477
-+#define USB_DEVICE_ID_XIROKU_SPX 0x1006
-+#define USB_DEVICE_ID_XIROKU_MPX 0x1007
-+#define USB_DEVICE_ID_XIROKU_CSR 0x100e
-+#define USB_DEVICE_ID_XIROKU_SPX1 0x1021
-+#define USB_DEVICE_ID_XIROKU_CSR1 0x1022
-+#define USB_DEVICE_ID_XIROKU_MPX1 0x1023
-+#define USB_DEVICE_ID_XIROKU_SPX2 0x1024
-+#define USB_DEVICE_ID_XIROKU_CSR2 0x1025
-+#define USB_DEVICE_ID_XIROKU_MPX2 0x1026
-+
- #define USB_VENDOR_ID_YEALINK 0x6993
- #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
-
-diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
-index f1c909f..995fc4c 100644
---- a/drivers/hid/hid-multitouch.c
-+++ b/drivers/hid/hid-multitouch.c
-@@ -609,12 +609,20 @@ static const struct hid_device_id mt_devices[] = {
- { .driver_data = MT_CLS_3M,
- HID_USB_DEVICE(USB_VENDOR_ID_3M,
- USB_DEVICE_ID_3M2256) },
-+ { .driver_data = MT_CLS_3M,
-+ HID_USB_DEVICE(USB_VENDOR_ID_3M,
-+ USB_DEVICE_ID_3M3266) },
-
- /* ActionStar panels */
- { .driver_data = MT_CLS_DEFAULT,
- HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR,
- USB_DEVICE_ID_ACTIONSTAR_1011) },
-
-+ /* Atmel panels */
-+ { .driver_data = MT_CLS_SERIAL,
-+ HID_USB_DEVICE(USB_VENDOR_ID_ATMEL,
-+ USB_DEVICE_ID_ATMEL_MULTITOUCH) },
-+
- /* Cando panels */
- { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
- HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
-@@ -645,23 +653,32 @@ static const struct hid_device_id mt_devices[] = {
- USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
-
- /* eGalax devices (resistive) */
-- { .driver_data = MT_CLS_EGALAX,
-+ { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
-- { .driver_data = MT_CLS_EGALAX,
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
-+ { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
-
- /* eGalax devices (capacitive) */
-- { .driver_data = MT_CLS_EGALAX,
-+ { .driver_data = MT_CLS_EGALAX,
-+ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
-+ { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
-- { .driver_data = MT_CLS_EGALAX,
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
-+ { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
-- { .driver_data = MT_CLS_EGALAX,
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
-+ { .driver_data = MT_CLS_EGALAX,
- HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-- USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) },
-+ { .driver_data = MT_CLS_EGALAX,
-+ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
-+ { .driver_data = MT_CLS_EGALAX,
-+ HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-+ USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
-
- /* Elo TouchSystems IntelliTouch Plus panel */
- { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID,
-@@ -678,6 +695,11 @@ static const struct hid_device_id mt_devices[] = {
- HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
- USB_DEVICE_ID_GOODTOUCH_000f) },
-
-+ /* Hanvon panels */
-+ { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
-+ HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
-+ USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
-+
- /* Ideacom panel */
- { .driver_data = MT_CLS_SERIAL,
- HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
-@@ -758,6 +780,35 @@ static const struct hid_device_id mt_devices[] = {
- HID_USB_DEVICE(USB_VENDOR_ID_XAT,
- USB_DEVICE_ID_XAT_CSR) },
-
-+ /* Xiroku */
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_SPX) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_MPX) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_CSR) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_SPX1) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_MPX1) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_CSR1) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_SPX2) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_MPX2) },
-+ { .driver_data = MT_CLS_DEFAULT,
-+ HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
-+ USB_DEVICE_ID_XIROKU_CSR2) },
-+
- { }
- };
- MODULE_DEVICE_TABLE(hid, mt_devices);
-diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
-index b6807db..5b667e5 100644
---- a/drivers/i2c/busses/i2c-ali1535.c
-+++ b/drivers/i2c/busses/i2c-ali1535.c
-@@ -140,7 +140,7 @@ static unsigned short ali1535_smba;
- defined to make the transition easier. */
- static int __devinit ali1535_setup(struct pci_dev *dev)
- {
-- int retval = -ENODEV;
-+ int retval;
- unsigned char temp;
-
- /* Check the following things:
-@@ -155,6 +155,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
- if (ali1535_smba == 0) {
- dev_warn(&dev->dev,
- "ALI1535_smb region uninitialized - upgrade BIOS?\n");
-+ retval = -ENODEV;
- goto exit;
- }
-
-@@ -167,6 +168,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
- ali1535_driver.name)) {
- dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
- ali1535_smba);
-+ retval = -EBUSY;
- goto exit;
- }
-
-@@ -174,6 +176,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
- pci_read_config_byte(dev, SMBCFG, &temp);
- if ((temp & ALI1535_SMBIO_EN) == 0) {
- dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
-+ retval = -ENODEV;
- goto exit_free;
- }
-
-@@ -181,6 +184,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
- pci_read_config_byte(dev, SMBHSTCFG, &temp);
- if ((temp & 1) == 0) {
- dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
-+ retval = -ENODEV;
- goto exit_free;
- }
-
-@@ -198,12 +202,11 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
- dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
- dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba);
-
-- retval = 0;
--exit:
-- return retval;
-+ return 0;
-
- exit_free:
- release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
-+exit:
- return retval;
- }
-
-diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
-index 18936ac..730215e 100644
---- a/drivers/i2c/busses/i2c-eg20t.c
-+++ b/drivers/i2c/busses/i2c-eg20t.c
-@@ -243,7 +243,7 @@ static void pch_i2c_init(struct i2c_algo_pch_data *adap)
- if (pch_clk > PCH_MAX_CLK)
- pch_clk = 62500;
-
-- pch_i2cbc = (pch_clk + (pch_i2c_speed * 4)) / pch_i2c_speed * 8;
-+ pch_i2cbc = (pch_clk + (pch_i2c_speed * 4)) / (pch_i2c_speed * 8);
- /* Set transfer speed in I2CBC */
- iowrite32(pch_i2cbc, p + PCH_I2CBC);
-
-diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
-index ff1e127..4853b52 100644
---- a/drivers/i2c/busses/i2c-nforce2.c
-+++ b/drivers/i2c/busses/i2c-nforce2.c
-@@ -356,7 +356,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
- error = acpi_check_region(smbus->base, smbus->size,
- nforce2_driver.name);
- if (error)
-- return -1;
-+ return error;
-
- if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
- dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
-diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
-index fa23faa..257c1a5 100644
---- a/drivers/i2c/busses/i2c-omap.c
-+++ b/drivers/i2c/busses/i2c-omap.c
-@@ -235,7 +235,7 @@ static const u8 reg_map_ip_v2[] = {
- [OMAP_I2C_BUF_REG] = 0x94,
- [OMAP_I2C_CNT_REG] = 0x98,
- [OMAP_I2C_DATA_REG] = 0x9c,
-- [OMAP_I2C_SYSC_REG] = 0x20,
-+ [OMAP_I2C_SYSC_REG] = 0x10,
- [OMAP_I2C_CON_REG] = 0xa4,
- [OMAP_I2C_OA_REG] = 0xa8,
- [OMAP_I2C_SA_REG] = 0xac,
-diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
-index 4375866..6d60284 100644
---- a/drivers/i2c/busses/i2c-sis5595.c
-+++ b/drivers/i2c/busses/i2c-sis5595.c
-@@ -147,7 +147,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
- u16 a;
- u8 val;
- int *i;
-- int retval = -ENODEV;
-+ int retval;
-
- /* Look for imposters */
- for (i = blacklist; *i != 0; i++) {
-@@ -223,7 +223,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
-
- error:
- release_region(sis5595_base + SMB_INDEX, 2);
-- return retval;
-+ return -ENODEV;
- }
-
- static int sis5595_transaction(struct i2c_adapter *adap)
-diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
-index e6f539e..b617fd0 100644
---- a/drivers/i2c/busses/i2c-sis630.c
-+++ b/drivers/i2c/busses/i2c-sis630.c
-@@ -393,7 +393,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev)
- {
- unsigned char b;
- struct pci_dev *dummy = NULL;
-- int retval = -ENODEV, i;
-+ int retval, i;
-
- /* check for supported SiS devices */
- for (i=0; supported[i] > 0 ; i++) {
-@@ -418,18 +418,21 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev)
- */
- if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
- dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
-+ retval = -ENODEV;
- goto exit;
- }
- /* if ACPI already enabled , do nothing */
- if (!(b & 0x80) &&
- pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
- dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
-+ retval = -ENODEV;
- goto exit;
- }
-
- /* Determine the ACPI base address */
- if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
- dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
-+ retval = -ENODEV;
- goto exit;
- }
-
-@@ -445,6 +448,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev)
- sis630_driver.name)) {
- dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
- "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
-+ retval = -EBUSY;
- goto exit;
- }
-
-diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
-index 0b012f1..58261d4 100644
---- a/drivers/i2c/busses/i2c-viapro.c
-+++ b/drivers/i2c/busses/i2c-viapro.c
-@@ -324,7 +324,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
- {
- unsigned char temp;
-- int error = -ENODEV;
-+ int error;
-
- /* Determine the address of the SMBus areas */
- if (force_addr) {
-@@ -390,6 +390,7 @@ found:
- dev_err(&pdev->dev, "SMBUS: Error: Host SMBus "
- "controller not enabled! - upgrade BIOS or "
- "use force=1\n");
-+ error = -ENODEV;
- goto release_region;
- }
- }
-@@ -422,9 +423,11 @@ found:
- "SMBus Via Pro adapter at %04x", vt596_smba);
-
- vt596_pdev = pci_dev_get(pdev);
-- if (i2c_add_adapter(&vt596_adapter)) {
-+ error = i2c_add_adapter(&vt596_adapter);
-+ if (error) {
- pci_dev_put(vt596_pdev);
- vt596_pdev = NULL;
-+ goto release_region;
- }
-
- /* Always return failure here. This is to allow other drivers to bind
-diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
-index d267b7a..a22ca84 100644
---- a/drivers/ide/ide-floppy_ioctl.c
-+++ b/drivers/ide/ide-floppy_ioctl.c
-@@ -292,8 +292,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
- * and CDROM_SEND_PACKET (legacy) ioctls
- */
- if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
-- err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk,
-- mode, cmd, argp);
-+ err = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
-
- if (err == -ENOTTY)
- err = generic_ide_ioctl(drive, bdev, cmd, arg);
-diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
-index 5d2f8e1..5b39216 100644
---- a/drivers/idle/intel_idle.c
-+++ b/drivers/idle/intel_idle.c
-@@ -348,7 +348,8 @@ static int intel_idle_probe(void)
- cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates);
-
- if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
-- !(ecx & CPUID5_ECX_INTERRUPT_BREAK))
-+ !(ecx & CPUID5_ECX_INTERRUPT_BREAK) ||
-+ !mwait_substates)
- return -ENODEV;
-
- pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
-@@ -394,7 +395,7 @@ static int intel_idle_probe(void)
- if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
- lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
- else {
-- smp_call_function(__setup_broadcast_timer, (void *)true, 1);
-+ on_each_cpu(__setup_broadcast_timer, (void *)true, 1);
- register_cpu_notifier(&setup_broadcast_notifier);
- }
-
-@@ -471,7 +472,7 @@ static int intel_idle_cpuidle_driver_init(void)
- }
-
- if (auto_demotion_disable_flags)
-- smp_call_function(auto_demotion_disable, NULL, 1);
-+ on_each_cpu(auto_demotion_disable, NULL, 1);
-
- return 0;
- }
-@@ -568,7 +569,7 @@ static void __exit intel_idle_exit(void)
- cpuidle_unregister_driver(&intel_idle_driver);
-
- if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) {
-- smp_call_function(__setup_broadcast_timer, (void *)false, 1);
-+ on_each_cpu(__setup_broadcast_timer, (void *)false, 1);
- unregister_cpu_notifier(&setup_broadcast_notifier);
- }
-
-diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
-index f84c080..9fb18c1 100644
---- a/drivers/md/dm-flakey.c
-+++ b/drivers/md/dm-flakey.c
-@@ -368,8 +368,17 @@ static int flakey_status(struct dm_target *ti, status_type_t type,
- static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg)
- {
- struct flakey_c *fc = ti->private;
-+ struct dm_dev *dev = fc->dev;
-+ int r = 0;
-
-- return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg);
-+ /*
-+ * Only pass ioctls through if the device sizes match exactly.
-+ */
-+ if (fc->start ||
-+ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
-+ r = scsi_verify_blk_ioctl(NULL, cmd);
-+
-+ return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
- }
-
- static int flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
-diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
-index 3921e3b..9728839 100644
---- a/drivers/md/dm-linear.c
-+++ b/drivers/md/dm-linear.c
-@@ -116,7 +116,17 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
- unsigned long arg)
- {
- struct linear_c *lc = (struct linear_c *) ti->private;
-- return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg);
-+ struct dm_dev *dev = lc->dev;
-+ int r = 0;
-+
-+ /*
-+ * Only pass ioctls through if the device sizes match exactly.
-+ */
-+ if (lc->start ||
-+ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
-+ r = scsi_verify_blk_ioctl(NULL, cmd);
-+
-+ return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
- }
-
- static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
-diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
-index 5e0090e..801d92d 100644
---- a/drivers/md/dm-mpath.c
-+++ b/drivers/md/dm-mpath.c
-@@ -1520,6 +1520,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
-
- spin_unlock_irqrestore(&m->lock, flags);
-
-+ /*
-+ * Only pass ioctls through if the device sizes match exactly.
-+ */
-+ if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
-+ r = scsi_verify_blk_ioctl(NULL, cmd);
-+
- return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
- }
-
-diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
-index ede2461..7d9e071 100644
---- a/drivers/md/raid1.c
-+++ b/drivers/md/raid1.c
-@@ -525,8 +525,17 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
- if (test_bit(WriteMostly, &rdev->flags)) {
- /* Don't balance among write-mostly, just
- * use the first as a last resort */
-- if (best_disk < 0)
-+ if (best_disk < 0) {
-+ if (is_badblock(rdev, this_sector, sectors,
-+ &first_bad, &bad_sectors)) {
-+ if (first_bad < this_sector)
-+ /* Cannot use this */
-+ continue;
-+ best_good_sectors = first_bad - this_sector;
-+ } else
-+ best_good_sectors = sectors;
- best_disk = disk;
-+ }
- continue;
- }
- /* This is a reasonable device to use. It might
-diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
-index bcb45be..f0482b2 100644
---- a/drivers/media/video/cx23885/cx23885-dvb.c
-+++ b/drivers/media/video/cx23885/cx23885-dvb.c
-@@ -940,6 +940,11 @@ static int dvb_register(struct cx23885_tsport *port)
-
- fe = dvb_attach(xc4000_attach, fe0->dvb.frontend,
- &dev->i2c_bus[1].i2c_adap, &cfg);
-+ if (!fe) {
-+ printk(KERN_ERR "%s/2: xc4000 attach failed\n",
-+ dev->name);
-+ goto frontend_detach;
-+ }
- }
- break;
- case CX23885_BOARD_TBS_6920:
-diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
-index 0d719fa..3929d93 100644
---- a/drivers/media/video/cx88/cx88-cards.c
-+++ b/drivers/media/video/cx88/cx88-cards.c
-@@ -1573,8 +1573,8 @@ static const struct cx88_board cx88_boards[] = {
- .name = "Pinnacle Hybrid PCTV",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
-- .radio_type = TUNER_XC2028,
-- .radio_addr = 0x61,
-+ .radio_type = UNSET,
-+ .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
-@@ -1611,8 +1611,8 @@ static const struct cx88_board cx88_boards[] = {
- .name = "Leadtek TV2000 XP Global",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
-- .radio_type = TUNER_XC2028,
-- .radio_addr = 0x61,
-+ .radio_type = UNSET,
-+ .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
-@@ -2043,8 +2043,8 @@ static const struct cx88_board cx88_boards[] = {
- .name = "Terratec Cinergy HT PCI MKII",
- .tuner_type = TUNER_XC2028,
- .tuner_addr = 0x61,
-- .radio_type = TUNER_XC2028,
-- .radio_addr = 0x61,
-+ .radio_type = UNSET,
-+ .radio_addr = ADDR_UNSET,
- .input = { {
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
-@@ -2082,9 +2082,9 @@ static const struct cx88_board cx88_boards[] = {
- [CX88_BOARD_WINFAST_DTV1800H] = {
- .name = "Leadtek WinFast DTV1800 Hybrid",
- .tuner_type = TUNER_XC2028,
-- .radio_type = TUNER_XC2028,
-+ .radio_type = UNSET,
- .tuner_addr = 0x61,
-- .radio_addr = 0x61,
-+ .radio_addr = ADDR_UNSET,
- /*
- * GPIO setting
- *
-@@ -2123,9 +2123,9 @@ static const struct cx88_board cx88_boards[] = {
- [CX88_BOARD_WINFAST_DTV1800H_XC4000] = {
- .name = "Leadtek WinFast DTV1800 H (XC4000)",
- .tuner_type = TUNER_XC4000,
-- .radio_type = TUNER_XC4000,
-+ .radio_type = UNSET,
- .tuner_addr = 0x61,
-- .radio_addr = 0x61,
-+ .radio_addr = ADDR_UNSET,
- /*
- * GPIO setting
- *
-@@ -2164,9 +2164,9 @@ static const struct cx88_board cx88_boards[] = {
- [CX88_BOARD_WINFAST_DTV2000H_PLUS] = {
- .name = "Leadtek WinFast DTV2000 H PLUS",
- .tuner_type = TUNER_XC4000,
-- .radio_type = TUNER_XC4000,
-+ .radio_type = UNSET,
- .tuner_addr = 0x61,
-- .radio_addr = 0x61,
-+ .radio_addr = ADDR_UNSET,
- /*
- * GPIO
- * 2: 1: mute audio
-diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
-index dadf11f..cf7788f 100644
---- a/drivers/media/video/uvc/uvc_v4l2.c
-+++ b/drivers/media/video/uvc/uvc_v4l2.c
-@@ -58,6 +58,15 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
- break;
-
- case V4L2_CTRL_TYPE_MENU:
-+ /* Prevent excessive memory consumption, as well as integer
-+ * overflows.
-+ */
-+ if (xmap->menu_count == 0 ||
-+ xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
-+ ret = -EINVAL;
-+ goto done;
-+ }
-+
- size = xmap->menu_count * sizeof(*map->menu_info);
- map->menu_info = kmalloc(size, GFP_KERNEL);
- if (map->menu_info == NULL) {
-diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
-index 4c1392e..bc446ba 100644
---- a/drivers/media/video/uvc/uvcvideo.h
-+++ b/drivers/media/video/uvc/uvcvideo.h
-@@ -113,6 +113,7 @@
-
- /* Maximum allowed number of control mappings per device */
- #define UVC_MAX_CONTROL_MAPPINGS 1024
-+#define UVC_MAX_CONTROL_MENU_ENTRIES 32
-
- /* Devices quirks */
- #define UVC_QUIRK_STATUS_INTERVAL 0x00000001
-diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
-index e1da8fc..639abee 100644
---- a/drivers/media/video/v4l2-ioctl.c
-+++ b/drivers/media/video/v4l2-ioctl.c
-@@ -2226,6 +2226,10 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
- struct v4l2_ext_controls *ctrls = parg;
-
- if (ctrls->count != 0) {
-+ if (ctrls->count > V4L2_CID_MAX_CTRLS) {
-+ ret = -EINVAL;
-+ break;
-+ }
- *user_ptr = (void __user *)ctrls->controls;
- *kernel_ptr = (void *)&ctrls->controls;
- *array_size = sizeof(struct v4l2_ext_control)
-diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
-index d240427..fb7c27f 100644
---- a/drivers/mmc/core/mmc.c
-+++ b/drivers/mmc/core/mmc.c
-@@ -1048,7 +1048,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
- *
- * WARNING: eMMC rules are NOT the same as SD DDR
- */
-- if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
-+ if (ddr == MMC_1_2V_DDR_MODE) {
- err = mmc_set_signal_voltage(host,
- MMC_SIGNAL_VOLTAGE_120, 0);
- if (err)
-diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
-index 19ed580..6ce32a7 100644
---- a/drivers/mmc/host/sdhci.c
-+++ b/drivers/mmc/host/sdhci.c
-@@ -1364,8 +1364,7 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
- if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
- (ios->timing == MMC_TIMING_UHS_SDR104) ||
- (ios->timing == MMC_TIMING_UHS_DDR50) ||
-- (ios->timing == MMC_TIMING_UHS_SDR25) ||
-- (ios->timing == MMC_TIMING_UHS_SDR12))
-+ (ios->timing == MMC_TIMING_UHS_SDR25))
- ctrl |= SDHCI_CTRL_HISPD;
-
- ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-@@ -2336,9 +2335,8 @@ int sdhci_suspend_host(struct sdhci_host *host)
- /* Disable tuning since we are suspending */
- if (host->version >= SDHCI_SPEC_300 && host->tuning_count &&
- host->tuning_mode == SDHCI_TUNING_MODE_1) {
-+ del_timer_sync(&host->tuning_timer);
- host->flags &= ~SDHCI_NEEDS_RETUNING;
-- mod_timer(&host->tuning_timer, jiffies +
-- host->tuning_count * HZ);
- }
-
- ret = mmc_suspend_host(host->mmc);
-diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
-index ed8b5e7..424ca5f 100644
---- a/drivers/mtd/mtd_blkdevs.c
-+++ b/drivers/mtd/mtd_blkdevs.c
-@@ -215,7 +215,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
-
- mutex_lock(&dev->lock);
-
-- if (dev->open++)
-+ if (dev->open)
- goto unlock;
-
- kref_get(&dev->ref);
-@@ -235,6 +235,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
- goto error_release;
-
- unlock:
-+ dev->open++;
- mutex_unlock(&dev->lock);
- blktrans_dev_put(dev);
- return ret;
-diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
-index 1e2fa62..f3cdce9 100644
---- a/drivers/mtd/mtdoops.c
-+++ b/drivers/mtd/mtdoops.c
-@@ -253,6 +253,9 @@ static void find_next_position(struct mtdoops_context *cxt)
- size_t retlen;
-
- for (page = 0; page < cxt->oops_pages; page++) {
-+ if (mtd->block_isbad &&
-+ mtd->block_isbad(mtd, page * record_size))
-+ continue;
- /* Assume the page is used */
- mark_page_used(cxt, page);
- ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
-@@ -369,7 +372,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
-
- /* oops_page_used is a bit field */
- cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages,
-- BITS_PER_LONG));
-+ BITS_PER_LONG) * sizeof(unsigned long));
- if (!cxt->oops_page_used) {
- printk(KERN_ERR "mtdoops: could not allocate page array\n");
- return;
-diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
-index 52ffd91..811642f 100644
---- a/drivers/mtd/tests/mtd_stresstest.c
-+++ b/drivers/mtd/tests/mtd_stresstest.c
-@@ -284,6 +284,12 @@ static int __init mtd_stresstest_init(void)
- (unsigned long long)mtd->size, mtd->erasesize,
- pgsize, ebcnt, pgcnt, mtd->oobsize);
-
-+ if (ebcnt < 2) {
-+ printk(PRINT_PREF "error: need at least 2 eraseblocks\n");
-+ err = -ENOSPC;
-+ goto out_put_mtd;
-+ }
-+
- /* Read or write up 2 eraseblocks at a time */
- bufsize = mtd->erasesize * 2;
-
-@@ -322,6 +328,7 @@ out:
- kfree(bbt);
- vfree(writebuf);
- vfree(readbuf);
-+out_put_mtd:
- put_mtd_device(mtd);
- if (err)
- printk(PRINT_PREF "error %d occurred\n", err);
-diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
-index 3320a50..ad76592 100644
---- a/drivers/mtd/ubi/cdev.c
-+++ b/drivers/mtd/ubi/cdev.c
-@@ -632,6 +632,9 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
- if (req->alignment != 1 && n)
- goto bad;
-
-+ if (!req->name[0] || !req->name_len)
-+ goto bad;
-+
- if (req->name_len > UBI_VOL_NAME_MAX) {
- err = -ENAMETOOLONG;
- goto bad;
-diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
-index 64fbb00..ead2cd1 100644
---- a/drivers/mtd/ubi/debug.h
-+++ b/drivers/mtd/ubi/debug.h
-@@ -43,7 +43,10 @@
- pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__)
-
- /* Just a debugging messages not related to any specific UBI subsystem */
--#define dbg_msg(fmt, ...) ubi_dbg_msg("msg", fmt, ##__VA_ARGS__)
-+#define dbg_msg(fmt, ...) \
-+ printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \
-+ current->pid, __func__, ##__VA_ARGS__)
-+
- /* General debugging messages */
- #define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__)
- /* Messages from the eraseblock association sub-system */
-diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
-index fb7f19b..cd26da8 100644
---- a/drivers/mtd/ubi/eba.c
-+++ b/drivers/mtd/ubi/eba.c
-@@ -1028,12 +1028,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
- * 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are
- * holding @ubi->move_mutex and go sleep on the LEB lock. So, if the
- * LEB is already locked, we just do not move it and return
-- * %MOVE_CANCEL_RACE, which means that UBI will re-try, but later.
-+ * %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because
-+ * we do not know the reasons of the contention - it may be just a
-+ * normal I/O on this LEB, so we want to re-try.
- */
- err = leb_write_trylock(ubi, vol_id, lnum);
- if (err) {
- dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum);
-- return MOVE_CANCEL_RACE;
-+ return MOVE_RETRY;
- }
-
- /*
-diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
-index dc64c76..d51d75d 100644
---- a/drivers/mtd/ubi/ubi.h
-+++ b/drivers/mtd/ubi/ubi.h
-@@ -120,6 +120,7 @@ enum {
- * PEB
- * MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the
- * target PEB
-+ * MOVE_RETRY: retry scrubbing the PEB
- */
- enum {
- MOVE_CANCEL_RACE = 1,
-@@ -127,6 +128,7 @@ enum {
- MOVE_TARGET_RD_ERR,
- MOVE_TARGET_WR_ERR,
- MOVE_CANCEL_BITFLIPS,
-+ MOVE_RETRY,
- };
-
- /**
-diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
-index 9ad18da..890754c 100644
---- a/drivers/mtd/ubi/vtbl.c
-+++ b/drivers/mtd/ubi/vtbl.c
-@@ -306,7 +306,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si,
- int copy, void *vtbl)
- {
- int err, tries = 0;
-- static struct ubi_vid_hdr *vid_hdr;
-+ struct ubi_vid_hdr *vid_hdr;
- struct ubi_scan_leb *new_seb;
-
- ubi_msg("create volume table (copy #%d)", copy + 1);
-diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
-index 42c684c..0696e36 100644
---- a/drivers/mtd/ubi/wl.c
-+++ b/drivers/mtd/ubi/wl.c
-@@ -795,7 +795,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
- protect = 1;
- goto out_not_moved;
- }
--
-+ if (err == MOVE_RETRY) {
-+ scrubbing = 1;
-+ goto out_not_moved;
-+ }
- if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR ||
- err == MOVE_TARGET_RD_ERR) {
- /*
-@@ -1049,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
-
- ubi_err("failed to erase PEB %d, error %d", pnum, err);
- kfree(wl_wrk);
-- kmem_cache_free(ubi_wl_entry_slab, e);
-
- if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
- err == -EBUSY) {
-@@ -1062,14 +1064,16 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
- goto out_ro;
- }
- return err;
-- } else if (err != -EIO) {
-+ }
-+
-+ kmem_cache_free(ubi_wl_entry_slab, e);
-+ if (err != -EIO)
- /*
- * If this is not %-EIO, we have no idea what to do. Scheduling
- * this physical eraseblock for erasure again would cause
- * errors again and again. Well, lets switch to R/O mode.
- */
- goto out_ro;
-- }
-
- /* It is %-EIO, the PEB went bad */
-
-diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
-index dd2625a..f5e063a 100644
---- a/drivers/net/usb/asix.c
-+++ b/drivers/net/usb/asix.c
-@@ -974,6 +974,7 @@ static int ax88772_link_reset(struct usbnet *dev)
-
- static int ax88772_reset(struct usbnet *dev)
- {
-+ struct asix_data *data = (struct asix_data *)&dev->data;
- int ret, embd_phy;
- u16 rx_ctl;
-
-@@ -1051,6 +1052,13 @@ static int ax88772_reset(struct usbnet *dev)
- goto out;
- }
-
-+ /* Rewrite MAC address */
-+ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
-+ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
-+ data->mac_addr);
-+ if (ret < 0)
-+ goto out;
-+
- /* Set RX_CTL to default values with 2k buffer, and enable cactus */
- ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
- if (ret < 0)
-@@ -1316,6 +1324,13 @@ static int ax88178_reset(struct usbnet *dev)
- if (ret < 0)
- return ret;
-
-+ /* Rewrite MAC address */
-+ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
-+ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
-+ data->mac_addr);
-+ if (ret < 0)
-+ return ret;
-+
- ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
- if (ret < 0)
- return ret;
-diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-index ccde784..f5ae3c6 100644
---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
-@@ -526,10 +526,11 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
- rxs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if (rxsp->status11 & AR_MichaelErr)
- rxs->rs_status |= ATH9K_RXERR_MIC;
-- if (rxsp->status11 & AR_KeyMiss)
-- rxs->rs_status |= ATH9K_RXERR_KEYMISS;
- }
-
-+ if (rxsp->status11 & AR_KeyMiss)
-+ rxs->rs_status |= ATH9K_RXERR_KEYMISS;
-+
- return 0;
- }
- EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
-diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
-index 9953881..8ddef3e 100644
---- a/drivers/net/wireless/ath/ath9k/calib.c
-+++ b/drivers/net/wireless/ath/ath9k/calib.c
-@@ -402,6 +402,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
- ah->noise = ath9k_hw_getchan_noise(ah, chan);
- return true;
- }
-+EXPORT_SYMBOL(ath9k_hw_getnf);
-
- void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
- struct ath9k_channel *chan)
-diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
-index ecdb6fd..bbcb777 100644
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -621,10 +621,11 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
- rs->rs_status |= ATH9K_RXERR_DECRYPT;
- else if (ads.ds_rxstatus8 & AR_MichaelErr)
- rs->rs_status |= ATH9K_RXERR_MIC;
-- if (ads.ds_rxstatus8 & AR_KeyMiss)
-- rs->rs_status |= ATH9K_RXERR_KEYMISS;
- }
-
-+ if (ads.ds_rxstatus8 & AR_KeyMiss)
-+ rs->rs_status |= ATH9K_RXERR_KEYMISS;
-+
- return 0;
- }
- EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
-diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
-index a9c5ae7..f76a814 100644
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1667,7 +1667,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
-
- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
- struct ieee80211_channel *curchan = hw->conf.channel;
-- struct ath9k_channel old_chan;
- int pos = curchan->hw_value;
- int old_pos = -1;
- unsigned long flags;
-@@ -1693,11 +1692,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
- * Preserve the current channel values, before updating
- * the same channel
- */
-- if (old_pos == pos) {
-- memcpy(&old_chan, &sc->sc_ah->channels[pos],
-- sizeof(struct ath9k_channel));
-- ah->curchan = &old_chan;
-- }
-+ if (ah->curchan && (old_pos == pos))
-+ ath9k_hw_getnf(ah, ah->curchan);
-
- ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
- curchan, conf->channel_type);
-diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c
-index b282d86..05f2ad1 100644
---- a/drivers/net/wireless/iwlegacy/iwl3945-base.c
-+++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c
-@@ -2656,14 +2656,13 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
- IWL_WARN(priv, "Invalid scan band\n");
- return -EIO;
- }
--
- /*
-- * If active scaning is requested but a certain channel
-- * is marked passive, we can do active scanning if we
-- * detect transmissions.
-+ * If active scaning is requested but a certain channel is marked
-+ * passive, we can do active scanning if we detect transmissions. For
-+ * passive only scanning disable switching to active on any channel.
- */
- scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-- IWL_GOOD_CRC_TH_DISABLED;
-+ IWL_GOOD_CRC_TH_NEVER;
-
- len = iwl_legacy_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- vif->addr, priv->scan_request->ie,
-diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
-index 1a52ed2..6465983 100644
---- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
-@@ -827,6 +827,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
- case IEEE80211_SMPS_STATIC:
- case IEEE80211_SMPS_DYNAMIC:
- return IWL_NUM_IDLE_CHAINS_SINGLE;
-+ case IEEE80211_SMPS_AUTOMATIC:
- case IEEE80211_SMPS_OFF:
- return active_cnt;
- default:
-diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
-index 5c7c17c..d552fa3 100644
---- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
-+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
-@@ -559,6 +559,9 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
-
- mutex_lock(&priv->shrd->mutex);
-
-+ if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
-+ goto out;
-+
- if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) {
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- goto out;
-diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
-index da48c8a..837b460 100644
---- a/drivers/net/wireless/rt2x00/rt2800pci.c
-+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
-@@ -422,7 +422,6 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
- static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
- enum dev_state state)
- {
-- int mask = (state == STATE_RADIO_IRQ_ON);
- u32 reg;
- unsigned long flags;
-
-@@ -436,25 +435,14 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
- }
-
- spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
-- rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, mask);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_AC0_DMA_DONE, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_AC1_DMA_DONE, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_AC2_DMA_DONE, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_AC3_DMA_DONE, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_HCCA_DMA_DONE, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_MGMT_DMA_DONE, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_MCU_COMMAND, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_RXTX_COHERENT, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, mask);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, mask);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, mask);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, mask);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, 0);
-- rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, 0);
-+ reg = 0;
-+ if (state == STATE_RADIO_IRQ_ON) {
-+ rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, 1);
-+ rt2x00_set_field32(&reg, INT_MASK_CSR_TBTT, 1);
-+ rt2x00_set_field32(&reg, INT_MASK_CSR_PRE_TBTT, 1);
-+ rt2x00_set_field32(&reg, INT_MASK_CSR_TX_FIFO_STATUS, 1);
-+ rt2x00_set_field32(&reg, INT_MASK_CSR_AUTO_WAKEUP, 1);
-+ }
- rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
- spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
-
-diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
-index 6f91a14..3fda6b1 100644
---- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
-+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
-@@ -196,6 +196,8 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
- /* Allocate skb buffer to contain firmware */
- /* info and tx descriptor info. */
- skb = dev_alloc_skb(frag_length);
-+ if (!skb)
-+ return false;
- skb_reserve(skb, extra_descoffset);
- seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
- extra_descoffset));
-@@ -573,6 +575,8 @@ static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd,
-
- len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
- skb = dev_alloc_skb(len);
-+ if (!skb)
-+ return false;
- cb_desc = (struct rtl_tcb_desc *)(skb->cb);
- cb_desc->queue_index = TXCMD_QUEUE;
- cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
-diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
-index 0e6d04d..e3efb43 100644
---- a/drivers/pci/msi.c
-+++ b/drivers/pci/msi.c
-@@ -870,5 +870,15 @@ EXPORT_SYMBOL(pci_msi_enabled);
-
- void pci_msi_init_pci_dev(struct pci_dev *dev)
- {
-+ int pos;
- INIT_LIST_HEAD(&dev->msi_list);
-+
-+ /* Disable the msi hardware to avoid screaming interrupts
-+ * during boot. This is the power on reset default so
-+ * usually this should be a noop.
-+ */
-+ pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
-+ if (pos)
-+ msi_set_enable(dev, pos, 0);
-+ msix_set_enable(dev, 0);
- }
-diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
-index dfbd5a6..258fef2 100644
---- a/drivers/pnp/quirks.c
-+++ b/drivers/pnp/quirks.c
-@@ -295,6 +295,45 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
- }
- }
-
-+#ifdef CONFIG_AMD_NB
-+
-+#include <asm/amd_nb.h>
-+
-+static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
-+{
-+ resource_size_t start, end;
-+ struct pnp_resource *pnp_res;
-+ struct resource *res;
-+ struct resource mmconfig_res, *mmconfig;
-+
-+ mmconfig = amd_get_mmconfig_range(&mmconfig_res);
-+ if (!mmconfig)
-+ return;
-+
-+ list_for_each_entry(pnp_res, &dev->resources, list) {
-+ res = &pnp_res->res;
-+ if (res->end < mmconfig->start || res->start > mmconfig->end ||
-+ (res->start == mmconfig->start && res->end == mmconfig->end))
-+ continue;
-+
-+ dev_info(&dev->dev, FW_BUG
-+ "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
-+ res, mmconfig);
-+ if (mmconfig->start < res->start) {
-+ start = mmconfig->start;
-+ end = res->start - 1;
-+ pnp_add_mem_resource(dev, start, end, 0);
-+ }
-+ if (mmconfig->end > res->end) {
-+ start = res->end + 1;
-+ end = mmconfig->end;
-+ pnp_add_mem_resource(dev, start, end, 0);
-+ }
-+ break;
-+ }
-+}
-+#endif
-+
- /*
- * PnP Quirks
- * Cards or devices that need some tweaking due to incomplete resource info
-@@ -322,6 +361,9 @@ static struct pnp_fixup pnp_fixups[] = {
- /* PnP resources that might overlap PCI BARs */
- {"PNP0c01", quirk_system_pci_resources},
- {"PNP0c02", quirk_system_pci_resources},
-+#ifdef CONFIG_AMD_NB
-+ {"PNP0c01", quirk_amd_mmconfig_area},
-+#endif
- {""}
- };
-
-diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
-index 8e28625..8a1c031 100644
---- a/drivers/rtc/interface.c
-+++ b/drivers/rtc/interface.c
-@@ -228,11 +228,11 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
- alarm->time.tm_hour = now.tm_hour;
-
- /* For simplicity, only support date rollover for now */
-- if (alarm->time.tm_mday == -1) {
-+ if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) {
- alarm->time.tm_mday = now.tm_mday;
- missing = day;
- }
-- if (alarm->time.tm_mon == -1) {
-+ if ((unsigned)alarm->time.tm_mon >= 12) {
- alarm->time.tm_mon = now.tm_mon;
- if (missing == none)
- missing = month;
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
-index beda04a..0794c72 100644
---- a/drivers/scsi/mpt2sas/mpt2sas_base.c
-+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
-@@ -65,6 +65,8 @@ static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
-
- #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
-
-+#define MAX_HBA_QUEUE_DEPTH 30000
-+#define MAX_CHAIN_DEPTH 100000
- static int max_queue_depth = -1;
- module_param(max_queue_depth, int, 0);
- MODULE_PARM_DESC(max_queue_depth, " max controller queue depth ");
-@@ -2311,8 +2313,6 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
- }
- if (ioc->chain_dma_pool)
- pci_pool_destroy(ioc->chain_dma_pool);
-- }
-- if (ioc->chain_lookup) {
- free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
- ioc->chain_lookup = NULL;
- }
-@@ -2330,9 +2330,7 @@ static int
- _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
- {
- struct mpt2sas_facts *facts;
-- u32 queue_size, queue_diff;
- u16 max_sge_elements;
-- u16 num_of_reply_frames;
- u16 chains_needed_per_io;
- u32 sz, total_sz, reply_post_free_sz;
- u32 retry_sz;
-@@ -2359,7 +2357,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
- max_request_credit = (max_queue_depth < facts->RequestCredit)
- ? max_queue_depth : facts->RequestCredit;
- else
-- max_request_credit = facts->RequestCredit;
-+ max_request_credit = min_t(u16, facts->RequestCredit,
-+ MAX_HBA_QUEUE_DEPTH);
-
- ioc->hba_queue_depth = max_request_credit;
- ioc->hi_priority_depth = facts->HighPriorityCredit;
-@@ -2400,50 +2399,25 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
- }
- ioc->chains_needed_per_io = chains_needed_per_io;
-
-- /* reply free queue sizing - taking into account for events */
-- num_of_reply_frames = ioc->hba_queue_depth + 32;
--
-- /* number of replies frames can't be a multiple of 16 */
-- /* decrease number of reply frames by 1 */
-- if (!(num_of_reply_frames % 16))
-- num_of_reply_frames--;
--
-- /* calculate number of reply free queue entries
-- * (must be multiple of 16)
-- */
--
-- /* (we know reply_free_queue_depth is not a multiple of 16) */
-- queue_size = num_of_reply_frames;
-- queue_size += 16 - (queue_size % 16);
-- ioc->reply_free_queue_depth = queue_size;
--
-- /* reply descriptor post queue sizing */
-- /* this size should be the number of request frames + number of reply
-- * frames
-- */
--
-- queue_size = ioc->hba_queue_depth + num_of_reply_frames + 1;
-- /* round up to 16 byte boundary */
-- if (queue_size % 16)
-- queue_size += 16 - (queue_size % 16);
--
-- /* check against IOC maximum reply post queue depth */
-- if (queue_size > facts->MaxReplyDescriptorPostQueueDepth) {
-- queue_diff = queue_size -
-- facts->MaxReplyDescriptorPostQueueDepth;
-+ /* reply free queue sizing - taking into account for 64 FW events */
-+ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
-
-- /* round queue_diff up to multiple of 16 */
-- if (queue_diff % 16)
-- queue_diff += 16 - (queue_diff % 16);
--
-- /* adjust hba_queue_depth, reply_free_queue_depth,
-- * and queue_size
-- */
-- ioc->hba_queue_depth -= (queue_diff / 2);
-- ioc->reply_free_queue_depth -= (queue_diff / 2);
-- queue_size = facts->MaxReplyDescriptorPostQueueDepth;
-+ /* align the reply post queue on the next 16 count boundary */
-+ if (!ioc->reply_free_queue_depth % 16)
-+ ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16;
-+ else
-+ ioc->reply_post_queue_depth = ioc->reply_free_queue_depth +
-+ 32 - (ioc->reply_free_queue_depth % 16);
-+ if (ioc->reply_post_queue_depth >
-+ facts->MaxReplyDescriptorPostQueueDepth) {
-+ ioc->reply_post_queue_depth = min_t(u16,
-+ (facts->MaxReplyDescriptorPostQueueDepth -
-+ (facts->MaxReplyDescriptorPostQueueDepth % 16)),
-+ (ioc->hba_queue_depth - (ioc->hba_queue_depth % 16)));
-+ ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16;
-+ ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64;
- }
-- ioc->reply_post_queue_depth = queue_size;
-+
-
- dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
- "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
-@@ -2529,15 +2503,12 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
- "depth(%d)\n", ioc->name, ioc->request,
- ioc->scsiio_depth));
-
-- /* loop till the allocation succeeds */
-- do {
-- sz = ioc->chain_depth * sizeof(struct chain_tracker);
-- ioc->chain_pages = get_order(sz);
-- ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
-- GFP_KERNEL, ioc->chain_pages);
-- if (ioc->chain_lookup == NULL)
-- ioc->chain_depth -= 100;
-- } while (ioc->chain_lookup == NULL);
-+ ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH);
-+ sz = ioc->chain_depth * sizeof(struct chain_tracker);
-+ ioc->chain_pages = get_order(sz);
-+
-+ ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
-+ GFP_KERNEL, ioc->chain_pages);
- ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
- ioc->request_sz, 16, 0);
- if (!ioc->chain_dma_pool) {
-diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
-index d570573..9bc6fb2 100644
---- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
-+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
-@@ -1007,8 +1007,8 @@ _scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
- spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
- if (list_empty(&ioc->free_chain_list)) {
- spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
-- printk(MPT2SAS_WARN_FMT "chain buffers not available\n",
-- ioc->name);
-+ dfailprintk(ioc, printk(MPT2SAS_WARN_FMT "chain buffers not "
-+ "available\n", ioc->name));
- return NULL;
- }
- chain_req = list_entry(ioc->free_chain_list.next,
-@@ -6714,6 +6714,7 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
- } else
- sas_target_priv_data = NULL;
- raid_device->responding = 1;
-+ spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
- starget_printk(KERN_INFO, raid_device->starget,
- "handle(0x%04x), wwid(0x%016llx)\n", handle,
- (unsigned long long)raid_device->wwid);
-@@ -6724,16 +6725,16 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
- */
- _scsih_init_warpdrive_properties(ioc, raid_device);
- if (raid_device->handle == handle)
-- goto out;
-+ return;
- printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
- raid_device->handle);
- raid_device->handle = handle;
- if (sas_target_priv_data)
- sas_target_priv_data->handle = handle;
-- goto out;
-+ return;
- }
- }
-- out:
-+
- spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
- }
-
-diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
-index fa3a591..4b63c73 100644
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -1074,6 +1074,10 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
- SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, "
- "cmd=0x%x\n", disk->disk_name, cmd));
-
-+ error = scsi_verify_blk_ioctl(bdev, cmd);
-+ if (error < 0)
-+ return error;
-+
- /*
- * If we are in the middle of error recovery, don't let anyone
- * else try and use this device. Also, if error recovery fails, it
-@@ -1096,7 +1100,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
- error = scsi_ioctl(sdp, cmd, p);
- break;
- default:
-- error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
-+ error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p);
- if (error != -ENOTTY)
- break;
- error = scsi_ioctl(sdp, cmd, p);
-@@ -1266,6 +1270,11 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
- {
- struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device;
-+ int ret;
-+
-+ ret = scsi_verify_blk_ioctl(bdev, cmd);
-+ if (ret < 0)
-+ return -ENOIOCTLCMD;
-
- /*
- * If we are in the middle of error recovery, don't let anyone
-@@ -1277,8 +1286,6 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
- return -ENODEV;
-
- if (sdev->host->hostt->compat_ioctl) {
-- int ret;
--
- ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
-
- return ret;
-diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
-index b4543f5..36d1ed7 100644
---- a/drivers/scsi/sym53c8xx_2/sym_glue.c
-+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
-@@ -839,6 +839,10 @@ static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
- struct sym_lcb *lp = sym_lp(tp, sdev->lun);
- unsigned long flags;
-
-+ /* if slave_alloc returned before allocating a sym_lcb, return */
-+ if (!lp)
-+ return;
-+
- spin_lock_irqsave(np->s.host->host_lock, flags);
-
- if (lp->busy_itlq || lp->busy_itl) {
-diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
-index 831468b..2e8c1be 100644
---- a/drivers/target/target_core_cdb.c
-+++ b/drivers/target/target_core_cdb.c
-@@ -94,6 +94,18 @@ target_emulate_inquiry_std(struct se_cmd *cmd)
- buf[2] = dev->transport->get_device_rev(dev);
-
- /*
-+ * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2
-+ *
-+ * SPC4 says:
-+ * A RESPONSE DATA FORMAT field set to 2h indicates that the
-+ * standard INQUIRY data is in the format defined in this
-+ * standard. Response data format values less than 2h are
-+ * obsolete. Response data format values greater than 2h are
-+ * reserved.
-+ */
-+ buf[3] = 2;
-+
-+ /*
- * Enable SCCS and TPGS fields for Emulated ALUA
- */
- if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED)
-diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
-index 0257658..e87d0eb 100644
---- a/drivers/target/target_core_transport.c
-+++ b/drivers/target/target_core_transport.c
-@@ -4353,6 +4353,7 @@ int transport_send_check_condition_and_sense(
- case TCM_NON_EXISTENT_LUN:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
- /* LOGICAL UNIT NOT SUPPORTED */
-@@ -4362,6 +4363,7 @@ int transport_send_check_condition_and_sense(
- case TCM_SECTOR_COUNT_TOO_MANY:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
- /* INVALID COMMAND OPERATION CODE */
-@@ -4370,6 +4372,7 @@ int transport_send_check_condition_and_sense(
- case TCM_UNKNOWN_MODE_PAGE:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
- /* INVALID FIELD IN CDB */
-@@ -4378,6 +4381,7 @@ int transport_send_check_condition_and_sense(
- case TCM_CHECK_CONDITION_ABORT_CMD:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* BUS DEVICE RESET FUNCTION OCCURRED */
-@@ -4387,6 +4391,7 @@ int transport_send_check_condition_and_sense(
- case TCM_INCORRECT_AMOUNT_OF_DATA:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* WRITE ERROR */
-@@ -4397,6 +4402,7 @@ int transport_send_check_condition_and_sense(
- case TCM_INVALID_CDB_FIELD:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* INVALID FIELD IN CDB */
-@@ -4405,6 +4411,7 @@ int transport_send_check_condition_and_sense(
- case TCM_INVALID_PARAMETER_LIST:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* INVALID FIELD IN PARAMETER LIST */
-@@ -4413,6 +4420,7 @@ int transport_send_check_condition_and_sense(
- case TCM_UNEXPECTED_UNSOLICITED_DATA:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* WRITE ERROR */
-@@ -4423,6 +4431,7 @@ int transport_send_check_condition_and_sense(
- case TCM_SERVICE_CRC_ERROR:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* PROTOCOL SERVICE CRC ERROR */
-@@ -4433,6 +4442,7 @@ int transport_send_check_condition_and_sense(
- case TCM_SNACK_REJECTED:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ABORTED COMMAND */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
- /* READ ERROR */
-@@ -4443,6 +4453,7 @@ int transport_send_check_condition_and_sense(
- case TCM_WRITE_PROTECTED:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* DATA PROTECT */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
- /* WRITE PROTECTED */
-@@ -4451,6 +4462,7 @@ int transport_send_check_condition_and_sense(
- case TCM_CHECK_CONDITION_UNIT_ATTENTION:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* UNIT ATTENTION */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
- core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
-@@ -4460,6 +4472,7 @@ int transport_send_check_condition_and_sense(
- case TCM_CHECK_CONDITION_NOT_READY:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* Not Ready */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY;
- transport_get_sense_codes(cmd, &asc, &ascq);
-@@ -4470,6 +4483,7 @@ int transport_send_check_condition_and_sense(
- default:
- /* CURRENT ERROR */
- buffer[offset] = 0x70;
-+ buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
- /* ILLEGAL REQUEST */
- buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
- /* LOGICAL UNIT COMMUNICATION FAILURE */
-diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
-index ede860f..a580b17 100644
---- a/drivers/xen/xenbus/xenbus_xs.c
-+++ b/drivers/xen/xenbus/xenbus_xs.c
-@@ -801,6 +801,12 @@ static int process_msg(void)
- goto out;
- }
-
-+ if (msg->hdr.len > XENSTORE_PAYLOAD_MAX) {
-+ kfree(msg);
-+ err = -EINVAL;
-+ goto out;
-+ }
-+
- body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH);
- if (body == NULL) {
- kfree(msg);
-diff --git a/fs/aio.c b/fs/aio.c
-index 78c514c..969beb0 100644
---- a/fs/aio.c
-+++ b/fs/aio.c
-@@ -476,14 +476,21 @@ static void kiocb_batch_init(struct kiocb_batch *batch, long total)
- batch->count = total;
- }
-
--static void kiocb_batch_free(struct kiocb_batch *batch)
-+static void kiocb_batch_free(struct kioctx *ctx, struct kiocb_batch *batch)
- {
- struct kiocb *req, *n;
-
-+ if (list_empty(&batch->head))
-+ return;
-+
-+ spin_lock_irq(&ctx->ctx_lock);
- list_for_each_entry_safe(req, n, &batch->head, ki_batch) {
- list_del(&req->ki_batch);
-+ list_del(&req->ki_list);
- kmem_cache_free(kiocb_cachep, req);
-+ ctx->reqs_active--;
- }
-+ spin_unlock_irq(&ctx->ctx_lock);
- }
-
- /*
-@@ -1742,7 +1749,7 @@ long do_io_submit(aio_context_t ctx_id, long nr,
- }
- blk_finish_plug(&plug);
-
-- kiocb_batch_free(&batch);
-+ kiocb_batch_free(ctx, &batch);
- put_ioctx(ctx);
- return i ? i : ret;
- }
-diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
-index f3670cf..63e4be4 100644
---- a/fs/cifs/connect.c
-+++ b/fs/cifs/connect.c
-@@ -2914,18 +2914,33 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
- #define CIFS_DEFAULT_IOSIZE (1024 * 1024)
-
- /*
-- * Windows only supports a max of 60k reads. Default to that when posix
-- * extensions aren't in force.
-+ * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
-+ * those values when posix extensions aren't in force. In actuality here, we
-+ * use 65536 to allow for a write that is a multiple of 4k. Most servers seem
-+ * to be ok with the extra byte even though Windows doesn't send writes that
-+ * are that large.
-+ *
-+ * Citation:
-+ *
-+ * http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx
- */
- #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
-+#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
-
- static unsigned int
- cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
- {
- __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
- struct TCP_Server_Info *server = tcon->ses->server;
-- unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
-- CIFS_DEFAULT_IOSIZE;
-+ unsigned int wsize;
-+
-+ /* start with specified wsize, or default */
-+ if (pvolume_info->wsize)
-+ wsize = pvolume_info->wsize;
-+ else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
-+ wsize = CIFS_DEFAULT_IOSIZE;
-+ else
-+ wsize = CIFS_DEFAULT_NON_POSIX_WSIZE;
-
- /* can server support 24-bit write sizes? (via UNIX extensions) */
- if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
-diff --git a/fs/dcache.c b/fs/dcache.c
-index 89509b5..f7908ae 100644
---- a/fs/dcache.c
-+++ b/fs/dcache.c
-@@ -242,6 +242,7 @@ static void dentry_lru_add(struct dentry *dentry)
- static void __dentry_lru_del(struct dentry *dentry)
- {
- list_del_init(&dentry->d_lru);
-+ dentry->d_flags &= ~DCACHE_SHRINK_LIST;
- dentry->d_sb->s_nr_dentry_unused--;
- dentry_stat.nr_unused--;
- }
-@@ -275,15 +276,15 @@ static void dentry_lru_prune(struct dentry *dentry)
- }
- }
-
--static void dentry_lru_move_tail(struct dentry *dentry)
-+static void dentry_lru_move_list(struct dentry *dentry, struct list_head *list)
- {
- spin_lock(&dcache_lru_lock);
- if (list_empty(&dentry->d_lru)) {
-- list_add_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
-+ list_add_tail(&dentry->d_lru, list);
- dentry->d_sb->s_nr_dentry_unused++;
- dentry_stat.nr_unused++;
- } else {
-- list_move_tail(&dentry->d_lru, &dentry->d_sb->s_dentry_lru);
-+ list_move_tail(&dentry->d_lru, list);
- }
- spin_unlock(&dcache_lru_lock);
- }
-@@ -769,14 +770,18 @@ static void shrink_dentry_list(struct list_head *list)
- }
-
- /**
-- * __shrink_dcache_sb - shrink the dentry LRU on a given superblock
-- * @sb: superblock to shrink dentry LRU.
-- * @count: number of entries to prune
-- * @flags: flags to control the dentry processing
-+ * prune_dcache_sb - shrink the dcache
-+ * @sb: superblock
-+ * @count: number of entries to try to free
-+ *
-+ * Attempt to shrink the superblock dcache LRU by @count entries. This is
-+ * done when we need more memory an called from the superblock shrinker
-+ * function.
- *
-- * If flags contains DCACHE_REFERENCED reference dentries will not be pruned.
-+ * This function may fail to free any resources if all the dentries are in
-+ * use.
- */
--static void __shrink_dcache_sb(struct super_block *sb, int count, int flags)
-+void prune_dcache_sb(struct super_block *sb, int count)
- {
- struct dentry *dentry;
- LIST_HEAD(referenced);
-@@ -795,18 +800,13 @@ relock:
- goto relock;
- }
-
-- /*
-- * If we are honouring the DCACHE_REFERENCED flag and the
-- * dentry has this flag set, don't free it. Clear the flag
-- * and put it back on the LRU.
-- */
-- if (flags & DCACHE_REFERENCED &&
-- dentry->d_flags & DCACHE_REFERENCED) {
-+ if (dentry->d_flags & DCACHE_REFERENCED) {
- dentry->d_flags &= ~DCACHE_REFERENCED;
- list_move(&dentry->d_lru, &referenced);
- spin_unlock(&dentry->d_lock);
- } else {
- list_move_tail(&dentry->d_lru, &tmp);
-+ dentry->d_flags |= DCACHE_SHRINK_LIST;
- spin_unlock(&dentry->d_lock);
- if (!--count)
- break;
-@@ -821,23 +821,6 @@ relock:
- }
-
- /**
-- * prune_dcache_sb - shrink the dcache
-- * @sb: superblock
-- * @nr_to_scan: number of entries to try to free
-- *
-- * Attempt to shrink the superblock dcache LRU by @nr_to_scan entries. This is
-- * done when we need more memory an called from the superblock shrinker
-- * function.
-- *
-- * This function may fail to free any resources if all the dentries are in
-- * use.
-- */
--void prune_dcache_sb(struct super_block *sb, int nr_to_scan)
--{
-- __shrink_dcache_sb(sb, nr_to_scan, DCACHE_REFERENCED);
--}
--
--/**
- * shrink_dcache_sb - shrink dcache for a superblock
- * @sb: superblock
- *
-@@ -1091,7 +1074,7 @@ EXPORT_SYMBOL(have_submounts);
- * drop the lock and return early due to latency
- * constraints.
- */
--static int select_parent(struct dentry * parent)
-+static int select_parent(struct dentry *parent, struct list_head *dispose)
- {
- struct dentry *this_parent;
- struct list_head *next;
-@@ -1113,17 +1096,21 @@ resume:
-
- spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
-
-- /*
-- * move only zero ref count dentries to the end
-- * of the unused list for prune_dcache
-+ /*
-+ * move only zero ref count dentries to the dispose list.
-+ *
-+ * Those which are presently on the shrink list, being processed
-+ * by shrink_dentry_list(), shouldn't be moved. Otherwise the
-+ * loop in shrink_dcache_parent() might not make any progress
-+ * and loop forever.
- */
-- if (!dentry->d_count) {
-- dentry_lru_move_tail(dentry);
-- found++;
-- } else {
-+ if (dentry->d_count) {
- dentry_lru_del(dentry);
-+ } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
-+ dentry_lru_move_list(dentry, dispose);
-+ dentry->d_flags |= DCACHE_SHRINK_LIST;
-+ found++;
- }
--
- /*
- * We can return to the caller if we have found some (this
- * ensures forward progress). We'll be coming back to find
-@@ -1180,14 +1167,13 @@ rename_retry:
- *
- * Prune the dcache to remove unused children of the parent dentry.
- */
--
- void shrink_dcache_parent(struct dentry * parent)
- {
-- struct super_block *sb = parent->d_sb;
-+ LIST_HEAD(dispose);
- int found;
-
-- while ((found = select_parent(parent)) != 0)
-- __shrink_dcache_sb(sb, found, 0);
-+ while ((found = select_parent(parent, &dispose)) != 0)
-+ shrink_dentry_list(&dispose);
- }
- EXPORT_SYMBOL(shrink_dcache_parent);
-
-diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
-index a567968..ab25f57 100644
---- a/fs/ext4/ioctl.c
-+++ b/fs/ext4/ioctl.c
-@@ -182,19 +182,22 @@ setversion_out:
- if (err)
- return err;
-
-- if (get_user(n_blocks_count, (__u32 __user *)arg))
-- return -EFAULT;
-+ if (get_user(n_blocks_count, (__u32 __user *)arg)) {
-+ err = -EFAULT;
-+ goto group_extend_out;
-+ }
-
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
- EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
- ext4_msg(sb, KERN_ERR,
- "Online resizing not supported with bigalloc");
-- return -EOPNOTSUPP;
-+ err = -EOPNOTSUPP;
-+ goto group_extend_out;
- }
-
- err = mnt_want_write(filp->f_path.mnt);
- if (err)
-- return err;
-+ goto group_extend_out;
-
- err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
- if (EXT4_SB(sb)->s_journal) {
-@@ -204,9 +207,10 @@ setversion_out:
- }
- if (err == 0)
- err = err2;
-+
- mnt_drop_write(filp->f_path.mnt);
-+group_extend_out:
- ext4_resize_end(sb);
--
- return err;
- }
-
-@@ -267,19 +271,22 @@ mext_out:
- return err;
-
- if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
-- sizeof(input)))
-- return -EFAULT;
-+ sizeof(input))) {
-+ err = -EFAULT;
-+ goto group_add_out;
-+ }
-
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
- EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
- ext4_msg(sb, KERN_ERR,
- "Online resizing not supported with bigalloc");
-- return -EOPNOTSUPP;
-+ err = -EOPNOTSUPP;
-+ goto group_add_out;
- }
-
- err = mnt_want_write(filp->f_path.mnt);
- if (err)
-- return err;
-+ goto group_add_out;
-
- err = ext4_group_add(sb, &input);
- if (EXT4_SB(sb)->s_journal) {
-@@ -289,9 +296,10 @@ mext_out:
- }
- if (err == 0)
- err = err2;
-+
- mnt_drop_write(filp->f_path.mnt);
-+group_add_out:
- ext4_resize_end(sb);
--
- return err;
- }
-
-diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index 3e1329e..9281dbe 100644
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -2006,17 +2006,16 @@ static int ext4_fill_flex_info(struct super_block *sb)
- struct ext4_group_desc *gdp = NULL;
- ext4_group_t flex_group_count;
- ext4_group_t flex_group;
-- int groups_per_flex = 0;
-+ unsigned int groups_per_flex = 0;
- size_t size;
- int i;
-
- sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
-- groups_per_flex = 1 << sbi->s_log_groups_per_flex;
--
-- if (groups_per_flex < 2) {
-+ if (sbi->s_log_groups_per_flex < 1 || sbi->s_log_groups_per_flex > 31) {
- sbi->s_log_groups_per_flex = 0;
- return 1;
- }
-+ groups_per_flex = 1 << sbi->s_log_groups_per_flex;
-
- /* We allocate both existing and potentially added groups */
- flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
-diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
-index 281ae95..3db6b82 100644
---- a/fs/nfs/blocklayout/blocklayout.c
-+++ b/fs/nfs/blocklayout/blocklayout.c
-@@ -146,14 +146,19 @@ static struct bio *bl_alloc_init_bio(int npg, sector_t isect,
- {
- struct bio *bio;
-
-+ npg = min(npg, BIO_MAX_PAGES);
- bio = bio_alloc(GFP_NOIO, npg);
-- if (!bio)
-- return NULL;
-+ if (!bio && (current->flags & PF_MEMALLOC)) {
-+ while (!bio && (npg /= 2))
-+ bio = bio_alloc(GFP_NOIO, npg);
-+ }
-
-- bio->bi_sector = isect - be->be_f_offset + be->be_v_offset;
-- bio->bi_bdev = be->be_mdev;
-- bio->bi_end_io = end_io;
-- bio->bi_private = par;
-+ if (bio) {
-+ bio->bi_sector = isect - be->be_f_offset + be->be_v_offset;
-+ bio->bi_bdev = be->be_mdev;
-+ bio->bi_end_io = end_io;
-+ bio->bi_private = par;
-+ }
- return bio;
- }
-
-@@ -779,16 +784,13 @@ bl_cleanup_layoutcommit(struct nfs4_layoutcommit_data *lcdata)
- static void free_blk_mountid(struct block_mount_id *mid)
- {
- if (mid) {
-- struct pnfs_block_dev *dev;
-- spin_lock(&mid->bm_lock);
-- while (!list_empty(&mid->bm_devlist)) {
-- dev = list_first_entry(&mid->bm_devlist,
-- struct pnfs_block_dev,
-- bm_node);
-+ struct pnfs_block_dev *dev, *tmp;
-+
-+ /* No need to take bm_lock as we are last user freeing bm_devlist */
-+ list_for_each_entry_safe(dev, tmp, &mid->bm_devlist, bm_node) {
- list_del(&dev->bm_node);
- bl_free_block_dev(dev);
- }
-- spin_unlock(&mid->bm_lock);
- kfree(mid);
- }
- }
-diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c
-index 19fa7b0..c69682a 100644
---- a/fs/nfs/blocklayout/extents.c
-+++ b/fs/nfs/blocklayout/extents.c
-@@ -139,11 +139,13 @@ static int _set_range(struct my_tree *tree, int32_t tag, u64 s, u64 length)
- }
-
- /* Ensure that future operations on given range of tree will not malloc */
--static int _preload_range(struct my_tree *tree, u64 offset, u64 length)
-+static int _preload_range(struct pnfs_inval_markings *marks,
-+ u64 offset, u64 length)
- {
- u64 start, end, s;
- int count, i, used = 0, status = -ENOMEM;
- struct pnfs_inval_tracking **storage;
-+ struct my_tree *tree = &marks->im_tree;
-
- dprintk("%s(%llu, %llu) enter\n", __func__, offset, length);
- start = normalize(offset, tree->mtt_step_size);
-@@ -161,12 +163,11 @@ static int _preload_range(struct my_tree *tree, u64 offset, u64 length)
- goto out_cleanup;
- }
-
-- /* Now need lock - HOW??? */
--
-+ spin_lock(&marks->im_lock);
- for (s = start; s < end; s += tree->mtt_step_size)
- used += _add_entry(tree, s, INTERNAL_EXISTS, storage[used]);
-+ spin_unlock(&marks->im_lock);
-
-- /* Unlock - HOW??? */
- status = 0;
-
- out_cleanup:
-@@ -286,7 +287,7 @@ int bl_mark_sectors_init(struct pnfs_inval_markings *marks,
-
- start = normalize(offset, marks->im_block_size);
- end = normalize_up(offset + length, marks->im_block_size);
-- if (_preload_range(&marks->im_tree, start, end - start))
-+ if (_preload_range(marks, start, end - start))
- goto outerr;
-
- spin_lock(&marks->im_lock);
-diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
-index 43926ad..54cea8a 100644
---- a/fs/nfs/callback_proc.c
-+++ b/fs/nfs/callback_proc.c
-@@ -339,7 +339,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
- dprintk("%s enter. slotid %d seqid %d\n",
- __func__, args->csa_slotid, args->csa_sequenceid);
-
-- if (args->csa_slotid > NFS41_BC_MAX_CALLBACKS)
-+ if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS)
- return htonl(NFS4ERR_BADSLOT);
-
- slot = tbl->slots + args->csa_slotid;
-diff --git a/fs/nfs/file.c b/fs/nfs/file.c
-index 606ef0f..c43a452 100644
---- a/fs/nfs/file.c
-+++ b/fs/nfs/file.c
-@@ -272,13 +272,13 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
- datasync);
-
- ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
-- if (ret)
-- return ret;
- mutex_lock(&inode->i_mutex);
-
- nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
- have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
- status = nfs_commit_inode(inode, FLUSH_SYNC);
-+ if (status >= 0 && ret < 0)
-+ status = ret;
- have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
- if (have_error)
- ret = xchg(&ctx->error, 0);
-diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
-index d9f4d78..055d702 100644
---- a/fs/nfs/nfs4proc.c
-+++ b/fs/nfs/nfs4proc.c
-@@ -3430,19 +3430,6 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
- */
- #define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT)
-
--static void buf_to_pages(const void *buf, size_t buflen,
-- struct page **pages, unsigned int *pgbase)
--{
-- const void *p = buf;
--
-- *pgbase = offset_in_page(buf);
-- p -= *pgbase;
-- while (p < buf + buflen) {
-- *(pages++) = virt_to_page(p);
-- p += PAGE_CACHE_SIZE;
-- }
--}
--
- static int buf_to_pages_noslab(const void *buf, size_t buflen,
- struct page **pages, unsigned int *pgbase)
- {
-@@ -3539,9 +3526,19 @@ out:
- nfs4_set_cached_acl(inode, acl);
- }
-
-+/*
-+ * The getxattr API returns the required buffer length when called with a
-+ * NULL buf. The NFSv4 acl tool then calls getxattr again after allocating
-+ * the required buf. On a NULL buf, we send a page of data to the server
-+ * guessing that the ACL request can be serviced by a page. If so, we cache
-+ * up to the page of ACL data, and the 2nd call to getxattr is serviced by
-+ * the cache. If not so, we throw away the page, and cache the required
-+ * length. The next getxattr call will then produce another round trip to
-+ * the server, this time with the input buf of the required size.
-+ */
- static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
- {
-- struct page *pages[NFS4ACL_MAXPAGES];
-+ struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
- struct nfs_getaclargs args = {
- .fh = NFS_FH(inode),
- .acl_pages = pages,
-@@ -3556,41 +3553,60 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
- .rpc_argp = &args,
- .rpc_resp = &res,
- };
-- struct page *localpage = NULL;
-- int ret;
-+ int ret = -ENOMEM, npages, i, acl_len = 0;
-
-- if (buflen < PAGE_SIZE) {
-- /* As long as we're doing a round trip to the server anyway,
-- * let's be prepared for a page of acl data. */
-- localpage = alloc_page(GFP_KERNEL);
-- resp_buf = page_address(localpage);
-- if (localpage == NULL)
-- return -ENOMEM;
-- args.acl_pages[0] = localpage;
-- args.acl_pgbase = 0;
-- args.acl_len = PAGE_SIZE;
-- } else {
-- resp_buf = buf;
-- buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
-+ npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
-+ /* As long as we're doing a round trip to the server anyway,
-+ * let's be prepared for a page of acl data. */
-+ if (npages == 0)
-+ npages = 1;
-+
-+ for (i = 0; i < npages; i++) {
-+ pages[i] = alloc_page(GFP_KERNEL);
-+ if (!pages[i])
-+ goto out_free;
-+ }
-+ if (npages > 1) {
-+ /* for decoding across pages */
-+ args.acl_scratch = alloc_page(GFP_KERNEL);
-+ if (!args.acl_scratch)
-+ goto out_free;
- }
-- ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0);
-+ args.acl_len = npages * PAGE_SIZE;
-+ args.acl_pgbase = 0;
-+ /* Let decode_getfacl know not to fail if the ACL data is larger than
-+ * the page we send as a guess */
-+ if (buf == NULL)
-+ res.acl_flags |= NFS4_ACL_LEN_REQUEST;
-+ resp_buf = page_address(pages[0]);
-+
-+ dprintk("%s buf %p buflen %ld npages %d args.acl_len %ld\n",
-+ __func__, buf, buflen, npages, args.acl_len);
-+ ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
-+ &msg, &args.seq_args, &res.seq_res, 0);
- if (ret)
- goto out_free;
-- if (res.acl_len > args.acl_len)
-- nfs4_write_cached_acl(inode, NULL, res.acl_len);
-+
-+ acl_len = res.acl_len - res.acl_data_offset;
-+ if (acl_len > args.acl_len)
-+ nfs4_write_cached_acl(inode, NULL, acl_len);
- else
-- nfs4_write_cached_acl(inode, resp_buf, res.acl_len);
-+ nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset,
-+ acl_len);
- if (buf) {
- ret = -ERANGE;
-- if (res.acl_len > buflen)
-+ if (acl_len > buflen)
- goto out_free;
-- if (localpage)
-- memcpy(buf, resp_buf, res.acl_len);
-+ _copy_from_pages(buf, pages, res.acl_data_offset,
-+ res.acl_len);
- }
-- ret = res.acl_len;
-+ ret = acl_len;
- out_free:
-- if (localpage)
-- __free_page(localpage);
-+ for (i = 0; i < npages; i++)
-+ if (pages[i])
-+ __free_page(pages[i]);
-+ if (args.acl_scratch)
-+ __free_page(args.acl_scratch);
- return ret;
- }
-
-@@ -3621,6 +3637,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
- nfs_zap_acl_cache(inode);
- ret = nfs4_read_cached_acl(inode, buf, buflen);
- if (ret != -ENOENT)
-+ /* -ENOENT is returned if there is no ACL or if there is an ACL
-+ * but no cached acl data, just the acl length */
- return ret;
- return nfs4_get_acl_uncached(inode, buf, buflen);
- }
-diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
-index e6161b2..dcaf693 100644
---- a/fs/nfs/nfs4xdr.c
-+++ b/fs/nfs/nfs4xdr.c
-@@ -2517,11 +2517,13 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
- encode_compound_hdr(xdr, req, &hdr);
- encode_sequence(xdr, &args->seq_args, &hdr);
- encode_putfh(xdr, args->fh, &hdr);
-- replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1;
-+ replen = hdr.replen + op_decode_hdr_maxsz + 1;
- encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
-
- xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
- args->acl_pages, args->acl_pgbase, args->acl_len);
-+ xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
-+
- encode_nops(&hdr);
- }
-
-@@ -4957,17 +4959,18 @@ decode_restorefh(struct xdr_stream *xdr)
- }
-
- static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
-- size_t *acl_len)
-+ struct nfs_getaclres *res)
- {
-- __be32 *savep;
-+ __be32 *savep, *bm_p;
- uint32_t attrlen,
- bitmap[3] = {0};
- struct kvec *iov = req->rq_rcv_buf.head;
- int status;
-
-- *acl_len = 0;
-+ res->acl_len = 0;
- if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
- goto out;
-+ bm_p = xdr->p;
- if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
- goto out;
- if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
-@@ -4979,18 +4982,30 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
- size_t hdrlen;
- u32 recvd;
-
-+ /* The bitmap (xdr len + bitmaps) and the attr xdr len words
-+ * are stored with the acl data to handle the problem of
-+ * variable length bitmaps.*/
-+ xdr->p = bm_p;
-+ res->acl_data_offset = be32_to_cpup(bm_p) + 2;
-+ res->acl_data_offset <<= 2;
-+
- /* We ignore &savep and don't do consistency checks on
- * the attr length. Let userspace figure it out.... */
- hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
-+ attrlen += res->acl_data_offset;
- recvd = req->rq_rcv_buf.len - hdrlen;
- if (attrlen > recvd) {
-- dprintk("NFS: server cheating in getattr"
-- " acl reply: attrlen %u > recvd %u\n",
-+ if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
-+ /* getxattr interface called with a NULL buf */
-+ res->acl_len = attrlen;
-+ goto out;
-+ }
-+ dprintk("NFS: acl reply: attrlen %u > recvd %u\n",
- attrlen, recvd);
- return -EINVAL;
- }
- xdr_read_pages(xdr, attrlen);
-- *acl_len = attrlen;
-+ res->acl_len = attrlen;
- } else
- status = -EOPNOTSUPP;
-
-@@ -6028,7 +6043,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
- status = decode_putfh(xdr);
- if (status)
- goto out;
-- status = decode_getacl(xdr, rqstp, &res->acl_len);
-+ status = decode_getacl(xdr, rqstp, res);
-
- out:
- return status;
-diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
-index c807ab9..55d0128 100644
---- a/fs/nfs/objlayout/objio_osd.c
-+++ b/fs/nfs/objlayout/objio_osd.c
-@@ -551,7 +551,8 @@ static const struct nfs_pageio_ops objio_pg_write_ops = {
- static struct pnfs_layoutdriver_type objlayout_type = {
- .id = LAYOUT_OSD2_OBJECTS,
- .name = "LAYOUT_OSD2_OBJECTS",
-- .flags = PNFS_LAYOUTRET_ON_SETATTR,
-+ .flags = PNFS_LAYOUTRET_ON_SETATTR |
-+ PNFS_LAYOUTRET_ON_ERROR,
-
- .alloc_layout_hdr = objlayout_alloc_layout_hdr,
- .free_layout_hdr = objlayout_free_layout_hdr,
-diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
-index 72074e3..b3c2903 100644
---- a/fs/nfs/objlayout/objlayout.c
-+++ b/fs/nfs/objlayout/objlayout.c
-@@ -254,6 +254,8 @@ objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
- oir->status = rdata->task.tk_status = status;
- if (status >= 0)
- rdata->res.count = status;
-+ else
-+ rdata->pnfs_error = status;
- objlayout_iodone(oir);
- /* must not use oir after this point */
-
-@@ -334,6 +336,8 @@ objlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
- if (status >= 0) {
- wdata->res.count = status;
- wdata->verf.committed = oir->committed;
-+ } else {
-+ wdata->pnfs_error = status;
- }
- objlayout_iodone(oir);
- /* must not use oir after this point */
-diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
-index 8e672a2..f881a63 100644
---- a/fs/nfs/pnfs.c
-+++ b/fs/nfs/pnfs.c
-@@ -1178,6 +1178,15 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
- put_lseg(data->lseg);
- data->lseg = NULL;
- dprintk("pnfs write error = %d\n", data->pnfs_error);
-+ if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
-+ PNFS_LAYOUTRET_ON_ERROR) {
-+ /* Don't lo_commit on error, Server will needs to
-+ * preform a file recovery.
-+ */
-+ clear_bit(NFS_INO_LAYOUTCOMMIT,
-+ &NFS_I(data->inode)->flags);
-+ pnfs_return_layout(data->inode);
-+ }
- }
- data->mds_ops->rpc_release(data);
- }
-@@ -1267,6 +1276,9 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
- put_lseg(data->lseg);
- data->lseg = NULL;
- dprintk("pnfs write error = %d\n", data->pnfs_error);
-+ if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
-+ PNFS_LAYOUTRET_ON_ERROR)
-+ pnfs_return_layout(data->inode);
-
- nfs_pageio_init_read_mds(&pgio, data->inode);
-
-diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
-index 1509530..53d593a 100644
---- a/fs/nfs/pnfs.h
-+++ b/fs/nfs/pnfs.h
-@@ -68,6 +68,7 @@ enum {
- enum layoutdriver_policy_flags {
- /* Should the pNFS client commit and return the layout upon a setattr */
- PNFS_LAYOUTRET_ON_SETATTR = 1 << 0,
-+ PNFS_LAYOUTRET_ON_ERROR = 1 << 1,
- };
-
- struct nfs4_deviceid_node;
-diff --git a/fs/nfs/super.c b/fs/nfs/super.c
-index 1347774..3ada13c 100644
---- a/fs/nfs/super.c
-+++ b/fs/nfs/super.c
-@@ -909,10 +909,24 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
- data->auth_flavor_len = 1;
- data->version = version;
- data->minorversion = 0;
-+ security_init_mnt_opts(&data->lsm_opts);
- }
- return data;
- }
-
-+static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data)
-+{
-+ if (data) {
-+ kfree(data->client_address);
-+ kfree(data->mount_server.hostname);
-+ kfree(data->nfs_server.export_path);
-+ kfree(data->nfs_server.hostname);
-+ kfree(data->fscache_uniq);
-+ security_free_mnt_opts(&data->lsm_opts);
-+ kfree(data);
-+ }
-+}
-+
- /*
- * Sanity-check a server address provided by the mount command.
- *
-@@ -2220,9 +2234,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
- data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
- mntfh = nfs_alloc_fhandle();
- if (data == NULL || mntfh == NULL)
-- goto out_free_fh;
--
-- security_init_mnt_opts(&data->lsm_opts);
-+ goto out;
-
- /* Validate the mount data */
- error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
-@@ -2234,8 +2246,6 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
- #ifdef CONFIG_NFS_V4
- if (data->version == 4) {
- mntroot = nfs4_try_mount(flags, dev_name, data);
-- kfree(data->client_address);
-- kfree(data->nfs_server.export_path);
- goto out;
- }
- #endif /* CONFIG_NFS_V4 */
-@@ -2290,13 +2300,8 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
- s->s_flags |= MS_ACTIVE;
-
- out:
-- kfree(data->nfs_server.hostname);
-- kfree(data->mount_server.hostname);
-- kfree(data->fscache_uniq);
-- security_free_mnt_opts(&data->lsm_opts);
--out_free_fh:
-+ nfs_free_parsed_mount_data(data);
- nfs_free_fhandle(mntfh);
-- kfree(data);
- return mntroot;
-
- out_err_nosb:
-@@ -2623,9 +2628,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
-
- mntfh = nfs_alloc_fhandle();
- if (data == NULL || mntfh == NULL)
-- goto out_free_fh;
--
-- security_init_mnt_opts(&data->lsm_opts);
-+ goto out;
-
- /* Get a volume representation */
- server = nfs4_create_server(data, mntfh);
-@@ -2677,13 +2680,10 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
-
- s->s_flags |= MS_ACTIVE;
-
-- security_free_mnt_opts(&data->lsm_opts);
- nfs_free_fhandle(mntfh);
- return mntroot;
-
- out:
-- security_free_mnt_opts(&data->lsm_opts);
--out_free_fh:
- nfs_free_fhandle(mntfh);
- return ERR_PTR(error);
-
-@@ -2838,7 +2838,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
-
- data = nfs_alloc_parsed_mount_data(4);
- if (data == NULL)
-- goto out_free_data;
-+ goto out;
-
- /* Validate the mount data */
- error = nfs4_validate_mount_data(raw_data, data, dev_name);
-@@ -2852,12 +2852,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
- error = PTR_ERR(res);
-
- out:
-- kfree(data->client_address);
-- kfree(data->nfs_server.export_path);
-- kfree(data->nfs_server.hostname);
-- kfree(data->fscache_uniq);
--out_free_data:
-- kfree(data);
-+ nfs_free_parsed_mount_data(data);
- dprintk("<-- nfs4_mount() = %d%s\n", error,
- error != 0 ? " [error]" : "");
- return res;
-diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
-index 62f3b90..5f312ab 100644
---- a/fs/nfsd/export.c
-+++ b/fs/nfsd/export.c
-@@ -87,7 +87,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
- struct svc_expkey key;
- struct svc_expkey *ek = NULL;
-
-- if (mesg[mlen-1] != '\n')
-+ if (mlen < 1 || mesg[mlen-1] != '\n')
- return -EINVAL;
- mesg[mlen-1] = 0;
-
-diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
-index 47e94e3..5abced7 100644
---- a/fs/nfsd/nfs4state.c
-+++ b/fs/nfsd/nfs4state.c
-@@ -3809,16 +3809,29 @@ nevermind:
- deny->ld_type = NFS4_WRITE_LT;
- }
-
-+static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner)
-+{
-+ struct nfs4_ol_stateid *lst;
-+
-+ if (!same_owner_str(&lo->lo_owner, owner, clid))
-+ return false;
-+ lst = list_first_entry(&lo->lo_owner.so_stateids,
-+ struct nfs4_ol_stateid, st_perstateowner);
-+ return lst->st_file->fi_inode == inode;
-+}
-+
- static struct nfs4_lockowner *
- find_lockowner_str(struct inode *inode, clientid_t *clid,
- struct xdr_netobj *owner)
- {
- unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner);
-+ struct nfs4_lockowner *lo;
- struct nfs4_stateowner *op;
-
- list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) {
-- if (same_owner_str(op, owner, clid))
-- return lockowner(op);
-+ lo = lockowner(op);
-+ if (same_lockowner_ino(lo, inode, clid, owner))
-+ return lo;
- }
- return NULL;
- }
-diff --git a/fs/notify/mark.c b/fs/notify/mark.c
-index e14587d..f104d56 100644
---- a/fs/notify/mark.c
-+++ b/fs/notify/mark.c
-@@ -135,9 +135,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
-
- mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
-
-- /* 1 from caller and 1 for being on i_list/g_list */
-- BUG_ON(atomic_read(&mark->refcnt) < 2);
--
- spin_lock(&group->mark_lock);
-
- if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
-@@ -182,6 +179,11 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
- iput(inode);
-
- /*
-+ * We don't necessarily have a ref on mark from caller so the above iput
-+ * may have already destroyed it. Don't touch from now on.
-+ */
-+
-+ /*
- * it's possible that this group tried to destroy itself, but this
- * this mark was simultaneously being freed by inode. If that's the
- * case, we finish freeing the group here.
-diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 851ba3d..1fc1dca 100644
---- a/fs/proc/base.c
-+++ b/fs/proc/base.c
-@@ -194,65 +194,7 @@ static int proc_root_link(struct inode *inode, struct path *path)
- return result;
- }
-
--static struct mm_struct *__check_mem_permission(struct task_struct *task)
--{
-- struct mm_struct *mm;
--
-- mm = get_task_mm(task);
-- if (!mm)
-- return ERR_PTR(-EINVAL);
--
-- /*
-- * A task can always look at itself, in case it chooses
-- * to use system calls instead of load instructions.
-- */
-- if (task == current)
-- return mm;
--
-- /*
-- * If current is actively ptrace'ing, and would also be
-- * permitted to freshly attach with ptrace now, permit it.
-- */
-- if (task_is_stopped_or_traced(task)) {
-- int match;
-- rcu_read_lock();
-- match = (ptrace_parent(task) == current);
-- rcu_read_unlock();
-- if (match && ptrace_may_access(task, PTRACE_MODE_ATTACH))
-- return mm;
-- }
--
-- /*
-- * No one else is allowed.
-- */
-- mmput(mm);
-- return ERR_PTR(-EPERM);
--}
--
--/*
-- * If current may access user memory in @task return a reference to the
-- * corresponding mm, otherwise ERR_PTR.
-- */
--static struct mm_struct *check_mem_permission(struct task_struct *task)
--{
-- struct mm_struct *mm;
-- int err;
--
-- /*
-- * Avoid racing if task exec's as we might get a new mm but validate
-- * against old credentials.
-- */
-- err = mutex_lock_killable(&task->signal->cred_guard_mutex);
-- if (err)
-- return ERR_PTR(err);
--
-- mm = __check_mem_permission(task);
-- mutex_unlock(&task->signal->cred_guard_mutex);
--
-- return mm;
--}
--
--struct mm_struct *mm_for_maps(struct task_struct *task)
-+static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
- {
- struct mm_struct *mm;
- int err;
-@@ -263,7 +205,7 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
-
- mm = get_task_mm(task);
- if (mm && mm != current->mm &&
-- !ptrace_may_access(task, PTRACE_MODE_READ)) {
-+ !ptrace_may_access(task, mode)) {
- mmput(mm);
- mm = ERR_PTR(-EACCES);
- }
-@@ -272,6 +214,11 @@ struct mm_struct *mm_for_maps(struct task_struct *task)
- return mm;
- }
-
-+struct mm_struct *mm_for_maps(struct task_struct *task)
-+{
-+ return mm_access(task, PTRACE_MODE_READ);
-+}
-+
- static int proc_pid_cmdline(struct task_struct *task, char * buffer)
- {
- int res = 0;
-@@ -816,38 +763,39 @@ static const struct file_operations proc_single_file_operations = {
-
- static int mem_open(struct inode* inode, struct file* file)
- {
-- file->private_data = (void*)((long)current->self_exec_id);
-+ struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
-+ struct mm_struct *mm;
-+
-+ if (!task)
-+ return -ESRCH;
-+
-+ mm = mm_access(task, PTRACE_MODE_ATTACH);
-+ put_task_struct(task);
-+
-+ if (IS_ERR(mm))
-+ return PTR_ERR(mm);
-+
- /* OK to pass negative loff_t, we can catch out-of-range */
- file->f_mode |= FMODE_UNSIGNED_OFFSET;
-+ file->private_data = mm;
-+
- return 0;
- }
-
- static ssize_t mem_read(struct file * file, char __user * buf,
- size_t count, loff_t *ppos)
- {
-- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
-+ int ret;
- char *page;
- unsigned long src = *ppos;
-- int ret = -ESRCH;
-- struct mm_struct *mm;
-+ struct mm_struct *mm = file->private_data;
-
-- if (!task)
-- goto out_no_task;
-+ if (!mm)
-+ return 0;
-
-- ret = -ENOMEM;
- page = (char *)__get_free_page(GFP_TEMPORARY);
- if (!page)
-- goto out;
--
-- mm = check_mem_permission(task);
-- ret = PTR_ERR(mm);
-- if (IS_ERR(mm))
-- goto out_free;
--
-- ret = -EIO;
--
-- if (file->private_data != (void*)((long)current->self_exec_id))
-- goto out_put;
-+ return -ENOMEM;
-
- ret = 0;
-
-@@ -874,13 +822,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
- }
- *ppos = src;
-
--out_put:
-- mmput(mm);
--out_free:
- free_page((unsigned long) page);
--out:
-- put_task_struct(task);
--out_no_task:
- return ret;
- }
-
-@@ -889,27 +831,15 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
- {
- int copied;
- char *page;
-- struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
- unsigned long dst = *ppos;
-- struct mm_struct *mm;
-+ struct mm_struct *mm = file->private_data;
-
-- copied = -ESRCH;
-- if (!task)
-- goto out_no_task;
-+ if (!mm)
-+ return 0;
-
-- copied = -ENOMEM;
- page = (char *)__get_free_page(GFP_TEMPORARY);
- if (!page)
-- goto out_task;
--
-- mm = check_mem_permission(task);
-- copied = PTR_ERR(mm);
-- if (IS_ERR(mm))
-- goto out_free;
--
-- copied = -EIO;
-- if (file->private_data != (void *)((long)current->self_exec_id))
-- goto out_mm;
-+ return -ENOMEM;
-
- copied = 0;
- while (count > 0) {
-@@ -933,13 +863,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
- }
- *ppos = dst;
-
--out_mm:
-- mmput(mm);
--out_free:
- free_page((unsigned long) page);
--out_task:
-- put_task_struct(task);
--out_no_task:
- return copied;
- }
-
-@@ -959,11 +883,20 @@ loff_t mem_lseek(struct file *file, loff_t offset, int orig)
- return file->f_pos;
- }
-
-+static int mem_release(struct inode *inode, struct file *file)
-+{
-+ struct mm_struct *mm = file->private_data;
-+
-+ mmput(mm);
-+ return 0;
-+}
-+
- static const struct file_operations proc_mem_operations = {
- .llseek = mem_lseek,
- .read = mem_read,
- .write = mem_write,
- .open = mem_open,
-+ .release = mem_release,
- };
-
- static ssize_t environ_read(struct file *file, char __user *buf,
-diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
-index e418c5a..7dcd2a2 100644
---- a/fs/proc/task_mmu.c
-+++ b/fs/proc/task_mmu.c
-@@ -518,6 +518,9 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
- if (!page)
- continue;
-
-+ if (PageReserved(page))
-+ continue;
-+
- /* Clear accessed and referenced bits. */
- ptep_test_and_clear_young(vma, addr, pte);
- ClearPageReferenced(page);
-diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
-index 766b1d4..29166ec 100644
---- a/fs/proc/uptime.c
-+++ b/fs/proc/uptime.c
-@@ -11,15 +11,20 @@ static int uptime_proc_show(struct seq_file *m, void *v)
- {
- struct timespec uptime;
- struct timespec idle;
-+ cputime64_t idletime;
-+ u64 nsec;
-+ u32 rem;
- int i;
-- cputime_t idletime = cputime_zero;
-
-+ idletime = 0;
- for_each_possible_cpu(i)
- idletime = cputime64_add(idletime, kstat_cpu(i).cpustat.idle);
-
- do_posix_clock_monotonic_gettime(&uptime);
- monotonic_to_bootbased(&uptime);
-- cputime_to_timespec(idletime, &idle);
-+ nsec = cputime64_to_jiffies64(idletime) * TICK_NSEC;
-+ idle.tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
-+ idle.tv_nsec = rem;
- seq_printf(m, "%lu.%02lu %lu.%02lu\n",
- (unsigned long) uptime.tv_sec,
- (uptime.tv_nsec / (NSEC_PER_SEC / 100)),
-diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
-index 8d9c468..c9d2941 100644
---- a/fs/ubifs/debug.h
-+++ b/fs/ubifs/debug.h
-@@ -175,22 +175,23 @@ const char *dbg_key_str1(const struct ubifs_info *c,
- const union ubifs_key *key);
-
- /*
-- * DBGKEY macros require @dbg_lock to be held, which it is in the dbg message
-- * macros.
-+ * TODO: these macros are now broken because there is no locking around them
-+ * and we use a global buffer for the key string. This means that in case of
-+ * concurrent execution we will end up with incorrect and messy key strings.
- */
- #define DBGKEY(key) dbg_key_str0(c, (key))
- #define DBGKEY1(key) dbg_key_str1(c, (key))
-
- extern spinlock_t dbg_lock;
-
--#define ubifs_dbg_msg(type, fmt, ...) do { \
-- spin_lock(&dbg_lock); \
-- pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \
-- spin_unlock(&dbg_lock); \
--} while (0)
-+#define ubifs_dbg_msg(type, fmt, ...) \
-+ pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__)
-
- /* Just a debugging messages not related to any specific UBIFS subsystem */
--#define dbg_msg(fmt, ...) ubifs_dbg_msg("msg", fmt, ##__VA_ARGS__)
-+#define dbg_msg(fmt, ...) \
-+ printk(KERN_DEBUG "UBIFS DBG (pid %d): %s: " fmt "\n", current->pid, \
-+ __func__, ##__VA_ARGS__)
-+
- /* General messages */
- #define dbg_gen(fmt, ...) ubifs_dbg_msg("gen", fmt, ##__VA_ARGS__)
- /* Additional journal messages */
-diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c
-index 8a24f0c..286a051 100644
---- a/fs/xfs/xfs_discard.c
-+++ b/fs/xfs/xfs_discard.c
-@@ -68,7 +68,7 @@ xfs_trim_extents(
- * Look up the longest btree in the AGF and start with it.
- */
- error = xfs_alloc_lookup_le(cur, 0,
-- XFS_BUF_TO_AGF(agbp)->agf_longest, &i);
-+ be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest), &i);
- if (error)
- goto out_del_cursor;
-
-@@ -84,7 +84,7 @@ xfs_trim_extents(
- if (error)
- goto out_del_cursor;
- XFS_WANT_CORRUPTED_GOTO(i == 1, out_del_cursor);
-- ASSERT(flen <= XFS_BUF_TO_AGF(agbp)->agf_longest);
-+ ASSERT(flen <= be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_longest));
-
- /*
- * Too small? Give up.
-diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h
-index 1739726..451823c 100644
---- a/include/acpi/acpi_numa.h
-+++ b/include/acpi/acpi_numa.h
-@@ -15,6 +15,7 @@ extern int pxm_to_node(int);
- extern int node_to_pxm(int);
- extern void __acpi_map_pxm_to_node(int, int);
- extern int acpi_map_pxm_to_node(int);
-+extern unsigned char acpi_srat_revision;
-
- #endif /* CONFIG_ACPI_NUMA */
- #endif /* __ACP_NUMA_H */
-diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
-index 94acd81..0ed1eb0 100644
---- a/include/linux/blkdev.h
-+++ b/include/linux/blkdev.h
-@@ -675,6 +675,9 @@ extern int blk_insert_cloned_request(struct request_queue *q,
- struct request *rq);
- extern void blk_delay_queue(struct request_queue *, unsigned long);
- extern void blk_recount_segments(struct request_queue *, struct bio *);
-+extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
-+extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
-+ unsigned int, void __user *);
- extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
- unsigned int, void __user *);
- extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
-diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
-index 5c4abce..b936763 100644
---- a/include/linux/crash_dump.h
-+++ b/include/linux/crash_dump.h
-@@ -5,6 +5,7 @@
- #include <linux/kexec.h>
- #include <linux/device.h>
- #include <linux/proc_fs.h>
-+#include <linux/elf.h>
-
- #define ELFCORE_ADDR_MAX (-1ULL)
- #define ELFCORE_ADDR_ERR (-2ULL)
-diff --git a/include/linux/dcache.h b/include/linux/dcache.h
-index ed9f74f..4eb8c80 100644
---- a/include/linux/dcache.h
-+++ b/include/linux/dcache.h
-@@ -203,6 +203,7 @@ struct dentry_operations {
-
- #define DCACHE_CANT_MOUNT 0x0100
- #define DCACHE_GENOCIDE 0x0200
-+#define DCACHE_SHRINK_LIST 0x0400
-
- #define DCACHE_NFSFS_RENAMED 0x1000
- /* this dentry has been "silly renamed" and has to be deleted on the last
-diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
-index b87068a..81572af 100644
---- a/include/linux/memcontrol.h
-+++ b/include/linux/memcontrol.h
-@@ -119,6 +119,8 @@ struct zone_reclaim_stat*
- mem_cgroup_get_reclaim_stat_from_page(struct page *page);
- extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg,
- struct task_struct *p);
-+extern void mem_cgroup_replace_page_cache(struct page *oldpage,
-+ struct page *newpage);
-
- #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
- extern int do_swap_account;
-@@ -366,6 +368,10 @@ static inline
- void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
- {
- }
-+static inline void mem_cgroup_replace_page_cache(struct page *oldpage,
-+ struct page *newpage)
-+{
-+}
- #endif /* CONFIG_CGROUP_MEM_CONT */
-
- #if !defined(CONFIG_CGROUP_MEM_RES_CTLR) || !defined(CONFIG_DEBUG_VM)
-diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
-index 2a7c533..6c898af 100644
---- a/include/linux/nfs_xdr.h
-+++ b/include/linux/nfs_xdr.h
-@@ -602,11 +602,16 @@ struct nfs_getaclargs {
- size_t acl_len;
- unsigned int acl_pgbase;
- struct page ** acl_pages;
-+ struct page * acl_scratch;
- struct nfs4_sequence_args seq_args;
- };
-
-+/* getxattr ACL interface flags */
-+#define NFS4_ACL_LEN_REQUEST 0x0001 /* zero length getxattr buffer */
- struct nfs_getaclres {
- size_t acl_len;
-+ size_t acl_data_offset;
-+ int acl_flags;
- struct nfs4_sequence_res seq_res;
- };
-
-diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
-index b5d9657..411c412 100644
---- a/include/linux/pci_regs.h
-+++ b/include/linux/pci_regs.h
-@@ -392,7 +392,7 @@
- #define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
- #define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
- #define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
--#define PCI_EXP_TYPE_RC_EC 0x10 /* Root Complex Event Collector */
-+#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
- #define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
- #define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
- #define PCI_EXP_DEVCAP 4 /* Device capabilities */
-diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
-index 9291ac3..6f10c9c 100644
---- a/include/linux/shmem_fs.h
-+++ b/include/linux/shmem_fs.h
-@@ -48,6 +48,7 @@ extern struct file *shmem_file_setup(const char *name,
- loff_t size, unsigned long flags);
- extern int shmem_zero_setup(struct vm_area_struct *);
- extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
-+extern void shmem_unlock_mapping(struct address_space *mapping);
- extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
- pgoff_t index, gfp_t gfp_mask);
- extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);
-diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
-index 85c50b4..c84e974 100644
---- a/include/linux/sunrpc/svcsock.h
-+++ b/include/linux/sunrpc/svcsock.h
-@@ -34,7 +34,7 @@ struct svc_sock {
- /*
- * Function prototypes.
- */
--void svc_close_all(struct list_head *);
-+void svc_close_all(struct svc_serv *);
- int svc_recv(struct svc_rqst *, long);
- int svc_send(struct svc_rqst *);
- void svc_drop(struct svc_rqst *);
-diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
-index a20970e..af70af3 100644
---- a/include/linux/sunrpc/xdr.h
-+++ b/include/linux/sunrpc/xdr.h
-@@ -191,6 +191,8 @@ extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
- struct xdr_array2_desc *desc);
- extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
- struct xdr_array2_desc *desc);
-+extern void _copy_from_pages(char *p, struct page **pages, size_t pgbase,
-+ size_t len);
-
- /*
- * Provide some simple tools for XDR buffer overflow-checking etc.
-diff --git a/include/linux/swap.h b/include/linux/swap.h
-index 1e22e12..67b3fa3 100644
---- a/include/linux/swap.h
-+++ b/include/linux/swap.h
-@@ -272,7 +272,7 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
- #endif
-
- extern int page_evictable(struct page *page, struct vm_area_struct *vma);
--extern void scan_mapping_unevictable_pages(struct address_space *);
-+extern void check_move_unevictable_pages(struct page **, int nr_pages);
-
- extern unsigned long scan_unevictable_pages;
- extern int scan_unevictable_handler(struct ctl_table *, int,
-diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
-index 4b752d5..45a7698 100644
---- a/include/linux/videodev2.h
-+++ b/include/linux/videodev2.h
-@@ -1131,6 +1131,7 @@ struct v4l2_querymenu {
- #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
-
- /* User-class control IDs defined by V4L2 */
-+#define V4L2_CID_MAX_CTRLS 1024
- #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
- #define V4L2_CID_USER_BASE V4L2_CID_BASE
- /* IDs reserved for driver specific controls */
-diff --git a/include/media/tuner.h b/include/media/tuner.h
-index 89c290b..29e1920 100644
---- a/include/media/tuner.h
-+++ b/include/media/tuner.h
-@@ -127,7 +127,6 @@
- #define TUNER_PHILIPS_FMD1216MEX_MK3 78
- #define TUNER_PHILIPS_FM1216MK5 79
- #define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */
--#define TUNER_XC4000 81 /* Xceive Silicon Tuner */
-
- #define TUNER_PARTSNIC_PTI_5NF05 81
- #define TUNER_PHILIPS_CU1216L 82
-@@ -136,6 +135,8 @@
- #define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */
- #define TUNER_TENA_TNF_5337 86
-
-+#define TUNER_XC4000 87 /* Xceive Silicon Tuner */
-+
- /* tv card specific */
- #define TDA9887_PRESENT (1<<0)
- #define TDA9887_PORT1_INACTIVE (1<<1)
-diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
-index 6873c7d..a79886c 100644
---- a/include/target/target_core_base.h
-+++ b/include/target/target_core_base.h
-@@ -34,6 +34,7 @@
- #define TRANSPORT_SENSE_BUFFER SCSI_SENSE_BUFFERSIZE
- /* Used by transport_send_check_condition_and_sense() */
- #define SPC_SENSE_KEY_OFFSET 2
-+#define SPC_ADD_SENSE_LEN_OFFSET 7
- #define SPC_ASC_KEY_OFFSET 12
- #define SPC_ASCQ_KEY_OFFSET 13
- #define TRANSPORT_IQN_LEN 224
-diff --git a/include/xen/interface/io/xs_wire.h b/include/xen/interface/io/xs_wire.h
-index f6f07aa..7cdfca2 100644
---- a/include/xen/interface/io/xs_wire.h
-+++ b/include/xen/interface/io/xs_wire.h
-@@ -87,4 +87,7 @@ struct xenstore_domain_interface {
- XENSTORE_RING_IDX rsp_cons, rsp_prod;
- };
-
-+/* Violating this is very bad. See docs/misc/xenstore.txt. */
-+#define XENSTORE_PAYLOAD_MAX 4096
-+
- #endif /* _XS_WIRE_H */
-diff --git a/init/do_mounts.c b/init/do_mounts.c
-index 0f6e1d9..db6e5ee 100644
---- a/init/do_mounts.c
-+++ b/init/do_mounts.c
-@@ -398,15 +398,42 @@ out:
- }
-
- #ifdef CONFIG_ROOT_NFS
-+
-+#define NFSROOT_TIMEOUT_MIN 5
-+#define NFSROOT_TIMEOUT_MAX 30
-+#define NFSROOT_RETRY_MAX 5
-+
- static int __init mount_nfs_root(void)
- {
- char *root_dev, *root_data;
-+ unsigned int timeout;
-+ int try, err;
-
-- if (nfs_root_data(&root_dev, &root_data) != 0)
-- return 0;
-- if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0)
-+ err = nfs_root_data(&root_dev, &root_data);
-+ if (err != 0)
- return 0;
-- return 1;
-+
-+ /*
-+ * The server or network may not be ready, so try several
-+ * times. Stop after a few tries in case the client wants
-+ * to fall back to other boot methods.
-+ */
-+ timeout = NFSROOT_TIMEOUT_MIN;
-+ for (try = 1; ; try++) {
-+ err = do_mount_root(root_dev, "nfs",
-+ root_mountflags, root_data);
-+ if (err == 0)
-+ return 1;
-+ if (try > NFSROOT_RETRY_MAX)
-+ break;
-+
-+ /* Wait, in case the server refused us immediately */
-+ ssleep(timeout);
-+ timeout <<= 1;
-+ if (timeout > NFSROOT_TIMEOUT_MAX)
-+ timeout = NFSROOT_TIMEOUT_MAX;
-+ }
-+ return 0;
- }
- #endif
-
-diff --git a/ipc/shm.c b/ipc/shm.c
-index 02ecf2c..b76be5b 100644
---- a/ipc/shm.c
-+++ b/ipc/shm.c
-@@ -870,9 +870,7 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
- case SHM_LOCK:
- case SHM_UNLOCK:
- {
-- struct file *uninitialized_var(shm_file);
--
-- lru_add_drain_all(); /* drain pagevecs to lru lists */
-+ struct file *shm_file;
-
- shp = shm_lock_check(ns, shmid);
- if (IS_ERR(shp)) {
-@@ -895,22 +893,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
- err = security_shm_shmctl(shp, cmd);
- if (err)
- goto out_unlock;
--
-- if(cmd==SHM_LOCK) {
-+
-+ shm_file = shp->shm_file;
-+ if (is_file_hugepages(shm_file))
-+ goto out_unlock;
-+
-+ if (cmd == SHM_LOCK) {
- struct user_struct *user = current_user();
-- if (!is_file_hugepages(shp->shm_file)) {
-- err = shmem_lock(shp->shm_file, 1, user);
-- if (!err && !(shp->shm_perm.mode & SHM_LOCKED)){
-- shp->shm_perm.mode |= SHM_LOCKED;
-- shp->mlock_user = user;
-- }
-+ err = shmem_lock(shm_file, 1, user);
-+ if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) {
-+ shp->shm_perm.mode |= SHM_LOCKED;
-+ shp->mlock_user = user;
- }
-- } else if (!is_file_hugepages(shp->shm_file)) {
-- shmem_lock(shp->shm_file, 0, shp->mlock_user);
-- shp->shm_perm.mode &= ~SHM_LOCKED;
-- shp->mlock_user = NULL;
-+ goto out_unlock;
- }
-+
-+ /* SHM_UNLOCK */
-+ if (!(shp->shm_perm.mode & SHM_LOCKED))
-+ goto out_unlock;
-+ shmem_lock(shm_file, 0, shp->mlock_user);
-+ shp->shm_perm.mode &= ~SHM_LOCKED;
-+ shp->mlock_user = NULL;
-+ get_file(shm_file);
- shm_unlock(shp);
-+ shmem_unlock_mapping(shm_file->f_mapping);
-+ fput(shm_file);
- goto out;
- }
- case IPC_RMID:
-diff --git a/kernel/kprobes.c b/kernel/kprobes.c
-index e5d8464..52fd049 100644
---- a/kernel/kprobes.c
-+++ b/kernel/kprobes.c
-@@ -1077,6 +1077,7 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
- /* Early boot. kretprobe_table_locks not yet initialized. */
- return;
-
-+ INIT_HLIST_HEAD(&empty_rp);
- hash = hash_ptr(tk, KPROBE_HASH_BITS);
- head = &kretprobe_inst_table[hash];
- kretprobe_table_lock(hash, &flags);
-@@ -1085,7 +1086,6 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
- recycle_rp_inst(ri, &empty_rp);
- }
- kretprobe_table_unlock(hash, &flags);
-- INIT_HLIST_HEAD(&empty_rp);
- hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
- hlist_del(&ri->hlist);
- kfree(ri);
-diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
-index b1e8943..25b4f4d 100644
---- a/kernel/trace/ftrace.c
-+++ b/kernel/trace/ftrace.c
-@@ -948,7 +948,7 @@ struct ftrace_func_probe {
- };
-
- enum {
-- FTRACE_ENABLE_CALLS = (1 << 0),
-+ FTRACE_UPDATE_CALLS = (1 << 0),
- FTRACE_DISABLE_CALLS = (1 << 1),
- FTRACE_UPDATE_TRACE_FUNC = (1 << 2),
- FTRACE_START_FUNC_RET = (1 << 3),
-@@ -1519,7 +1519,7 @@ int ftrace_text_reserved(void *start, void *end)
-
-
- static int
--__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
-+__ftrace_replace_code(struct dyn_ftrace *rec, int update)
- {
- unsigned long ftrace_addr;
- unsigned long flag = 0UL;
-@@ -1527,17 +1527,17 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
- ftrace_addr = (unsigned long)FTRACE_ADDR;
-
- /*
-- * If we are enabling tracing:
-+ * If we are updating calls:
- *
- * If the record has a ref count, then we need to enable it
- * because someone is using it.
- *
- * Otherwise we make sure its disabled.
- *
-- * If we are disabling tracing, then disable all records that
-+ * If we are disabling calls, then disable all records that
- * are enabled.
- */
-- if (enable && (rec->flags & ~FTRACE_FL_MASK))
-+ if (update && (rec->flags & ~FTRACE_FL_MASK))
- flag = FTRACE_FL_ENABLED;
-
- /* If the state of this record hasn't changed, then do nothing */
-@@ -1553,7 +1553,7 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
- return ftrace_make_nop(NULL, rec, ftrace_addr);
- }
-
--static void ftrace_replace_code(int enable)
-+static void ftrace_replace_code(int update)
- {
- struct dyn_ftrace *rec;
- struct ftrace_page *pg;
-@@ -1567,7 +1567,7 @@ static void ftrace_replace_code(int enable)
- if (rec->flags & FTRACE_FL_FREE)
- continue;
-
-- failed = __ftrace_replace_code(rec, enable);
-+ failed = __ftrace_replace_code(rec, update);
- if (failed) {
- ftrace_bug(failed, rec->ip);
- /* Stop processing */
-@@ -1623,7 +1623,7 @@ static int __ftrace_modify_code(void *data)
- */
- function_trace_stop++;
-
-- if (*command & FTRACE_ENABLE_CALLS)
-+ if (*command & FTRACE_UPDATE_CALLS)
- ftrace_replace_code(1);
- else if (*command & FTRACE_DISABLE_CALLS)
- ftrace_replace_code(0);
-@@ -1691,7 +1691,7 @@ static int ftrace_startup(struct ftrace_ops *ops, int command)
- return -ENODEV;
-
- ftrace_start_up++;
-- command |= FTRACE_ENABLE_CALLS;
-+ command |= FTRACE_UPDATE_CALLS;
-
- /* ops marked global share the filter hashes */
- if (ops->flags & FTRACE_OPS_FL_GLOBAL) {
-@@ -1743,8 +1743,7 @@ static void ftrace_shutdown(struct ftrace_ops *ops, int command)
- if (ops != &global_ops || !global_start_up)
- ops->flags &= ~FTRACE_OPS_FL_ENABLED;
-
-- if (!ftrace_start_up)
-- command |= FTRACE_DISABLE_CALLS;
-+ command |= FTRACE_UPDATE_CALLS;
-
- if (saved_ftrace_func != ftrace_trace_function) {
- saved_ftrace_func = ftrace_trace_function;
-@@ -1766,7 +1765,7 @@ static void ftrace_startup_sysctl(void)
- saved_ftrace_func = NULL;
- /* ftrace_start_up is true if we want ftrace running */
- if (ftrace_start_up)
-- ftrace_run_update_code(FTRACE_ENABLE_CALLS);
-+ ftrace_run_update_code(FTRACE_UPDATE_CALLS);
- }
-
- static void ftrace_shutdown_sysctl(void)
-@@ -2919,7 +2918,7 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len,
- ret = ftrace_hash_move(ops, enable, orig_hash, hash);
- if (!ret && ops->flags & FTRACE_OPS_FL_ENABLED
- && ftrace_enabled)
-- ftrace_run_update_code(FTRACE_ENABLE_CALLS);
-+ ftrace_run_update_code(FTRACE_UPDATE_CALLS);
-
- mutex_unlock(&ftrace_lock);
-
-@@ -3107,7 +3106,7 @@ ftrace_regex_release(struct inode *inode, struct file *file)
- orig_hash, iter->hash);
- if (!ret && (iter->ops->flags & FTRACE_OPS_FL_ENABLED)
- && ftrace_enabled)
-- ftrace_run_update_code(FTRACE_ENABLE_CALLS);
-+ ftrace_run_update_code(FTRACE_UPDATE_CALLS);
-
- mutex_unlock(&ftrace_lock);
- }
-diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
-index db110b8..f1539de 100644
---- a/kernel/tracepoint.c
-+++ b/kernel/tracepoint.c
-@@ -634,10 +634,11 @@ static int tracepoint_module_coming(struct module *mod)
- int ret = 0;
-
- /*
-- * We skip modules that tain the kernel, especially those with different
-- * module header (for forced load), to make sure we don't cause a crash.
-+ * We skip modules that taint the kernel, especially those with different
-+ * module headers (for forced load), to make sure we don't cause a crash.
-+ * Staging and out-of-tree GPL modules are fine.
- */
-- if (mod->taints)
-+ if (mod->taints & ~((1 << TAINT_OOT_MODULE) | (1 << TAINT_CRAP)))
- return 0;
- mutex_lock(&tracepoints_mutex);
- tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL);
-diff --git a/mm/filemap.c b/mm/filemap.c
-index 5f0a3c9..90286a4 100644
---- a/mm/filemap.c
-+++ b/mm/filemap.c
-@@ -393,24 +393,11 @@ EXPORT_SYMBOL(filemap_write_and_wait_range);
- int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
- {
- int error;
-- struct mem_cgroup *memcg = NULL;
-
- VM_BUG_ON(!PageLocked(old));
- VM_BUG_ON(!PageLocked(new));
- VM_BUG_ON(new->mapping);
-
-- /*
-- * This is not page migration, but prepare_migration and
-- * end_migration does enough work for charge replacement.
-- *
-- * In the longer term we probably want a specialized function
-- * for moving the charge from old to new in a more efficient
-- * manner.
-- */
-- error = mem_cgroup_prepare_migration(old, new, &memcg, gfp_mask);
-- if (error)
-- return error;
--
- error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
- if (!error) {
- struct address_space *mapping = old->mapping;
-@@ -432,13 +419,12 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
- if (PageSwapBacked(new))
- __inc_zone_page_state(new, NR_SHMEM);
- spin_unlock_irq(&mapping->tree_lock);
-+ /* mem_cgroup codes must not be called under tree_lock */
-+ mem_cgroup_replace_page_cache(old, new);
- radix_tree_preload_end();
- if (freepage)
- freepage(old);
- page_cache_release(old);
-- mem_cgroup_end_migration(memcg, old, new, true);
-- } else {
-- mem_cgroup_end_migration(memcg, old, new, false);
- }
-
- return error;
-diff --git a/mm/memcontrol.c b/mm/memcontrol.c
-index b63f5f7..f538e9b 100644
---- a/mm/memcontrol.c
-+++ b/mm/memcontrol.c
-@@ -3366,6 +3366,50 @@ void mem_cgroup_end_migration(struct mem_cgroup *memcg,
- cgroup_release_and_wakeup_rmdir(&memcg->css);
- }
-
-+/*
-+ * At replace page cache, newpage is not under any memcg but it's on
-+ * LRU. So, this function doesn't touch res_counter but handles LRU
-+ * in correct way. Both pages are locked so we cannot race with uncharge.
-+ */
-+void mem_cgroup_replace_page_cache(struct page *oldpage,
-+ struct page *newpage)
-+{
-+ struct mem_cgroup *memcg;
-+ struct page_cgroup *pc;
-+ struct zone *zone;
-+ enum charge_type type = MEM_CGROUP_CHARGE_TYPE_CACHE;
-+ unsigned long flags;
-+
-+ if (mem_cgroup_disabled())
-+ return;
-+
-+ pc = lookup_page_cgroup(oldpage);
-+ /* fix accounting on old pages */
-+ lock_page_cgroup(pc);
-+ memcg = pc->mem_cgroup;
-+ mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), -1);
-+ ClearPageCgroupUsed(pc);
-+ unlock_page_cgroup(pc);
-+
-+ if (PageSwapBacked(oldpage))
-+ type = MEM_CGROUP_CHARGE_TYPE_SHMEM;
-+
-+ zone = page_zone(newpage);
-+ pc = lookup_page_cgroup(newpage);
-+ /*
-+ * Even if newpage->mapping was NULL before starting replacement,
-+ * the newpage may be on LRU(or pagevec for LRU) already. We lock
-+ * LRU while we overwrite pc->mem_cgroup.
-+ */
-+ spin_lock_irqsave(&zone->lru_lock, flags);
-+ if (PageLRU(newpage))
-+ del_page_from_lru_list(zone, newpage, page_lru(newpage));
-+ __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type);
-+ if (PageLRU(newpage))
-+ add_page_to_lru_list(zone, newpage, page_lru(newpage));
-+ spin_unlock_irqrestore(&zone->lru_lock, flags);
-+}
-+
- #ifdef CONFIG_DEBUG_VM
- static struct page_cgroup *lookup_page_cgroup_used(struct page *page)
- {
-diff --git a/mm/page_alloc.c b/mm/page_alloc.c
-index 2b8ba3a..485be89 100644
---- a/mm/page_alloc.c
-+++ b/mm/page_alloc.c
-@@ -5608,6 +5608,17 @@ __count_immobile_pages(struct zone *zone, struct page *page, int count)
- bool is_pageblock_removable_nolock(struct page *page)
- {
- struct zone *zone = page_zone(page);
-+ unsigned long pfn = page_to_pfn(page);
-+
-+ /*
-+ * We have to be careful here because we are iterating over memory
-+ * sections which are not zone aware so we might end up outside of
-+ * the zone but still within the section.
-+ */
-+ if (!zone || zone->zone_start_pfn > pfn ||
-+ zone->zone_start_pfn + zone->spanned_pages <= pfn)
-+ return false;
-+
- return __count_immobile_pages(zone, page, 0);
- }
-
-diff --git a/mm/shmem.c b/mm/shmem.c
-index d672250..6c253f7 100644
---- a/mm/shmem.c
-+++ b/mm/shmem.c
-@@ -379,7 +379,7 @@ static int shmem_free_swap(struct address_space *mapping,
- /*
- * Pagevec may contain swap entries, so shuffle up pages before releasing.
- */
--static void shmem_pagevec_release(struct pagevec *pvec)
-+static void shmem_deswap_pagevec(struct pagevec *pvec)
- {
- int i, j;
-
-@@ -389,7 +389,36 @@ static void shmem_pagevec_release(struct pagevec *pvec)
- pvec->pages[j++] = page;
- }
- pvec->nr = j;
-- pagevec_release(pvec);
-+}
-+
-+/*
-+ * SysV IPC SHM_UNLOCK restore Unevictable pages to their evictable lists.
-+ */
-+void shmem_unlock_mapping(struct address_space *mapping)
-+{
-+ struct pagevec pvec;
-+ pgoff_t indices[PAGEVEC_SIZE];
-+ pgoff_t index = 0;
-+
-+ pagevec_init(&pvec, 0);
-+ /*
-+ * Minor point, but we might as well stop if someone else SHM_LOCKs it.
-+ */
-+ while (!mapping_unevictable(mapping)) {
-+ /*
-+ * Avoid pagevec_lookup(): find_get_pages() returns 0 as if it
-+ * has finished, if it hits a row of PAGEVEC_SIZE swap entries.
-+ */
-+ pvec.nr = shmem_find_get_pages_and_swap(mapping, index,
-+ PAGEVEC_SIZE, pvec.pages, indices);
-+ if (!pvec.nr)
-+ break;
-+ index = indices[pvec.nr - 1] + 1;
-+ shmem_deswap_pagevec(&pvec);
-+ check_move_unevictable_pages(pvec.pages, pvec.nr);
-+ pagevec_release(&pvec);
-+ cond_resched();
-+ }
- }
-
- /*
-@@ -440,7 +469,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
- }
- unlock_page(page);
- }
-- shmem_pagevec_release(&pvec);
-+ shmem_deswap_pagevec(&pvec);
-+ pagevec_release(&pvec);
- mem_cgroup_uncharge_end();
- cond_resched();
- index++;
-@@ -470,7 +500,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
- continue;
- }
- if (index == start && indices[0] > end) {
-- shmem_pagevec_release(&pvec);
-+ shmem_deswap_pagevec(&pvec);
-+ pagevec_release(&pvec);
- break;
- }
- mem_cgroup_uncharge_start();
-@@ -494,7 +525,8 @@ void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
- }
- unlock_page(page);
- }
-- shmem_pagevec_release(&pvec);
-+ shmem_deswap_pagevec(&pvec);
-+ pagevec_release(&pvec);
- mem_cgroup_uncharge_end();
- index++;
- }
-@@ -1068,13 +1100,6 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
- user_shm_unlock(inode->i_size, user);
- info->flags &= ~VM_LOCKED;
- mapping_clear_unevictable(file->f_mapping);
-- /*
-- * Ensure that a racing putback_lru_page() can see
-- * the pages of this mapping are evictable when we
-- * skip them due to !PageLRU during the scan.
-- */
-- smp_mb__after_clear_bit();
-- scan_mapping_unevictable_pages(file->f_mapping);
- }
- retval = 0;
-
-@@ -2446,6 +2471,10 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
- return 0;
- }
-
-+void shmem_unlock_mapping(struct address_space *mapping)
-+{
-+}
-+
- void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend)
- {
- truncate_inode_pages_range(inode->i_mapping, lstart, lend);
-diff --git a/mm/slub.c b/mm/slub.c
-index ed3334d..1a919f0 100644
---- a/mm/slub.c
-+++ b/mm/slub.c
-@@ -2166,6 +2166,11 @@ redo:
- goto new_slab;
- }
-
-+ /* must check again c->freelist in case of cpu migration or IRQ */
-+ object = c->freelist;
-+ if (object)
-+ goto load_freelist;
-+
- stat(s, ALLOC_SLOWPATH);
-
- do {
-diff --git a/mm/vmscan.c b/mm/vmscan.c
-index f54a05b..cb33d9c 100644
---- a/mm/vmscan.c
-+++ b/mm/vmscan.c
-@@ -636,7 +636,7 @@ redo:
- * When racing with an mlock or AS_UNEVICTABLE clearing
- * (page is unlocked) make sure that if the other thread
- * does not observe our setting of PG_lru and fails
-- * isolation/check_move_unevictable_page,
-+ * isolation/check_move_unevictable_pages,
- * we see PG_mlocked/AS_UNEVICTABLE cleared below and move
- * the page back to the evictable list.
- *
-@@ -3353,97 +3353,59 @@ int page_evictable(struct page *page, struct vm_area_struct *vma)
- return 1;
- }
-
-+#ifdef CONFIG_SHMEM
- /**
-- * check_move_unevictable_page - check page for evictability and move to appropriate zone lru list
-- * @page: page to check evictability and move to appropriate lru list
-- * @zone: zone page is in
-+ * check_move_unevictable_pages - check pages for evictability and move to appropriate zone lru list
-+ * @pages: array of pages to check
-+ * @nr_pages: number of pages to check
- *
-- * Checks a page for evictability and moves the page to the appropriate
-- * zone lru list.
-+ * Checks pages for evictability and moves them to the appropriate lru list.
- *
-- * Restrictions: zone->lru_lock must be held, page must be on LRU and must
-- * have PageUnevictable set.
-+ * This function is only used for SysV IPC SHM_UNLOCK.
- */
--static void check_move_unevictable_page(struct page *page, struct zone *zone)
-+void check_move_unevictable_pages(struct page **pages, int nr_pages)
- {
-- VM_BUG_ON(PageActive(page));
--
--retry:
-- ClearPageUnevictable(page);
-- if (page_evictable(page, NULL)) {
-- enum lru_list l = page_lru_base_type(page);
-+ struct zone *zone = NULL;
-+ int pgscanned = 0;
-+ int pgrescued = 0;
-+ int i;
-
-- __dec_zone_state(zone, NR_UNEVICTABLE);
-- list_move(&page->lru, &zone->lru[l].list);
-- mem_cgroup_move_lists(page, LRU_UNEVICTABLE, l);
-- __inc_zone_state(zone, NR_INACTIVE_ANON + l);
-- __count_vm_event(UNEVICTABLE_PGRESCUED);
-- } else {
-- /*
-- * rotate unevictable list
-- */
-- SetPageUnevictable(page);
-- list_move(&page->lru, &zone->lru[LRU_UNEVICTABLE].list);
-- mem_cgroup_rotate_lru_list(page, LRU_UNEVICTABLE);
-- if (page_evictable(page, NULL))
-- goto retry;
-- }
--}
-+ for (i = 0; i < nr_pages; i++) {
-+ struct page *page = pages[i];
-+ struct zone *pagezone;
-
--/**
-- * scan_mapping_unevictable_pages - scan an address space for evictable pages
-- * @mapping: struct address_space to scan for evictable pages
-- *
-- * Scan all pages in mapping. Check unevictable pages for
-- * evictability and move them to the appropriate zone lru list.
-- */
--void scan_mapping_unevictable_pages(struct address_space *mapping)
--{
-- pgoff_t next = 0;
-- pgoff_t end = (i_size_read(mapping->host) + PAGE_CACHE_SIZE - 1) >>
-- PAGE_CACHE_SHIFT;
-- struct zone *zone;
-- struct pagevec pvec;
-+ pgscanned++;
-+ pagezone = page_zone(page);
-+ if (pagezone != zone) {
-+ if (zone)
-+ spin_unlock_irq(&zone->lru_lock);
-+ zone = pagezone;
-+ spin_lock_irq(&zone->lru_lock);
-+ }
-
-- if (mapping->nrpages == 0)
-- return;
-+ if (!PageLRU(page) || !PageUnevictable(page))
-+ continue;
-
-- pagevec_init(&pvec, 0);
-- while (next < end &&
-- pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
-- int i;
-- int pg_scanned = 0;
--
-- zone = NULL;
--
-- for (i = 0; i < pagevec_count(&pvec); i++) {
-- struct page *page = pvec.pages[i];
-- pgoff_t page_index = page->index;
-- struct zone *pagezone = page_zone(page);
--
-- pg_scanned++;
-- if (page_index > next)
-- next = page_index;
-- next++;
--
-- if (pagezone != zone) {
-- if (zone)
-- spin_unlock_irq(&zone->lru_lock);
-- zone = pagezone;
-- spin_lock_irq(&zone->lru_lock);
-- }
-+ if (page_evictable(page, NULL)) {
-+ enum lru_list lru = page_lru_base_type(page);
-
-- if (PageLRU(page) && PageUnevictable(page))
-- check_move_unevictable_page(page, zone);
-+ VM_BUG_ON(PageActive(page));
-+ ClearPageUnevictable(page);
-+ __dec_zone_state(zone, NR_UNEVICTABLE);
-+ list_move(&page->lru, &zone->lru[lru].list);
-+ mem_cgroup_move_lists(page, LRU_UNEVICTABLE, lru);
-+ __inc_zone_state(zone, NR_INACTIVE_ANON + lru);
-+ pgrescued++;
- }
-- if (zone)
-- spin_unlock_irq(&zone->lru_lock);
-- pagevec_release(&pvec);
--
-- count_vm_events(UNEVICTABLE_PGSCANNED, pg_scanned);
- }
-
-+ if (zone) {
-+ __count_vm_events(UNEVICTABLE_PGRESCUED, pgrescued);
-+ __count_vm_events(UNEVICTABLE_PGSCANNED, pgscanned);
-+ spin_unlock_irq(&zone->lru_lock);
-+ }
- }
-+#endif /* CONFIG_SHMEM */
-
- static void warn_scan_unevictable_pages(void)
- {
-diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
-index ea10a51..73495f1 100644
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -702,6 +702,8 @@ struct tpt_led_trigger {
- * well be on the operating channel
- * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
- * determine if we are on the operating channel or not
-+ * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
-+ * gets only set in conjunction with SCAN_SW_SCANNING
- * @SCAN_COMPLETED: Set for our scan work function when the driver reported
- * that the scan completed.
- * @SCAN_ABORTED: Set for our scan work function when the driver reported
-@@ -710,6 +712,7 @@ struct tpt_led_trigger {
- enum {
- SCAN_SW_SCANNING,
- SCAN_HW_SCANNING,
-+ SCAN_OFF_CHANNEL,
- SCAN_COMPLETED,
- SCAN_ABORTED,
- };
-@@ -1140,14 +1143,10 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
- void ieee80211_sched_scan_stopped_work(struct work_struct *work);
-
- /* off-channel helpers */
--bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
--void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
-- bool tell_ap);
--void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
-- bool offchannel_ps_enable);
-+void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local);
-+void ieee80211_offchannel_stop_station(struct ieee80211_local *local);
- void ieee80211_offchannel_return(struct ieee80211_local *local,
-- bool enable_beaconing,
-- bool offchannel_ps_disable);
-+ bool enable_beaconing);
- void ieee80211_hw_roc_setup(struct ieee80211_local *local);
-
- /* interface handling */
-diff --git a/net/mac80211/main.c b/net/mac80211/main.c
-index cae4435..a7536fd 100644
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -92,47 +92,6 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
- ieee80211_configure_filter(local);
- }
-
--/*
-- * Returns true if we are logically configured to be on
-- * the operating channel AND the hardware-conf is currently
-- * configured on the operating channel. Compares channel-type
-- * as well.
-- */
--bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
--{
-- struct ieee80211_channel *chan, *scan_chan;
-- enum nl80211_channel_type channel_type;
--
-- /* This logic needs to match logic in ieee80211_hw_config */
-- if (local->scan_channel) {
-- chan = local->scan_channel;
-- /* If scanning on oper channel, use whatever channel-type
-- * is currently in use.
-- */
-- if (chan == local->oper_channel)
-- channel_type = local->_oper_channel_type;
-- else
-- channel_type = NL80211_CHAN_NO_HT;
-- } else if (local->tmp_channel) {
-- chan = scan_chan = local->tmp_channel;
-- channel_type = local->tmp_channel_type;
-- } else {
-- chan = local->oper_channel;
-- channel_type = local->_oper_channel_type;
-- }
--
-- if (chan != local->oper_channel ||
-- channel_type != local->_oper_channel_type)
-- return false;
--
-- /* Check current hardware-config against oper_channel. */
-- if ((local->oper_channel != local->hw.conf.channel) ||
-- (local->_oper_channel_type != local->hw.conf.channel_type))
-- return false;
--
-- return true;
--}
--
- int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
- {
- struct ieee80211_channel *chan, *scan_chan;
-@@ -145,9 +104,6 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
-
- scan_chan = local->scan_channel;
-
-- /* If this off-channel logic ever changes, ieee80211_on_oper_channel
-- * may need to change as well.
-- */
- offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
- if (scan_chan) {
- chan = scan_chan;
-@@ -158,19 +114,17 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
- channel_type = local->_oper_channel_type;
- else
- channel_type = NL80211_CHAN_NO_HT;
-- } else if (local->tmp_channel) {
-+ local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
-+ } else if (local->tmp_channel &&
-+ local->oper_channel != local->tmp_channel) {
- chan = scan_chan = local->tmp_channel;
- channel_type = local->tmp_channel_type;
-+ local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
- } else {
- chan = local->oper_channel;
- channel_type = local->_oper_channel_type;
-- }
--
-- if (chan != local->oper_channel ||
-- channel_type != local->_oper_channel_type)
-- local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
-- else
- local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
-+ }
-
- offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
-
-@@ -279,7 +233,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
-
- if (changed & BSS_CHANGED_BEACON_ENABLED) {
- if (local->quiescing || !ieee80211_sdata_running(sdata) ||
-- test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) {
-+ test_bit(SCAN_SW_SCANNING, &local->scanning)) {
- sdata->vif.bss_conf.enable_beacon = false;
- } else {
- /*
-diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
-index 3d41441..1b239be 100644
---- a/net/mac80211/offchannel.c
-+++ b/net/mac80211/offchannel.c
-@@ -18,14 +18,10 @@
- #include "driver-trace.h"
-
- /*
-- * Tell our hardware to disable PS.
-- * Optionally inform AP that we will go to sleep so that it will buffer
-- * the frames while we are doing off-channel work. This is optional
-- * because we *may* be doing work on-operating channel, and want our
-- * hardware unconditionally awake, but still let the AP send us normal frames.
-+ * inform AP that we will go to sleep so that it will buffer the frames
-+ * while we scan
- */
--static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
-- bool tell_ap)
-+static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
- {
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-@@ -46,8 +42,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata,
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- }
-
-- if (tell_ap && (!local->offchannel_ps_enabled ||
-- !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)))
-+ if (!(local->offchannel_ps_enabled) ||
-+ !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
- /*
- * If power save was enabled, no need to send a nullfunc
- * frame because AP knows that we are sleeping. But if the
-@@ -82,9 +78,6 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
- * we are sleeping, let's just enable power save mode in
- * hardware.
- */
-- /* TODO: Only set hardware if CONF_PS changed?
-- * TODO: Should we set offchannel_ps_enabled to false?
-- */
- local->hw.conf.flags |= IEEE80211_CONF_PS;
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
- } else if (local->hw.conf.dynamic_ps_timeout > 0) {
-@@ -103,61 +96,63 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
- ieee80211_sta_reset_conn_monitor(sdata);
- }
-
--void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
-- bool offchannel_ps_enable)
-+void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local)
- {
- struct ieee80211_sub_if_data *sdata;
-
-- /*
-- * notify the AP about us leaving the channel and stop all
-- * STA interfaces.
-- */
- mutex_lock(&local->iflist_mtx);
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (!ieee80211_sdata_running(sdata))
- continue;
-
-- if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
-- set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
--
-- /* Check to see if we should disable beaconing. */
-+ /* disable beaconing */
- if (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC ||
- sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
- ieee80211_bss_info_change_notify(
- sdata, BSS_CHANGED_BEACON_ENABLED);
-
-- if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
-+ /*
-+ * only handle non-STA interfaces here, STA interfaces
-+ * are handled in ieee80211_offchannel_stop_station(),
-+ * e.g., from the background scan state machine.
-+ *
-+ * In addition, do not stop monitor interface to allow it to be
-+ * used from user space controlled off-channel operations.
-+ */
-+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
-+ sdata->vif.type != NL80211_IFTYPE_MONITOR) {
-+ set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
- netif_tx_stop_all_queues(sdata->dev);
-- if (offchannel_ps_enable &&
-- (sdata->vif.type == NL80211_IFTYPE_STATION) &&
-- sdata->u.mgd.associated)
-- ieee80211_offchannel_ps_enable(sdata, true);
- }
- }
- mutex_unlock(&local->iflist_mtx);
- }
-
--void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
-- bool tell_ap)
-+void ieee80211_offchannel_stop_station(struct ieee80211_local *local)
- {
- struct ieee80211_sub_if_data *sdata;
-
-+ /*
-+ * notify the AP about us leaving the channel and stop all STA interfaces
-+ */
- mutex_lock(&local->iflist_mtx);
- list_for_each_entry(sdata, &local->interfaces, list) {
- if (!ieee80211_sdata_running(sdata))
- continue;
-
-- if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-- sdata->u.mgd.associated)
-- ieee80211_offchannel_ps_enable(sdata, tell_ap);
-+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-+ set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
-+ netif_tx_stop_all_queues(sdata->dev);
-+ if (sdata->u.mgd.associated)
-+ ieee80211_offchannel_ps_enable(sdata);
-+ }
- }
- mutex_unlock(&local->iflist_mtx);
- }
-
- void ieee80211_offchannel_return(struct ieee80211_local *local,
-- bool enable_beaconing,
-- bool offchannel_ps_disable)
-+ bool enable_beaconing)
- {
- struct ieee80211_sub_if_data *sdata;
-
-@@ -167,8 +162,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
- continue;
-
- /* Tell AP we're back */
-- if (offchannel_ps_disable &&
-- sdata->vif.type == NL80211_IFTYPE_STATION) {
-+ if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- if (sdata->u.mgd.associated)
- ieee80211_offchannel_ps_disable(sdata);
- }
-@@ -188,7 +182,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
- netif_tx_wake_all_queues(sdata->dev);
- }
-
-- /* Check to see if we should re-enable beaconing */
-+ /* re-enable beaconing */
- if (enable_beaconing &&
- (sdata->vif.type == NL80211_IFTYPE_AP ||
- sdata->vif.type == NL80211_IFTYPE_ADHOC ||
-diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
-index fb123e2..5c51607 100644
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -421,10 +421,16 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
- return RX_CONTINUE;
-
- if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
-- test_bit(SCAN_SW_SCANNING, &local->scanning) ||
- local->sched_scanning)
- return ieee80211_scan_rx(rx->sdata, skb);
-
-+ if (test_bit(SCAN_SW_SCANNING, &local->scanning)) {
-+ /* drop all the other packets during a software scan anyway */
-+ if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
-+ dev_kfree_skb(skb);
-+ return RX_QUEUED;
-+ }
-+
- /* scanning finished during invoking of handlers */
- I802_DEBUG_INC(local->rx_handlers_drop_passive_scan);
- return RX_DROP_UNUSABLE;
-@@ -2858,7 +2864,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
- local->dot11ReceivedFragmentCount++;
-
- if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
-- test_bit(SCAN_SW_SCANNING, &local->scanning)))
-+ test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
- status->rx_flags |= IEEE80211_RX_IN_SCAN;
-
- if (ieee80211_is_mgmt(fc))
-diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
-index 105436d..5279300 100644
---- a/net/mac80211/scan.c
-+++ b/net/mac80211/scan.c
-@@ -213,14 +213,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
- if (bss)
- ieee80211_rx_bss_put(sdata->local, bss);
-
-- /* If we are on-operating-channel, and this packet is for the
-- * current channel, pass the pkt on up the stack so that
-- * the rest of the stack can make use of it.
-- */
-- if (ieee80211_cfg_on_oper_channel(sdata->local)
-- && (channel == sdata->local->oper_channel))
-- return RX_CONTINUE;
--
- dev_kfree_skb(skb);
- return RX_QUEUED;
- }
-@@ -264,8 +256,6 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
- bool was_hw_scan)
- {
- struct ieee80211_local *local = hw_to_local(hw);
-- bool on_oper_chan;
-- bool enable_beacons = false;
-
- lockdep_assert_held(&local->mtx);
-
-@@ -298,25 +288,11 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted,
- local->scanning = 0;
- local->scan_channel = NULL;
-
-- on_oper_chan = ieee80211_cfg_on_oper_channel(local);
--
-- if (was_hw_scan || !on_oper_chan)
-- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-- else
-- /* Set power back to normal operating levels. */
-- ieee80211_hw_config(local, 0);
--
-+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
- if (!was_hw_scan) {
-- bool on_oper_chan2;
- ieee80211_configure_filter(local);
- drv_sw_scan_complete(local);
-- on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
-- /* We should always be on-channel at this point. */
-- WARN_ON(!on_oper_chan2);
-- if (on_oper_chan2 && (on_oper_chan != on_oper_chan2))
-- enable_beacons = true;
--
-- ieee80211_offchannel_return(local, enable_beacons, true);
-+ ieee80211_offchannel_return(local, true);
- }
-
- ieee80211_recalc_idle(local);
-@@ -357,15 +333,13 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
- */
- drv_sw_scan_start(local);
-
-+ ieee80211_offchannel_stop_beaconing(local);
-+
- local->leave_oper_channel_time = 0;
- local->next_scan_state = SCAN_DECISION;
- local->scan_channel_idx = 0;
-
-- /* We always want to use off-channel PS, even if we
-- * are not really leaving oper-channel. Don't
-- * tell the AP though, as long as we are on-channel.
-- */
-- ieee80211_offchannel_enable_all_ps(local, false);
-+ drv_flush(local, false);
-
- ieee80211_configure_filter(local);
-
-@@ -508,20 +482,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
- }
- mutex_unlock(&local->iflist_mtx);
-
-- next_chan = local->scan_req->channels[local->scan_channel_idx];
--
-- if (ieee80211_cfg_on_oper_channel(local)) {
-- /* We're currently on operating channel. */
-- if (next_chan == local->oper_channel)
-- /* We don't need to move off of operating channel. */
-- local->next_scan_state = SCAN_SET_CHANNEL;
-- else
-- /*
-- * We do need to leave operating channel, as next
-- * scan is somewhere else.
-- */
-- local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
-- } else {
-+ if (local->scan_channel) {
- /*
- * we're currently scanning a different channel, let's
- * see if we can scan another channel without interfering
-@@ -537,6 +498,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
- *
- * Otherwise switch back to the operating channel.
- */
-+ next_chan = local->scan_req->channels[local->scan_channel_idx];
-
- bad_latency = time_after(jiffies +
- ieee80211_scan_get_channel_time(next_chan),
-@@ -554,6 +516,12 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
- local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
- else
- local->next_scan_state = SCAN_SET_CHANNEL;
-+ } else {
-+ /*
-+ * we're on the operating channel currently, let's
-+ * leave that channel now to scan another one
-+ */
-+ local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
- }
-
- *next_delay = 0;
-@@ -562,10 +530,9 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local,
- static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
- unsigned long *next_delay)
- {
-- /* PS will already be in off-channel mode,
-- * we do that once at the beginning of scanning.
-- */
-- ieee80211_offchannel_stop_vifs(local, false);
-+ ieee80211_offchannel_stop_station(local);
-+
-+ __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
-
- /*
- * What if the nullfunc frames didn't arrive?
-@@ -588,15 +555,15 @@ static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *loca
- {
- /* switch back to the operating channel */
- local->scan_channel = NULL;
-- if (!ieee80211_cfg_on_oper_channel(local))
-- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
-
- /*
-- * Re-enable vifs and beaconing. Leave PS
-- * in off-channel state..will put that back
-- * on-channel at the end of scanning.
-+ * Only re-enable station mode interface now; beaconing will be
-+ * re-enabled once the full scan has been completed.
- */
-- ieee80211_offchannel_return(local, true, false);
-+ ieee80211_offchannel_return(local, false);
-+
-+ __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
-
- *next_delay = HZ / 5;
- local->next_scan_state = SCAN_DECISION;
-diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
-index 1f8b120..eff1f4e 100644
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -259,8 +259,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
- if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
- return TX_CONTINUE;
-
-- if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
-- test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
-+ if (unlikely(test_bit(SCAN_OFF_CHANNEL, &tx->local->scanning)) &&
- !ieee80211_is_probe_req(hdr->frame_control) &&
- !ieee80211_is_nullfunc(hdr->frame_control))
- /*
-diff --git a/net/mac80211/work.c b/net/mac80211/work.c
-index 6c53b6d..99165ef 100644
---- a/net/mac80211/work.c
-+++ b/net/mac80211/work.c
-@@ -899,26 +899,6 @@ static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct,
- return false;
- }
-
--static enum nl80211_channel_type
--ieee80211_calc_ct(enum nl80211_channel_type wk_ct,
-- enum nl80211_channel_type oper_ct)
--{
-- switch (wk_ct) {
-- case NL80211_CHAN_NO_HT:
-- return oper_ct;
-- case NL80211_CHAN_HT20:
-- if (oper_ct != NL80211_CHAN_NO_HT)
-- return oper_ct;
-- return wk_ct;
-- case NL80211_CHAN_HT40MINUS:
-- case NL80211_CHAN_HT40PLUS:
-- return wk_ct;
-- }
-- WARN_ON(1); /* shouldn't get here */
-- return wk_ct;
--}
--
--
- static void ieee80211_work_timer(unsigned long data)
- {
- struct ieee80211_local *local = (void *) data;
-@@ -969,52 +949,18 @@ static void ieee80211_work_work(struct work_struct *work)
- }
-
- if (!started && !local->tmp_channel) {
-- bool on_oper_chan;
-- bool tmp_chan_changed = false;
-- bool on_oper_chan2;
-- enum nl80211_channel_type wk_ct;
-- on_oper_chan = ieee80211_cfg_on_oper_channel(local);
--
-- /* Work with existing channel type if possible. */
-- wk_ct = wk->chan_type;
-- if (wk->chan == local->hw.conf.channel)
-- wk_ct = ieee80211_calc_ct(wk->chan_type,
-- local->hw.conf.channel_type);
--
-- if (local->tmp_channel)
-- if ((local->tmp_channel != wk->chan) ||
-- (local->tmp_channel_type != wk_ct))
-- tmp_chan_changed = true;
--
-- local->tmp_channel = wk->chan;
-- local->tmp_channel_type = wk_ct;
- /*
-- * Leave the station vifs in awake mode if they
-- * happen to be on the same channel as
-- * the requested channel.
-+ * TODO: could optimize this by leaving the
-+ * station vifs in awake mode if they
-+ * happen to be on the same channel as
-+ * the requested channel
- */
-- on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
-- if (on_oper_chan != on_oper_chan2) {
-- if (on_oper_chan2) {
-- /* going off oper channel, PS too */
-- ieee80211_offchannel_stop_vifs(local,
-- true);
-- ieee80211_hw_config(local, 0);
-- } else {
-- /* going on channel, but leave PS
-- * off-channel. */
-- ieee80211_hw_config(local, 0);
-- ieee80211_offchannel_return(local,
-- true,
-- false);
-- }
-- } else if (tmp_chan_changed)
-- /* Still off-channel, but on some other
-- * channel, so update hardware.
-- * PS should already be off-channel.
-- */
-- ieee80211_hw_config(local, 0);
-+ ieee80211_offchannel_stop_beaconing(local);
-+ ieee80211_offchannel_stop_station(local);
-
-+ local->tmp_channel = wk->chan;
-+ local->tmp_channel_type = wk->chan_type;
-+ ieee80211_hw_config(local, 0);
- started = true;
- wk->timeout = jiffies;
- }
-@@ -1100,8 +1046,7 @@ static void ieee80211_work_work(struct work_struct *work)
- * we still need to do a hardware config. Currently,
- * we cannot be here while scanning, however.
- */
-- if (!ieee80211_cfg_on_oper_channel(local))
-- ieee80211_hw_config(local, 0);
-+ ieee80211_hw_config(local, 0);
-
- /* At the least, we need to disable offchannel_ps,
- * so just go ahead and run the entire offchannel
-@@ -1109,7 +1054,7 @@ static void ieee80211_work_work(struct work_struct *work)
- * beaconing if we were already on-oper-channel
- * as a future optimization.
- */
-- ieee80211_offchannel_return(local, true, true);
-+ ieee80211_offchannel_return(local, true);
-
- /* give connection some time to breathe */
- run_again(local, jiffies + HZ/2);
-diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
-index f614ce7..28a39bb 100644
---- a/net/mac80211/wpa.c
-+++ b/net/mac80211/wpa.c
-@@ -106,7 +106,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
- if (status->flag & RX_FLAG_MMIC_ERROR)
- goto mic_fail;
-
-- if (!(status->flag & RX_FLAG_IV_STRIPPED))
-+ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key)
- goto update_iv;
-
- return RX_CONTINUE;
-diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
-index 6e03888..d4ad50e 100644
---- a/net/sunrpc/svc.c
-+++ b/net/sunrpc/svc.c
-@@ -167,6 +167,7 @@ svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
-
- fail_free:
- kfree(m->to_pool);
-+ m->to_pool = NULL;
- fail:
- return -ENOMEM;
- }
-@@ -287,7 +288,9 @@ svc_pool_map_put(void)
- if (!--m->count) {
- m->mode = SVC_POOL_DEFAULT;
- kfree(m->to_pool);
-+ m->to_pool = NULL;
- kfree(m->pool_to);
-+ m->pool_to = NULL;
- m->npools = 0;
- }
-
-@@ -527,17 +530,20 @@ svc_destroy(struct svc_serv *serv)
- printk("svc_destroy: no threads for serv=%p!\n", serv);
-
- del_timer_sync(&serv->sv_temptimer);
--
-- svc_close_all(&serv->sv_tempsocks);
-+ /*
-+ * The set of xprts (contained in the sv_tempsocks and
-+ * sv_permsocks lists) is now constant, since it is modified
-+ * only by accepting new sockets (done by service threads in
-+ * svc_recv) or aging old ones (done by sv_temptimer), or
-+ * configuration changes (excluded by whatever locking the
-+ * caller is using--nfsd_mutex in the case of nfsd). So it's
-+ * safe to traverse those lists and shut everything down:
-+ */
-+ svc_close_all(serv);
-
- if (serv->sv_shutdown)
- serv->sv_shutdown(serv);
-
-- svc_close_all(&serv->sv_permsocks);
--
-- BUG_ON(!list_empty(&serv->sv_permsocks));
-- BUG_ON(!list_empty(&serv->sv_tempsocks));
--
- cache_clean_deferred(serv);
-
- if (svc_serv_is_pooled(serv))
-diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
-index 447cd0e..9ed2cd0 100644
---- a/net/sunrpc/svc_xprt.c
-+++ b/net/sunrpc/svc_xprt.c
-@@ -893,14 +893,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
- spin_lock_bh(&serv->sv_lock);
- if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
- list_del_init(&xprt->xpt_list);
-- /*
-- * 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);
-+ BUG_ON(!list_empty(&xprt->xpt_ready));
- if (test_bit(XPT_TEMP, &xprt->xpt_flags))
- serv->sv_tmpcnt--;
- spin_unlock_bh(&serv->sv_lock);
-@@ -928,22 +921,48 @@ void svc_close_xprt(struct svc_xprt *xprt)
- }
- EXPORT_SYMBOL_GPL(svc_close_xprt);
-
--void svc_close_all(struct list_head *xprt_list)
-+static void svc_close_list(struct list_head *xprt_list)
-+{
-+ struct svc_xprt *xprt;
-+
-+ list_for_each_entry(xprt, xprt_list, xpt_list) {
-+ set_bit(XPT_CLOSE, &xprt->xpt_flags);
-+ set_bit(XPT_BUSY, &xprt->xpt_flags);
-+ }
-+}
-+
-+void svc_close_all(struct svc_serv *serv)
- {
-+ struct svc_pool *pool;
- struct svc_xprt *xprt;
- struct svc_xprt *tmp;
-+ int i;
-+
-+ svc_close_list(&serv->sv_tempsocks);
-+ svc_close_list(&serv->sv_permsocks);
-
-+ for (i = 0; i < serv->sv_nrpools; i++) {
-+ pool = &serv->sv_pools[i];
-+
-+ spin_lock_bh(&pool->sp_lock);
-+ while (!list_empty(&pool->sp_sockets)) {
-+ xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready);
-+ list_del_init(&xprt->xpt_ready);
-+ }
-+ spin_unlock_bh(&pool->sp_lock);
-+ }
- /*
-- * The server is shutting down, and no more threads are running.
-- * svc_xprt_enqueue() might still be running, but at worst it
-- * will re-add the xprt to sp_sockets, which will soon get
-- * freed. So we don't bother with any more locking, and don't
-- * leave the close to the (nonexistent) server threads:
-+ * At this point the sp_sockets lists will stay empty, since
-+ * svc_enqueue will not add new entries without taking the
-+ * sp_lock and checking XPT_BUSY.
- */
-- list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
-- set_bit(XPT_CLOSE, &xprt->xpt_flags);
-+ list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list)
- svc_delete_xprt(xprt);
-- }
-+ list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list)
-+ svc_delete_xprt(xprt);
-+
-+ BUG_ON(!list_empty(&serv->sv_permsocks));
-+ BUG_ON(!list_empty(&serv->sv_tempsocks));
- }
-
- /*
-diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
-index 277ebd4..593f4c6 100644
---- a/net/sunrpc/xdr.c
-+++ b/net/sunrpc/xdr.c
-@@ -296,7 +296,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
- * Copies data into an arbitrary memory location from an array of pages
- * The copy is assumed to be non-overlapping.
- */
--static void
-+void
- _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
- {
- struct page **pgfrom;
-@@ -324,6 +324,7 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
-
- } while ((len -= copy) != 0);
- }
-+EXPORT_SYMBOL_GPL(_copy_from_pages);
-
- /*
- * xdr_shrink_bufhead
-diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
-index ec7afce..bccf07d 100644
---- a/scripts/kconfig/streamline_config.pl
-+++ b/scripts/kconfig/streamline_config.pl
-@@ -250,33 +250,61 @@ if ($kconfig) {
- read_kconfig($kconfig);
- }
-
-+sub convert_vars {
-+ my ($line, %vars) = @_;
-+
-+ my $process = "";
-+
-+ while ($line =~ s/^(.*?)(\$\((.*?)\))//) {
-+ my $start = $1;
-+ my $variable = $2;
-+ my $var = $3;
-+
-+ if (defined($vars{$var})) {
-+ $process .= $start . $vars{$var};
-+ } else {
-+ $process .= $start . $variable;
-+ }
-+ }
-+
-+ $process .= $line;
-+
-+ return $process;
-+}
-+
- # Read all Makefiles to map the configs to the objects
- foreach my $makefile (@makefiles) {
-
-- my $cont = 0;
-+ my $line = "";
-+ my %make_vars;
-
- open(MIN,$makefile) || die "Can't open $makefile";
- while (<MIN>) {
-+ # if this line ends with a backslash, continue
-+ chomp;
-+ if (/^(.*)\\$/) {
-+ $line .= $1;
-+ next;
-+ }
-+
-+ $line .= $_;
-+ $_ = $line;
-+ $line = "";
-+
- my $objs;
-
-- # is this a line after a line with a backslash?
-- if ($cont && /(\S.*)$/) {
-- $objs = $1;
-- }
-- $cont = 0;
-+ $_ = convert_vars($_, %make_vars);
-
- # collect objects after obj-$(CONFIG_FOO_BAR)
- if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) {
- $var = $1;
- $objs = $2;
-+
-+ # check if variables are set
-+ } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) {
-+ $make_vars{$1} = $2;
- }
- if (defined($objs)) {
-- # test if the line ends with a backslash
-- if ($objs =~ m,(.*)\\$,) {
-- $objs = $1;
-- $cont = 1;
-- }
--
- foreach my $obj (split /\s+/,$objs) {
- $obj =~ s/-/_/g;
- if ($obj =~ /(.*)\.o$/) {
-diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h
-index f40a6af6..54e35c1 100644
---- a/scripts/recordmcount.h
-+++ b/scripts/recordmcount.h
-@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
- succeed_file();
- }
- if (w(txthdr->sh_type) != SHT_PROGBITS ||
-- !(w(txthdr->sh_flags) & SHF_EXECINSTR))
-+ !(_w(txthdr->sh_flags) & SHF_EXECINSTR))
- return NULL;
- return txtname;
- }
-diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
-index 0d50df0..88a2788 100644
---- a/security/integrity/ima/ima_api.c
-+++ b/security/integrity/ima/ima_api.c
-@@ -178,8 +178,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
- strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
-
- result = ima_store_template(entry, violation, inode);
-- if (!result)
-+ if (!result || result == -EEXIST)
- iint->flags |= IMA_MEASURED;
-- else
-+ if (result < 0)
- kfree(entry);
- }
-diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
-index 8e28f04..55a6271 100644
---- a/security/integrity/ima/ima_queue.c
-+++ b/security/integrity/ima/ima_queue.c
-@@ -23,6 +23,8 @@
- #include <linux/slab.h>
- #include "ima.h"
-
-+#define AUDIT_CAUSE_LEN_MAX 32
-+
- LIST_HEAD(ima_measurements); /* list of all measurements */
-
- /* key: inode (before secure-hashing a file) */
-@@ -94,7 +96,8 @@ static int ima_pcr_extend(const u8 *hash)
-
- result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
- if (result != 0)
-- pr_err("IMA: Error Communicating to TPM chip\n");
-+ pr_err("IMA: Error Communicating to TPM chip, result: %d\n",
-+ result);
- return result;
- }
-
-@@ -106,14 +109,16 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
- {
- u8 digest[IMA_DIGEST_SIZE];
- const char *audit_cause = "hash_added";
-+ char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
- int audit_info = 1;
-- int result = 0;
-+ int result = 0, tpmresult = 0;
-
- mutex_lock(&ima_extend_list_mutex);
- if (!violation) {
- memcpy(digest, entry->digest, sizeof digest);
- if (ima_lookup_digest_entry(digest)) {
- audit_cause = "hash_exists";
-+ result = -EEXIST;
- goto out;
- }
- }
-@@ -128,9 +133,11 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
- if (violation) /* invalidate pcr */
- memset(digest, 0xff, sizeof digest);
-
-- result = ima_pcr_extend(digest);
-- if (result != 0) {
-- audit_cause = "TPM error";
-+ tpmresult = ima_pcr_extend(digest);
-+ if (tpmresult != 0) {
-+ snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
-+ tpmresult);
-+ audit_cause = tpm_audit_cause;
- audit_info = 0;
- }
- out:
-diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
-index 4a9b4b2..867558c 100644
---- a/security/tomoyo/util.c
-+++ b/security/tomoyo/util.c
-@@ -492,13 +492,13 @@ static bool tomoyo_correct_word2(const char *string, size_t len)
- if (d < '0' || d > '7' || e < '0' || e > '7')
- break;
- c = tomoyo_make_byte(c, d, e);
-- if (tomoyo_invalid(c))
-- continue; /* pattern is not \000 */
-+ if (c <= ' ' || c >= 127)
-+ continue;
- }
- goto out;
- } else if (in_repetition && c == '/') {
- goto out;
-- } else if (tomoyo_invalid(c)) {
-+ } else if (c <= ' ' || c >= 127) {
- goto out;
- }
- }
-diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
-index c2f79e6..5b2b75b 100644
---- a/sound/pci/hda/hda_intel.c
-+++ b/sound/pci/hda/hda_intel.c
-@@ -2509,6 +2509,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
- SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS 1101HA", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
-+ SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
- SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
-diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
-index 618ddad..368f0c5 100644
---- a/sound/pci/hda/hda_local.h
-+++ b/sound/pci/hda/hda_local.h
-@@ -487,7 +487,12 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
- }
-
- /* get the widget type from widget capability bits */
--#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
-+static inline int get_wcaps_type(unsigned int wcaps)
-+{
-+ if (!wcaps)
-+ return -1; /* invalid type */
-+ return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
-+}
-
- static inline unsigned int get_wcaps_channels(u32 wcaps)
- {
-diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
-index 2c981b5..254ab52 100644
---- a/sound/pci/hda/hda_proc.c
-+++ b/sound/pci/hda/hda_proc.c
-@@ -54,6 +54,8 @@ static const char *get_wid_type_name(unsigned int wid_value)
- [AC_WID_BEEP] = "Beep Generator Widget",
- [AC_WID_VENDOR] = "Vendor Defined Widget",
- };
-+ if (wid_value == -1)
-+ return "UNKNOWN Widget";
- wid_value &= 0xf;
- if (names[wid_value])
- return names[wid_value];
-diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
-index 70a7abd..5b0a9bb 100644
---- a/sound/pci/hda/patch_cirrus.c
-+++ b/sound/pci/hda/patch_cirrus.c
-@@ -920,16 +920,14 @@ static void cs_automute(struct hda_codec *codec)
-
- /* mute speakers if spdif or hp jack is plugged in */
- for (i = 0; i < cfg->speaker_outs; i++) {
-+ int pin_ctl = hp_present ? 0 : PIN_OUT;
-+ /* detect on spdif is specific to CS421x */
-+ if (spdif_present && (spec->vendor_nid == CS421X_VENDOR_NID))
-+ pin_ctl = 0;
-+
- nid = cfg->speaker_pins[i];
- snd_hda_codec_write(codec, nid, 0,
-- AC_VERB_SET_PIN_WIDGET_CONTROL,
-- hp_present ? 0 : PIN_OUT);
-- /* detect on spdif is specific to CS421x */
-- if (spec->vendor_nid == CS421X_VENDOR_NID) {
-- snd_hda_codec_write(codec, nid, 0,
-- AC_VERB_SET_PIN_WIDGET_CONTROL,
-- spdif_present ? 0 : PIN_OUT);
-- }
-+ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
- }
- if (spec->gpio_eapd_hp) {
- unsigned int gpio = hp_present ?
-@@ -1771,30 +1769,19 @@ static int build_cs421x_output(struct hda_codec *codec)
- struct auto_pin_cfg *cfg = &spec->autocfg;
- struct snd_kcontrol *kctl;
- int err;
-- char *name = "HP/Speakers";
-+ char *name = "Master";
-
- fix_volume_caps(codec, dac);
-- if (!spec->vmaster_sw) {
-- err = add_vmaster(codec, dac);
-- if (err < 0)
-- return err;
-- }
-
- err = add_mute(codec, name, 0,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
- if (err < 0)
- return err;
-- err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
-- if (err < 0)
-- return err;
-
- err = add_volume(codec, name, 0,
- HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
- if (err < 0)
- return err;
-- err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
-- if (err < 0)
-- return err;
-
- if (cfg->speaker_outs) {
- err = snd_hda_ctl_add(codec, 0,
-diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
-index 0de2119..7072251 100644
---- a/sound/pci/hda/patch_conexant.c
-+++ b/sound/pci/hda/patch_conexant.c
-@@ -1120,8 +1120,6 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
-
- static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
- SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
-- SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
-- CXT5045_LAPTOP_HPSENSE),
- SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
- SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
- SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
-diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
-index 616678f..f3c73a9 100644
---- a/sound/pci/hda/patch_sigmatel.c
-+++ b/sound/pci/hda/patch_sigmatel.c
-@@ -1631,7 +1631,7 @@ static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
- "Dell Studio 1557", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe,
-- "Dell Studio XPS 1645", STAC_DELL_M6_BOTH),
-+ "Dell Studio XPS 1645", STAC_DELL_M6_DMIC),
- SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413,
- "Dell Studio 1558", STAC_DELL_M6_DMIC),
- {} /* terminator */
-@@ -4326,6 +4326,27 @@ static void stac_store_hints(struct hda_codec *codec)
- }
- }
-
-+static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
-+ const hda_nid_t *pins)
-+{
-+ while (num_pins--)
-+ stac_issue_unsol_event(codec, *pins++);
-+}
-+
-+/* fake event to set up pins */
-+static void stac_fake_hp_events(struct hda_codec *codec)
-+{
-+ struct sigmatel_spec *spec = codec->spec;
-+
-+ if (spec->autocfg.hp_outs)
-+ stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
-+ spec->autocfg.hp_pins);
-+ if (spec->autocfg.line_outs &&
-+ spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
-+ stac_issue_unsol_events(codec, spec->autocfg.line_outs,
-+ spec->autocfg.line_out_pins);
-+}
-+
- static int stac92xx_init(struct hda_codec *codec)
- {
- struct sigmatel_spec *spec = codec->spec;
-@@ -4376,10 +4397,7 @@ static int stac92xx_init(struct hda_codec *codec)
- stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
- AC_PINCTL_OUT_EN);
- /* fake event to set up pins */
-- if (cfg->hp_pins[0])
-- stac_issue_unsol_event(codec, cfg->hp_pins[0]);
-- else if (cfg->line_out_pins[0])
-- stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
-+ stac_fake_hp_events(codec);
- } else {
- stac92xx_auto_init_multi_out(codec);
- stac92xx_auto_init_hp_out(codec);
-@@ -5028,19 +5046,11 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
- #ifdef CONFIG_PM
- static int stac92xx_resume(struct hda_codec *codec)
- {
-- struct sigmatel_spec *spec = codec->spec;
--
- stac92xx_init(codec);
- snd_hda_codec_resume_amp(codec);
- snd_hda_codec_resume_cache(codec);
- /* fake event to set up pins again to override cached values */
-- if (spec->hp_detect) {
-- if (spec->autocfg.hp_pins[0])
-- stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
-- else if (spec->autocfg.line_out_pins[0])
-- stac_issue_unsol_event(codec,
-- spec->autocfg.line_out_pins[0]);
-- }
-+ stac_fake_hp_events(codec);
- return 0;
- }
-
-diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
-index b513762..8d69e59 100644
---- a/sound/pci/hda/patch_via.c
-+++ b/sound/pci/hda/patch_via.c
-@@ -2200,7 +2200,10 @@ static int via_auto_create_loopback_switch(struct hda_codec *codec)
- {
- struct via_spec *spec = codec->spec;
-
-- if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
-+ if (!spec->aa_mix_nid)
-+ return 0; /* no loopback switching available */
-+ if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth ||
-+ spec->speaker_path.depth))
- return 0; /* no loopback switching available */
- if (!via_clone_control(spec, &via_aamix_ctl_enum))
- return -ENOMEM;
-diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
-index e328cfb..e525da2 100644
---- a/sound/pci/ice1712/amp.c
-+++ b/sound/pci/ice1712/amp.c
-@@ -68,8 +68,11 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
-
- static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
- {
-- /* we use pins 39 and 41 of the VT1616 for left and right read outputs */
-- snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
-+ if (ice->ac97)
-+ /* we use pins 39 and 41 of the VT1616 for left and right
-+ read outputs */
-+ snd_ac97_write_cache(ice->ac97, 0x5a,
-+ snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
- return 0;
- }
-
-diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
-index 42d1ab1..915546a 100644
---- a/sound/pci/oxygen/xonar_wm87x6.c
-+++ b/sound/pci/oxygen/xonar_wm87x6.c
-@@ -177,6 +177,7 @@ static void wm8776_registers_init(struct oxygen *chip)
- struct xonar_wm87x6 *data = chip->model_data;
-
- wm8776_write(chip, WM8776_RESET, 0);
-+ wm8776_write(chip, WM8776_PHASESWAP, WM8776_PH_MASK);
- wm8776_write(chip, WM8776_DACCTRL1, WM8776_DZCEN |
- WM8776_PL_LEFT_LEFT | WM8776_PL_RIGHT_RIGHT);
- wm8776_write(chip, WM8776_DACMUTE, chip->dac_mute ? WM8776_DMUTE : 0);
-diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
-index 81c6ede..08dcce5 100644
---- a/sound/usb/endpoint.c
-+++ b/sound/usb/endpoint.c
-@@ -17,6 +17,7 @@
-
- #include <linux/gfp.h>
- #include <linux/init.h>
-+#include <linux/ratelimit.h>
- #include <linux/usb.h>
- #include <linux/usb/audio.h>
-
-@@ -458,8 +459,8 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
-
- for (i = 0; i < urb->number_of_packets; i++) {
- cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-- if (urb->iso_frame_desc[i].status) {
-- snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
-+ if (urb->iso_frame_desc[i].status && printk_ratelimit()) {
-+ snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
- // continue;
- }
- bytes = urb->iso_frame_desc[i].actual_length;
-diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
-index c400ade..1e7a47a 100644
---- a/sound/usb/usx2y/usb_stream.c
-+++ b/sound/usb/usx2y/usb_stream.c
-@@ -674,7 +674,7 @@ dotry:
- inurb->transfer_buffer_length =
- inurb->number_of_packets *
- inurb->iso_frame_desc[0].length;
-- preempt_disable();
-+
- if (u == 0) {
- int now;
- struct usb_device *dev = inurb->dev;
-@@ -686,19 +686,17 @@ dotry:
- }
- err = usb_submit_urb(inurb, GFP_ATOMIC);
- if (err < 0) {
-- preempt_enable();
- snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
- " returned %i\n", u, err);
- return err;
- }
- err = usb_submit_urb(outurb, GFP_ATOMIC);
- if (err < 0) {
-- preempt_enable();
- snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
- " returned %i\n", u, err);
- return err;
- }
-- preempt_enable();
-+
- if (inurb->start_frame != outurb->start_frame) {
- snd_printd(KERN_DEBUG
- "u[%i] start_frames differ in:%u out:%u\n",
diff --git a/3.2.2/0000_README b/3.2.4/0000_README
index a38ba28..97fce67 100644
--- a/3.2.2/0000_README
+++ b/3.2.4/0000_README
@@ -2,11 +2,15 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1001_linux-3.2.2.patch
+Patch: 1002_linux-3.2.3.patch
From: http://www.kernel.org
-Desc: Linux 3.2.2
+Desc: Linux 3.2.3
-Patch: 4420_grsecurity-2.2.2-3.2.2-201201272014.patch
+Patch: 1003_linux-3.2.4.patch
+From: http://www.kernel.org
+Desc: Linux 3.2.4
+
+Patch: 4420_grsecurity-2.2.2-3.2.4-201202032052.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.2.4/1002_linux-3.2.3.patch b/3.2.4/1002_linux-3.2.3.patch
new file mode 100644
index 0000000..98925b0
--- /dev/null
+++ b/3.2.4/1002_linux-3.2.3.patch
@@ -0,0 +1,3760 @@
+diff --git a/Makefile b/Makefile
+index 2f684da..d45e887 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 2
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+
+diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
+index aa64294..f5bbe0ef 100644
+--- a/arch/arm/mach-at91/setup.c
++++ b/arch/arm/mach-at91/setup.c
+@@ -27,9 +27,12 @@ EXPORT_SYMBOL(at91_soc_initdata);
+ void __init at91rm9200_set_type(int type)
+ {
+ if (type == ARCH_REVISON_9200_PQFP)
+- at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
+- else
+ at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
++ else
++ at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
++
++ pr_info("AT91: filled in soc subtype: %s\n",
++ at91_get_soc_subtype(&at91_soc_initdata));
+ }
+
+ void __init at91_init_irq_default(void)
+diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
+index a3e0c86..52af004 100644
+--- a/arch/arm/mach-ux500/Kconfig
++++ b/arch/arm/mach-ux500/Kconfig
+@@ -7,6 +7,7 @@ config UX500_SOC_COMMON
+ select HAS_MTU
+ select ARM_ERRATA_753970
+ select ARM_ERRATA_754322
++ select ARM_ERRATA_764369
+
+ menu "Ux500 SoC"
+
+diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
+index 6826fae..306cff0 100644
+--- a/arch/arm/mach-ux500/board-mop500-sdi.c
++++ b/arch/arm/mach-ux500/board-mop500-sdi.c
+@@ -233,6 +233,8 @@ void __init snowball_sdi_init(void)
+ {
+ u32 periphid = 0x10480180;
+
++ /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported on sdi0 */
++ mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED;
+ mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
+
+ /* On-board eMMC */
+diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
+index e70a737..40cc7aa 100644
+--- a/arch/arm/mm/proc-v7.S
++++ b/arch/arm/mm/proc-v7.S
+@@ -271,10 +271,6 @@ ENDPROC(cpu_v7_do_resume)
+ * Initialise TLB, Caches, and MMU state ready to switch the MMU
+ * on. Return in r0 the new CP15 C1 control register setting.
+ *
+- * We automatically detect if we have a Harvard cache, and use the
+- * Harvard cache control instructions insead of the unified cache
+- * control instructions.
+- *
+ * This should be able to cover all ARMv7 cores.
+ *
+ * It is assumed that:
+@@ -373,9 +369,7 @@ __v7_setup:
+ #endif
+
+ 3: mov r10, #0
+-#ifdef HARVARD_CACHE
+ mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
+-#endif
+ dsb
+ #ifdef CONFIG_MMU
+ mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
+diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
+index 4203d10..c4ac15c 100644
+--- a/arch/m68k/atari/config.c
++++ b/arch/m68k/atari/config.c
+@@ -414,9 +414,9 @@ void __init config_atari(void)
+ * FDC val = 4 -> Supervisor only */
+ asm volatile ("\n"
+ " .chip 68030\n"
+- " pmove %0@,%/tt1\n"
++ " pmove %0,%/tt1\n"
+ " .chip 68k"
+- : : "a" (&tt1_val));
++ : : "m" (tt1_val));
+ } else {
+ asm volatile ("\n"
+ " .chip 68040\n"
+@@ -569,10 +569,10 @@ static void atari_reset(void)
+ : "d0");
+ } else
+ asm volatile ("\n"
+- " pmove %0@,%%tc\n"
++ " pmove %0,%%tc\n"
+ " jmp %1@"
+ : /* no outputs */
+- : "a" (&tc_val), "a" (reset_addr));
++ : "m" (tc_val), "a" (reset_addr));
+ }
+
+
+diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c
+index 1bc223a..aa4ffb8 100644
+--- a/arch/m68k/kernel/process_mm.c
++++ b/arch/m68k/kernel/process_mm.c
+@@ -189,8 +189,8 @@ void flush_thread(void)
+ current->thread.fs = __USER_DS;
+ if (!FPU_IS_EMU)
+ asm volatile (".chip 68k/68881\n\t"
+- "frestore %0@\n\t"
+- ".chip 68k" : : "a" (&zero));
++ "frestore %0\n\t"
++ ".chip 68k" : : "m" (zero));
+ }
+
+ /*
+diff --git a/arch/m68k/kernel/process_no.c b/arch/m68k/kernel/process_no.c
+index 69c1803..5e1078c 100644
+--- a/arch/m68k/kernel/process_no.c
++++ b/arch/m68k/kernel/process_no.c
+@@ -163,8 +163,8 @@ void flush_thread(void)
+ #ifdef CONFIG_FPU
+ if (!FPU_IS_EMU)
+ asm volatile (".chip 68k/68881\n\t"
+- "frestore %0@\n\t"
+- ".chip 68k" : : "a" (&zero));
++ "frestore %0\n\t"
++ ".chip 68k" : : "m" (zero));
+ #endif
+ }
+
+diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
+index 89362f2..eb67469 100644
+--- a/arch/m68k/kernel/traps.c
++++ b/arch/m68k/kernel/traps.c
+@@ -552,13 +552,13 @@ static inline void bus_error030 (struct frame *fp)
+
+ #ifdef DEBUG
+ asm volatile ("ptestr %3,%2@,#7,%0\n\t"
+- "pmove %%psr,%1@"
+- : "=a&" (desc)
+- : "a" (&temp), "a" (addr), "d" (ssw));
++ "pmove %%psr,%1"
++ : "=a&" (desc), "=m" (temp)
++ : "a" (addr), "d" (ssw));
+ #else
+ asm volatile ("ptestr %2,%1@,#7\n\t"
+- "pmove %%psr,%0@"
+- : : "a" (&temp), "a" (addr), "d" (ssw));
++ "pmove %%psr,%0"
++ : "=m" (temp) : "a" (addr), "d" (ssw));
+ #endif
+ mmusr = temp;
+
+@@ -605,20 +605,18 @@ static inline void bus_error030 (struct frame *fp)
+ !(ssw & RW) ? "write" : "read", addr,
+ fp->ptregs.pc, ssw);
+ asm volatile ("ptestr #1,%1@,#0\n\t"
+- "pmove %%psr,%0@"
+- : /* no outputs */
+- : "a" (&temp), "a" (addr));
++ "pmove %%psr,%0"
++ : "=m" (temp)
++ : "a" (addr));
+ mmusr = temp;
+
+ printk ("level 0 mmusr is %#x\n", mmusr);
+ #if 0
+- asm volatile ("pmove %%tt0,%0@"
+- : /* no outputs */
+- : "a" (&tlong));
++ asm volatile ("pmove %%tt0,%0"
++ : "=m" (tlong));
+ printk("tt0 is %#lx, ", tlong);
+- asm volatile ("pmove %%tt1,%0@"
+- : /* no outputs */
+- : "a" (&tlong));
++ asm volatile ("pmove %%tt1,%0"
++ : "=m" (tlong));
+ printk("tt1 is %#lx\n", tlong);
+ #endif
+ #ifdef DEBUG
+@@ -668,13 +666,13 @@ static inline void bus_error030 (struct frame *fp)
+
+ #ifdef DEBUG
+ asm volatile ("ptestr #1,%2@,#7,%0\n\t"
+- "pmove %%psr,%1@"
+- : "=a&" (desc)
+- : "a" (&temp), "a" (addr));
++ "pmove %%psr,%1"
++ : "=a&" (desc), "=m" (temp)
++ : "a" (addr));
+ #else
+ asm volatile ("ptestr #1,%1@,#7\n\t"
+- "pmove %%psr,%0@"
+- : : "a" (&temp), "a" (addr));
++ "pmove %%psr,%0"
++ : "=m" (temp) : "a" (addr));
+ #endif
+ mmusr = temp;
+
+diff --git a/arch/m68k/mm/cache.c b/arch/m68k/mm/cache.c
+index 5437fff..5550aa4 100644
+--- a/arch/m68k/mm/cache.c
++++ b/arch/m68k/mm/cache.c
+@@ -52,9 +52,9 @@ static unsigned long virt_to_phys_slow(unsigned long vaddr)
+ unsigned long *descaddr;
+
+ asm volatile ("ptestr %3,%2@,#7,%0\n\t"
+- "pmove %%psr,%1@"
+- : "=a&" (descaddr)
+- : "a" (&mmusr), "a" (vaddr), "d" (get_fs().seg));
++ "pmove %%psr,%1"
++ : "=a&" (descaddr), "=m" (mmusr)
++ : "a" (vaddr), "d" (get_fs().seg));
+ if (mmusr & (MMU_I|MMU_B|MMU_L))
+ return 0;
+ descaddr = phys_to_virt((unsigned long)descaddr);
+diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
+index 54a13aa..21f7385 100644
+--- a/arch/x86/include/asm/uv/uv_hub.h
++++ b/arch/x86/include/asm/uv/uv_hub.h
+@@ -318,13 +318,13 @@ uv_gpa_in_mmr_space(unsigned long gpa)
+ /* UV global physical address --> socket phys RAM */
+ static inline unsigned long uv_gpa_to_soc_phys_ram(unsigned long gpa)
+ {
+- unsigned long paddr = gpa & uv_hub_info->gpa_mask;
++ unsigned long paddr;
+ unsigned long remap_base = uv_hub_info->lowmem_remap_base;
+ unsigned long remap_top = uv_hub_info->lowmem_remap_top;
+
+ gpa = ((gpa << uv_hub_info->m_shift) >> uv_hub_info->m_shift) |
+ ((gpa >> uv_hub_info->n_lshift) << uv_hub_info->m_val);
+- gpa = gpa & uv_hub_info->gpa_mask;
++ paddr = gpa & uv_hub_info->gpa_mask;
+ if (paddr >= remap_base && paddr < remap_base + remap_top)
+ paddr -= remap_base;
+ return paddr;
+diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
+index d494799..ac52c15 100644
+--- a/arch/x86/kernel/microcode_amd.c
++++ b/arch/x86/kernel/microcode_amd.c
+@@ -300,13 +300,33 @@ free_table:
+ return state;
+ }
+
++/*
++ * AMD microcode firmware naming convention, up to family 15h they are in
++ * the legacy file:
++ *
++ * amd-ucode/microcode_amd.bin
++ *
++ * This legacy file is always smaller than 2K in size.
++ *
++ * Starting at family 15h they are in family specific firmware files:
++ *
++ * amd-ucode/microcode_amd_fam15h.bin
++ * amd-ucode/microcode_amd_fam16h.bin
++ * ...
++ *
++ * These might be larger than 2K.
++ */
+ static enum ucode_state request_microcode_amd(int cpu, struct device *device)
+ {
+- const char *fw_name = "amd-ucode/microcode_amd.bin";
++ char fw_name[36] = "amd-ucode/microcode_amd.bin";
+ const struct firmware *fw;
+ enum ucode_state ret = UCODE_NFOUND;
++ struct cpuinfo_x86 *c = &cpu_data(cpu);
++
++ if (c->x86 >= 0x15)
++ snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86);
+
+- if (request_firmware(&fw, fw_name, device)) {
++ if (request_firmware(&fw, (const char *)fw_name, device)) {
+ pr_err("failed to load file %s\n", fw_name);
+ goto out;
+ }
+diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
+index 7b65f75..7c1b765 100644
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -151,17 +151,18 @@ void bpf_jit_compile(struct sk_filter *fp)
+ cleanup_addr = proglen; /* epilogue address */
+
+ for (pass = 0; pass < 10; pass++) {
++ u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen;
+ /* no prologue/epilogue for trivial filters (RET something) */
+ proglen = 0;
+ prog = temp;
+
+- if (seen) {
++ if (seen_or_pass0) {
+ EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
+ EMIT4(0x48, 0x83, 0xec, 96); /* subq $96,%rsp */
+ /* note : must save %rbx in case bpf_error is hit */
+- if (seen & (SEEN_XREG | SEEN_DATAREF))
++ if (seen_or_pass0 & (SEEN_XREG | SEEN_DATAREF))
+ EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */
+- if (seen & SEEN_XREG)
++ if (seen_or_pass0 & SEEN_XREG)
+ CLEAR_X(); /* make sure we dont leek kernel memory */
+
+ /*
+@@ -170,7 +171,7 @@ void bpf_jit_compile(struct sk_filter *fp)
+ * r9 = skb->len - skb->data_len
+ * r8 = skb->data
+ */
+- if (seen & SEEN_DATAREF) {
++ if (seen_or_pass0 & SEEN_DATAREF) {
+ if (offsetof(struct sk_buff, len) <= 127)
+ /* mov off8(%rdi),%r9d */
+ EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len));
+@@ -260,9 +261,14 @@ void bpf_jit_compile(struct sk_filter *fp)
+ case BPF_S_ALU_DIV_X: /* A /= X; */
+ seen |= SEEN_XREG;
+ EMIT2(0x85, 0xdb); /* test %ebx,%ebx */
+- if (pc_ret0 != -1)
+- EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4));
+- else {
++ if (pc_ret0 > 0) {
++ /* addrs[pc_ret0 - 1] is start address of target
++ * (addrs[i] - 4) is the address following this jmp
++ * ("xor %edx,%edx; div %ebx" being 4 bytes long)
++ */
++ EMIT_COND_JMP(X86_JE, addrs[pc_ret0 - 1] -
++ (addrs[i] - 4));
++ } else {
+ EMIT_COND_JMP(X86_JNE, 2 + 5);
+ CLEAR_A();
+ EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */
+@@ -335,12 +341,12 @@ void bpf_jit_compile(struct sk_filter *fp)
+ }
+ /* fallinto */
+ case BPF_S_RET_A:
+- if (seen) {
++ if (seen_or_pass0) {
+ if (i != flen - 1) {
+ EMIT_JMP(cleanup_addr - addrs[i]);
+ break;
+ }
+- if (seen & SEEN_XREG)
++ if (seen_or_pass0 & SEEN_XREG)
+ EMIT4(0x48, 0x8b, 0x5d, 0xf8); /* mov -8(%rbp),%rbx */
+ EMIT1(0xc9); /* leaveq */
+ }
+@@ -483,8 +489,9 @@ common_load: seen |= SEEN_DATAREF;
+ goto common_load;
+ case BPF_S_LDX_B_MSH:
+ if ((int)K < 0) {
+- if (pc_ret0 != -1) {
+- EMIT_JMP(addrs[pc_ret0] - addrs[i]);
++ if (pc_ret0 > 0) {
++ /* addrs[pc_ret0 - 1] is the start address */
++ EMIT_JMP(addrs[pc_ret0 - 1] - addrs[i]);
+ break;
+ }
+ CLEAR_A();
+@@ -599,13 +606,14 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+ * use it to give the cleanup instruction(s) addr
+ */
+ cleanup_addr = proglen - 1; /* ret */
+- if (seen)
++ if (seen_or_pass0)
+ cleanup_addr -= 1; /* leaveq */
+- if (seen & SEEN_XREG)
++ if (seen_or_pass0 & SEEN_XREG)
+ cleanup_addr -= 4; /* mov -8(%rbp),%rbx */
+
+ if (image) {
+- WARN_ON(proglen != oldproglen);
++ if (proglen != oldproglen)
++ pr_err("bpb_jit_compile proglen=%u != oldproglen=%u\n", proglen, oldproglen);
+ break;
+ }
+ if (proglen == oldproglen) {
+diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
+index 9010ca7..81aee5a 100644
+--- a/arch/x86/platform/uv/tlb_uv.c
++++ b/arch/x86/platform/uv/tlb_uv.c
+@@ -1860,6 +1860,8 @@ static void __init init_per_cpu_tunables(void)
+ bcp->cong_reps = congested_reps;
+ bcp->cong_period = congested_period;
+ bcp->clocks_per_100_usec = usec_2_cycles(100);
++ spin_lock_init(&bcp->queue_lock);
++ spin_lock_init(&bcp->uvhub_lock);
+ }
+ }
+
+diff --git a/arch/x86/platform/uv/uv_irq.c b/arch/x86/platform/uv/uv_irq.c
+index 374a05d..f25c276 100644
+--- a/arch/x86/platform/uv/uv_irq.c
++++ b/arch/x86/platform/uv/uv_irq.c
+@@ -25,7 +25,7 @@ struct uv_irq_2_mmr_pnode{
+ int irq;
+ };
+
+-static spinlock_t uv_irq_lock;
++static DEFINE_SPINLOCK(uv_irq_lock);
+ static struct rb_root uv_irq_root;
+
+ static int uv_set_irq_affinity(struct irq_data *, const struct cpumask *, bool);
+diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
+index cc9b1e1..d69cc6c 100644
+--- a/arch/x86/xen/spinlock.c
++++ b/arch/x86/xen/spinlock.c
+@@ -116,9 +116,26 @@ static inline void spin_time_accum_blocked(u64 start)
+ }
+ #endif /* CONFIG_XEN_DEBUG_FS */
+
++/*
++ * Size struct xen_spinlock so it's the same as arch_spinlock_t.
++ */
++#if NR_CPUS < 256
++typedef u8 xen_spinners_t;
++# define inc_spinners(xl) \
++ asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory");
++# define dec_spinners(xl) \
++ asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory");
++#else
++typedef u16 xen_spinners_t;
++# define inc_spinners(xl) \
++ asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory");
++# define dec_spinners(xl) \
++ asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory");
++#endif
++
+ struct xen_spinlock {
+ unsigned char lock; /* 0 -> free; 1 -> locked */
+- unsigned short spinners; /* count of waiting cpus */
++ xen_spinners_t spinners; /* count of waiting cpus */
+ };
+
+ static int xen_spin_is_locked(struct arch_spinlock *lock)
+@@ -164,8 +181,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
+
+ wmb(); /* set lock of interest before count */
+
+- asm(LOCK_PREFIX " incw %0"
+- : "+m" (xl->spinners) : : "memory");
++ inc_spinners(xl);
+
+ return prev;
+ }
+@@ -176,8 +192,7 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl)
+ */
+ static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev)
+ {
+- asm(LOCK_PREFIX " decw %0"
+- : "+m" (xl->spinners) : : "memory");
++ dec_spinners(xl);
+ wmb(); /* decrement count before restoring lock */
+ __this_cpu_write(lock_spinners, prev);
+ }
+@@ -373,6 +388,8 @@ void xen_uninit_lock_cpu(int cpu)
+
+ void __init xen_init_spinlocks(void)
+ {
++ BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t));
++
+ pv_lock_ops.spin_is_locked = xen_spin_is_locked;
+ pv_lock_ops.spin_is_contended = xen_spin_is_contended;
+ pv_lock_ops.spin_lock = xen_spin_lock;
+diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
+index 9ed9f60..88f160b 100644
+--- a/crypto/sha512_generic.c
++++ b/crypto/sha512_generic.c
+@@ -21,8 +21,6 @@
+ #include <linux/percpu.h>
+ #include <asm/byteorder.h>
+
+-static DEFINE_PER_CPU(u64[80], msg_schedule);
+-
+ static inline u64 Ch(u64 x, u64 y, u64 z)
+ {
+ return z ^ (x & (y ^ z));
+@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
+
+ static inline void BLEND_OP(int I, u64 *W)
+ {
+- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
++ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
+ }
+
+ static void
+@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input)
+ u64 a, b, c, d, e, f, g, h, t1, t2;
+
+ int i;
+- u64 *W = get_cpu_var(msg_schedule);
++ u64 W[16];
+
+ /* load the input */
+ for (i = 0; i < 16; i++)
+ LOAD_OP(i, W, input);
+
+- for (i = 16; i < 80; i++) {
+- BLEND_OP(i, W);
+- }
+-
+ /* 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];
+
+- /* now iterate */
+- for (i=0; i<80; i+=8) {
+- 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;
+- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+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+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+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+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+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+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+7];
+- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
++#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);
+ }
+
+ state[0] += a; state[1] += b; state[2] += c; state[3] += d;
+@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input)
+
+ /* erase our data */
+ a = b = c = d = e = f = g = h = t1 = t2 = 0;
+- memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
+- put_cpu_var(msg_schedule);
+ }
+
+ static int
+diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
+index 3f4051a..c7e5282 100644
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -432,6 +432,9 @@ static int probe_itpm(struct tpm_chip *chip)
+ out:
+ itpm = rem_itpm;
+ tpm_tis_ready(chip);
++ /* some TPMs need a break here otherwise they will not work
++ * correctly on the immediately subsequent command */
++ msleep(chip->vendor.timeout_b);
+ release_locality(chip, chip->vendor.locality, 0);
+
+ return rc;
+diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
+index 3f46772..ba23790 100644
+--- a/drivers/gpu/drm/drm_auth.c
++++ b/drivers/gpu/drm/drm_auth.c
+@@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv,
+ * Searches and unlinks the entry in drm_device::magiclist with the magic
+ * number hash key, while holding the drm_device::struct_mutex lock.
+ */
+-static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
++int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+ {
+ struct drm_magic_entry *pt;
+ struct drm_hash_item *hash;
+@@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic)
+ * If there is a magic number in drm_file::magic then use it, otherwise
+ * searches an unique non-zero magic number and add it associating it with \p
+ * file_priv.
++ * This ioctl needs protection by the drm_global_mutex, which protects
++ * struct drm_file::magic and struct drm_magic_entry::priv.
+ */
+ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ {
+@@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ * \return zero if authentication successed, or a negative number otherwise.
+ *
+ * Checks if \p file_priv is associated with the magic number passed in \arg.
++ * This ioctl needs protection by the drm_global_mutex, which protects
++ * struct drm_file::magic and struct drm_magic_entry::priv.
+ */
+ int drm_authmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
+index 4911e1d..828bf65 100644
+--- a/drivers/gpu/drm/drm_fops.c
++++ b/drivers/gpu/drm/drm_fops.c
+@@ -487,6 +487,11 @@ int drm_release(struct inode *inode, struct file *filp)
+ (long)old_encode_dev(file_priv->minor->device),
+ dev->open_count);
+
++ /* Release any auth tokens that might point to this file_priv,
++ (do that under the drm_global_mutex) */
++ if (file_priv->magic)
++ (void) drm_remove_magic(file_priv->master, file_priv->magic);
++
+ /* if the master has gone away we can't do anything with the lock */
+ if (file_priv->minor->master)
+ drm_master_release(dev, filp);
+diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
+index 7886e4f..43cbafe 100644
+--- a/drivers/gpu/drm/i915/i915_suspend.c
++++ b/drivers/gpu/drm/i915/i915_suspend.c
+@@ -822,7 +822,7 @@ int i915_save_state(struct drm_device *dev)
+
+ if (IS_IRONLAKE_M(dev))
+ ironlake_disable_drps(dev);
+- if (IS_GEN6(dev))
++ if (INTEL_INFO(dev)->gen >= 6)
+ gen6_disable_rps(dev);
+
+ /* Cache mode state */
+@@ -881,7 +881,7 @@ int i915_restore_state(struct drm_device *dev)
+ intel_init_emon(dev);
+ }
+
+- if (IS_GEN6(dev)) {
++ if (INTEL_INFO(dev)->gen >= 6) {
+ gen6_enable_rps(dev_priv);
+ gen6_update_ring_freq(dev_priv);
+ }
+diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
+index ca70e2f..30a9af9 100644
+--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
+@@ -631,6 +631,19 @@ render_ring_add_request(struct intel_ring_buffer *ring,
+ }
+
+ static u32
++gen6_ring_get_seqno(struct intel_ring_buffer *ring)
++{
++ struct drm_device *dev = ring->dev;
++
++ /* Workaround to force correct ordering between irq and seqno writes on
++ * ivb (and maybe also on snb) by reading from a CS register (like
++ * ACTHD) before reading the status page. */
++ if (IS_GEN7(dev))
++ intel_ring_get_active_head(ring);
++ return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
++}
++
++static u32
+ ring_get_seqno(struct intel_ring_buffer *ring)
+ {
+ return intel_read_status_page(ring, I915_GEM_HWS_INDEX);
+@@ -795,6 +808,12 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
+ if (!dev->irq_enabled)
+ return false;
+
++ /* It looks like we need to prevent the gt from suspending while waiting
++ * for an notifiy irq, otherwise irqs seem to get lost on at least the
++ * blt/bsd rings on ivb. */
++ if (IS_GEN7(dev))
++ gen6_gt_force_wake_get(dev_priv);
++
+ spin_lock(&ring->irq_lock);
+ if (ring->irq_refcount++ == 0) {
+ ring->irq_mask &= ~rflag;
+@@ -819,6 +838,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
+ ironlake_disable_irq(dev_priv, gflag);
+ }
+ spin_unlock(&ring->irq_lock);
++
++ if (IS_GEN7(dev))
++ gen6_gt_force_wake_put(dev_priv);
+ }
+
+ static bool
+@@ -1316,7 +1338,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = {
+ .write_tail = gen6_bsd_ring_write_tail,
+ .flush = gen6_ring_flush,
+ .add_request = gen6_add_request,
+- .get_seqno = ring_get_seqno,
++ .get_seqno = gen6_ring_get_seqno,
+ .irq_get = gen6_bsd_ring_get_irq,
+ .irq_put = gen6_bsd_ring_put_irq,
+ .dispatch_execbuffer = gen6_ring_dispatch_execbuffer,
+@@ -1451,7 +1473,7 @@ static const struct intel_ring_buffer gen6_blt_ring = {
+ .write_tail = ring_write_tail,
+ .flush = blt_ring_flush,
+ .add_request = gen6_add_request,
+- .get_seqno = ring_get_seqno,
++ .get_seqno = gen6_ring_get_seqno,
+ .irq_get = blt_ring_get_irq,
+ .irq_put = blt_ring_put_irq,
+ .dispatch_execbuffer = gen6_ring_dispatch_execbuffer,
+@@ -1474,6 +1496,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
+ ring->flush = gen6_render_ring_flush;
+ ring->irq_get = gen6_render_ring_get_irq;
+ ring->irq_put = gen6_render_ring_put_irq;
++ ring->get_seqno = gen6_ring_get_seqno;
+ } else if (IS_GEN5(dev)) {
+ ring->add_request = pc_render_add_request;
+ ring->get_seqno = pc_render_get_seqno;
+diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
+index f7b9268..e334ec3 100644
+--- a/drivers/gpu/drm/i915/intel_sdvo.c
++++ b/drivers/gpu/drm/i915/intel_sdvo.c
+@@ -1066,15 +1066,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
+
+ /* Set the SDVO control regs. */
+ if (INTEL_INFO(dev)->gen >= 4) {
+- sdvox = 0;
++ /* The real mode polarity is set by the SDVO commands, using
++ * struct intel_sdvo_dtd. */
++ sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH;
+ if (intel_sdvo->is_hdmi)
+ sdvox |= intel_sdvo->color_range;
+ if (INTEL_INFO(dev)->gen < 5)
+ sdvox |= SDVO_BORDER_ENABLE;
+- if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
+- sdvox |= SDVO_VSYNC_ACTIVE_HIGH;
+- if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
+- sdvox |= SDVO_HSYNC_ACTIVE_HIGH;
+ } else {
+ sdvox = I915_READ(intel_sdvo->sdvo_reg);
+ switch (intel_sdvo->sdvo_reg) {
+diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
+index 6fb335a..a71557c 100644
+--- a/drivers/gpu/drm/radeon/atombios_dp.c
++++ b/drivers/gpu/drm/radeon/atombios_dp.c
+@@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
+ return false;
+ }
+
+-static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
+- struct drm_connector *connector)
++int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
++ struct drm_connector *connector)
+ {
+ struct drm_device *dev = encoder->dev;
+ struct radeon_device *rdev = dev->dev_private;
+@@ -558,7 +558,7 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
+ int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+
+ if (!ASIC_IS_DCE4(rdev))
+- return;
++ return panel_mode;
+
+ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) ==
+ ENCODER_OBJECT_ID_NUTMEG)
+@@ -572,14 +572,7 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
+ panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
+ }
+
+- atombios_dig_encoder_setup(encoder,
+- ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
+- panel_mode);
+-
+- if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
+- (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
+- radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
+- }
++ return panel_mode;
+ }
+
+ void radeon_dp_set_link_config(struct drm_connector *connector,
+@@ -717,6 +710,8 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
+
+ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
+ {
++ struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder);
++ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
+ u8 tmp;
+
+ /* power up the sink */
+@@ -732,7 +727,10 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
+ radeon_write_dpcd_reg(dp_info->radeon_connector,
+ DP_DOWNSPREAD_CTRL, 0);
+
+- radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector);
++ if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) &&
++ (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) {
++ radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1);
++ }
+
+ /* set the lane count on the sink */
+ tmp = dp_info->dp_lane_count;
+diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c
+index 39c04c1..0f8eb48 100644
+--- a/drivers/gpu/drm/radeon/atombios_encoders.c
++++ b/drivers/gpu/drm/radeon/atombios_encoders.c
+@@ -1352,7 +1352,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ /* some early dce3.2 boards have a bug in their transmitter control table */
+- if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
++ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) ||
++ ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+ else
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+@@ -1362,8 +1363,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
+ ATOM_TRANSMITTER_ACTION_POWER_ON);
+ radeon_dig_connector->edp_on = true;
+ }
+- if (ASIC_IS_DCE4(rdev))
+- atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
+ radeon_dp_link_train(encoder, connector);
+ if (ASIC_IS_DCE4(rdev))
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
+@@ -1374,7 +1373,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ case DRM_MODE_DPMS_OFF:
+- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
++ else
++ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
+ if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
+ if (ASIC_IS_DCE4(rdev))
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
+@@ -1821,7 +1823,21 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+- if (ASIC_IS_DCE4(rdev)) {
++ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
++ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
++ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
++
++ if (!connector)
++ dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
++ else
++ dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
++
++ /* setup and enable the encoder */
++ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
++ atombios_dig_encoder_setup(encoder,
++ ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
++ dig->panel_mode);
++ } else if (ASIC_IS_DCE4(rdev)) {
+ /* disable the transmitter */
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
+ /* setup and enable the encoder */
+diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+index 8f86aeb..e7ddb49 100644
+--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+@@ -134,6 +134,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev)
+ /* Dell RS690 only seems to work with MSIs. */
+ if ((rdev->pdev->device == 0x791f) &&
+ (rdev->pdev->subsystem_vendor == 0x1028) &&
++ (rdev->pdev->subsystem_device == 0x01fc))
++ return true;
++
++ /* Dell RS690 only seems to work with MSIs. */
++ if ((rdev->pdev->device == 0x791f) &&
++ (rdev->pdev->subsystem_vendor == 0x1028) &&
+ (rdev->pdev->subsystem_device == 0x01fd))
+ return true;
+
+diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
+index 2c2e75e..8254d5a 100644
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -362,6 +362,7 @@ struct radeon_encoder_atom_dig {
+ struct backlight_device *bl_dev;
+ int dpms_mode;
+ uint8_t backlight_level;
++ int panel_mode;
+ };
+
+ struct radeon_encoder_atom_dac {
+@@ -482,6 +483,8 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder,
+ extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
+ extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
+ extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
++extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
++ struct drm_connector *connector);
+ extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);
+ extern void radeon_atom_encoder_init(struct radeon_device *rdev);
+ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index f94b33a..7c88f1f 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
+ unsigned int *handle)
+ {
+ if (handle)
+- handle = 0;
++ *handle = 0;
+
+ return 0;
+ }
+diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
+index 92f9497..6dbfd3e 100644
+--- a/drivers/hwmon/f71805f.c
++++ b/drivers/hwmon/f71805f.c
+@@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg)
+
+ static inline u8 temp_to_reg(long val)
+ {
+- if (val < 0)
+- val = 0;
+- else if (val > 1000 * 0xff)
+- val = 0xff;
+- return ((val + 500) / 1000);
++ if (val <= 0)
++ return 0;
++ if (val >= 1000 * 0xff)
++ return 0xff;
++ return (val + 500) / 1000;
+ }
+
+ /*
+diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
+index fe4104c..5357925 100644
+--- a/drivers/hwmon/sht15.c
++++ b/drivers/hwmon/sht15.c
+@@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb,
+
+ static int __devinit sht15_probe(struct platform_device *pdev)
+ {
+- int ret = 0;
++ int ret;
+ struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+ u8 status = 0;
+
+@@ -901,6 +901,7 @@ static int __devinit sht15_probe(struct platform_device *pdev)
+ init_waitqueue_head(&data->wait_queue);
+
+ if (pdev->dev.platform_data == NULL) {
++ ret = -EINVAL;
+ dev_err(&pdev->dev, "no platform data supplied\n");
+ goto err_free_data;
+ }
+diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
+index 93f5fc7..4b57ab6 100644
+--- a/drivers/hwmon/w83627ehf.c
++++ b/drivers/hwmon/w83627ehf.c
+@@ -1319,6 +1319,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
+ {
+ struct w83627ehf_data *data = dev_get_drvdata(dev);
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
++ struct w83627ehf_sio_data *sio_data = dev->platform_data;
+ int nr = sensor_attr->index;
+ unsigned long val;
+ int err;
+@@ -1330,6 +1331,11 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
+
+ if (val > 1)
+ return -EINVAL;
++
++ /* On NCT67766F, DC mode is only supported for pwm1 */
++ if (sio_data->kind == nct6776 && nr && val != 1)
++ return -EINVAL;
++
+ mutex_lock(&data->update_lock);
+ reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]);
+ data->pwm_mode[nr] = val;
+diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
+index 106b88a..30431d8 100644
+--- a/drivers/net/bonding/bond_alb.c
++++ b/drivers/net/bonding/bond_alb.c
+@@ -871,16 +871,12 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
+ }
+ }
+
+-/* hw is a boolean parameter that determines whether we should try and
+- * set the hw address of the device as well as the hw address of the
+- * net_device
+- */
+-static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
++static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
+ {
+ struct net_device *dev = slave->dev;
+ struct sockaddr s_addr;
+
+- if (!hw) {
++ if (slave->bond->params.mode == BOND_MODE_TLB) {
+ memcpy(dev->dev_addr, addr, dev->addr_len);
+ return 0;
+ }
+@@ -910,8 +906,8 @@ static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct
+ u8 tmp_mac_addr[ETH_ALEN];
+
+ memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
+- alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
+- alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr);
++ alb_set_slave_mac_addr(slave2, tmp_mac_addr);
+
+ }
+
+@@ -1058,8 +1054,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
+
+ /* Try setting slave mac to bond address and fall-through
+ to code handling that situation below... */
+- alb_set_slave_mac_addr(slave, bond->dev->dev_addr,
+- bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(slave, bond->dev->dev_addr);
+ }
+
+ /* The slave's address is equal to the address of the bond.
+@@ -1095,8 +1090,7 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
+ }
+
+ if (free_mac_slave) {
+- alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
+- bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr);
+
+ pr_warning("%s: Warning: the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
+ bond->dev->name, slave->dev->name,
+@@ -1451,8 +1445,7 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
+ {
+ int res;
+
+- res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
+- bond->alb_info.rlb_enabled);
++ res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr);
+ if (res) {
+ return res;
+ }
+@@ -1603,8 +1596,7 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
+ alb_swap_mac_addr(bond, swap_slave, new_slave);
+ } else {
+ /* set the new_slave to the bond mac address */
+- alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
+- bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr);
+ }
+
+ if (swap_slave) {
+@@ -1664,8 +1656,7 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
+ alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
+ alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
+ } else {
+- alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
+- bond->alb_info.rlb_enabled);
++ alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr);
+
+ read_lock(&bond->lock);
+ alb_send_learning_packets(bond->curr_active_slave, bond_dev->dev_addr);
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 7413497..959d448 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -172,6 +172,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
+ skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN);
+ if (!skb)
+ return RX_HANDLER_CONSUMED;
++ eth = eth_hdr(skb);
+ src = macvlan_hash_lookup(port, eth->h_source);
+ if (!src)
+ /* frame comes from an external address */
+diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+index 510e9bb..453f58e 100644
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -8217,13 +8217,21 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
+
+ void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
+ {
++ int timeout = 20;
++
+ /* flush packet queue when requested */
+ if (drop)
+ brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
+
+ /* wait for queue and DMA fifos to run dry */
+- while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0)
++ while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
+ brcms_msleep(wlc->wl, 1);
++
++ if (--timeout == 0)
++ break;
++ }
++
++ WARN_ON_ONCE(timeout == 0);
+ }
+
+ void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
+diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+index 1920237..1daf01e 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
++++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+@@ -957,11 +957,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
+ }
+ #endif
+
+- spin_unlock_irqrestore(&trans->shrd->lock, flags);
+-
+ /* saved interrupt in inta variable now we can reset trans_pcie->inta */
+ trans_pcie->inta = 0;
+
++ spin_unlock_irqrestore(&trans->shrd->lock, flags);
++
+ /* Now service all interrupt bits discovered above. */
+ if (inta & CSR_INT_BIT_HW_ERR) {
+ IWL_ERR(trans, "Hardware error detected. Restarting.\n");
+diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
+index 0794c72..b1ddfef 100644
+--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
++++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
+@@ -4033,7 +4033,8 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
+ ioc->reply_free[i] = cpu_to_le32(reply_address);
+
+ /* initialize reply queues */
+- _base_assign_reply_queues(ioc);
++ if (ioc->is_driver_loading)
++ _base_assign_reply_queues(ioc);
+
+ /* initialize Reply Post Free Queue */
+ reply_post_free = (long)ioc->reply_post_free;
+@@ -4081,24 +4082,17 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
+
+
+ if (ioc->is_driver_loading) {
+-
+-
+-
+- ioc->wait_for_discovery_to_complete =
+- _base_determine_wait_on_discovery(ioc);
+- return r; /* scan_start and scan_finished support */
+- }
+-
+-
+- if (ioc->wait_for_discovery_to_complete && ioc->is_warpdrive) {
+- if (ioc->manu_pg10.OEMIdentifier == 0x80) {
++ if (ioc->is_warpdrive && ioc->manu_pg10.OEMIdentifier
++ == 0x80) {
+ hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
+ MFG_PAGE10_HIDE_SSDS_MASK);
+ if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
+ ioc->mfg_pg10_hide_flag = hide_flag;
+ }
++ ioc->wait_for_discovery_to_complete =
++ _base_determine_wait_on_discovery(ioc);
++ return r; /* scan_start and scan_finished support */
+ }
+-
+ r = _base_send_port_enable(ioc, sleep_flag);
+ if (r)
+ return r;
+diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+index 9bc6fb2..2824a90 100644
+--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
++++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+@@ -8001,7 +8001,6 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ goto out_attach_fail;
+ }
+
+- scsi_scan_host(shost);
+ if (ioc->is_warpdrive) {
+ if (ioc->mfg_pg10_hide_flag == MFG_PAGE10_EXPOSE_ALL_DISKS)
+ ioc->hide_drives = 0;
+@@ -8015,8 +8014,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ }
+ } else
+ ioc->hide_drives = 0;
++ scsi_scan_host(shost);
+
+- _scsih_probe_devices(ioc);
+ return 0;
+
+ out_attach_fail:
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
+index 00233af..8e00926 100644
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1740,9 +1740,19 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
+ {
+ struct uart_amba_port *uap = amba_ports[co->index];
+ unsigned int status, old_cr, new_cr;
++ unsigned long flags;
++ int locked = 1;
+
+ clk_enable(uap->clk);
+
++ local_irq_save(flags);
++ if (uap->port.sysrq)
++ locked = 0;
++ else if (oops_in_progress)
++ locked = spin_trylock(&uap->port.lock);
++ else
++ spin_lock(&uap->port.lock);
++
+ /*
+ * First save the CR then disable the interrupts
+ */
+@@ -1762,6 +1772,10 @@ pl011_console_write(struct console *co, const char *s, unsigned int count)
+ } while (status & UART01x_FR_BUSY);
+ writew(old_cr, uap->port.membase + UART011_CR);
+
++ if (locked)
++ spin_unlock(&uap->port.lock);
++ local_irq_restore(flags);
++
+ clk_disable(uap->clk);
+ }
+
+diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
+index 7c867a0..7545fe1 100644
+--- a/drivers/tty/serial/jsm/jsm_driver.c
++++ b/drivers/tty/serial/jsm/jsm_driver.c
+@@ -251,6 +251,7 @@ static void jsm_io_resume(struct pci_dev *pdev)
+ struct jsm_board *brd = pci_get_drvdata(pdev);
+
+ pci_restore_state(pdev);
++ pci_save_state(pdev);
+
+ jsm_uart_port_init(brd);
+ }
+diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c
+index ef9dd62..bf6e238 100644
+--- a/drivers/tty/tty_port.c
++++ b/drivers/tty/tty_port.c
+@@ -227,7 +227,6 @@ int tty_port_block_til_ready(struct tty_port *port,
+ int do_clocal = 0, retval;
+ unsigned long flags;
+ DEFINE_WAIT(wait);
+- int cd;
+
+ /* block if port is in the process of being closed */
+ if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
+@@ -284,11 +283,14 @@ int tty_port_block_til_ready(struct tty_port *port,
+ retval = -ERESTARTSYS;
+ break;
+ }
+- /* Probe the carrier. For devices with no carrier detect this
+- will always return true */
+- cd = tty_port_carrier_raised(port);
++ /*
++ * Probe the carrier. For devices with no carrier detect
++ * tty_port_carrier_raised will always return true.
++ * Never ask drivers if CLOCAL is set, this causes troubles
++ * on some hardware.
++ */
+ if (!(port->flags & ASYNC_CLOSING) &&
+- (do_clocal || cd))
++ (do_clocal || tty_port_carrier_raised(port)))
+ break;
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
+index efe6849..fd4aee1 100644
+--- a/drivers/usb/class/cdc-wdm.c
++++ b/drivers/usb/class/cdc-wdm.c
+@@ -57,6 +57,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
+
+ #define WDM_MAX 16
+
++/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */
++#define WDM_DEFAULT_BUFSIZE 256
+
+ static DEFINE_MUTEX(wdm_mutex);
+
+@@ -88,7 +90,8 @@ struct wdm_device {
+ int count;
+ dma_addr_t shandle;
+ dma_addr_t ihandle;
+- struct mutex lock;
++ struct mutex wlock;
++ struct mutex rlock;
+ wait_queue_head_t wait;
+ struct work_struct rxwork;
+ int werr;
+@@ -323,7 +326,7 @@ static ssize_t wdm_write
+ }
+
+ /* concurrent writes and disconnect */
+- r = mutex_lock_interruptible(&desc->lock);
++ r = mutex_lock_interruptible(&desc->wlock);
+ rv = -ERESTARTSYS;
+ if (r) {
+ kfree(buf);
+@@ -386,7 +389,7 @@ static ssize_t wdm_write
+ out:
+ usb_autopm_put_interface(desc->intf);
+ outnp:
+- mutex_unlock(&desc->lock);
++ mutex_unlock(&desc->wlock);
+ outnl:
+ return rv < 0 ? rv : count;
+ }
+@@ -399,7 +402,7 @@ static ssize_t wdm_read
+ struct wdm_device *desc = file->private_data;
+
+
+- rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */
++ rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */
+ if (rv < 0)
+ return -ERESTARTSYS;
+
+@@ -467,14 +470,16 @@ retry:
+ for (i = 0; i < desc->length - cntr; i++)
+ desc->ubuf[i] = desc->ubuf[i + cntr];
+
++ spin_lock_irq(&desc->iuspin);
+ desc->length -= cntr;
++ spin_unlock_irq(&desc->iuspin);
+ /* in case we had outstanding data */
+ if (!desc->length)
+ clear_bit(WDM_READ, &desc->flags);
+ rv = cntr;
+
+ err:
+- mutex_unlock(&desc->lock);
++ mutex_unlock(&desc->rlock);
+ return rv;
+ }
+
+@@ -540,7 +545,8 @@ static int wdm_open(struct inode *inode, struct file *file)
+ }
+ intf->needs_remote_wakeup = 1;
+
+- mutex_lock(&desc->lock);
++ /* using write lock to protect desc->count */
++ mutex_lock(&desc->wlock);
+ if (!desc->count++) {
+ desc->werr = 0;
+ desc->rerr = 0;
+@@ -553,7 +559,7 @@ static int wdm_open(struct inode *inode, struct file *file)
+ } else {
+ rv = 0;
+ }
+- mutex_unlock(&desc->lock);
++ mutex_unlock(&desc->wlock);
+ usb_autopm_put_interface(desc->intf);
+ out:
+ mutex_unlock(&wdm_mutex);
+@@ -565,9 +571,11 @@ static int wdm_release(struct inode *inode, struct file *file)
+ struct wdm_device *desc = file->private_data;
+
+ mutex_lock(&wdm_mutex);
+- mutex_lock(&desc->lock);
++
++ /* using write lock to protect desc->count */
++ mutex_lock(&desc->wlock);
+ desc->count--;
+- mutex_unlock(&desc->lock);
++ mutex_unlock(&desc->wlock);
+
+ if (!desc->count) {
+ dev_dbg(&desc->intf->dev, "wdm_release: cleanup");
+@@ -630,7 +638,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
+ struct usb_cdc_dmm_desc *dmhd;
+ u8 *buffer = intf->altsetting->extra;
+ int buflen = intf->altsetting->extralen;
+- u16 maxcom = 0;
++ u16 maxcom = WDM_DEFAULT_BUFSIZE;
+
+ if (!buffer)
+ goto out;
+@@ -665,7 +673,8 @@ next_desc:
+ desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
+ if (!desc)
+ goto out;
+- mutex_init(&desc->lock);
++ mutex_init(&desc->rlock);
++ mutex_init(&desc->wlock);
+ spin_lock_init(&desc->iuspin);
+ init_waitqueue_head(&desc->wait);
+ desc->wMaxCommand = maxcom;
+@@ -716,7 +725,7 @@ next_desc:
+ goto err;
+
+ desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf),
+- desc->bMaxPacketSize0,
++ desc->wMaxCommand,
+ GFP_KERNEL,
+ &desc->response->transfer_dma);
+ if (!desc->inbuf)
+@@ -779,11 +788,13 @@ static void wdm_disconnect(struct usb_interface *intf)
+ /* to terminate pending flushes */
+ clear_bit(WDM_IN_USE, &desc->flags);
+ spin_unlock_irqrestore(&desc->iuspin, flags);
+- mutex_lock(&desc->lock);
++ wake_up_all(&desc->wait);
++ mutex_lock(&desc->rlock);
++ mutex_lock(&desc->wlock);
+ kill_urbs(desc);
+ cancel_work_sync(&desc->rxwork);
+- mutex_unlock(&desc->lock);
+- wake_up_all(&desc->wait);
++ mutex_unlock(&desc->wlock);
++ mutex_unlock(&desc->rlock);
+ if (!desc->count)
+ cleanup(desc);
+ mutex_unlock(&wdm_mutex);
+@@ -798,8 +809,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
+ dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor);
+
+ /* if this is an autosuspend the caller does the locking */
+- if (!PMSG_IS_AUTO(message))
+- mutex_lock(&desc->lock);
++ if (!PMSG_IS_AUTO(message)) {
++ mutex_lock(&desc->rlock);
++ mutex_lock(&desc->wlock);
++ }
+ spin_lock_irq(&desc->iuspin);
+
+ if (PMSG_IS_AUTO(message) &&
+@@ -815,8 +828,10 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message)
+ kill_urbs(desc);
+ cancel_work_sync(&desc->rxwork);
+ }
+- if (!PMSG_IS_AUTO(message))
+- mutex_unlock(&desc->lock);
++ if (!PMSG_IS_AUTO(message)) {
++ mutex_unlock(&desc->wlock);
++ mutex_unlock(&desc->rlock);
++ }
+
+ return rv;
+ }
+@@ -854,7 +869,8 @@ static int wdm_pre_reset(struct usb_interface *intf)
+ {
+ struct wdm_device *desc = usb_get_intfdata(intf);
+
+- mutex_lock(&desc->lock);
++ mutex_lock(&desc->rlock);
++ mutex_lock(&desc->wlock);
+ kill_urbs(desc);
+
+ /*
+@@ -876,7 +892,8 @@ static int wdm_post_reset(struct usb_interface *intf)
+ int rv;
+
+ rv = recover_from_urb_loss(desc);
+- mutex_unlock(&desc->lock);
++ mutex_unlock(&desc->wlock);
++ mutex_unlock(&desc->rlock);
+ return 0;
+ }
+
+diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
+index 69a4e43..27bd50a 100644
+--- a/drivers/usb/dwc3/ep0.c
++++ b/drivers/usb/dwc3/ep0.c
+@@ -149,20 +149,14 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
+
+ direction = !!(dep->flags & DWC3_EP0_DIR_IN);
+
+- if (dwc->ep0state == EP0_STATUS_PHASE) {
+- type = dwc->three_stage_setup
+- ? DWC3_TRBCTL_CONTROL_STATUS3
+- : DWC3_TRBCTL_CONTROL_STATUS2;
+- } else if (dwc->ep0state == EP0_DATA_PHASE) {
+- type = DWC3_TRBCTL_CONTROL_DATA;
+- } else {
+- /* should never happen */
+- WARN_ON(1);
++ if (dwc->ep0state != EP0_DATA_PHASE) {
++ dev_WARN(dwc->dev, "Unexpected pending request\n");
+ return 0;
+ }
+
+ ret = dwc3_ep0_start_trans(dwc, direction,
+- req->request.dma, req->request.length, type);
++ req->request.dma, req->request.length,
++ DWC3_TRBCTL_CONTROL_DATA);
+ dep->flags &= ~(DWC3_EP_PENDING_REQUEST |
+ DWC3_EP0_DIR_IN);
+ }
+diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
+index c9fa3bf..6ad0ad6 100644
+--- a/drivers/usb/gadget/langwell_udc.c
++++ b/drivers/usb/gadget/langwell_udc.c
+@@ -1522,8 +1522,7 @@ static void langwell_udc_stop(struct langwell_udc *dev)
+
+
+ /* stop all USB activities */
+-static void stop_activity(struct langwell_udc *dev,
+- struct usb_gadget_driver *driver)
++static void stop_activity(struct langwell_udc *dev)
+ {
+ struct langwell_ep *ep;
+ dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+@@ -1535,9 +1534,9 @@ static void stop_activity(struct langwell_udc *dev,
+ }
+
+ /* report disconnect; the driver is already quiesced */
+- if (driver) {
++ if (dev->driver) {
+ spin_unlock(&dev->lock);
+- driver->disconnect(&dev->gadget);
++ dev->driver->disconnect(&dev->gadget);
+ spin_lock(&dev->lock);
+ }
+
+@@ -1925,11 +1924,10 @@ static int langwell_stop(struct usb_gadget *g,
+
+ /* stop all usb activities */
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
+- stop_activity(dev, driver);
+- spin_unlock_irqrestore(&dev->lock, flags);
+-
+ dev->gadget.dev.driver = NULL;
+ dev->driver = NULL;
++ stop_activity(dev);
++ spin_unlock_irqrestore(&dev->lock, flags);
+
+ device_remove_file(&dev->pdev->dev, &dev_attr_function);
+
+@@ -2733,7 +2731,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
+ dev->bus_reset = 1;
+
+ /* reset all the queues, stop all USB activities */
+- stop_activity(dev, dev->driver);
++ stop_activity(dev);
+ dev->usb_state = USB_STATE_DEFAULT;
+ } else {
+ dev_vdbg(&dev->pdev->dev, "device controller reset\n");
+@@ -2741,7 +2739,7 @@ static void handle_usb_reset(struct langwell_udc *dev)
+ langwell_udc_reset(dev);
+
+ /* reset all the queues, stop all USB activities */
+- stop_activity(dev, dev->driver);
++ stop_activity(dev);
+
+ /* reset ep0 dQH and endptctrl */
+ ep0_reset(dev);
+@@ -3367,7 +3365,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state)
+
+ spin_lock_irq(&dev->lock);
+ /* stop all usb activities */
+- stop_activity(dev, dev->driver);
++ stop_activity(dev);
+ spin_unlock_irq(&dev->lock);
+
+ /* free dTD dma_pool and dQH */
+diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
+index c7f291a..85ea14e 100644
+--- a/drivers/usb/gadget/storage_common.c
++++ b/drivers/usb/gadget/storage_common.c
+@@ -598,16 +598,16 @@ static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = {
+ | USB_5GBPS_OPERATION),
+ .bFunctionalitySupport = USB_LOW_SPEED_OPERATION,
+ .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT,
+- .bU2DevExitLat = USB_DEFAULT_U2_DEV_EXIT_LAT,
++ .bU2DevExitLat = cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT),
+ };
+
+ static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = {
+ .bLength = USB_DT_BOS_SIZE,
+ .bDescriptorType = USB_DT_BOS,
+
+- .wTotalLength = USB_DT_BOS_SIZE
++ .wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE
+ + USB_DT_USB_EXT_CAP_SIZE
+- + USB_DT_USB_SS_CAP_SIZE,
++ + USB_DT_USB_SS_CAP_SIZE),
+
+ .bNumDeviceCaps = 2,
+ };
+diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
+index e90344a..b556a72 100644
+--- a/drivers/usb/host/ehci-fsl.c
++++ b/drivers/usb/host/ehci-fsl.c
+@@ -125,7 +125,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
+ */
+ if (pdata->init && pdata->init(pdev)) {
+ retval = -ENODEV;
+- goto err3;
++ goto err4;
+ }
+
+ /* Enable USB controller, 83xx or 8536 */
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index d28c586..ae92dc4 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1215,6 +1215,7 @@ static void handle_vendor_event(struct xhci_hcd *xhci,
+ *
+ * Returns a zero-based port number, which is suitable for indexing into each of
+ * the split roothubs' port arrays and bus state arrays.
++ * Add one to it in order to call xhci_find_slot_id_by_port.
+ */
+ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd,
+ struct xhci_hcd *xhci, u32 port_id)
+@@ -1335,7 +1336,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
+ xhci_set_link_state(xhci, port_array, faked_port_index,
+ XDEV_U0);
+ slot_id = xhci_find_slot_id_by_port(hcd, xhci,
+- faked_port_index);
++ faked_port_index + 1);
+ if (!slot_id) {
+ xhci_dbg(xhci, "slot_id is zero\n");
+ goto cleanup;
+@@ -3372,7 +3373,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
+ /* Check TD length */
+ if (running_total != td_len) {
+ xhci_err(xhci, "ISOC TD length unmatch\n");
+- return -EINVAL;
++ ret = -EINVAL;
++ goto cleanup;
+ }
+ }
+
+diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
+index 417b8f2..59689fa 100644
+--- a/drivers/usb/misc/usbsevseg.c
++++ b/drivers/usb/misc/usbsevseg.c
+@@ -24,7 +24,7 @@
+
+ #define VENDOR_ID 0x0fc5
+ #define PRODUCT_ID 0x1227
+-#define MAXLEN 6
++#define MAXLEN 8
+
+ /* table of devices that work with this driver */
+ static const struct usb_device_id id_table[] = {
+diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
+index f9a3f62..7c569f5 100644
+--- a/drivers/usb/musb/davinci.c
++++ b/drivers/usb/musb/davinci.c
+@@ -33,9 +33,6 @@
+ #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+
+-#include <mach/hardware.h>
+-#include <mach/memory.h>
+-#include <asm/gpio.h>
+ #include <mach/cputype.h>
+
+ #include <asm/mach-types.h>
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index a1a324b..a515237 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -39,6 +39,8 @@ static void cp210x_get_termios(struct tty_struct *,
+ struct usb_serial_port *port);
+ static void cp210x_get_termios_port(struct usb_serial_port *port,
+ unsigned int *cflagp, unsigned int *baudp);
++static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
++ struct ktermios *);
+ static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
+ struct ktermios*);
+ static int cp210x_tiocmget(struct tty_struct *);
+@@ -138,6 +140,7 @@ static const struct usb_device_id id_table[] = {
+ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
++ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
+ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
+ { } /* Terminating Entry */
+ };
+@@ -201,6 +204,8 @@ static struct usb_serial_driver cp210x_device = {
+ #define CP210X_EMBED_EVENTS 0x15
+ #define CP210X_GET_EVENTSTATE 0x16
+ #define CP210X_SET_CHARS 0x19
++#define CP210X_GET_BAUDRATE 0x1D
++#define CP210X_SET_BAUDRATE 0x1E
+
+ /* CP210X_IFC_ENABLE */
+ #define UART_ENABLE 0x0001
+@@ -354,8 +359,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port,
+ * Quantises the baud rate as per AN205 Table 1
+ */
+ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
+- if (baud <= 56) baud = 0;
+- else if (baud <= 300) baud = 300;
++ if (baud <= 300)
++ baud = 300;
+ else if (baud <= 600) baud = 600;
+ else if (baud <= 1200) baud = 1200;
+ else if (baud <= 1800) baud = 1800;
+@@ -383,17 +388,15 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
+ else if (baud <= 491520) baud = 460800;
+ else if (baud <= 567138) baud = 500000;
+ else if (baud <= 670254) baud = 576000;
+- else if (baud <= 1053257) baud = 921600;
+- else if (baud <= 1474560) baud = 1228800;
+- else if (baud <= 2457600) baud = 1843200;
+- else baud = 3686400;
++ else if (baud < 1000000)
++ baud = 921600;
++ else if (baud > 2000000)
++ baud = 2000000;
+ return baud;
+ }
+
+ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
+ {
+- int result;
+-
+ dbg("%s - port %d", __func__, port->number);
+
+ if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) {
+@@ -402,13 +405,14 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
+ return -EPROTO;
+ }
+
+- result = usb_serial_generic_open(tty, port);
+- if (result)
+- return result;
+-
+ /* Configure the termios structure */
+ cp210x_get_termios(tty, port);
+- return 0;
++
++ /* The baud rate must be initialised on cp2104 */
++ if (tty)
++ cp210x_change_speed(tty, port, NULL);
++
++ return usb_serial_generic_open(tty, port);
+ }
+
+ static void cp210x_close(struct usb_serial_port *port)
+@@ -460,10 +464,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
+
+ dbg("%s - port %d", __func__, port->number);
+
+- cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);
+- /* Convert to baudrate */
+- if (baud)
+- baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
++ cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4);
+
+ dbg("%s - baud rate = %d", __func__, baud);
+ *baudp = baud;
+@@ -577,11 +578,64 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
+ *cflagp = cflag;
+ }
+
++/*
++ * CP2101 supports the following baud rates:
++ *
++ * 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800,
++ * 38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600
++ *
++ * CP2102 and CP2103 support the following additional rates:
++ *
++ * 4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000,
++ * 576000
++ *
++ * The device will map a requested rate to a supported one, but the result
++ * of requests for rates greater than 1053257 is undefined (see AN205).
++ *
++ * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud,
++ * respectively, with an error less than 1%. The actual rates are determined
++ * by
++ *
++ * div = round(freq / (2 x prescale x request))
++ * actual = freq / (2 x prescale x div)
++ *
++ * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps
++ * or 1 otherwise.
++ * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1
++ * otherwise.
++ */
++static void cp210x_change_speed(struct tty_struct *tty,
++ struct usb_serial_port *port, struct ktermios *old_termios)
++{
++ u32 baud;
++
++ baud = tty->termios->c_ospeed;
++
++ /* This maps the requested rate to a rate valid on cp2102 or cp2103,
++ * or to an arbitrary rate in [1M,2M].
++ *
++ * NOTE: B0 is not implemented.
++ */
++ baud = cp210x_quantise_baudrate(baud);
++
++ dbg("%s - setting baud rate to %u", __func__, baud);
++ if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud,
++ sizeof(baud))) {
++ dev_warn(&port->dev, "failed to set baud rate to %u\n", baud);
++ if (old_termios)
++ baud = old_termios->c_ospeed;
++ else
++ baud = 9600;
++ }
++
++ tty_encode_baud_rate(tty, baud, baud);
++}
++
+ static void cp210x_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios)
+ {
+ unsigned int cflag, old_cflag;
+- unsigned int baud = 0, bits;
++ unsigned int bits;
+ unsigned int modem_ctl[4];
+
+ dbg("%s - port %d", __func__, port->number);
+@@ -592,20 +646,9 @@ static void cp210x_set_termios(struct tty_struct *tty,
+ tty->termios->c_cflag &= ~CMSPAR;
+ cflag = tty->termios->c_cflag;
+ old_cflag = old_termios->c_cflag;
+- baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty));
+-
+- /* If the baud rate is to be updated*/
+- if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
+- dbg("%s - Setting baud rate to %d baud", __func__,
+- baud);
+- if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
+- ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
+- dbg("Baud rate requested not supported by device");
+- baud = tty_termios_baud_rate(old_termios);
+- }
+- }
+- /* Report back the resulting baud rate */
+- tty_encode_baud_rate(tty, baud, baud);
++
++ if (tty->termios->c_ospeed != old_termios->c_ospeed)
++ cp210x_change_speed(tty, port, old_termios);
+
+ /* If the number of data bits is to be updated */
+ if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index ff3db5d..058b92c 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -797,6 +797,7 @@ static struct usb_device_id id_table_combined [] = {
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) },
+ { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
+ { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+@@ -805,6 +806,8 @@ static struct usb_device_id id_table_combined [] = {
+ { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+ { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
++ { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID),
++ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) },
+ { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) },
+@@ -841,6 +844,7 @@ static struct usb_device_id id_table_combined [] = {
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(ST_VID, ST_STMCLT1030_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk },
++ { USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
+ { }, /* Optional parameter entry */
+ { } /* Terminating entry */
+ };
+@@ -1333,8 +1337,7 @@ static int set_serial_info(struct tty_struct *tty,
+ goto check_and_exit;
+ }
+
+- if ((new_serial.baud_base != priv->baud_base) &&
+- (new_serial.baud_base < 9600)) {
++ if (new_serial.baud_base != priv->baud_base) {
+ mutex_unlock(&priv->cfg_lock);
+ return -EINVAL;
+ }
+@@ -1824,6 +1827,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
+
+ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
+ {
++ struct ktermios dummy;
+ struct usb_device *dev = port->serial->dev;
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int result;
+@@ -1842,8 +1846,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
+ This is same behaviour as serial.c/rs_open() - Kuba */
+
+ /* ftdi_set_termios will send usb control messages */
+- if (tty)
+- ftdi_set_termios(tty, port, tty->termios);
++ if (tty) {
++ memset(&dummy, 0, sizeof(dummy));
++ ftdi_set_termios(tty, port, &dummy);
++ }
+
+ /* Start reading from the device */
+ result = usb_serial_generic_open(tty, port);
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 055b64e..76d4f31 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -39,6 +39,13 @@
+ /* www.candapter.com Ewert Energy Systems CANdapter device */
+ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
+
++/*
++ * Texas Instruments XDS100v2 JTAG / BeagleBone A3
++ * http://processors.wiki.ti.com/index.php/XDS100
++ * http://beagleboard.org/bone
++ */
++#define TI_XDS100V2_PID 0xa6d0
++
+ #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */
+
+ /* US Interface Navigator (http://www.usinterface.com/) */
+@@ -525,6 +532,12 @@
+ #define ADI_GNICEPLUS_PID 0xF001
+
+ /*
++ * Hornby Elite
++ */
++#define HORNBY_VID 0x04D8
++#define HORNBY_ELITE_PID 0x000A
++
++/*
+ * RATOC REX-USB60F
+ */
+ #define RATOC_VENDOR_ID 0x0584
+@@ -1168,3 +1181,9 @@
+ */
+ /* TagTracer MIFARE*/
+ #define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0
++
++/*
++ * Rainforest Automation
++ */
++/* ZigBee controller */
++#define FTDI_RF_R106 0x8A28
+diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
+index 0aac00a..8a90d58 100644
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2677,15 +2677,7 @@ cleanup:
+
+ static void edge_disconnect(struct usb_serial *serial)
+ {
+- int i;
+- struct edgeport_port *edge_port;
+-
+ dbg("%s", __func__);
+-
+- for (i = 0; i < serial->num_ports; ++i) {
+- edge_port = usb_get_serial_port_data(serial->port[i]);
+- edge_remove_sysfs_attrs(edge_port->port);
+- }
+ }
+
+ static void edge_release(struct usb_serial *serial)
+@@ -2764,6 +2756,7 @@ static struct usb_serial_driver edgeport_1port_device = {
+ .disconnect = edge_disconnect,
+ .release = edge_release,
+ .port_probe = edge_create_sysfs_attrs,
++ .port_remove = edge_remove_sysfs_attrs,
+ .ioctl = edge_ioctl,
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+@@ -2795,6 +2788,7 @@ static struct usb_serial_driver edgeport_2port_device = {
+ .disconnect = edge_disconnect,
+ .release = edge_release,
+ .port_probe = edge_create_sysfs_attrs,
++ .port_remove = edge_remove_sysfs_attrs,
+ .ioctl = edge_ioctl,
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c96b6b6..2a9ed6e 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -480,6 +480,10 @@ static void option_instat_callback(struct urb *urb);
+ #define ZD_VENDOR_ID 0x0685
+ #define ZD_PRODUCT_7000 0x7000
+
++/* LG products */
++#define LG_VENDOR_ID 0x1004
++#define LG_PRODUCT_L02C 0x618f
++
+ /* some devices interfaces need special handling due to a number of reasons */
+ enum option_blacklist_reason {
+ OPTION_BLACKLIST_NONE = 0,
+@@ -1183,6 +1187,7 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
+ { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) },
++ { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
+diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c
+index 30b73e6..a348198 100644
+--- a/drivers/usb/serial/qcaux.c
++++ b/drivers/usb/serial/qcaux.c
+@@ -36,6 +36,7 @@
+ #define UTSTARCOM_PRODUCT_UM175_V1 0x3712
+ #define UTSTARCOM_PRODUCT_UM175_V2 0x3714
+ #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715
++#define PANTECH_PRODUCT_UML190_VZW 0x3716
+ #define PANTECH_PRODUCT_UML290_VZW 0x3718
+
+ /* CMOTECH devices */
+@@ -67,7 +68,11 @@ static struct usb_device_id id_table[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
+- { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) }, /* NMEA */
++ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) }, /* WMC */
++ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, /* DIAG */
+ { },
+ };
+ MODULE_DEVICE_TABLE(usb, id_table);
+diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
+index 0ce5f79..32c93d7 100644
+--- a/drivers/usb/storage/realtek_cr.c
++++ b/drivers/usb/storage/realtek_cr.c
+@@ -791,7 +791,7 @@ static void rts51x_suspend_timer_fn(unsigned long data)
+ rts51x_set_stat(chip, RTS51X_STAT_SS);
+ /* ignore mass storage interface's children */
+ pm_suspend_ignore_children(&us->pusb_intf->dev, true);
+- usb_autopm_put_interface(us->pusb_intf);
++ usb_autopm_put_interface_async(us->pusb_intf);
+ US_DEBUGP("%s: RTS51X_STAT_SS 01,"
+ "intf->pm_usage_cnt:%d, power.usage:%d\n",
+ __func__,
+diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
+index 2a83425..68b19ab 100644
+--- a/fs/ecryptfs/crypto.c
++++ b/fs/ecryptfs/crypto.c
+@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
+ (unsigned long long)(extent_base + extent_offset), rc);
+ goto out;
+ }
+- if (unlikely(ecryptfs_verbosity > 0)) {
+- ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
+- "with iv:\n");
+- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+- "encryption:\n");
+- ecryptfs_dump_hex((char *)
+- (page_address(page)
+- + (extent_offset * crypt_stat->extent_size)),
+- 8);
+- }
+ rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
+ page, (extent_offset
+ * crypt_stat->extent_size),
+@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
+ goto out;
+ }
+ rc = 0;
+- if (unlikely(ecryptfs_verbosity > 0)) {
+- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; "
+- "rc = [%d]\n",
+- (unsigned long long)(extent_base + extent_offset), rc);
+- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+- "encryption:\n");
+- ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
+- }
+ out:
+ return rc;
+ }
+@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
+ (unsigned long long)(extent_base + extent_offset), rc);
+ goto out;
+ }
+- if (unlikely(ecryptfs_verbosity > 0)) {
+- ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
+- "with iv:\n");
+- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
+- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
+- "decryption:\n");
+- ecryptfs_dump_hex((char *)
+- (page_address(enc_extent_page)
+- + (extent_offset * crypt_stat->extent_size)),
+- 8);
+- }
+ rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
+ (extent_offset
+ * crypt_stat->extent_size),
+@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
+ goto out;
+ }
+ rc = 0;
+- if (unlikely(ecryptfs_verbosity > 0)) {
+- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; "
+- "rc = [%d]\n",
+- (unsigned long long)(extent_base + extent_offset), rc);
+- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
+- "decryption:\n");
+- ecryptfs_dump_hex((char *)(page_address(page)
+- + (extent_offset
+- * crypt_stat->extent_size)), 8);
+- }
+ out:
+ return rc;
+ }
+@@ -1620,7 +1580,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
+ rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
+ if (rc) {
+ printk(KERN_DEBUG "Valid eCryptfs headers not found in "
+- "file header region or xattr region\n");
++ "file header region or xattr region, inode %lu\n",
++ ecryptfs_inode->i_ino);
+ rc = -EINVAL;
+ goto out;
+ }
+@@ -1629,7 +1590,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
+ ECRYPTFS_DONT_VALIDATE_HEADER_SIZE);
+ if (rc) {
+ printk(KERN_DEBUG "Valid eCryptfs headers not found in "
+- "file xattr region either\n");
++ "file xattr region either, inode %lu\n",
++ ecryptfs_inode->i_ino);
+ rc = -EINVAL;
+ }
+ if (crypt_stat->mount_crypt_stat->flags
+@@ -1640,7 +1602,8 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
+ "crypto metadata only in the extended attribute "
+ "region, but eCryptfs was mounted without "
+ "xattr support enabled. eCryptfs will not treat "
+- "this like an encrypted file.\n");
++ "this like an encrypted file, inode %lu\n",
++ ecryptfs_inode->i_ino);
+ rc = -EINVAL;
+ }
+ }
+diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
+index 32f90a3..d2039ca 100644
+--- a/fs/ecryptfs/inode.c
++++ b/fs/ecryptfs/inode.c
+@@ -841,18 +841,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
+ size_t num_zeros = (PAGE_CACHE_SIZE
+ - (ia->ia_size & ~PAGE_CACHE_MASK));
+
+-
+- /*
+- * XXX(truncate) this should really happen at the begginning
+- * of ->setattr. But the code is too messy to that as part
+- * of a larger patch. ecryptfs is also totally missing out
+- * on the inode_change_ok check at the beginning of
+- * ->setattr while would include this.
+- */
+- rc = inode_newsize_ok(inode, ia->ia_size);
+- if (rc)
+- goto out;
+-
+ if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
+ truncate_setsize(inode, ia->ia_size);
+ lower_ia->ia_size = ia->ia_size;
+@@ -902,6 +890,28 @@ out:
+ return rc;
+ }
+
++static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset)
++{
++ struct ecryptfs_crypt_stat *crypt_stat;
++ loff_t lower_oldsize, lower_newsize;
++
++ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
++ lower_oldsize = upper_size_to_lower_size(crypt_stat,
++ i_size_read(inode));
++ lower_newsize = upper_size_to_lower_size(crypt_stat, offset);
++ if (lower_newsize > lower_oldsize) {
++ /*
++ * The eCryptfs inode and the new *lower* size are mixed here
++ * because we may not have the lower i_mutex held and/or it may
++ * not be appropriate to call inode_newsize_ok() with inodes
++ * from other filesystems.
++ */
++ return inode_newsize_ok(inode, lower_newsize);
++ }
++
++ return 0;
++}
++
+ /**
+ * ecryptfs_truncate
+ * @dentry: The ecryptfs layer dentry
+@@ -918,6 +928,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+ struct iattr lower_ia = { .ia_valid = 0 };
+ int rc;
+
++ rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length);
++ if (rc)
++ return 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);
+@@ -997,6 +1011,16 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
+ }
+ }
+ mutex_unlock(&crypt_stat->cs_mutex);
++
++ rc = inode_change_ok(inode, ia);
++ if (rc)
++ goto out;
++ if (ia->ia_valid & ATTR_SIZE) {
++ rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size);
++ if (rc)
++ goto out;
++ }
++
+ if (S_ISREG(inode->i_mode)) {
+ rc = filemap_write_and_wait(inode->i_mapping);
+ if (rc)
+diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
+index 940a82e..0dc5a3d 100644
+--- a/fs/ecryptfs/miscdev.c
++++ b/fs/ecryptfs/miscdev.c
+@@ -409,11 +409,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
+ ssize_t sz = 0;
+ char *data;
+ uid_t euid = current_euid();
++ unsigned char packet_size_peek[3];
+ int rc;
+
+- if (count == 0)
++ if (count == 0) {
+ goto out;
++ } else if (count == (1 + 4)) {
++ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
++ goto memdup;
++ } else if (count < (1 + 4 + 1)
++ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
++ printk(KERN_WARNING "%s: Acceptable packet size range is "
++ "[%d-%lu], but amount of data written is [%zu].",
++ __func__, (1 + 4 + 1),
++ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
++ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
++ return -EINVAL;
++ }
++
++ if (copy_from_user(packet_size_peek, (buf + 1 + 4),
++ sizeof(packet_size_peek))) {
++ printk(KERN_WARNING "%s: Error while inspecting packet size\n",
++ __func__);
++ return -EFAULT;
++ }
++
++ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
++ &packet_size_length);
++ if (rc) {
++ printk(KERN_WARNING "%s: Error parsing packet length; "
++ "rc = [%d]\n", __func__, rc);
++ return rc;
++ }
++
++ if ((1 + 4 + packet_size_length + packet_size) != count) {
++ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
++ packet_size);
++ return -EINVAL;
++ }
+
++memdup:
+ data = memdup_user(buf, count);
+ if (IS_ERR(data)) {
+ printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
+@@ -435,23 +471,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
+ }
+ memcpy(&counter_nbo, &data[i], 4);
+ seq = be32_to_cpu(counter_nbo);
+- i += 4;
+- rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
+- &packet_size_length);
+- if (rc) {
+- printk(KERN_WARNING "%s: Error parsing packet length; "
+- "rc = [%d]\n", __func__, rc);
+- goto out_free;
+- }
+- i += packet_size_length;
+- if ((1 + 4 + packet_size_length + packet_size) != count) {
+- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
+- " + packet_size([%zd]))([%zd]) != "
+- "count([%zd]). Invalid packet format.\n",
+- __func__, packet_size_length, packet_size,
+- (1 + packet_size_length + packet_size), count);
+- goto out_free;
+- }
++ i += 4 + packet_size_length;
+ rc = ecryptfs_miscdev_response(&data[i], packet_size,
+ euid, current_user_ns(),
+ task_pid(current), seq);
+diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
+index 3745f7c..54eb14c 100644
+--- a/fs/ecryptfs/read_write.c
++++ b/fs/ecryptfs/read_write.c
+@@ -132,6 +132,11 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
+ size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
+ size_t total_remaining_bytes = ((offset + size) - pos);
+
++ if (fatal_signal_pending(current)) {
++ rc = -EINTR;
++ break;
++ }
++
+ if (num_bytes > total_remaining_bytes)
+ num_bytes = total_remaining_bytes;
+ if (pos < offset) {
+@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
+ }
+ pos += num_bytes;
+ }
+- if ((offset + size) > ecryptfs_file_size) {
+- i_size_write(ecryptfs_inode, (offset + size));
++ if (pos > ecryptfs_file_size) {
++ i_size_write(ecryptfs_inode, pos);
+ if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
+- rc = ecryptfs_write_inode_size_to_metadata(
++ int rc2;
++
++ rc2 = ecryptfs_write_inode_size_to_metadata(
+ ecryptfs_inode);
+- if (rc) {
++ if (rc2) {
+ printk(KERN_ERR "Problem with "
+ "ecryptfs_write_inode_size_to_metadata; "
+- "rc = [%d]\n", rc);
++ "rc = [%d]\n", rc2);
++ if (!rc)
++ rc = rc2;
+ goto out;
+ }
+ }
+diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
+index f94fc48..5c93ffc 100644
+--- a/fs/jbd/checkpoint.c
++++ b/fs/jbd/checkpoint.c
+@@ -453,8 +453,6 @@ out:
+ *
+ * Return <0 on error, 0 on success, 1 if there was nothing to clean up.
+ *
+- * Called with the journal lock held.
+- *
+ * This is the only part of the journaling code which really needs to be
+ * aware of transaction aborts. Checkpointing involves writing to the
+ * main filesystem area rather than to the journal, so it can proceed
+@@ -472,13 +470,14 @@ int cleanup_journal_tail(journal_t *journal)
+ if (is_journal_aborted(journal))
+ return 1;
+
+- /* OK, work out the oldest transaction remaining in the log, and
++ /*
++ * OK, work out the oldest transaction remaining in the log, and
+ * the log block it starts at.
+ *
+ * If the log is now empty, we need to work out which is the
+ * next transaction ID we will write, and where it will
+- * start. */
+-
++ * start.
++ */
+ spin_lock(&journal->j_state_lock);
+ spin_lock(&journal->j_list_lock);
+ transaction = journal->j_checkpoint_transactions;
+@@ -504,7 +503,25 @@ int cleanup_journal_tail(journal_t *journal)
+ spin_unlock(&journal->j_state_lock);
+ return 1;
+ }
++ spin_unlock(&journal->j_state_lock);
++
++ /*
++ * We need to make sure that any blocks that were recently written out
++ * --- perhaps by log_do_checkpoint() --- are flushed out before we
++ * drop the transactions from the journal. It's unlikely this will be
++ * necessary, especially with an appropriately sized journal, but we
++ * need this to guarantee correctness. Fortunately
++ * cleanup_journal_tail() doesn't get called all that often.
++ */
++ if (journal->j_flags & JFS_BARRIER)
++ blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+
++ spin_lock(&journal->j_state_lock);
++ if (!tid_gt(first_tid, journal->j_tail_sequence)) {
++ spin_unlock(&journal->j_state_lock);
++ /* Someone else cleaned up journal so return 0 */
++ return 0;
++ }
+ /* OK, update the superblock to recover the freed space.
+ * Physical blocks come first: have we wrapped beyond the end of
+ * the log? */
+diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
+index 5b43e96..008bf06 100644
+--- a/fs/jbd/recovery.c
++++ b/fs/jbd/recovery.c
+@@ -20,6 +20,7 @@
+ #include <linux/fs.h>
+ #include <linux/jbd.h>
+ #include <linux/errno.h>
++#include <linux/blkdev.h>
+ #endif
+
+ /*
+@@ -263,6 +264,9 @@ int journal_recover(journal_t *journal)
+ err2 = sync_blockdev(journal->j_fs_dev);
+ if (!err)
+ err = err2;
++ /* Flush disk caches to get replayed data on the permanent storage */
++ if (journal->j_flags & JFS_BARRIER)
++ blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+
+ return err;
+ }
+diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
+index d4e6080b..779789a 100644
+--- a/fs/sysfs/file.c
++++ b/fs/sysfs/file.c
+@@ -493,6 +493,12 @@ int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
+ const void *ns = NULL;
+ int err;
+
++ if (!dir_sd) {
++ WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n",
++ kobject_name(kobj));
++ return -ENOENT;
++ }
++
+ err = 0;
+ if (!sysfs_ns_type(dir_sd))
+ goto out;
+diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
+index c81b22f..deb804b 100644
+--- a/fs/sysfs/inode.c
++++ b/fs/sysfs/inode.c
+@@ -318,8 +318,11 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const cha
+ struct sysfs_addrm_cxt acxt;
+ struct sysfs_dirent *sd;
+
+- if (!dir_sd)
++ if (!dir_sd) {
++ WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n",
++ name);
+ return -ENOENT;
++ }
+
+ sysfs_addrm_start(&acxt, dir_sd);
+
+diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
+index ce9268a..ee98d0b 100644
+--- a/fs/xfs/xfs_vnodeops.c
++++ b/fs/xfs/xfs_vnodeops.c
+@@ -131,7 +131,8 @@ xfs_readlink(
+ __func__, (unsigned long long) ip->i_ino,
+ (long long) pathlen);
+ ASSERT(0);
+- return XFS_ERROR(EFSCORRUPTED);
++ error = XFS_ERROR(EFSCORRUPTED);
++ goto out;
+ }
+
+
+diff --git a/include/drm/drmP.h b/include/drm/drmP.h
+index 1f9e951..bf4b2dc 100644
+--- a/include/drm/drmP.h
++++ b/include/drm/drmP.h
+@@ -1328,6 +1328,7 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+ extern int drm_authmagic(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
++extern int drm_remove_magic(struct drm_master *master, drm_magic_t magic);
+
+ /* Cache management (drm_cache.c) */
+ void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h
+index 3419bf5..d55f434 100644
+--- a/include/net/netns/generic.h
++++ b/include/net/netns/generic.h
+@@ -41,6 +41,7 @@ static inline void *net_generic(const struct net *net, int id)
+ ptr = ng->ptr[id - 1];
+ rcu_read_unlock();
+
++ BUG_ON(!ptr);
+ return ptr;
+ }
+ #endif
+diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
+index f1fa1f6..68223e4 100644
+--- a/net/caif/caif_dev.c
++++ b/net/caif/caif_dev.c
+@@ -53,7 +53,6 @@ struct cfcnfg *get_cfcnfg(struct net *net)
+ struct caif_net *caifn;
+ BUG_ON(!net);
+ caifn = net_generic(net, caif_net_id);
+- BUG_ON(!caifn);
+ return caifn->cfg;
+ }
+ EXPORT_SYMBOL(get_cfcnfg);
+@@ -63,7 +62,6 @@ static struct caif_device_entry_list *caif_device_list(struct net *net)
+ struct caif_net *caifn;
+ BUG_ON(!net);
+ caifn = net_generic(net, caif_net_id);
+- BUG_ON(!caifn);
+ return &caifn->caifdevs;
+ }
+
+@@ -92,7 +90,6 @@ static struct caif_device_entry *caif_device_alloc(struct net_device *dev)
+ struct caif_device_entry *caifd;
+
+ caifdevs = caif_device_list(dev_net(dev));
+- BUG_ON(!caifdevs);
+
+ caifd = kzalloc(sizeof(*caifd), GFP_KERNEL);
+ if (!caifd)
+@@ -112,7 +109,7 @@ static struct caif_device_entry *caif_get(struct net_device *dev)
+ struct caif_device_entry_list *caifdevs =
+ caif_device_list(dev_net(dev));
+ struct caif_device_entry *caifd;
+- BUG_ON(!caifdevs);
++
+ list_for_each_entry_rcu(caifd, &caifdevs->list, list) {
+ if (caifd->netdev == dev)
+ return caifd;
+@@ -353,7 +350,7 @@ static struct notifier_block caif_device_notifier = {
+ static int caif_init_net(struct net *net)
+ {
+ struct caif_net *caifn = net_generic(net, caif_net_id);
+- BUG_ON(!caifn);
++
+ INIT_LIST_HEAD(&caifn->caifdevs.list);
+ mutex_init(&caifn->caifdevs.lock);
+
+@@ -418,7 +415,7 @@ static int __init caif_device_init(void)
+ {
+ int result;
+
+- result = register_pernet_device(&caif_net_ops);
++ result = register_pernet_subsys(&caif_net_ops);
+
+ if (result)
+ return result;
+@@ -431,7 +428,7 @@ static int __init caif_device_init(void)
+
+ static void __exit caif_device_exit(void)
+ {
+- unregister_pernet_device(&caif_net_ops);
++ unregister_pernet_subsys(&caif_net_ops);
+ unregister_netdevice_notifier(&caif_device_notifier);
+ dev_remove_pack(&caif_packet_type);
+ }
+diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
+index 00523ec..86ff37c 100644
+--- a/net/caif/cfcnfg.c
++++ b/net/caif/cfcnfg.c
+@@ -309,7 +309,6 @@ int caif_connect_client(struct net *net, struct caif_connect_request *conn_req,
+ int err;
+ struct cfctrl_link_param param;
+ struct cfcnfg *cfg = get_cfcnfg(net);
+- caif_assert(cfg != NULL);
+
+ rcu_read_lock();
+ err = caif_connect_req_to_link_param(cfg, conn_req, &param);
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index 385aefe..0329404 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -990,9 +990,9 @@ static ssize_t store_xps_map(struct netdev_queue *queue,
+ nonempty = 1;
+ }
+
+- if (nonempty)
+- RCU_INIT_POINTER(dev->xps_maps, new_dev_maps);
+- else {
++ if (nonempty) {
++ rcu_assign_pointer(dev->xps_maps, new_dev_maps);
++ } else {
+ kfree(new_dev_maps);
+ RCU_INIT_POINTER(dev->xps_maps, NULL);
+ }
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index aefcd7a..0e950fd 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -30,6 +30,20 @@ EXPORT_SYMBOL(init_net);
+
+ #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */
+
++static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS;
++
++static struct net_generic *net_alloc_generic(void)
++{
++ struct net_generic *ng;
++ size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]);
++
++ ng = kzalloc(generic_size, GFP_KERNEL);
++ if (ng)
++ ng->len = max_gen_ptrs;
++
++ return ng;
++}
++
+ static int net_assign_generic(struct net *net, int id, void *data)
+ {
+ struct net_generic *ng, *old_ng;
+@@ -43,8 +57,7 @@ static int net_assign_generic(struct net *net, int id, void *data)
+ if (old_ng->len >= id)
+ goto assign;
+
+- ng = kzalloc(sizeof(struct net_generic) +
+- id * sizeof(void *), GFP_KERNEL);
++ ng = net_alloc_generic();
+ if (ng == NULL)
+ return -ENOMEM;
+
+@@ -59,7 +72,6 @@ static int net_assign_generic(struct net *net, int id, void *data)
+ * the old copy for kfree after a grace period.
+ */
+
+- ng->len = id;
+ memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
+
+ rcu_assign_pointer(net->gen, ng);
+@@ -161,18 +173,6 @@ out_undo:
+ goto out;
+ }
+
+-static struct net_generic *net_alloc_generic(void)
+-{
+- struct net_generic *ng;
+- size_t generic_size = sizeof(struct net_generic) +
+- INITIAL_NET_GEN_PTRS * sizeof(void *);
+-
+- ng = kzalloc(generic_size, GFP_KERNEL);
+- if (ng)
+- ng->len = INITIAL_NET_GEN_PTRS;
+-
+- return ng;
+-}
+
+ #ifdef CONFIG_NET_NS
+ static struct kmem_cache *net_cachep;
+@@ -483,6 +483,7 @@ again:
+ }
+ return error;
+ }
++ max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id);
+ }
+ error = __register_pernet_operations(list, ops);
+ if (error) {
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index cf64c1f..5d4d896 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -763,7 +763,7 @@ int __netpoll_setup(struct netpoll *np)
+ }
+
+ /* last thing to do is link it to the net device structure */
+- RCU_INIT_POINTER(ndev->npinfo, npinfo);
++ rcu_assign_pointer(ndev->npinfo, npinfo);
+
+ return 0;
+
+diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
+index 2ab16e1..74d321a 100644
+--- a/net/decnet/dn_dev.c
++++ b/net/decnet/dn_dev.c
+@@ -388,7 +388,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
+ }
+
+ ifa->ifa_next = dn_db->ifa_list;
+- RCU_INIT_POINTER(dn_db->ifa_list, ifa);
++ rcu_assign_pointer(dn_db->ifa_list, ifa);
+
+ dn_ifaddr_notify(RTM_NEWADDR, ifa);
+ blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
+@@ -1093,7 +1093,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err)
+
+ memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms));
+
+- RCU_INIT_POINTER(dev->dn_ptr, dn_db);
++ rcu_assign_pointer(dev->dn_ptr, dn_db);
+ dn_db->dev = dev;
+ init_timer(&dn_db->timer);
+
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index 65f01dc..e41c40f 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -258,7 +258,7 @@ static struct in_device *inetdev_init(struct net_device *dev)
+ ip_mc_up(in_dev);
+
+ /* we can receive as soon as ip_ptr is set -- do this last */
+- RCU_INIT_POINTER(dev->ip_ptr, in_dev);
++ rcu_assign_pointer(dev->ip_ptr, in_dev);
+ out:
+ return in_dev;
+ out_kfree:
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 37b6711..3ce23f9 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -205,7 +205,7 @@ static inline struct tnode *node_parent_rcu(const struct rt_trie_node *node)
+ return (struct tnode *)(parent & ~NODE_TYPE_MASK);
+ }
+
+-/* Same as RCU_INIT_POINTER
++/* Same as rcu_assign_pointer
+ * but that macro() assumes that value is a pointer.
+ */
+ static inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr)
+@@ -529,7 +529,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *
+ if (n)
+ node_set_parent(n, tn);
+
+- RCU_INIT_POINTER(tn->child[i], n);
++ rcu_assign_pointer(tn->child[i], n);
+ }
+
+ #define MAX_WORK 10
+@@ -1015,7 +1015,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn)
+
+ tp = node_parent((struct rt_trie_node *) tn);
+ if (!tp)
+- RCU_INIT_POINTER(t->trie, (struct rt_trie_node *)tn);
++ rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
+
+ tnode_free_flush();
+ if (!tp)
+@@ -1027,7 +1027,7 @@ static void trie_rebalance(struct trie *t, struct tnode *tn)
+ if (IS_TNODE(tn))
+ tn = (struct tnode *)resize(t, (struct tnode *)tn);
+
+- RCU_INIT_POINTER(t->trie, (struct rt_trie_node *)tn);
++ rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
+ tnode_free_flush();
+ }
+
+@@ -1164,7 +1164,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
+ put_child(t, (struct tnode *)tp, cindex,
+ (struct rt_trie_node *)tn);
+ } else {
+- RCU_INIT_POINTER(t->trie, (struct rt_trie_node *)tn);
++ rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
+ tp = tn;
+ }
+ }
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index c3cc64c..c8989a7 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -1244,7 +1244,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
+
+ im->next_rcu = in_dev->mc_list;
+ in_dev->mc_count++;
+- RCU_INIT_POINTER(in_dev->mc_list, im);
++ rcu_assign_pointer(in_dev->mc_list, im);
+
+ #ifdef CONFIG_IP_MULTICAST
+ igmpv3_del_delrec(in_dev, im->multiaddr);
+@@ -1816,7 +1816,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
+ iml->next_rcu = inet->mc_list;
+ iml->sflist = NULL;
+ iml->sfmode = MCAST_EXCLUDE;
+- RCU_INIT_POINTER(inet->mc_list, iml);
++ rcu_assign_pointer(inet->mc_list, iml);
+ ip_mc_inc_group(in_dev, addr);
+ err = 0;
+ done:
+@@ -2003,7 +2003,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
+ atomic_sub(IP_SFLSIZE(psl->sl_max), &sk->sk_omem_alloc);
+ kfree_rcu(psl, rcu);
+ }
+- RCU_INIT_POINTER(pmc->sflist, newpsl);
++ rcu_assign_pointer(pmc->sflist, newpsl);
+ psl = newpsl;
+ }
+ rv = 1; /* > 0 for insert logic below if sl_count is 0 */
+@@ -2106,7 +2106,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
+ } else
+ (void) ip_mc_del_src(in_dev, &msf->imsf_multiaddr, pmc->sfmode,
+ 0, NULL, 0);
+- RCU_INIT_POINTER(pmc->sflist, newpsl);
++ rcu_assign_pointer(pmc->sflist, newpsl);
+ pmc->sfmode = msf->imsf_fmode;
+ err = 0;
+ done:
+diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
+index 0b2e732..17ad951 100644
+--- a/net/ipv4/ipip.c
++++ b/net/ipv4/ipip.c
+@@ -231,7 +231,7 @@ static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t)
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+- RCU_INIT_POINTER(*tp, t->next);
++ rcu_assign_pointer(*tp, t->next);
+ break;
+ }
+ }
+@@ -241,8 +241,8 @@ static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t)
+ {
+ struct ip_tunnel __rcu **tp = ipip_bucket(ipn, t);
+
+- RCU_INIT_POINTER(t->next, rtnl_dereference(*tp));
+- RCU_INIT_POINTER(*tp, t);
++ rcu_assign_pointer(t->next, rtnl_dereference(*tp));
++ rcu_assign_pointer(*tp, t);
+ }
+
+ static struct ip_tunnel * ipip_tunnel_locate(struct net *net,
+@@ -792,7 +792,7 @@ static int __net_init ipip_fb_tunnel_init(struct net_device *dev)
+ return -ENOMEM;
+
+ dev_hold(dev);
+- RCU_INIT_POINTER(ipn->tunnels_wc[0], tunnel);
++ rcu_assign_pointer(ipn->tunnels_wc[0], tunnel);
+ return 0;
+ }
+
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 76a7f07..d2aae27 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -1225,7 +1225,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi
+
+ ret = ip_ra_control(sk, 1, mrtsock_destruct);
+ if (ret == 0) {
+- RCU_INIT_POINTER(mrt->mroute_sk, sk);
++ rcu_assign_pointer(mrt->mroute_sk, sk);
+ IPV4_DEVCONF_ALL(net, MC_FORWARDING)++;
+ }
+ rtnl_unlock();
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index a9db4b1..c89e354 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -630,7 +630,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
+ arg.iov[0].iov_len = sizeof(rep.th);
+
+ #ifdef CONFIG_TCP_MD5SIG
+- key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr) : NULL;
++ key = sk ? tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->saddr) : NULL;
+ if (key) {
+ rep.opt[0] = htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 63170e2..097e0c7 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1138,11 +1138,9 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
+ sk_mem_uncharge(sk, len);
+ sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
+
+- /* Any change of skb->len requires recalculation of tso
+- * factor and mss.
+- */
++ /* Any change of skb->len requires recalculation of tso factor. */
+ if (tcp_skb_pcount(skb) > 1)
+- tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk));
++ tcp_set_skb_tso_segs(sk, skb, tcp_skb_mss(skb));
+
+ return 0;
+ }
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 36806de..836c4ea 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -429,7 +429,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
+ ndev->tstamp = jiffies;
+ addrconf_sysctl_register(ndev);
+ /* protected by rtnl_lock */
+- RCU_INIT_POINTER(dev->ip6_ptr, ndev);
++ rcu_assign_pointer(dev->ip6_ptr, ndev);
+
+ /* Join all-node multicast group */
+ ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes);
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 4e2e9ff..d19f499 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -218,8 +218,8 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
+ {
+ struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms);
+
+- RCU_INIT_POINTER(t->next , rtnl_dereference(*tp));
+- RCU_INIT_POINTER(*tp, t);
++ rcu_assign_pointer(t->next , rtnl_dereference(*tp));
++ rcu_assign_pointer(*tp, t);
+ }
+
+ /**
+@@ -237,7 +237,7 @@ ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t)
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+- RCU_INIT_POINTER(*tp, t->next);
++ rcu_assign_pointer(*tp, t->next);
+ break;
+ }
+ }
+@@ -1450,7 +1450,7 @@ static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev)
+
+ t->parms.proto = IPPROTO_IPV6;
+ dev_hold(dev);
+- RCU_INIT_POINTER(ip6n->tnls_wc[0], t);
++ rcu_assign_pointer(ip6n->tnls_wc[0], t);
+ return 0;
+ }
+
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index 331af3b..361ebf3 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -131,7 +131,7 @@ static mh_filter_t __rcu *mh_filter __read_mostly;
+
+ int rawv6_mh_filter_register(mh_filter_t filter)
+ {
+- RCU_INIT_POINTER(mh_filter, filter);
++ rcu_assign_pointer(mh_filter, filter);
+ return 0;
+ }
+ EXPORT_SYMBOL(rawv6_mh_filter_register);
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 96f3623..72a939d 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -182,7 +182,7 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
+ (iter = rtnl_dereference(*tp)) != NULL;
+ tp = &iter->next) {
+ if (t == iter) {
+- RCU_INIT_POINTER(*tp, t->next);
++ rcu_assign_pointer(*tp, t->next);
+ break;
+ }
+ }
+@@ -192,8 +192,8 @@ static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t)
+ {
+ struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t);
+
+- RCU_INIT_POINTER(t->next, rtnl_dereference(*tp));
+- RCU_INIT_POINTER(*tp, t);
++ rcu_assign_pointer(t->next, rtnl_dereference(*tp));
++ rcu_assign_pointer(*tp, t);
+ }
+
+ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
+@@ -393,7 +393,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
+ p->addr = a->addr;
+ p->flags = a->flags;
+ t->prl_count++;
+- RCU_INIT_POINTER(t->prl, p);
++ rcu_assign_pointer(t->prl, p);
+ out:
+ return err;
+ }
+@@ -1177,7 +1177,7 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
+ if (!dev->tstats)
+ return -ENOMEM;
+ dev_hold(dev);
+- RCU_INIT_POINTER(sitn->tunnels_wc[0], tunnel);
++ rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
+ return 0;
+ }
+
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 2dea4bb..b859e4a 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1084,7 +1084,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
+
+ #ifdef CONFIG_TCP_MD5SIG
+ if (sk)
+- key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
++ key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr);
+ #endif
+
+ if (th->ack)
+diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
+index d21e7eb..55670ec 100644
+--- a/net/l2tp/l2tp_ip.c
++++ b/net/l2tp/l2tp_ip.c
+@@ -393,11 +393,6 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb)
+ {
+ int rc;
+
+- if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
+- goto drop;
+-
+- nf_reset(skb);
+-
+ /* Charge it to the socket, dropping if the queue is full. */
+ rc = sock_queue_rcv_skb(sk, skb);
+ if (rc < 0)
+diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
+index 93b2434..41c2310 100644
+--- a/net/mac80211/agg-rx.c
++++ b/net/mac80211/agg-rx.c
+@@ -326,7 +326,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
+ status = WLAN_STATUS_SUCCESS;
+
+ /* activate it for RX */
+- RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
++ rcu_assign_pointer(sta->ampdu_mlme.tid_rx[tid], tid_agg_rx);
+
+ if (timeout)
+ mod_timer(&tid_agg_rx->session_timer, TU_TO_EXP_TIME(timeout));
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index d06c65f..11cee76 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -575,7 +575,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
+
+ sdata->vif.bss_conf.dtim_period = new->dtim_period;
+
+- RCU_INIT_POINTER(sdata->u.ap.beacon, new);
++ rcu_assign_pointer(sdata->u.ap.beacon, new);
+
+ synchronize_rcu();
+
+@@ -922,7 +922,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
+ return -EBUSY;
+ }
+
+- RCU_INIT_POINTER(vlansdata->u.vlan.sta, sta);
++ rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
+ }
+
+ sta->sdata = vlansdata;
+diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
+index ede9a8b..3ece106 100644
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -184,7 +184,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+ *pos++ = 0; /* U-APSD no in use */
+ }
+
+- RCU_INIT_POINTER(ifibss->presp, skb);
++ rcu_assign_pointer(ifibss->presp, skb);
+
+ sdata->vif.bss_conf.beacon_int = beacon_int;
+ sdata->vif.bss_conf.basic_rates = basic_rates;
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index b1b1bb3..9da8626 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2719,7 +2719,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
+ {
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+- struct ieee80211_work *wk;
+ u8 bssid[ETH_ALEN];
+ bool assoc_bss = false;
+
+@@ -2732,30 +2731,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
+ assoc_bss = true;
+ } else {
+ bool not_auth_yet = false;
++ struct ieee80211_work *tmp, *wk = NULL;
+
+ mutex_unlock(&ifmgd->mtx);
+
+ mutex_lock(&local->mtx);
+- list_for_each_entry(wk, &local->work_list, list) {
+- if (wk->sdata != sdata)
++ list_for_each_entry(tmp, &local->work_list, list) {
++ if (tmp->sdata != sdata)
+ continue;
+
+- if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
+- wk->type != IEEE80211_WORK_AUTH &&
+- wk->type != IEEE80211_WORK_ASSOC &&
+- wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
++ if (tmp->type != IEEE80211_WORK_DIRECT_PROBE &&
++ tmp->type != IEEE80211_WORK_AUTH &&
++ tmp->type != IEEE80211_WORK_ASSOC &&
++ tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
+ continue;
+
+- if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
++ if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
+ continue;
+
+- not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE;
+- list_del_rcu(&wk->list);
+- free_work(wk);
++ not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
++ list_del_rcu(&tmp->list);
++ synchronize_rcu();
++ wk = tmp;
+ break;
+ }
+ mutex_unlock(&local->mtx);
+
++ if (wk && wk->type == IEEE80211_WORK_ASSOC) {
++ /* clean up dummy sta & TX sync */
++ sta_info_destroy_addr(wk->sdata, wk->filter_ta);
++ if (wk->assoc.synced)
++ drv_finish_tx_sync(local, wk->sdata,
++ wk->filter_ta,
++ IEEE80211_TX_SYNC_ASSOC);
++ } else if (wk && wk->type == IEEE80211_WORK_AUTH) {
++ if (wk->probe_auth.synced)
++ drv_finish_tx_sync(local, wk->sdata,
++ wk->filter_ta,
++ IEEE80211_TX_SYNC_AUTH);
++ }
++ kfree(wk);
++
+ /*
+ * If somebody requests authentication and we haven't
+ * sent out an auth frame yet there's no need to send
+diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
+index 8eaa746..1fdd8ff 100644
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -73,7 +73,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
+ if (!s)
+ return -ENOENT;
+ if (s == sta) {
+- RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)],
++ rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
+ s->hnext);
+ return 0;
+ }
+@@ -83,7 +83,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
+ s = rcu_dereference_protected(s->hnext,
+ lockdep_is_held(&local->sta_lock));
+ if (rcu_access_pointer(s->hnext)) {
+- RCU_INIT_POINTER(s->hnext, sta->hnext);
++ rcu_assign_pointer(s->hnext, sta->hnext);
+ return 0;
+ }
+
+@@ -232,7 +232,7 @@ static void sta_info_hash_add(struct ieee80211_local *local,
+ struct sta_info *sta)
+ {
+ sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)];
+- RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
++ rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
+ }
+
+ static void sta_unblock(struct work_struct *wk)
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index 7202b06..1d15193 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -776,7 +776,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
+ if (exp->helper) {
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
+ if (help)
+- RCU_INIT_POINTER(help->helper, exp->helper);
++ rcu_assign_pointer(help->helper, exp->helper);
+ }
+
+ #ifdef CONFIG_NF_CONNTRACK_MARK
+diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
+index b62c414..14af632 100644
+--- a/net/netfilter/nf_conntrack_ecache.c
++++ b/net/netfilter/nf_conntrack_ecache.c
+@@ -91,7 +91,7 @@ int nf_conntrack_register_notifier(struct net *net,
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+- RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, new);
++ rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
+ mutex_unlock(&nf_ct_ecache_mutex);
+ return ret;
+
+@@ -128,7 +128,7 @@ int nf_ct_expect_register_notifier(struct net *net,
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+- RCU_INIT_POINTER(net->ct.nf_expect_event_cb, new);
++ rcu_assign_pointer(net->ct.nf_expect_event_cb, new);
+ mutex_unlock(&nf_ct_ecache_mutex);
+ return ret;
+
+diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
+index 4605c94..641ff5f 100644
+--- a/net/netfilter/nf_conntrack_extend.c
++++ b/net/netfilter/nf_conntrack_extend.c
+@@ -169,7 +169,7 @@ int nf_ct_extend_register(struct nf_ct_ext_type *type)
+ before updating alloc_size */
+ type->alloc_size = ALIGN(sizeof(struct nf_ct_ext), type->align)
+ + type->len;
+- RCU_INIT_POINTER(nf_ct_ext_types[type->id], type);
++ rcu_assign_pointer(nf_ct_ext_types[type->id], type);
+ update_alloc_size(type);
+ out:
+ mutex_unlock(&nf_ct_ext_type_mutex);
+diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
+index 93c4bdb..bbe23ba 100644
+--- a/net/netfilter/nf_conntrack_helper.c
++++ b/net/netfilter/nf_conntrack_helper.c
+@@ -145,7 +145,7 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
+ memset(&help->help, 0, sizeof(help->help));
+ }
+
+- RCU_INIT_POINTER(help->helper, helper);
++ rcu_assign_pointer(help->helper, helper);
+ out:
+ return ret;
+ }
+diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
+index 257e772..782cdcd 100644
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -1163,7 +1163,7 @@ ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
+ return -EOPNOTSUPP;
+ }
+
+- RCU_INIT_POINTER(help->helper, helper);
++ rcu_assign_pointer(help->helper, helper);
+
+ return 0;
+ }
+diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
+index ce0c406..957374a 100644
+--- a/net/netfilter/nf_log.c
++++ b/net/netfilter/nf_log.c
+@@ -55,7 +55,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
+ llog = rcu_dereference_protected(nf_loggers[pf],
+ lockdep_is_held(&nf_log_mutex));
+ if (llog == NULL)
+- RCU_INIT_POINTER(nf_loggers[pf], logger);
++ rcu_assign_pointer(nf_loggers[pf], logger);
+ }
+
+ mutex_unlock(&nf_log_mutex);
+@@ -92,7 +92,7 @@ int nf_log_bind_pf(u_int8_t pf, const struct nf_logger *logger)
+ mutex_unlock(&nf_log_mutex);
+ return -ENOENT;
+ }
+- RCU_INIT_POINTER(nf_loggers[pf], logger);
++ rcu_assign_pointer(nf_loggers[pf], logger);
+ mutex_unlock(&nf_log_mutex);
+ return 0;
+ }
+@@ -250,7 +250,7 @@ static int nf_log_proc_dostring(ctl_table *table, int write,
+ mutex_unlock(&nf_log_mutex);
+ return -ENOENT;
+ }
+- RCU_INIT_POINTER(nf_loggers[tindex], logger);
++ rcu_assign_pointer(nf_loggers[tindex], logger);
+ mutex_unlock(&nf_log_mutex);
+ } else {
+ mutex_lock(&nf_log_mutex);
+diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
+index 99ffd28..b3a7db6 100644
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -40,7 +40,7 @@ int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
+ else if (old)
+ ret = -EBUSY;
+ else {
+- RCU_INIT_POINTER(queue_handler[pf], qh);
++ rcu_assign_pointer(queue_handler[pf], qh);
+ ret = 0;
+ }
+ mutex_unlock(&queue_handler_mutex);
+diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
+index c879c1a..b4f8d84 100644
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -59,7 +59,7 @@ int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
+ nfnl_unlock();
+ return -EBUSY;
+ }
+- RCU_INIT_POINTER(subsys_table[n->subsys_id], n);
++ rcu_assign_pointer(subsys_table[n->subsys_id], n);
+ nfnl_unlock();
+
+ return 0;
+@@ -210,7 +210,7 @@ static int __net_init nfnetlink_net_init(struct net *net)
+ if (!nfnl)
+ return -ENOMEM;
+ net->nfnl_stash = nfnl;
+- RCU_INIT_POINTER(net->nfnl, nfnl);
++ rcu_assign_pointer(net->nfnl, nfnl);
+ return 0;
+ }
+
+diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
+index 3f905e5..e5330ed 100644
+--- a/net/netlabel/netlabel_domainhash.c
++++ b/net/netlabel/netlabel_domainhash.c
+@@ -282,7 +282,7 @@ int __init netlbl_domhsh_init(u32 size)
+ INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);
+
+ spin_lock(&netlbl_domhsh_lock);
+- RCU_INIT_POINTER(netlbl_domhsh, hsh_tbl);
++ rcu_assign_pointer(netlbl_domhsh, hsh_tbl);
+ spin_unlock(&netlbl_domhsh_lock);
+
+ return 0;
+@@ -330,7 +330,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
+ &rcu_dereference(netlbl_domhsh)->tbl[bkt]);
+ } else {
+ INIT_LIST_HEAD(&entry->list);
+- RCU_INIT_POINTER(netlbl_domhsh_def, entry);
++ rcu_assign_pointer(netlbl_domhsh_def, entry);
+ }
+
+ if (entry->type == NETLBL_NLTYPE_ADDRSELECT) {
+diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
+index e251c2c..d463f5a 100644
+--- a/net/netlabel/netlabel_unlabeled.c
++++ b/net/netlabel/netlabel_unlabeled.c
+@@ -354,7 +354,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
+ INIT_LIST_HEAD(&iface->list);
+ if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
+ goto add_iface_failure;
+- RCU_INIT_POINTER(netlbl_unlhsh_def, iface);
++ rcu_assign_pointer(netlbl_unlhsh_def, iface);
+ }
+ spin_unlock(&netlbl_unlhsh_lock);
+
+@@ -1447,11 +1447,9 @@ int __init netlbl_unlabel_init(u32 size)
+ for (iter = 0; iter < hsh_tbl->size; iter++)
+ INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);
+
+- rcu_read_lock();
+ spin_lock(&netlbl_unlhsh_lock);
+- RCU_INIT_POINTER(netlbl_unlhsh, hsh_tbl);
++ rcu_assign_pointer(netlbl_unlhsh, hsh_tbl);
+ spin_unlock(&netlbl_unlhsh_lock);
+- rcu_read_unlock();
+
+ register_netdevice_notifier(&netlbl_unlhsh_netdev_notifier);
+
+diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
+index bf10ea8..d65f699 100644
+--- a/net/phonet/af_phonet.c
++++ b/net/phonet/af_phonet.c
+@@ -480,7 +480,7 @@ int __init_or_module phonet_proto_register(unsigned int protocol,
+ if (proto_tab[protocol])
+ err = -EBUSY;
+ else
+- RCU_INIT_POINTER(proto_tab[protocol], pp);
++ rcu_assign_pointer(proto_tab[protocol], pp);
+ mutex_unlock(&proto_tab_lock);
+
+ return err;
+diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
+index c582761..9b9a85e 100644
+--- a/net/phonet/pn_dev.c
++++ b/net/phonet/pn_dev.c
+@@ -390,7 +390,7 @@ int phonet_route_add(struct net_device *dev, u8 daddr)
+ daddr = daddr >> 2;
+ mutex_lock(&routes->lock);
+ if (routes->table[daddr] == NULL) {
+- RCU_INIT_POINTER(routes->table[daddr], dev);
++ rcu_assign_pointer(routes->table[daddr], dev);
+ dev_hold(dev);
+ err = 0;
+ }
+diff --git a/net/phonet/socket.c b/net/phonet/socket.c
+index 3f8d0b1..4c7eff3 100644
+--- a/net/phonet/socket.c
++++ b/net/phonet/socket.c
+@@ -680,7 +680,7 @@ int pn_sock_bind_res(struct sock *sk, u8 res)
+ mutex_lock(&resource_mutex);
+ if (pnres.sk[res] == NULL) {
+ sock_hold(sk);
+- RCU_INIT_POINTER(pnres.sk[res], sk);
++ rcu_assign_pointer(pnres.sk[res], sk);
+ ret = 0;
+ }
+ mutex_unlock(&resource_mutex);
+diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
+index bb6ad81..424ff62 100644
+--- a/net/rds/af_rds.c
++++ b/net/rds/af_rds.c
+@@ -68,7 +68,6 @@ static int rds_release(struct socket *sock)
+ {
+ struct sock *sk = sock->sk;
+ struct rds_sock *rs;
+- unsigned long flags;
+
+ if (!sk)
+ goto out;
+@@ -94,10 +93,10 @@ static int rds_release(struct socket *sock)
+ rds_rdma_drop_keys(rs);
+ rds_notify_queue_get(rs, NULL);
+
+- spin_lock_irqsave(&rds_sock_lock, flags);
++ spin_lock_bh(&rds_sock_lock);
+ list_del_init(&rs->rs_item);
+ rds_sock_count--;
+- spin_unlock_irqrestore(&rds_sock_lock, flags);
++ spin_unlock_bh(&rds_sock_lock);
+
+ rds_trans_put(rs->rs_transport);
+
+@@ -409,7 +408,6 @@ static const struct proto_ops rds_proto_ops = {
+
+ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
+ {
+- unsigned long flags;
+ struct rds_sock *rs;
+
+ sock_init_data(sock, sk);
+@@ -426,10 +424,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
+ spin_lock_init(&rs->rs_rdma_lock);
+ rs->rs_rdma_keys = RB_ROOT;
+
+- spin_lock_irqsave(&rds_sock_lock, flags);
++ spin_lock_bh(&rds_sock_lock);
+ list_add_tail(&rs->rs_item, &rds_sock_list);
+ rds_sock_count++;
+- spin_unlock_irqrestore(&rds_sock_lock, flags);
++ spin_unlock_bh(&rds_sock_lock);
+
+ return 0;
+ }
+@@ -471,12 +469,11 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
+ {
+ struct rds_sock *rs;
+ struct rds_incoming *inc;
+- unsigned long flags;
+ unsigned int total = 0;
+
+ len /= sizeof(struct rds_info_message);
+
+- spin_lock_irqsave(&rds_sock_lock, flags);
++ spin_lock_bh(&rds_sock_lock);
+
+ list_for_each_entry(rs, &rds_sock_list, rs_item) {
+ read_lock(&rs->rs_recv_lock);
+@@ -492,7 +489,7 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
+ read_unlock(&rs->rs_recv_lock);
+ }
+
+- spin_unlock_irqrestore(&rds_sock_lock, flags);
++ spin_unlock_bh(&rds_sock_lock);
+
+ lens->nr = total;
+ lens->each = sizeof(struct rds_info_message);
+@@ -504,11 +501,10 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
+ {
+ struct rds_info_socket sinfo;
+ struct rds_sock *rs;
+- unsigned long flags;
+
+ len /= sizeof(struct rds_info_socket);
+
+- spin_lock_irqsave(&rds_sock_lock, flags);
++ spin_lock_bh(&rds_sock_lock);
+
+ if (len < rds_sock_count)
+ goto out;
+@@ -529,7 +525,7 @@ out:
+ lens->nr = rds_sock_count;
+ lens->each = sizeof(struct rds_info_socket);
+
+- spin_unlock_irqrestore(&rds_sock_lock, flags);
++ spin_unlock_bh(&rds_sock_lock);
+ }
+
+ static void rds_exit(void)
+diff --git a/net/socket.c b/net/socket.c
+index 2877647..2dce67a 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2472,7 +2472,7 @@ int sock_register(const struct net_proto_family *ops)
+ lockdep_is_held(&net_family_lock)))
+ err = -EEXIST;
+ else {
+- RCU_INIT_POINTER(net_families[ops->family], ops);
++ rcu_assign_pointer(net_families[ops->family], ops);
+ err = 0;
+ }
+ spin_unlock(&net_family_lock);
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index afb5655..db0efde 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -122,7 +122,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
+ if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
+ return;
+ gss_get_ctx(ctx);
+- RCU_INIT_POINTER(gss_cred->gc_ctx, ctx);
++ rcu_assign_pointer(gss_cred->gc_ctx, ctx);
+ set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
+ smp_mb__before_clear_bit();
+ clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index b595a3d..d99678a 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1915,7 +1915,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct sk_buff *skb;
+
+ unix_state_lock(sk);
+- skb = skb_dequeue(&sk->sk_receive_queue);
++ skb = skb_peek(&sk->sk_receive_queue);
+ if (skb == NULL) {
+ unix_sk(sk)->recursion_level = 0;
+ if (copied >= target)
+@@ -1955,11 +1955,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (check_creds) {
+ /* Never glue messages from different writers */
+ if ((UNIXCB(skb).pid != siocb->scm->pid) ||
+- (UNIXCB(skb).cred != siocb->scm->cred)) {
+- skb_queue_head(&sk->sk_receive_queue, skb);
+- sk->sk_data_ready(sk, skb->len);
++ (UNIXCB(skb).cred != siocb->scm->cred))
+ break;
+- }
+ } else {
+ /* Copy credentials */
+ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
+@@ -1974,8 +1971,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+
+ chunk = min_t(unsigned int, skb->len, size);
+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+- skb_queue_head(&sk->sk_receive_queue, skb);
+- sk->sk_data_ready(sk, skb->len);
+ if (copied == 0)
+ copied = -EFAULT;
+ break;
+@@ -1990,13 +1985,10 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (UNIXCB(skb).fp)
+ unix_detach_fds(siocb->scm, skb);
+
+- /* put the skb back if we didn't use it up.. */
+- if (skb->len) {
+- skb_queue_head(&sk->sk_receive_queue, skb);
+- sk->sk_data_ready(sk, skb->len);
++ if (skb->len)
+ break;
+- }
+
++ skb_unlink(skb, &sk->sk_receive_queue);
+ consume_skb(skb);
+
+ if (siocb->scm->fp)
+@@ -2007,9 +1999,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ if (UNIXCB(skb).fp)
+ siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
+
+- /* put message back and return */
+- skb_queue_head(&sk->sk_receive_queue, skb);
+- sk->sk_data_ready(sk, skb->len);
+ break;
+ }
+ } while (size);
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index d0a42df..7cae73e 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -2927,7 +2927,7 @@ static int __net_init xfrm_user_net_init(struct net *net)
+ if (nlsk == NULL)
+ return -ENOMEM;
+ net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */
+- RCU_INIT_POINTER(net->xfrm.nlsk, nlsk);
++ rcu_assign_pointer(net->xfrm.nlsk, nlsk);
+ return 0;
+ }
+
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 5b2b75b..192e6c0 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -461,6 +461,7 @@ struct azx {
+ unsigned int irq_pending_warned :1;
+ unsigned int probing :1; /* codec probing phase */
+ unsigned int snoop:1;
++ unsigned int align_buffer_size:1;
+
+ /* for debugging */
+ unsigned int last_cmd[AZX_MAX_CODECS];
+@@ -1697,7 +1698,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
+ runtime->hw.rates = hinfo->rates;
+ snd_pcm_limit_hw_rates(runtime);
+ snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
+- if (align_buffer_size)
++ if (chip->align_buffer_size)
+ /* constrain buffer sizes to be multiple of 128
+ bytes. This is more efficient in terms of memory
+ access but isn't required by the HDA spec and
+@@ -2753,8 +2754,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
+ }
+
+ /* disable buffer size rounding to 128-byte multiples if supported */
++ chip->align_buffer_size = align_buffer_size;
+ if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
+- align_buffer_size = 0;
++ chip->align_buffer_size = 0;
+
+ /* allow 64bit DMA address if supported by H/W */
+ if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 1d07e8f..5f03c40 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5223,6 +5223,7 @@ static const struct hda_amp_list alc861_loopbacks[] = {
+ /* Pin config fixes */
+ enum {
+ PINFIX_FSC_AMILO_PI1505,
++ PINFIX_ASUS_A6RP,
+ };
+
+ static const struct alc_fixup alc861_fixups[] = {
+@@ -5234,9 +5235,19 @@ static const struct alc_fixup alc861_fixups[] = {
+ { }
+ }
+ },
++ [PINFIX_ASUS_A6RP] = {
++ .type = ALC_FIXUP_VERBS,
++ .v.verbs = (const struct hda_verb[]) {
++ /* node 0x0f VREF seems controlling the master output */
++ { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
++ { }
++ },
++ },
+ };
+
+ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
++ SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP),
++ SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
+ SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
+ {}
+ };
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index f3c73a9..ccdac27 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -4253,13 +4253,15 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
+ return 1;
+ }
+
+-static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
++static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
+ {
+ int i;
+ for (i = 0; i < cfg->hp_outs; i++)
+ if (cfg->hp_pins[i] == nid)
+ return 1; /* nid is a HP-Out */
+-
++ for (i = 0; i < cfg->line_outs; i++)
++ if (cfg->line_out_pins[i] == nid)
++ return 1; /* nid is a line-Out */
+ return 0; /* nid is not a HP-Out */
+ };
+
+@@ -4465,7 +4467,7 @@ static int stac92xx_init(struct hda_codec *codec)
+ continue;
+ }
+
+- if (is_nid_hp_pin(cfg, nid))
++ if (is_nid_out_jack_pin(cfg, nid))
+ continue; /* already has an unsol event */
+
+ pinctl = snd_hda_codec_read(codec, nid, 0,
+@@ -4950,7 +4952,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
+ /* BIOS bug: unfilled OEM string */
+ if (strstr(dev->name, "HP_Mute_LED_P_G")) {
+ set_hp_led_gpio(codec);
+- spec->gpio_led_polarity = 1;
++ switch (codec->subsystem_id) {
++ case 0x103c148a:
++ spec->gpio_led_polarity = 0;
++ break;
++ default:
++ spec->gpio_led_polarity = 1;
++ break;
++ }
+ return 1;
+ }
+ }
+diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
+index 42d9039..d0beeec 100644
+--- a/sound/soc/codecs/wm5100.c
++++ b/sound/soc/codecs/wm5100.c
+@@ -1379,6 +1379,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
+
+ switch (wm5100->rev) {
+ case 0:
++ regcache_cache_bypass(wm5100->regmap, true);
+ snd_soc_write(codec, 0x11, 0x3);
+ snd_soc_write(codec, 0x203, 0xc);
+ snd_soc_write(codec, 0x206, 0);
+@@ -1394,6 +1395,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
+ snd_soc_write(codec,
+ wm5100_reva_patches[i].reg,
+ wm5100_reva_patches[i].val);
++ regcache_cache_bypass(wm5100->regmap, false);
+ break;
+ default:
+ break;
+@@ -1404,6 +1406,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
+ break;
+
+ case SND_SOC_BIAS_OFF:
++ regcache_cache_only(wm5100->regmap, true);
+ if (wm5100->pdata.ldo_ena)
+ gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
+ regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
+diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
+index a33b04d..6d98a57 100644
+--- a/sound/soc/codecs/wm8996.c
++++ b/sound/soc/codecs/wm8996.c
+@@ -1049,7 +1049,8 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,
+- SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
++ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
++ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
+@@ -1932,6 +1933,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
+ struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
+ int lfclk = 0;
+ int ratediv = 0;
++ int sync = WM8996_REG_SYNC;
+ int src;
+ int old;
+
+@@ -1976,6 +1978,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
+ case 32000:
+ case 32768:
+ lfclk = WM8996_LFCLK_ENA;
++ sync = 0;
+ break;
+ default:
+ dev_warn(codec->dev, "Unsupported clock rate %dHz\n",
+@@ -1989,6 +1992,8 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai,
+ WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK,
+ src << WM8996_SYSCLK_SRC_SHIFT | ratediv);
+ snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);
++ snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1,
++ WM8996_REG_SYNC, sync);
+ snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1,
+ WM8996_SYSCLK_ENA, old);
+
+diff --git a/sound/soc/codecs/wm8996.h b/sound/soc/codecs/wm8996.h
+index 0fde643..de9ac3e 100644
+--- a/sound/soc/codecs/wm8996.h
++++ b/sound/soc/codecs/wm8996.h
+@@ -1567,6 +1567,10 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
+ /*
+ * R257 (0x101) - Control Interface (1)
+ */
++#define WM8996_REG_SYNC 0x8000 /* REG_SYNC */
++#define WM8996_REG_SYNC_MASK 0x8000 /* REG_SYNC */
++#define WM8996_REG_SYNC_SHIFT 15 /* REG_SYNC */
++#define WM8996_REG_SYNC_WIDTH 1 /* REG_SYNC */
+ #define WM8996_AUTO_INC 0x0004 /* AUTO_INC */
+ #define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */
+ #define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */
diff --git a/3.2.4/1003_linux-3.2.4.patch b/3.2.4/1003_linux-3.2.4.patch
new file mode 100644
index 0000000..e49de55
--- /dev/null
+++ b/3.2.4/1003_linux-3.2.4.patch
@@ -0,0 +1,40 @@
+diff --git a/Makefile b/Makefile
+index d45e887..c8e187e 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 2
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = Saber-toothed Squirrel
+
+diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
+index d0beeec..42d9039 100644
+--- a/sound/soc/codecs/wm5100.c
++++ b/sound/soc/codecs/wm5100.c
+@@ -1379,7 +1379,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
+
+ switch (wm5100->rev) {
+ case 0:
+- regcache_cache_bypass(wm5100->regmap, true);
+ snd_soc_write(codec, 0x11, 0x3);
+ snd_soc_write(codec, 0x203, 0xc);
+ snd_soc_write(codec, 0x206, 0);
+@@ -1395,7 +1394,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
+ snd_soc_write(codec,
+ wm5100_reva_patches[i].reg,
+ wm5100_reva_patches[i].val);
+- regcache_cache_bypass(wm5100->regmap, false);
+ break;
+ default:
+ break;
+@@ -1406,7 +1404,6 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec,
+ break;
+
+ case SND_SOC_BIAS_OFF:
+- regcache_cache_only(wm5100->regmap, true);
+ if (wm5100->pdata.ldo_ena)
+ gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
+ regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
diff --git a/3.2.2/4420_grsecurity-2.2.2-3.2.2-201201272014.patch b/3.2.4/4420_grsecurity-2.2.2-3.2.4-201202032052.patch
index 3f6029d..9b95205 100644
--- a/3.2.2/4420_grsecurity-2.2.2-3.2.2-201201272014.patch
+++ b/3.2.4/4420_grsecurity-2.2.2-3.2.4-201202032052.patch
@@ -186,7 +186,7 @@ index 81c287f..d456d02 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 2f684da..bf21f8d 100644
+index c8e187e..c445af7 100644
--- a/Makefile
+++ b/Makefile
@@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -12223,19 +12223,18 @@ index 2af127d..8ff7ac0 100644
atomic_set(&mce_callin, 0);
atomic_set(&global_nwo, 0);
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c
-index 5c0e653..51ddf2c 100644
+index 5c0e653..0882b0a 100644
--- a/arch/x86/kernel/cpu/mcheck/p5.c
+++ b/arch/x86/kernel/cpu/mcheck/p5.c
-@@ -11,7 +11,7 @@
- #include <asm/processor.h>
+@@ -12,6 +12,7 @@
#include <asm/system.h>
#include <asm/mce.h>
--#include <asm/msr.h>
+ #include <asm/msr.h>
+#include <asm/pgtable.h>
/* By default disabled */
int mce_p5_enabled __read_mostly;
-@@ -50,7 +50,9 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+@@ -50,7 +51,9 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
if (!cpu_has(c, X86_FEATURE_MCE))
return;
@@ -22963,7 +22962,7 @@ index 7b179b4..6bd1777 100644
return (void *)vaddr;
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
-index be1ef57..9680edc 100644
+index be1ef57..55f0160 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -97,7 +97,7 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
@@ -22975,7 +22974,17 @@ index be1ef57..9680edc 100644
return NULL;
WARN_ON_ONCE(is_ram);
}
-@@ -344,7 +344,7 @@ static int __init early_ioremap_debug_setup(char *str)
+@@ -315,6 +315,9 @@ void *xlate_dev_mem_ptr(unsigned long phys)
+
+ /* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
+ if (page_is_ram(start >> PAGE_SHIFT))
++#ifdef CONFIG_HIGHMEM
++ if ((start >> PAGE_SHIFT) < max_low_pfn)
++#endif
+ return __va(phys);
+
+ addr = (void __force *)ioremap_cache(start, PAGE_SIZE);
+@@ -344,7 +347,7 @@ static int __init early_ioremap_debug_setup(char *str)
early_param("early_ioremap_debug", early_ioremap_debug_setup);
static __initdata int after_paging_init;
@@ -22984,7 +22993,7 @@ index be1ef57..9680edc 100644
static inline pmd_t * __init early_ioremap_pmd(unsigned long addr)
{
-@@ -381,8 +381,7 @@ void __init early_ioremap_init(void)
+@@ -381,8 +384,7 @@ void __init early_ioremap_init(void)
slot_virt[i] = __fix_to_virt(FIX_BTMAP_BEGIN - NR_FIX_BTMAPS*i);
pmd = early_ioremap_pmd(fix_to_virt(FIX_BTMAP_BEGIN));
@@ -23725,7 +23734,7 @@ index 6687022..ceabcfa 100644
+ pax_force_retaddr
ret
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
-index 7b65f75..63097f6 100644
+index 7c1b765..180e3b2 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -117,6 +117,10 @@ static inline void bpf_flush_icache(void *start, void *end)
@@ -23750,7 +23759,7 @@ index 7b65f75..63097f6 100644
/* Before first pass, make a rough estimation of addrs[]
* each bpf instruction is translated to less than 64 bytes
*/
-@@ -585,11 +593,12 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -592,11 +600,12 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
if (image) {
if (unlikely(proglen + ilen > oldproglen)) {
pr_err("bpb_jit_compile fatal error\n");
@@ -23766,7 +23775,7 @@ index 7b65f75..63097f6 100644
}
proglen += ilen;
addrs[i] = proglen;
-@@ -609,7 +618,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -617,7 +626,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
break;
}
if (proglen == oldproglen) {
@@ -23775,7 +23784,7 @@ index 7b65f75..63097f6 100644
proglen,
sizeof(struct work_struct)));
if (!image)
-@@ -631,24 +640,27 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
+@@ -639,24 +648,27 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
fp->bpf_func = (void *)image;
}
out:
@@ -24994,109 +25003,6 @@ index 671d4d6..5f24030 100644
static void cryptd_queue_worker(struct work_struct *work);
-diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
-index 9ed9f60..88f160b 100644
---- a/crypto/sha512_generic.c
-+++ b/crypto/sha512_generic.c
-@@ -21,8 +21,6 @@
- #include <linux/percpu.h>
- #include <asm/byteorder.h>
-
--static DEFINE_PER_CPU(u64[80], msg_schedule);
--
- static inline u64 Ch(u64 x, u64 y, u64 z)
- {
- return z ^ (x & (y ^ z));
-@@ -80,7 +78,7 @@ static inline void LOAD_OP(int I, u64 *W, const u8 *input)
-
- static inline void BLEND_OP(int I, u64 *W)
- {
-- W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16];
-+ W[I % 16] += s1(W[(I-2) % 16]) + W[(I-7) % 16] + s0(W[(I-15) % 16]);
- }
-
- static void
-@@ -89,38 +87,48 @@ sha512_transform(u64 *state, const u8 *input)
- u64 a, b, c, d, e, f, g, h, t1, t2;
-
- int i;
-- u64 *W = get_cpu_var(msg_schedule);
-+ u64 W[16];
-
- /* load the input */
- for (i = 0; i < 16; i++)
- LOAD_OP(i, W, input);
-
-- for (i = 16; i < 80; i++) {
-- BLEND_OP(i, W);
-- }
--
- /* 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];
-
-- /* now iterate */
-- for (i=0; i<80; i+=8) {
-- 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;
-- t1 = g + e1(d) + Ch(d,e,f) + sha512_K[i+1] + W[i+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+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+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+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+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+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+7];
-- t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2;
-+#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);
- }
-
- state[0] += a; state[1] += b; state[2] += c; state[3] += d;
-@@ -128,8 +136,6 @@ sha512_transform(u64 *state, const u8 *input)
-
- /* erase our data */
- a = b = c = d = e = f = g = h = t1 = t2 = 0;
-- memset(W, 0, sizeof(__get_cpu_var(msg_schedule)));
-- put_cpu_var(msg_schedule);
- }
-
- static int
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index 5d41894..22021e4 100644
--- a/drivers/acpi/apei/cper.c
@@ -27943,7 +27849,7 @@ index 40c187c..5746164 100644
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
-index 4911e1d..484c8a3 100644
+index 828bf65..cdaa0e9 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -71,7 +71,7 @@ static int drm_setup(struct drm_device * dev)
@@ -27982,9 +27888,9 @@ index 4911e1d..484c8a3 100644
- dev->open_count);
+ local_read(&dev->open_count));
- /* if the master has gone away we can't do anything with the lock */
- if (file_priv->minor->master)
-@@ -566,8 +566,8 @@ int drm_release(struct inode *inode, struct file *filp)
+ /* Release any auth tokens that might point to this file_priv,
+ (do that under the drm_global_mutex) */
+@@ -571,8 +571,8 @@ int drm_release(struct inode *inode, struct file *filp)
* End inline drm_release
*/
@@ -29164,7 +29070,7 @@ index 66f6729..2d6de0a 100644
mutex_lock(&resource->lock);
resource->trip[attr->index - 7] = temp;
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
-index fe4104c..346febb 100644
+index 5357925..6cf0418 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -166,7 +166,7 @@ struct sht15_data {
@@ -41403,80 +41309,24 @@ index f7908ae..920a680 100644
dcache_init();
inode_init();
-diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
-index 2a83425..b082cec 100644
---- a/fs/ecryptfs/crypto.c
-+++ b/fs/ecryptfs/crypto.c
-@@ -417,17 +417,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
- (unsigned long long)(extent_base + extent_offset), rc);
- goto out;
- }
-- if (unlikely(ecryptfs_verbosity > 0)) {
-- ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
-- "with iv:\n");
-- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
-- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
-- "encryption:\n");
-- ecryptfs_dump_hex((char *)
-- (page_address(page)
-- + (extent_offset * crypt_stat->extent_size)),
-- 8);
-- }
- rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
- page, (extent_offset
- * crypt_stat->extent_size),
-@@ -440,14 +429,6 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
- goto out;
- }
- rc = 0;
-- if (unlikely(ecryptfs_verbosity > 0)) {
-- ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16llx]; "
-- "rc = [%d]\n",
-- (unsigned long long)(extent_base + extent_offset), rc);
-- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
-- "encryption:\n");
-- ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
-- }
- out:
- return rc;
- }
-@@ -543,17 +524,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
- (unsigned long long)(extent_base + extent_offset), rc);
- goto out;
- }
-- if (unlikely(ecryptfs_verbosity > 0)) {
-- ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
-- "with iv:\n");
-- ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
-- ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
-- "decryption:\n");
-- ecryptfs_dump_hex((char *)
-- (page_address(enc_extent_page)
-- + (extent_offset * crypt_stat->extent_size)),
-- 8);
-- }
- rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
- (extent_offset
- * crypt_stat->extent_size),
-@@ -567,16 +537,6 @@ static int ecryptfs_decrypt_extent(struct page *page,
- goto out;
- }
- rc = 0;
-- if (unlikely(ecryptfs_verbosity > 0)) {
-- ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16llx]; "
-- "rc = [%d]\n",
-- (unsigned long long)(extent_base + extent_offset), rc);
-- ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
-- "decryption:\n");
-- ecryptfs_dump_hex((char *)(page_address(page)
-- + (extent_offset
-- * crypt_stat->extent_size)), 8);
-- }
- out:
- return rc;
+diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
+index f3a257d..715ac0f 100644
+--- a/fs/debugfs/inode.c
++++ b/fs/debugfs/inode.c
+@@ -261,7 +261,11 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
+ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
+ {
+ return debugfs_create_file(name,
++#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
++ S_IFDIR | S_IRWXU,
++#else
+ S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
++#endif
+ parent, NULL, NULL);
}
+ EXPORT_SYMBOL_GPL(debugfs_create_dir);
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
-index 32f90a3..a766407 100644
+index d2039ca..a766407 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -691,7 +691,7 @@ static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
@@ -41506,84 +41356,8 @@ index 32f90a3..a766407 100644
if (!IS_ERR(buf)) {
/* Free the char* */
kfree(buf);
-@@ -841,18 +841,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
- size_t num_zeros = (PAGE_CACHE_SIZE
- - (ia->ia_size & ~PAGE_CACHE_MASK));
-
--
-- /*
-- * XXX(truncate) this should really happen at the begginning
-- * of ->setattr. But the code is too messy to that as part
-- * of a larger patch. ecryptfs is also totally missing out
-- * on the inode_change_ok check at the beginning of
-- * ->setattr while would include this.
-- */
-- rc = inode_newsize_ok(inode, ia->ia_size);
-- if (rc)
-- goto out;
--
- if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
- truncate_setsize(inode, ia->ia_size);
- lower_ia->ia_size = ia->ia_size;
-@@ -902,6 +890,28 @@ out:
- return rc;
- }
-
-+static int ecryptfs_inode_newsize_ok(struct inode *inode, loff_t offset)
-+{
-+ struct ecryptfs_crypt_stat *crypt_stat;
-+ loff_t lower_oldsize, lower_newsize;
-+
-+ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
-+ lower_oldsize = upper_size_to_lower_size(crypt_stat,
-+ i_size_read(inode));
-+ lower_newsize = upper_size_to_lower_size(crypt_stat, offset);
-+ if (lower_newsize > lower_oldsize) {
-+ /*
-+ * The eCryptfs inode and the new *lower* size are mixed here
-+ * because we may not have the lower i_mutex held and/or it may
-+ * not be appropriate to call inode_newsize_ok() with inodes
-+ * from other filesystems.
-+ */
-+ return inode_newsize_ok(inode, lower_newsize);
-+ }
-+
-+ return 0;
-+}
-+
- /**
- * ecryptfs_truncate
- * @dentry: The ecryptfs layer dentry
-@@ -918,6 +928,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
- struct iattr lower_ia = { .ia_valid = 0 };
- int rc;
-
-+ rc = ecryptfs_inode_newsize_ok(dentry->d_inode, new_length);
-+ if (rc)
-+ return 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);
-@@ -997,6 +1011,16 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
- }
- }
- mutex_unlock(&crypt_stat->cs_mutex);
-+
-+ rc = inode_change_ok(inode, ia);
-+ if (rc)
-+ goto out;
-+ if (ia->ia_valid & ATTR_SIZE) {
-+ rc = ecryptfs_inode_newsize_ok(inode, ia->ia_size);
-+ if (rc)
-+ goto out;
-+ }
-+
- if (S_ISREG(inode->i_mode)) {
- rc = filemap_write_and_wait(inode->i_mapping);
- if (rc)
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
-index 940a82e..d3cdeea 100644
+index 0dc5a3d..d3cdeea 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -328,7 +328,7 @@ check_list:
@@ -41595,82 +41369,8 @@ index 940a82e..d3cdeea 100644
goto out_unlock_msg_ctx;
i += packet_length_size;
if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
-@@ -409,11 +409,47 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
- ssize_t sz = 0;
- char *data;
- uid_t euid = current_euid();
-+ unsigned char packet_size_peek[3];
- int rc;
-
-- if (count == 0)
-+ if (count == 0) {
- goto out;
-+ } else if (count == (1 + 4)) {
-+ /* Likely a harmless MSG_HELO or MSG_QUIT - no packet length */
-+ goto memdup;
-+ } else if (count < (1 + 4 + 1)
-+ || count > (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
-+ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES)) {
-+ printk(KERN_WARNING "%s: Acceptable packet size range is "
-+ "[%d-%lu], but amount of data written is [%zu].",
-+ __func__, (1 + 4 + 1),
-+ (1 + 4 + 2 + sizeof(struct ecryptfs_message) + 4
-+ + ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES), count);
-+ return -EINVAL;
-+ }
-
-+ if (copy_from_user(packet_size_peek, (buf + 1 + 4),
-+ sizeof(packet_size_peek))) {
-+ printk(KERN_WARNING "%s: Error while inspecting packet size\n",
-+ __func__);
-+ return -EFAULT;
-+ }
-+
-+ rc = ecryptfs_parse_packet_length(packet_size_peek, &packet_size,
-+ &packet_size_length);
-+ if (rc) {
-+ printk(KERN_WARNING "%s: Error parsing packet length; "
-+ "rc = [%d]\n", __func__, rc);
-+ return rc;
-+ }
-+
-+ if ((1 + 4 + packet_size_length + packet_size) != count) {
-+ printk(KERN_WARNING "%s: Invalid packet size [%zu]\n", __func__,
-+ packet_size);
-+ return -EINVAL;
-+ }
-+
-+memdup:
- data = memdup_user(buf, count);
- if (IS_ERR(data)) {
- printk(KERN_ERR "%s: memdup_user returned error [%ld]\n",
-@@ -435,23 +471,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
- }
- memcpy(&counter_nbo, &data[i], 4);
- seq = be32_to_cpu(counter_nbo);
-- i += 4;
-- rc = ecryptfs_parse_packet_length(&data[i], &packet_size,
-- &packet_size_length);
-- if (rc) {
-- printk(KERN_WARNING "%s: Error parsing packet length; "
-- "rc = [%d]\n", __func__, rc);
-- goto out_free;
-- }
-- i += packet_size_length;
-- if ((1 + 4 + packet_size_length + packet_size) != count) {
-- printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])"
-- " + packet_size([%zd]))([%zd]) != "
-- "count([%zd]). Invalid packet format.\n",
-- __func__, packet_size_length, packet_size,
-- (1 + packet_size_length + packet_size), count);
-- goto out_free;
-- }
-+ i += 4 + packet_size_length;
- rc = ecryptfs_miscdev_response(&data[i], packet_size,
- euid, current_user_ns(),
- task_pid(current), seq);
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
-index 3745f7c..7d040a8 100644
+index 54eb14c..e51b453 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -48,7 +48,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
@@ -41682,7 +41382,7 @@ index 3745f7c..7d040a8 100644
set_fs(fs_save);
mark_inode_dirty_sync(ecryptfs_inode);
return rc;
-@@ -130,13 +130,18 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
+@@ -130,7 +130,12 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
@@ -41694,7 +41394,9 @@ index 3745f7c..7d040a8 100644
+ break;
+ }
- if (num_bytes > total_remaining_bytes)
+ if (fatal_signal_pending(current)) {
+ rc = -EINTR;
+@@ -141,7 +146,7 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
num_bytes = total_remaining_bytes;
if (pos < offset) {
/* remaining zeros to write, up to destination offset */
@@ -41703,32 +41405,7 @@ index 3745f7c..7d040a8 100644
if (num_bytes > total_remaining_zeros)
num_bytes = total_remaining_zeros;
-@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
- }
- pos += num_bytes;
- }
-- if ((offset + size) > ecryptfs_file_size) {
-- i_size_write(ecryptfs_inode, (offset + size));
-+ if (pos > ecryptfs_file_size) {
-+ i_size_write(ecryptfs_inode, pos);
- if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
-- rc = ecryptfs_write_inode_size_to_metadata(
-+ int rc2;
-+
-+ rc2 = ecryptfs_write_inode_size_to_metadata(
- ecryptfs_inode);
-- if (rc) {
-+ if (rc2) {
- printk(KERN_ERR "Problem with "
- "ecryptfs_write_inode_size_to_metadata; "
-- "rc = [%d]\n", rc);
-+ "rc = [%d]\n", rc2);
-+ if (!rc)
-+ rc = rc2;
- goto out;
- }
- }
-@@ -235,7 +244,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
+@@ -244,7 +249,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
return -EIO;
fs_save = get_fs();
set_fs(get_ds());
@@ -45585,7 +45262,7 @@ index 3a1dafd..d41fc37 100644
+}
+#endif
diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 1fc1dca..813fd0b 100644
+index 1fc1dca..357b933 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -107,6 +107,22 @@ struct pid_entry {
@@ -45611,24 +45288,34 @@ index 1fc1dca..813fd0b 100644
#define NOD(NAME, MODE, IOP, FOP, OP) { \
.name = (NAME), \
.len = sizeof(NAME) - 1, \
-@@ -204,10 +220,12 @@ static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
- return ERR_PTR(err);
+@@ -194,26 +210,6 @@ static int proc_root_link(struct inode *inode, struct path *path)
+ return result;
+ }
- mm = get_task_mm(task);
+-static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
+-{
+- struct mm_struct *mm;
+- int err;
+-
+- err = mutex_lock_killable(&task->signal->cred_guard_mutex);
+- if (err)
+- return ERR_PTR(err);
+-
+- mm = get_task_mm(task);
- if (mm && mm != current->mm &&
- !ptrace_may_access(task, mode)) {
- mmput(mm);
- mm = ERR_PTR(-EACCES);
-+ if (mm) {
-+ if ((mm != current->mm && !ptrace_may_access(task, mode)) ||
-+ (mode == PTRACE_MODE_ATTACH && (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task)))) {
-+ mmput(mm);
-+ mm = ERR_PTR(-EACCES);
-+ }
- }
- mutex_unlock(&task->signal->cred_guard_mutex);
-
-@@ -229,6 +247,9 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
+- }
+- mutex_unlock(&task->signal->cred_guard_mutex);
+-
+- return mm;
+-}
+-
+ struct mm_struct *mm_for_maps(struct task_struct *task)
+ {
+ return mm_access(task, PTRACE_MODE_READ);
+@@ -229,6 +225,9 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)
if (!mm->arg_end)
goto out_mm; /* Shh! No looking before we're done */
@@ -45638,7 +45325,7 @@ index 1fc1dca..813fd0b 100644
len = mm->arg_end - mm->arg_start;
if (len > PAGE_SIZE)
-@@ -256,12 +277,28 @@ out:
+@@ -256,12 +255,28 @@ out:
return res;
}
@@ -45667,7 +45354,7 @@ index 1fc1dca..813fd0b 100644
do {
nwords += 2;
} while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
-@@ -275,7 +312,7 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
+@@ -275,7 +290,7 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
}
@@ -45676,7 +45363,7 @@ index 1fc1dca..813fd0b 100644
/*
* Provides a wchan file via kallsyms in a proper one-value-per-file format.
* Returns the resolved symbol. If that fails, simply return the address.
-@@ -314,7 +351,7 @@ static void unlock_trace(struct task_struct *task)
+@@ -314,7 +329,7 @@ static void unlock_trace(struct task_struct *task)
mutex_unlock(&task->signal->cred_guard_mutex);
}
@@ -45685,7 +45372,7 @@ index 1fc1dca..813fd0b 100644
#define MAX_STACK_TRACE_DEPTH 64
-@@ -505,7 +542,7 @@ static int proc_pid_limits(struct task_struct *task, char *buffer)
+@@ -505,7 +520,7 @@ static int proc_pid_limits(struct task_struct *task, char *buffer)
return count;
}
@@ -45694,7 +45381,7 @@ index 1fc1dca..813fd0b 100644
static int proc_pid_syscall(struct task_struct *task, char *buffer)
{
long nr;
-@@ -534,7 +571,7 @@ static int proc_pid_syscall(struct task_struct *task, char *buffer)
+@@ -534,7 +549,7 @@ static int proc_pid_syscall(struct task_struct *task, char *buffer)
/************************************************************************/
/* permission checks */
@@ -45703,7 +45390,7 @@ index 1fc1dca..813fd0b 100644
{
struct task_struct *task;
int allowed = 0;
-@@ -544,7 +581,10 @@ static int proc_fd_access_allowed(struct inode *inode)
+@@ -544,7 +559,10 @@ static int proc_fd_access_allowed(struct inode *inode)
*/
task = get_proc_task(inode);
if (task) {
@@ -45715,26 +45402,164 @@ index 1fc1dca..813fd0b 100644
put_task_struct(task);
}
return allowed;
-@@ -826,6 +866,10 @@ static ssize_t mem_read(struct file * file, char __user * buf,
- return ret;
- }
+@@ -775,6 +793,13 @@ static int mem_open(struct inode* inode, struct file* file)
+ if (IS_ERR(mm))
+ return PTR_ERR(mm);
-+#define mem_write NULL
++ if (mm) {
++ /* ensure this mm_struct can't be freed */
++ atomic_inc(&mm->mm_count);
++ /* but do not pin its memory */
++ mmput(mm);
++ }
+
-+#ifndef mem_write
-+/* They were right the first time */
- static ssize_t mem_write(struct file * file, const char __user *buf,
- size_t count, loff_t *ppos)
+ /* OK to pass negative loff_t, we can catch out-of-range */
+ file->f_mode |= FMODE_UNSIGNED_OFFSET;
+ file->private_data = mm;
+@@ -782,57 +807,18 @@ static int mem_open(struct inode* inode, struct file* file)
+ return 0;
+ }
+
+-static ssize_t mem_read(struct file * file, char __user * buf,
+- size_t count, loff_t *ppos)
++static ssize_t mem_rw(struct file *file, char __user *buf,
++ size_t count, loff_t *ppos, int write)
{
-@@ -866,6 +910,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
+- int ret;
+- char *page;
+- unsigned long src = *ppos;
+ struct mm_struct *mm = file->private_data;
+-
+- if (!mm)
+- return 0;
+-
+- page = (char *)__get_free_page(GFP_TEMPORARY);
+- if (!page)
+- return -ENOMEM;
+-
+- ret = 0;
+-
+- while (count > 0) {
+- int this_len, retval;
+-
+- this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+- retval = access_remote_vm(mm, src, page, this_len, 0);
+- if (!retval) {
+- if (!ret)
+- ret = -EIO;
+- break;
+- }
+-
+- if (copy_to_user(buf, page, retval)) {
+- ret = -EFAULT;
+- break;
+- }
+-
+- ret += retval;
+- src += retval;
+- buf += retval;
+- count -= retval;
+- }
+- *ppos = src;
+-
+- free_page((unsigned long) page);
+- return ret;
+-}
+-
+-static ssize_t mem_write(struct file * file, const char __user *buf,
+- size_t count, loff_t *ppos)
+-{
+- int copied;
++ unsigned long addr = *ppos;
++ ssize_t copied;
+ char *page;
+- unsigned long dst = *ppos;
+- struct mm_struct *mm = file->private_data;
++
++#ifdef CONFIG_GRKERNSEC
++ if (write)
++ return -EPERM;
++#endif
+
+ if (!mm)
+ return 0;
+@@ -842,31 +828,54 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
+ return -ENOMEM;
+
+ copied = 0;
++ if (!atomic_inc_not_zero(&mm->mm_users))
++ goto free;
++
+ while (count > 0) {
+- int this_len, retval;
++ int this_len = min_t(int, count, PAGE_SIZE);
+
+- this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+- if (copy_from_user(page, buf, this_len)) {
++ if (write && copy_from_user(page, buf, this_len)) {
+ copied = -EFAULT;
+ break;
+ }
+- retval = access_remote_vm(mm, dst, page, this_len, 1);
+- if (!retval) {
++
++ this_len = access_remote_vm(mm, addr, page, this_len, write);
++ if (!this_len) {
+ if (!copied)
+ copied = -EIO;
+ break;
+ }
+- copied += retval;
+- buf += retval;
+- dst += retval;
+- count -= retval;
++
++ if (!write && copy_to_user(buf, page, this_len)) {
++ copied = -EFAULT;
++ break;
++ }
++
++ buf += this_len;
++ addr += this_len;
++ copied += this_len;
++ count -= this_len;
+ }
+- *ppos = dst;
++ *ppos = addr;
+
++ mmput(mm);
++free:
free_page((unsigned long) page);
return copied;
}
-+#endif
++static ssize_t mem_read(struct file *file, char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ return mem_rw(file, buf, count, ppos, 0);
++}
++
++static ssize_t mem_write(struct file *file, const char __user *buf,
++ size_t count, loff_t *ppos)
++{
++ return mem_rw(file, (char __user*)buf, count, ppos, 1);
++}
++
loff_t mem_lseek(struct file *file, loff_t offset, int orig)
{
-@@ -911,6 +956,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+ switch (orig) {
+@@ -886,8 +895,8 @@ loff_t mem_lseek(struct file *file, loff_t offset, int orig)
+ static int mem_release(struct inode *inode, struct file *file)
+ {
+ struct mm_struct *mm = file->private_data;
+-
+- mmput(mm);
++ if (mm)
++ mmdrop(mm);
+ return 0;
+ }
+
+@@ -911,6 +920,9 @@ static ssize_t environ_read(struct file *file, char __user *buf,
if (!task)
goto out_no_task;
@@ -45744,7 +45569,7 @@ index 1fc1dca..813fd0b 100644
ret = -ENOMEM;
page = (char *)__get_free_page(GFP_TEMPORARY);
if (!page)
-@@ -1533,7 +1581,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -1533,7 +1545,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
path_put(&nd->path);
/* Are we allowed to snoop on the tasks file descriptors? */
@@ -45753,7 +45578,7 @@ index 1fc1dca..813fd0b 100644
goto out;
error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
-@@ -1572,8 +1620,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
+@@ -1572,8 +1584,18 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
struct path path;
/* Are we allowed to snoop on the tasks file descriptors? */
@@ -45774,7 +45599,7 @@ index 1fc1dca..813fd0b 100644
error = PROC_I(inode)->op.proc_get_link(inode, &path);
if (error)
-@@ -1638,7 +1696,11 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t
+@@ -1638,7 +1660,11 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t
rcu_read_lock();
cred = __task_cred(task);
inode->i_uid = cred->euid;
@@ -45786,7 +45611,7 @@ index 1fc1dca..813fd0b 100644
rcu_read_unlock();
}
security_task_to_inode(task, inode);
-@@ -1656,6 +1718,9 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+@@ -1656,6 +1682,9 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
struct inode *inode = dentry->d_inode;
struct task_struct *task;
const struct cred *cred;
@@ -45796,7 +45621,7 @@ index 1fc1dca..813fd0b 100644
generic_fillattr(inode, stat);
-@@ -1663,13 +1728,41 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+@@ -1663,13 +1692,41 @@ int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
stat->uid = 0;
stat->gid = 0;
task = pid_task(proc_pid(inode), PIDTYPE_PID);
@@ -45839,7 +45664,7 @@ index 1fc1dca..813fd0b 100644
}
rcu_read_unlock();
return 0;
-@@ -1706,11 +1799,20 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
+@@ -1706,11 +1763,20 @@ int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
if (task) {
if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
@@ -45860,7 +45685,7 @@ index 1fc1dca..813fd0b 100644
rcu_read_unlock();
} else {
inode->i_uid = 0;
-@@ -1828,7 +1930,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
+@@ -1828,7 +1894,8 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info)
int fd = proc_fd(inode);
if (task) {
@@ -45870,7 +45695,7 @@ index 1fc1dca..813fd0b 100644
put_task_struct(task);
}
if (files) {
-@@ -2096,11 +2199,21 @@ static const struct file_operations proc_fd_operations = {
+@@ -2096,11 +2163,21 @@ static const struct file_operations proc_fd_operations = {
*/
static int proc_fd_permission(struct inode *inode, int mask)
{
@@ -45894,7 +45719,7 @@ index 1fc1dca..813fd0b 100644
return rv;
}
-@@ -2210,6 +2323,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
+@@ -2210,6 +2287,9 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
if (!task)
goto out_no_task;
@@ -45904,7 +45729,7 @@ index 1fc1dca..813fd0b 100644
/*
* Yes, it does not scale. And it should not. Don't add
* new entries into /proc/<tgid>/ without very good reasons.
-@@ -2254,6 +2370,9 @@ static int proc_pident_readdir(struct file *filp,
+@@ -2254,6 +2334,9 @@ static int proc_pident_readdir(struct file *filp,
if (!task)
goto out_no_task;
@@ -45914,7 +45739,7 @@ index 1fc1dca..813fd0b 100644
ret = 0;
i = filp->f_pos;
switch (i) {
-@@ -2524,7 +2643,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+@@ -2524,7 +2607,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
void *cookie)
{
@@ -45923,7 +45748,7 @@ index 1fc1dca..813fd0b 100644
if (!IS_ERR(s))
__putname(s);
}
-@@ -2722,7 +2841,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2722,7 +2805,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
#endif
REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
@@ -45932,7 +45757,7 @@ index 1fc1dca..813fd0b 100644
INF("syscall", S_IRUGO, proc_pid_syscall),
#endif
INF("cmdline", S_IRUGO, proc_pid_cmdline),
-@@ -2747,10 +2866,10 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2747,10 +2830,10 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -45945,7 +45770,7 @@ index 1fc1dca..813fd0b 100644
ONE("stack", S_IRUGO, proc_pid_stack),
#endif
#ifdef CONFIG_SCHEDSTATS
-@@ -2784,6 +2903,9 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2784,6 +2867,9 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_HARDWALL
INF("hardwall", S_IRUGO, proc_pid_hardwall),
#endif
@@ -45955,7 +45780,7 @@ index 1fc1dca..813fd0b 100644
};
static int proc_tgid_base_readdir(struct file * filp,
-@@ -2909,7 +3031,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
+@@ -2909,7 +2995,14 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
if (!inode)
goto out;
@@ -45970,7 +45795,7 @@ index 1fc1dca..813fd0b 100644
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
-@@ -2951,7 +3080,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
+@@ -2951,7 +3044,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
if (!task)
goto out;
@@ -45982,7 +45807,7 @@ index 1fc1dca..813fd0b 100644
put_task_struct(task);
out:
return result;
-@@ -3016,6 +3149,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+@@ -3016,6 +3113,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
{
unsigned int nr;
struct task_struct *reaper;
@@ -45994,7 +45819,7 @@ index 1fc1dca..813fd0b 100644
struct tgid_iter iter;
struct pid_namespace *ns;
-@@ -3039,8 +3177,27 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
+@@ -3039,8 +3141,27 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
for (iter = next_tgid(ns, iter);
iter.task;
iter.tgid += 1, iter = next_tgid(ns, iter)) {
@@ -46023,7 +45848,7 @@ index 1fc1dca..813fd0b 100644
put_task_struct(iter.task);
goto out;
}
-@@ -3068,7 +3225,7 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3068,7 +3189,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
@@ -46032,7 +45857,7 @@ index 1fc1dca..813fd0b 100644
INF("syscall", S_IRUGO, proc_pid_syscall),
#endif
INF("cmdline", S_IRUGO, proc_pid_cmdline),
-@@ -3092,10 +3249,10 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3092,10 +3213,10 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -46894,8 +46719,31 @@ index fa2defa..8601650 100644
ret = -EAGAIN;
pipe_unlock(ipipe);
+diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
+index 7fdf6a7..e6cd8ad 100644
+--- a/fs/sysfs/dir.c
++++ b/fs/sysfs/dir.c
+@@ -642,6 +642,18 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
+ struct sysfs_dirent *sd;
+ int rc;
+
++#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
++ const char *parent_name = parent_sd->s_name;
++
++ mode = S_IFDIR | S_IRWXU;
++
++ if ((!strcmp(parent_name, "") && (!strcmp(name, "devices") || !strcmp(name, "fs"))) ||
++ (!strcmp(parent_name, "devices") && !strcmp(name, "system")) ||
++ (!strcmp(parent_name, "fs") && (!strcmp(name, "selinux") || !strcmp(name, "fuse"))) ||
++ (!strcmp(parent_name, "system") && !strcmp(name, "cpu")))
++ mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
++#endif
++
+ /* allocate */
+ sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
+ if (!sd)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
-index d4e6080b..0e58b99 100644
+index 779789a..f58193c 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -37,7 +37,7 @@ static DEFINE_SPINLOCK(sysfs_open_dirent_lock);
@@ -46943,22 +46791,6 @@ index d4e6080b..0e58b99 100644
wake_up_interruptible(&od->poll);
}
-diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
-index e34f0d9..740ea7b 100644
---- a/fs/sysfs/mount.c
-+++ b/fs/sysfs/mount.c
-@@ -36,7 +36,11 @@ struct sysfs_dirent sysfs_root = {
- .s_name = "",
- .s_count = ATOMIC_INIT(1),
- .s_flags = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT),
-+#ifdef CONFIG_GRKERNSEC_SYSFS_RESTRICT
-+ .s_mode = S_IFDIR | S_IRWXU,
-+#else
- .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
-+#endif
- .s_ino = 1,
- };
-
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index a7ac78f..02158e1 100644
--- a/fs/sysfs/symlink.c
@@ -47151,26 +46983,12 @@ index 23ce927..e274cc1 100644
if (!IS_ERR(s))
kfree(s);
-diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
-index ce9268a..ee98d0b 100644
---- a/fs/xfs/xfs_vnodeops.c
-+++ b/fs/xfs/xfs_vnodeops.c
-@@ -131,7 +131,8 @@ xfs_readlink(
- __func__, (unsigned long long) ip->i_ino,
- (long long) pathlen);
- ASSERT(0);
-- return XFS_ERROR(EFSCORRUPTED);
-+ error = XFS_ERROR(EFSCORRUPTED);
-+ goto out;
- }
-
-
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..ab77366
+index 0000000..dfd3d34
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1065 @@
+@@ -0,0 +1,1069 @@
+#
+# grecurity configuration
+#
@@ -47641,15 +47459,19 @@ index 0000000..ab77366
+ depends on SYSFS
+ help
+ If you say Y here, sysfs (the pseudo-filesystem mounted at /sys) and
-+ any filesystem normally mounted under it (e.g. debugfs) will only
-+ be accessible by root. These filesystems generally provide access
++ any filesystem normally mounted under it (e.g. debugfs) will be
++ mostly accessible only by root. These filesystems generally provide access
+ to hardware and debug information that isn't appropriate for unprivileged
+ users of the system. Sysfs and debugfs have also become a large source
+ of new vulnerabilities, ranging from infoleaks to local compromise.
+ There has been very little oversight with an eye toward security involved
+ in adding new exporters of information to these filesystems, so their
+ use is discouraged.
-+ This option is equivalent to a chmod 0700 of the mount paths.
++ For reasons of compatibility, a few directories have been whitelisted
++ for access by non-root users:
++ /sys/fs/selinux
++ /sys/fs/fuse
++ /sys/devices/system/cpu
+
+config GRKERNSEC_ROFS
+ bool "Runtime read-only mount protection"
@@ -56948,10 +56770,10 @@ index 0000000..0dc13c3
+EXPORT_SYMBOL(gr_log_timechange);
diff --git a/grsecurity/grsec_tpe.c b/grsecurity/grsec_tpe.c
new file mode 100644
-index 0000000..4a78774
+index 0000000..a35ba33
--- /dev/null
+++ b/grsecurity/grsec_tpe.c
-@@ -0,0 +1,39 @@
+@@ -0,0 +1,73 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/file.h>
@@ -56966,25 +56788,59 @@ index 0000000..4a78774
+#ifdef CONFIG_GRKERNSEC
+ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
+ const struct cred *cred = current_cred();
++ char *msg = NULL;
++ char *msg2 = NULL;
++
++ // never restrict root
++ if (!cred->uid)
++ return 1;
+
-+ if (cred->uid && ((grsec_enable_tpe &&
++ if (grsec_enable_tpe) {
+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
-+ ((grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid)) ||
-+ (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid)))
++ if (grsec_enable_tpe_invert && !in_group_p(grsec_tpe_gid))
++ msg = "not being in trusted group";
++ else if (!grsec_enable_tpe_invert && in_group_p(grsec_tpe_gid))
++ msg = "being in untrusted group";
+#else
-+ in_group_p(grsec_tpe_gid)
++ if (in_group_p(grsec_tpe_gid))
++ msg = "being in untrusted group";
+#endif
-+ ) || gr_acl_tpe_check()) &&
-+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
-+ (inode->i_mode & S_IWOTH))))) {
-+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
++ }
++ if (!msg && gr_acl_tpe_check())
++ msg = "being in untrusted role";
++
++ // not in any affected group/role
++ if (!msg)
++ goto next_check;
++
++ if (inode->i_uid)
++ msg2 = "file in non-root-owned directory";
++ else if (inode->i_mode & S_IWOTH)
++ msg2 = "file in world-writable directory";
++ else if (inode->i_mode & S_IWGRP)
++ msg2 = "file in group-writable directory";
++
++ if (msg && msg2) {
++ char fullmsg[64] = {0};
++ snprintf(fullmsg, sizeof(fullmsg)-1, "%s and %s", msg, msg2);
++ gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, fullmsg, file->f_path.dentry, file->f_path.mnt);
+ return 0;
+ }
++ msg = NULL;
++next_check:
+#ifdef CONFIG_GRKERNSEC_TPE_ALL
-+ if (cred->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
-+ ((inode->i_uid && (inode->i_uid != cred->uid)) ||
-+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
-+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
++ if (!grsec_enable_tpe || !grsec_enable_tpe_all)
++ return 1;
++
++ if (inode->i_uid && (inode->i_uid != cred->uid))
++ msg = "directory not owned by user";
++ else if (inode->i_mode & S_IWOTH)
++ msg = "file in world-writable directory";
++ else if (inode->i_mode & S_IWGRP)
++ msg = "file in group-writable directory";
++
++ if (msg) {
++ gr_log_str_fs(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, msg, file->f_path.dentry, file->f_path.mnt);
+ return 0;
+ }
+#endif
@@ -57589,7 +57445,7 @@ index b5e2e4c..6a5373e 100644
/**
* PERCPU_SECTION - define output section for percpu area, simple version
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 1f9e951..14ef517 100644
+index bf4b2dc..2d0762f 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -72,6 +72,7 @@
@@ -59014,7 +58870,7 @@ index 0000000..da390f1
+#endif
diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
new file mode 100644
-index 0000000..dfb15ef
+index 0000000..b3347e2
--- /dev/null
+++ b/include/linux/grmsg.h
@@ -0,0 +1,109 @@
@@ -59052,7 +58908,7 @@ index 0000000..dfb15ef
+#define GR_UNSAFESHARE_EXEC_ACL_MSG "denied exec with cloned fs of %.950s by "
+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
-+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
++#define GR_EXEC_TPE_MSG "denied untrusted exec (due to %.64s) of %.950s by "
+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
+#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
@@ -60435,7 +60291,7 @@ index 2148b12..519b820 100644
static inline void anon_vma_merge(struct vm_area_struct *vma,
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 1c4f3e9..c5b241a 100644
+index 1c4f3e9..f29cbeb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -101,6 +101,7 @@ struct bio_list;
@@ -60639,7 +60495,20 @@ index 1c4f3e9..c5b241a 100644
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
struct pid_namespace *ns);
-@@ -2251,7 +2343,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2235,6 +2327,12 @@ static inline void mmdrop(struct mm_struct * mm)
+ extern void mmput(struct mm_struct *);
+ /* Grab a reference to a task's mm, if it is not already going away */
+ extern struct mm_struct *get_task_mm(struct task_struct *task);
++/*
++ * Grab a reference to a task's mm, if it is not already going away
++ * and ptrace_may_access with the mode parameter passed to it
++ * succeeds.
++ */
++extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode);
+ /* Remove the current tasks stale references to the old mm_struct */
+ extern void mm_release(struct task_struct *, struct mm_struct *);
+ /* Allocate a new mm structure and copy contents from tsk->mm */
+@@ -2251,7 +2349,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
extern void exit_itimers(struct signal_struct *);
extern void flush_itimer_signals(void);
@@ -60648,7 +60517,7 @@ index 1c4f3e9..c5b241a 100644
extern void daemonize(const char *, ...);
extern int allow_signal(int);
-@@ -2416,13 +2508,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2416,13 +2514,17 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
#endif
@@ -63319,7 +63188,7 @@ index e6e01b9..619f837 100644
if (group_dead)
diff --git a/kernel/fork.c b/kernel/fork.c
-index da4a6a1..c04943c 100644
+index da4a6a1..0973380 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -280,7 +280,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
@@ -63536,7 +63405,34 @@ index da4a6a1..c04943c 100644
}
static inline int mm_alloc_pgd(struct mm_struct *mm)
-@@ -829,13 +866,14 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
+@@ -644,6 +681,26 @@ struct mm_struct *get_task_mm(struct task_struct *task)
+ }
+ EXPORT_SYMBOL_GPL(get_task_mm);
+
++struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
++{
++ struct mm_struct *mm;
++ int err;
++
++ err = mutex_lock_killable(&task->signal->cred_guard_mutex);
++ if (err)
++ return ERR_PTR(err);
++
++ mm = get_task_mm(task);
++ if (mm && ((mm != current->mm && !ptrace_may_access(task, mode)) ||
++ (mode == PTRACE_MODE_ATTACH && (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))))) {
++ mmput(mm);
++ mm = ERR_PTR(-EACCES);
++ }
++ mutex_unlock(&task->signal->cred_guard_mutex);
++
++ return mm;
++}
++
+ /* Please note the differences between mmput and mm_release.
+ * mmput is called whenever we stop holding onto a mm_struct,
+ * error success whatever.
+@@ -829,13 +886,14 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
spin_unlock(&fs->lock);
return -EAGAIN;
}
@@ -63552,7 +63448,7 @@ index da4a6a1..c04943c 100644
return 0;
}
-@@ -1097,6 +1135,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+@@ -1097,6 +1155,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
#endif
retval = -EAGAIN;
@@ -63562,7 +63458,7 @@ index da4a6a1..c04943c 100644
if (atomic_read(&p->real_cred->user->processes) >=
task_rlimit(p, RLIMIT_NPROC)) {
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
-@@ -1256,6 +1297,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
+@@ -1256,6 +1317,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if (clone_flags & CLONE_THREAD)
p->tgid = current->tgid;
@@ -63571,7 +63467,7 @@ index da4a6a1..c04943c 100644
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
* Clear TID on mm_release()?
-@@ -1418,6 +1461,8 @@ bad_fork_cleanup_count:
+@@ -1418,6 +1481,8 @@ bad_fork_cleanup_count:
bad_fork_free:
free_task(p);
fork_out:
@@ -63580,7 +63476,7 @@ index da4a6a1..c04943c 100644
return ERR_PTR(retval);
}
-@@ -1518,6 +1563,8 @@ long do_fork(unsigned long clone_flags,
+@@ -1518,6 +1583,8 @@ long do_fork(unsigned long clone_flags,
if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr);
@@ -63589,7 +63485,7 @@ index da4a6a1..c04943c 100644
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
-@@ -1627,7 +1674,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
+@@ -1627,7 +1694,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
return 0;
/* don't need lock here; in the worst case we'll do useless copy */
@@ -63598,7 +63494,7 @@ index da4a6a1..c04943c 100644
return 0;
*new_fsp = copy_fs_struct(fs);
-@@ -1716,7 +1763,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
+@@ -1716,7 +1783,8 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
fs = current->fs;
spin_lock(&fs->lock);
current->fs = new_fs;
@@ -66227,7 +66123,7 @@ index 2c71d91..1021f81 100644
struct tasklet_struct *list;
diff --git a/kernel/sys.c b/kernel/sys.c
-index 481611f..0754d86 100644
+index 481611f..4665125 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -158,6 +158,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error)
@@ -66296,7 +66192,29 @@ index 481611f..0754d86 100644
if (nsown_capable(CAP_SETUID)) {
new->suid = new->uid = uid;
if (uid != old->uid) {
-@@ -786,6 +808,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+@@ -775,9 +797,18 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+
+ retval = -EPERM;
+ if (!nsown_capable(CAP_SETUID)) {
+- if (ruid != (uid_t) -1 && ruid != old->uid &&
+- ruid != old->euid && ruid != old->suid)
+- goto error;
++ // if RBAC is enabled, require CAP_SETUID to change
++ // uid to euid (from a suid binary, for instance)
++ // this is a hardening of normal permissions, not
++ // weakening
++ if (gr_acl_is_enabled()) {
++ if (ruid != (uid_t) -1 && ruid != old->uid)
++ goto error;
++ } else {
++ if (ruid != (uid_t) -1 && ruid != old->uid &&
++ ruid != old->euid && ruid != old->suid)
++ goto error;
++ }
+ if (euid != (uid_t) -1 && euid != old->uid &&
+ euid != old->euid && euid != old->suid)
+ goto error;
+@@ -786,6 +817,9 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
goto error;
}
@@ -66306,7 +66224,29 @@ index 481611f..0754d86 100644
if (ruid != (uid_t) -1) {
new->uid = ruid;
if (ruid != old->uid) {
-@@ -850,6 +875,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+@@ -839,9 +873,18 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+
+ retval = -EPERM;
+ if (!nsown_capable(CAP_SETGID)) {
+- if (rgid != (gid_t) -1 && rgid != old->gid &&
+- rgid != old->egid && rgid != old->sgid)
+- goto error;
++ // if RBAC is enabled, require CAP_SETGID to change
++ // gid to egid (from a sgid binary, for instance)
++ // this is a hardening of normal permissions, not
++ // weakening
++ if (gr_acl_is_enabled()) {
++ if (rgid != (gid_t) -1 && rgid != old->gid)
++ goto error;
++ } else {
++ if (rgid != (gid_t) -1 && rgid != old->gid &&
++ rgid != old->egid && rgid != old->sgid)
++ goto error;
++ }
+ if (egid != (gid_t) -1 && egid != old->gid &&
+ egid != old->egid && egid != old->sgid)
+ goto error;
+@@ -850,6 +893,9 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
goto error;
}
@@ -66316,7 +66256,7 @@ index 481611f..0754d86 100644
if (rgid != (gid_t) -1)
new->gid = rgid;
if (egid != (gid_t) -1)
-@@ -896,6 +924,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
+@@ -896,6 +942,9 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
old = current_cred();
old_fsuid = old->fsuid;
@@ -66326,7 +66266,7 @@ index 481611f..0754d86 100644
if (uid == old->uid || uid == old->euid ||
uid == old->suid || uid == old->fsuid ||
nsown_capable(CAP_SETUID)) {
-@@ -906,6 +937,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
+@@ -906,6 +955,7 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
}
}
@@ -66334,7 +66274,7 @@ index 481611f..0754d86 100644
abort_creds(new);
return old_fsuid;
-@@ -932,12 +964,16 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
+@@ -932,12 +982,16 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
if (gid == old->gid || gid == old->egid ||
gid == old->sgid || gid == old->fsgid ||
nsown_capable(CAP_SETGID)) {
@@ -66351,7 +66291,7 @@ index 481611f..0754d86 100644
abort_creds(new);
return old_fsgid;
-@@ -1189,7 +1225,10 @@ static int override_release(char __user *release, int len)
+@@ -1189,7 +1243,10 @@ static int override_release(char __user *release, int len)
}
v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
snprintf(buf, len, "2.6.%u%s", v, rest);
@@ -66363,7 +66303,7 @@ index 481611f..0754d86 100644
}
return ret;
}
-@@ -1243,19 +1282,19 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
+@@ -1243,19 +1300,19 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
return -EFAULT;
down_read(&uts_sem);
@@ -66388,7 +66328,7 @@ index 481611f..0754d86 100644
__OLD_UTS_LEN);
error |= __put_user(0, name->machine + __OLD_UTS_LEN);
up_read(&uts_sem);
-@@ -1720,7 +1759,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
+@@ -1720,7 +1777,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
error = get_dumpable(me->mm);
break;
case PR_SET_DUMPABLE:
@@ -70360,7 +70300,7 @@ index 716eb4a..8d10419 100644
static const int *pcpu_unit_map __read_mostly; /* cpu -> unit */
diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
-index e920aa3..78fe584 100644
+index e920aa3..137702a 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -13,6 +13,7 @@
@@ -70398,21 +70338,40 @@ index e920aa3..78fe584 100644
}
if (nr_pages == 0)
-@@ -298,8 +299,13 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec,
+@@ -298,23 +299,23 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec,
goto free_proc_pages;
}
-+ if (gr_handle_ptrace(task, vm_write ? PTRACE_POKETEXT : PTRACE_ATTACH)) {
-+ rc = -EPERM;
-+ goto put_task_struct;
-+ }
-+
- task_lock(task);
+- task_lock(task);
- if (__ptrace_may_access(task, PTRACE_MODE_ATTACH)) {
-+ if (ptrace_may_access_nolock(task, PTRACE_MODE_ATTACH)) {
- task_unlock(task);
+- task_unlock(task);
++ if (gr_handle_ptrace(task, vm_write ? PTRACE_POKETEXT : PTRACE_ATTACH)) {
rc = -EPERM;
goto put_task_struct;
+ }
+- mm = task->mm;
+
+- if (!mm || (task->flags & PF_KTHREAD)) {
+- task_unlock(task);
+- rc = -EINVAL;
++ mm = mm_access(task, PTRACE_MODE_ATTACH);
++ if (!mm || IS_ERR(mm)) {
++ rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH;
++ /*
++ * Explicitly map EACCES to EPERM as EPERM is a more a
++ * appropriate error code for process_vw_readv/writev
++ */
++ if (rc == -EACCES)
++ rc = -EPERM;
+ goto put_task_struct;
+ }
+
+- atomic_inc(&mm->mm_users);
+- task_unlock(task);
+-
+ for (i = 0; i < riovcnt && iov_l_curr_idx < liovcnt; i++) {
+ rc = process_vm_rw_single_vec(
+ (unsigned long)rvec[i].iov_base, rvec[i].iov_len,
diff --git a/mm/rmap.c b/mm/rmap.c
index a4fd368..e0ffec7 100644
--- a/mm/rmap.c
@@ -72994,7 +72953,7 @@ index 94cdbc5..0cb0063 100644
ts = peer->tcp_ts;
tsage = get_seconds() - peer->tcp_ts_stamp;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
-index a9db4b1..3c03301 100644
+index c89e354..8bd55c8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -87,6 +87,9 @@ int sysctl_tcp_tw_reuse __read_mostly;
@@ -73277,7 +73236,7 @@ index 5a65eea..bd913a1 100644
int udp4_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index 36806de..b86f74c 100644
+index 836c4ea..cbb74dc 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2149,7 +2149,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
@@ -73325,7 +73284,7 @@ index 26cb08c..8af9877 100644
msg.msg_flags = flags;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
-index 331af3b..7789844 100644
+index 361ebf3..d5628fb 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -377,7 +377,7 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
@@ -73415,7 +73374,7 @@ index 331af3b..7789844 100644
static int raw6_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
-index 2dea4bb..dca8ac5 100644
+index b859e4a..f9d1589 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -93,6 +93,10 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
@@ -74282,7 +74241,7 @@ index d9d4970..d5a6a68 100644
return 0;
}
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
-index bf10ea8..aeb4c3e 100644
+index d65f699..05aa6ce 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -41,7 +41,7 @@ static struct phonet_protocol *phonet_proto_get(unsigned int protocol)
@@ -74335,7 +74294,7 @@ index 2ba6e9f..409573f 100644
break;
}
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
-index 3f8d0b1..74635e0 100644
+index 4c7eff3..59c727f 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -613,8 +613,13 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v)
@@ -74795,7 +74754,7 @@ index 54a7cd2..944edae 100644
to += addrlen;
cnt++;
diff --git a/net/socket.c b/net/socket.c
-index 2877647..08e2fde 100644
+index 2dce67a..1e91168 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -88,6 +88,7 @@
@@ -75360,7 +75319,7 @@ index 1983717..4d6102c 100644
sub->evt.event = htohl(event, sub->swap);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
-index b595a3d..b1cd354 100644
+index d99678a..3514a21 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -767,6 +767,12 @@ static struct sock *unix_find_other(struct net *net,
@@ -75851,10 +75810,10 @@ index 5c11312..72742b5 100644
write_hex_cnt = 0;
for (i = 0; i < logo_clutsize; i++) {
diff --git a/security/Kconfig b/security/Kconfig
-index 51bd5a0..8465ae6 100644
+index 51bd5a0..eeabc9f 100644
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -4,6 +4,626 @@
+@@ -4,6 +4,627 @@
menu "Security options"
@@ -76364,6 +76323,7 @@ index 51bd5a0..8465ae6 100644
+
+config PAX_MEMORY_SANITIZE
+ bool "Sanitize all freed memory"
++ depends on !HIBERNATION
+ help
+ By saying Y here the kernel will erase memory pages as soon as they
+ are freed. This in turn reduces the lifetime of data stored in the
@@ -76481,7 +76441,7 @@ index 51bd5a0..8465ae6 100644
config KEYS
bool "Enable access key retention support"
help
-@@ -169,7 +789,7 @@ config INTEL_TXT
+@@ -169,7 +790,7 @@ config INTEL_TXT
config LSM_MMAP_MIN_ADDR
int "Low address space for LSM to protect from user allocation"
depends on SECURITY && SECURITY_SELINUX
diff --git a/3.2.2/4421_grsec-remove-localversion-grsec.patch b/3.2.4/4421_grsec-remove-localversion-grsec.patch
index 31cf878..31cf878 100644
--- a/3.2.2/4421_grsec-remove-localversion-grsec.patch
+++ b/3.2.4/4421_grsec-remove-localversion-grsec.patch
diff --git a/3.2.2/4422_grsec-mute-warnings.patch b/3.2.4/4422_grsec-mute-warnings.patch
index e85abd6..e85abd6 100644
--- a/3.2.2/4422_grsec-mute-warnings.patch
+++ b/3.2.4/4422_grsec-mute-warnings.patch
diff --git a/3.2.2/4423_grsec-remove-protected-paths.patch b/3.2.4/4423_grsec-remove-protected-paths.patch
index 4afb3e2..4afb3e2 100644
--- a/3.2.2/4423_grsec-remove-protected-paths.patch
+++ b/3.2.4/4423_grsec-remove-protected-paths.patch
diff --git a/3.2.2/4425_grsec-pax-without-grsec.patch b/3.2.4/4425_grsec-pax-without-grsec.patch
index 9992f51..9992f51 100644
--- a/3.2.2/4425_grsec-pax-without-grsec.patch
+++ b/3.2.4/4425_grsec-pax-without-grsec.patch
diff --git a/3.2.2/4430_grsec-kconfig-default-gids.patch b/3.2.4/4430_grsec-kconfig-default-gids.patch
index 3c76d91..0807a4e 100644
--- a/3.2.2/4430_grsec-kconfig-default-gids.patch
+++ b/3.2.4/4430_grsec-kconfig-default-gids.patch
@@ -21,7 +21,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
config GRKERNSEC_PROC_ADD
bool "Additional restrictions"
-@@ -658,7 +658,7 @@
+@@ -662,7 +662,7 @@
config GRKERNSEC_AUDIT_GID
int "GID for auditing"
depends on GRKERNSEC_AUDIT_GROUP
@@ -30,7 +30,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
config GRKERNSEC_EXECLOG
bool "Exec logging"
-@@ -864,7 +864,7 @@
+@@ -866,7 +866,7 @@
config GRKERNSEC_TPE_GID
int "GID for untrusted users"
depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
@@ -39,7 +39,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Setting this GID determines what group TPE restrictions will be
*enabled* for. If the sysctl option is enabled, a sysctl option
-@@ -873,7 +873,7 @@
+@@ -875,7 +875,7 @@
config GRKERNSEC_TPE_GID
int "GID for trusted users"
depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
@@ -48,7 +48,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Setting this GID determines what group TPE restrictions will be
*disabled* for. If the sysctl option is enabled, a sysctl option
-@@ -946,7 +946,7 @@
+@@ -948,7 +948,7 @@
config GRKERNSEC_SOCKET_ALL_GID
int "GID to deny all sockets for"
depends on GRKERNSEC_SOCKET_ALL
@@ -57,7 +57,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Here you can choose the GID to disable socket access for. Remember to
add the users you want socket access disabled for to the GID
-@@ -967,7 +967,7 @@
+@@ -969,7 +969,7 @@
config GRKERNSEC_SOCKET_CLIENT_GID
int "GID to deny client sockets for"
depends on GRKERNSEC_SOCKET_CLIENT
@@ -66,7 +66,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
help
Here you can choose the GID to disable client socket access for.
Remember to add the users you want client socket access disabled for to
-@@ -985,7 +985,7 @@
+@@ -987,7 +987,7 @@
config GRKERNSEC_SOCKET_SERVER_GID
int "GID to deny server sockets for"
depends on GRKERNSEC_SOCKET_SERVER
diff --git a/3.2.2/4435_grsec-kconfig-gentoo.patch b/3.2.4/4435_grsec-kconfig-gentoo.patch
index 1e145df..587b7d9 100644
--- a/3.2.2/4435_grsec-kconfig-gentoo.patch
+++ b/3.2.4/4435_grsec-kconfig-gentoo.patch
@@ -341,7 +341,7 @@ diff -Naur a/security/Kconfig b/security/Kconfig
default ""
config PAX_KERNEXEC_MODULE_TEXT
-@@ -555,8 +556,9 @@
+@@ -556,8 +557,9 @@
config PAX_MEMORY_UDEREF
bool "Prevent invalid userland pointer dereference"
diff --git a/3.2.2/4437-grsec-kconfig-proc-user.patch b/3.2.4/4437-grsec-kconfig-proc-user.patch
index 72b894a..72b894a 100644
--- a/3.2.2/4437-grsec-kconfig-proc-user.patch
+++ b/3.2.4/4437-grsec-kconfig-proc-user.patch
diff --git a/3.2.2/4440_selinux-avc_audit-log-curr_ip.patch b/3.2.4/4440_selinux-avc_audit-log-curr_ip.patch
index f9f62df..7c9894c 100644
--- a/3.2.2/4440_selinux-avc_audit-log-curr_ip.patch
+++ b/3.2.4/4440_selinux-avc_audit-log-curr_ip.patch
@@ -28,7 +28,7 @@ Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org>
diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig
--- a/grsecurity/Kconfig 2011-04-17 19:25:54.000000000 -0400
+++ b/grsecurity/Kconfig 2011-04-17 19:32:53.000000000 -0400
-@@ -1295,6 +1295,27 @@
+@@ -1297,6 +1297,27 @@
menu "Logging Options"
depends on GRKERNSEC
diff --git a/3.2.2/4445_disable-compat_vdso.patch b/3.2.4/4445_disable-compat_vdso.patch
index 4742d01..4742d01 100644
--- a/3.2.2/4445_disable-compat_vdso.patch
+++ b/3.2.4/4445_disable-compat_vdso.patch