diff options
author | 2012-02-05 11:21:29 -0500 | |
---|---|---|
committer | 2012-02-05 11:21:29 -0500 | |
commit | cb29449ba86b1b7d605c9b24417178739547505b (patch) | |
tree | b2a00706a601f9aadd0e3f4e0e3574de2524ccca | |
parent | Grsec/PaX: 2.2.2-2.6.32.55-201201272054 + 2.2.2-3.2.2-201201272014 (diff) | |
download | hardened-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_README | 6 | ||||
-rw-r--r-- | 2.6.32/1055_linux-2.6.32.56.patch | 716 | ||||
-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.patch | 6 | ||||
-rw-r--r-- | 2.6.32/4430_grsec-kconfig-default-gids.patch | 14 | ||||
-rw-r--r-- | 2.6.32/4435_grsec-kconfig-gentoo.patch | 4 | ||||
-rw-r--r-- | 2.6.32/4437-grsec-kconfig-proc-user.patch | 4 | ||||
-rw-r--r-- | 2.6.32/4440_selinux-avc_audit-log-curr_ip.patch | 2 | ||||
-rw-r--r-- | 3.2.2/1001_linux-3.2.2.patch | 6552 | ||||
-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.patch | 3760 | ||||
-rw-r--r-- | 3.2.4/1003_linux-3.2.4.patch | 40 | ||||
-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, ®); -- rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); -- rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_TBTT, mask); -- rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, mask); -- rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, mask); -- rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, mask); -- rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); -- rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); -+ reg = 0; -+ if (state == STATE_RADIO_IRQ_ON) { -+ rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, 1); -+ rt2x00_set_field32(®, INT_MASK_CSR_TBTT, 1); -+ rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, 1); -+ rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); -+ rt2x00_set_field32(®, 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, ¶m); +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 |