diff -druNp --no-dereference linux-libre-3.2.91-gnu1/arch/powerpc/include/asm/qe.h linux-libre-3.2.92-gnu1/arch/powerpc/include/asm/qe.h
--- linux-libre-3.2.91-gnu1/arch/powerpc/include/asm/qe.h	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/arch/powerpc/include/asm/qe.h	2017-08-25 21:14:07.000000000 -0400
@@ -193,6 +193,7 @@ static inline int qe_alive_during_sleep(
 #define qe_muram_free cpm_muram_free
 #define qe_muram_addr cpm_muram_addr
 #define qe_muram_offset cpm_muram_offset
+#define qe_muram_dma cpm_muram_dma
 
 /* Structure that defines QE firmware binary files.
  *
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/arch/x86/boot/boot.h linux-libre-3.2.92-gnu1/arch/x86/boot/boot.h
--- linux-libre-3.2.91-gnu1/arch/x86/boot/boot.h	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/arch/x86/boot/boot.h	2017-08-25 21:14:07.000000000 -0400
@@ -16,7 +16,7 @@
 #ifndef BOOT_BOOT_H
 #define BOOT_BOOT_H
 
-#define STACK_SIZE	512	/* Minimum number of bytes for stack */
+#define STACK_SIZE	1024	/* Minimum number of bytes for stack */
 
 #ifndef __ASSEMBLY__
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/arch/x86/mm/numa_32.c linux-libre-3.2.92-gnu1/arch/x86/mm/numa_32.c
--- linux-libre-3.2.91-gnu1/arch/x86/mm/numa_32.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/arch/x86/mm/numa_32.c	2017-08-25 21:14:07.000000000 -0400
@@ -261,5 +261,6 @@ void __init initmem_init(void)
 	printk(KERN_DEBUG "High memory starts at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(highstart_pfn));
 
+	__vmalloc_start_set = true;
 	setup_bootmem_allocator();
 }
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/arch/x86/um/ptrace_64.c linux-libre-3.2.92-gnu1/arch/x86/um/ptrace_64.c
--- linux-libre-3.2.91-gnu1/arch/x86/um/ptrace_64.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/arch/x86/um/ptrace_64.c	2017-08-25 21:14:07.000000000 -0400
@@ -120,7 +120,7 @@ int poke_user(struct task_struct *child,
 	else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
 		(addr <= offsetof(struct user, u_debugreg[7]))) {
 		addr -= offsetof(struct user, u_debugreg[0]);
-		addr = addr >> 2;
+		addr = addr >> 3;
 		if ((addr == 4) || (addr == 5))
 			return -EIO;
 		child->thread.arch.debugregs[addr] = data;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/ata/libata-scsi.c linux-libre-3.2.92-gnu1/drivers/ata/libata-scsi.c
--- linux-libre-3.2.91-gnu1/drivers/ata/libata-scsi.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/ata/libata-scsi.c	2017-08-25 21:14:07.000000000 -0400
@@ -3056,6 +3056,14 @@ static unsigned int ata_scsi_write_same_
 	if (unlikely(!dev->dma_mode))
 		goto invalid_fld;
 
+	/*
+	 * We only allow sending this command through the block layer,
+	 * as it modifies the DATA OUT buffer, which would corrupt user
+	 * memory for SG_IO commands.
+	 */
+	if (unlikely(scmd->request->cmd_type != REQ_TYPE_FS))
+		goto invalid_fld;
+
 	if (unlikely(scmd->cmd_len < 16))
 		goto invalid_fld;
 	scsi_16_lba_len(cdb, &block, &n_block);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/gpu/drm/i915/intel_display.c linux-libre-3.2.92-gnu1/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-3.2.91-gnu1/drivers/gpu/drm/i915/intel_display.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/gpu/drm/i915/intel_display.c	2017-08-25 21:14:07.000000000 -0400
@@ -6995,9 +6995,9 @@ static void do_intel_finish_page_flip(st
 			  &obj->pending_flip.counter);
 
 	wake_up(&dev_priv->pending_flip_queue);
-	schedule_work(&work->work);
-
 	trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
+
+	schedule_work(&work->work);
 }
 
 void intel_finish_page_flip(struct drm_device *dev, int pipe)
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/infiniband/core/uverbs_cmd.c linux-libre-3.2.92-gnu1/drivers/infiniband/core/uverbs_cmd.c
--- linux-libre-3.2.91-gnu1/drivers/infiniband/core/uverbs_cmd.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/infiniband/core/uverbs_cmd.c	2017-08-25 21:14:07.000000000 -0400
@@ -2440,6 +2440,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib
 	struct ib_qp                 *qp;
 	struct ib_uverbs_mcast_entry *mcast;
 	int                           ret = -EINVAL;
+	bool                          found = false;
 
 	if (copy_from_user(&cmd, buf, sizeof cmd))
 		return -EFAULT;
@@ -2448,10 +2449,6 @@ ssize_t ib_uverbs_detach_mcast(struct ib
 	if (!qp)
 		return -EINVAL;
 
-	ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
-	if (ret)
-		goto out_put;
-
 	obj = container_of(qp->uobject, struct ib_uqp_object, uevent.uobject);
 
 	list_for_each_entry(mcast, &obj->mcast_list, list)
@@ -2459,9 +2456,17 @@ ssize_t ib_uverbs_detach_mcast(struct ib
 		    !memcmp(cmd.gid, mcast->gid.raw, sizeof mcast->gid.raw)) {
 			list_del(&mcast->list);
 			kfree(mcast);
+			found = true;
 			break;
 		}
 
+	if (!found) {
+		ret = -EINVAL;
+		goto out_put;
+	}
+
+	ret = ib_detach_mcast(qp, (union ib_gid *)cmd.gid, cmd.mlid);
+
 out_put:
 	put_qp_write(qp);
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/infiniband/core/verbs.c linux-libre-3.2.92-gnu1/drivers/infiniband/core/verbs.c
--- linux-libre-3.2.91-gnu1/drivers/infiniband/core/verbs.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/infiniband/core/verbs.c	2017-08-25 21:14:07.000000000 -0400
@@ -1185,7 +1185,9 @@ int ib_attach_mcast(struct ib_qp *qp, un
 {
 	if (!qp->device->attach_mcast)
 		return -ENOSYS;
-	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+	    lid < 0xC000 ||
+	    lid == be16_to_cpu(IB_LID_PERMISSIVE))
 		return -EINVAL;
 
 	return qp->device->attach_mcast(qp, gid, lid);
@@ -1196,7 +1198,9 @@ int ib_detach_mcast(struct ib_qp *qp, un
 {
 	if (!qp->device->detach_mcast)
 		return -ENOSYS;
-	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
+	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
+	    lid < 0xC000 ||
+	    lid == be16_to_cpu(IB_LID_PERMISSIVE))
 		return -EINVAL;
 
 	return qp->device->detach_mcast(qp, gid, lid);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/Makefile linux-libre-3.2.92-gnu1/drivers/Makefile
--- linux-libre-3.2.91-gnu1/drivers/Makefile	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/Makefile	2017-08-25 21:14:07.000000000 -0400
@@ -73,6 +73,7 @@ obj-$(CONFIG_USB_OTG_UTILS)	+= usb/
 obj-$(CONFIG_USB)		+= usb/
 obj-$(CONFIG_PCI)		+= usb/
 obj-$(CONFIG_USB_GADGET)	+= usb/
+obj-$(CONFIG_OF)		+= usb/
 obj-$(CONFIG_SERIO)		+= input/serio/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
 obj-$(CONFIG_INPUT)		+= input/
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/dvb/dvb-usb/digitv.c linux-libre-3.2.92-gnu1/drivers/media/dvb/dvb-usb/digitv.c
--- linux-libre-3.2.91-gnu1/drivers/media/dvb/dvb-usb/digitv.c	2017-07-18 16:19:06.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/dvb/dvb-usb/digitv.c	2017-08-26 10:02:58.000000000 -0400
@@ -30,6 +30,10 @@ static int digitv_ctrl_msg(struct dvb_us
 {
 	int wo = (rbuf == NULL || rlen == 0); /* write-only */
 	u8 sndbuf[7],rcvbuf[7];
+
+	if (wlen > 4 || rlen > 4)
+		return -EIO;
+
 	memset(sndbuf,0,7); memset(rcvbuf,0,7);
 
 	sndbuf[0] = cmd;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/dvb/dvb-usb/dw2102.c linux-libre-3.2.92-gnu1/drivers/media/dvb/dvb-usb/dw2102.c
--- linux-libre-3.2.91-gnu1/drivers/media/dvb/dvb-usb/dw2102.c	2017-07-18 16:19:26.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/dvb/dvb-usb/dw2102.c	2017-08-26 10:03:03.000000000 -0400
@@ -28,6 +28,9 @@
 #include "stb6100.h"
 #include "stb6100_proc.h"
 
+/* Max transfer size done by I2C transfer functions */
+#define MAX_XFER_SIZE  64
+
 #ifndef USB_PID_DW2102
 #define USB_PID_DW2102 0x2102
 #endif
@@ -231,6 +234,20 @@ static int dw2102_serit_i2c_transfer(str
 
 	switch (num) {
 	case 2:
+		if (msg[0].len != 1) {
+			warn("i2c rd: len=%d is not 1!\n",
+			     msg[0].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+
+		if (2 + msg[1].len > sizeof(buf6)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[1].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+
 		/* read si2109 register by number */
 		buf6[0] = msg[0].addr << 1;
 		buf6[1] = msg[0].len;
@@ -246,6 +263,13 @@ static int dw2102_serit_i2c_transfer(str
 	case 1:
 		switch (msg[0].addr) {
 		case 0x68:
+			if (2 + msg[0].len > sizeof(buf6)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[0].len);
+				num = -EOPNOTSUPP;
+				break;
+			}
+
 			/* write to si2109 register */
 			buf6[0] = msg[0].addr << 1;
 			buf6[1] = msg[0].len;
@@ -287,7 +311,22 @@ static int dw2102_earda_i2c_transfer(str
 	case 2: {
 		/* read */
 		/* first write first register number */
-		u8 ibuf[msg[1].len + 2], obuf[3];
+		u8 ibuf[MAX_XFER_SIZE], obuf[3];
+
+		if (2 + msg[0].len != sizeof(obuf)) {
+			warn("i2c rd: len=%d is not 1!\n",
+			     msg[0].len);
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
+
+		if (2 + msg[1].len > sizeof(ibuf)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[1].len);
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
+
 		obuf[0] = msg[0].addr << 1;
 		obuf[1] = msg[0].len;
 		obuf[2] = msg[0].buf[0];
@@ -304,7 +343,15 @@ static int dw2102_earda_i2c_transfer(str
 		switch (msg[0].addr) {
 		case 0x68: {
 			/* write to register */
-			u8 obuf[msg[0].len + 2];
+			u8 obuf[MAX_XFER_SIZE];
+
+			if (2 + msg[0].len > sizeof(obuf)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[1].len);
+				ret = -EOPNOTSUPP;
+				goto unlock;
+			}
+
 			obuf[0] = msg[0].addr << 1;
 			obuf[1] = msg[0].len;
 			memcpy(obuf + 2, msg[0].buf, msg[0].len);
@@ -314,7 +361,15 @@ static int dw2102_earda_i2c_transfer(str
 		}
 		case 0x61: {
 			/* write to tuner */
-			u8 obuf[msg[0].len + 2];
+			u8 obuf[MAX_XFER_SIZE];
+
+			if (2 + msg[0].len > sizeof(obuf)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[1].len);
+				ret = -EOPNOTSUPP;
+				goto unlock;
+			}
+
 			obuf[0] = msg[0].addr << 1;
 			obuf[1] = msg[0].len;
 			memcpy(obuf + 2, msg[0].buf, msg[0].len);
@@ -341,9 +396,11 @@ static int dw2102_earda_i2c_transfer(str
 
 		break;
 	}
+	ret = num;
 
+unlock:
 	mutex_unlock(&d->i2c_mutex);
-	return num;
+	return ret;
 }
 
 static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
@@ -381,7 +438,15 @@ static int dw2104_i2c_transfer(struct i2
 		default: {
 			if (msg[j].flags == I2C_M_RD) {
 				/* read registers */
-				u8  ibuf[msg[j].len + 2];
+				u8  ibuf[MAX_XFER_SIZE];
+
+				if (2 + msg[j].len > sizeof(ibuf)) {
+					warn("i2c rd: len=%d is too big!\n",
+					     msg[j].len);
+					ret = -EOPNOTSUPP;
+					goto unlock;
+				}
+
 				ret = dw210x_op_rw(d->udev, 0xc3,
 						(msg[j].addr << 1) + 1, 0,
 						ibuf, msg[j].len + 2,
@@ -410,7 +475,15 @@ static int dw2104_i2c_transfer(struct i2
 				} while (len > 0);
 			} else {
 				/* write registers */
-				u8 obuf[msg[j].len + 2];
+				u8 obuf[MAX_XFER_SIZE];
+
+				if (2 + msg[j].len > sizeof(obuf)) {
+					warn("i2c wr: len=%d is too big!\n",
+					     msg[j].len);
+					ret = -EOPNOTSUPP;
+					goto unlock;
+				}
+
 				obuf[0] = msg[j].addr << 1;
 				obuf[1] = msg[j].len;
 				memcpy(obuf + 2, msg[j].buf, msg[j].len);
@@ -423,9 +496,11 @@ static int dw2104_i2c_transfer(struct i2
 		}
 
 	}
+	ret = num;
 
+unlock:
 	mutex_unlock(&d->i2c_mutex);
-	return num;
+	return ret;
 }
 
 static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -443,7 +518,20 @@ static int dw3101_i2c_transfer(struct i2
 	case 2: {
 		/* read */
 		/* first write first register number */
-		u8 ibuf[msg[1].len + 2], obuf[3];
+		u8 ibuf[MAX_XFER_SIZE], obuf[3];
+
+		if (2 + msg[0].len != sizeof(obuf)) {
+			warn("i2c rd: len=%d is not 1!\n",
+			     msg[0].len);
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
+		if (2 + msg[1].len > sizeof(ibuf)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[1].len);
+			ret = -EOPNOTSUPP;
+			goto unlock;
+		}
 		obuf[0] = msg[0].addr << 1;
 		obuf[1] = msg[0].len;
 		obuf[2] = msg[0].buf[0];
@@ -461,7 +549,14 @@ static int dw3101_i2c_transfer(struct i2
 		case 0x60:
 		case 0x0c: {
 			/* write to register */
-			u8 obuf[msg[0].len + 2];
+			u8 obuf[MAX_XFER_SIZE];
+
+			if (2 + msg[0].len > sizeof(obuf)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[0].len);
+				ret = -EOPNOTSUPP;
+				goto unlock;
+			}
 			obuf[0] = msg[0].addr << 1;
 			obuf[1] = msg[0].len;
 			memcpy(obuf + 2, msg[0].buf, msg[0].len);
@@ -486,9 +581,11 @@ static int dw3101_i2c_transfer(struct i2
 				msg[i].flags == 0 ? ">>>" : "<<<");
 		debug_dump(msg[i].buf, msg[i].len, deb_xfer);
 	}
+	ret = num;
 
+unlock:
 	mutex_unlock(&d->i2c_mutex);
-	return num;
+	return ret;
 }
 
 static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -544,7 +641,15 @@ static int s6x0_i2c_transfer(struct i2c_
 		default: {
 			if (msg[j].flags == I2C_M_RD) {
 				/* read registers */
-				u8 ibuf[msg[j].len];
+				u8 ibuf[MAX_XFER_SIZE];
+
+				if (msg[j].len > sizeof(ibuf)) {
+					warn("i2c rd: len=%d is too big!\n",
+					     msg[j].len);
+					ret = -EOPNOTSUPP;
+					goto unlock;
+				}
+
 				ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
 						ibuf, msg[j].len,
 						DW210X_READ_MSG);
@@ -571,7 +676,15 @@ static int s6x0_i2c_transfer(struct i2c_
 				} while (len > 0);
 			} else if (j < (num - 1)) {
 				/* write register addr before read */
-				u8 obuf[msg[j].len + 2];
+				u8 obuf[MAX_XFER_SIZE];
+
+				if (2 + msg[j].len > sizeof(obuf)) {
+					warn("i2c wr: len=%d is too big!\n",
+					     msg[j].len);
+					ret = -EOPNOTSUPP;
+					goto unlock;
+				}
+
 				obuf[0] = msg[j + 1].len;
 				obuf[1] = (msg[j].addr << 1);
 				memcpy(obuf + 2, msg[j].buf, msg[j].len);
@@ -583,7 +696,14 @@ static int s6x0_i2c_transfer(struct i2c_
 				break;
 			} else {
 				/* write registers */
-				u8 obuf[msg[j].len + 2];
+				u8 obuf[MAX_XFER_SIZE];
+
+				if (2 + msg[j].len > sizeof(obuf)) {
+					warn("i2c wr: len=%d is too big!\n",
+					     msg[j].len);
+					ret = -EOPNOTSUPP;
+					goto unlock;
+				}
 				obuf[0] = msg[j].len + 1;
 				obuf[1] = (msg[j].addr << 1);
 				memcpy(obuf + 2, msg[j].buf, msg[j].len);
@@ -596,9 +716,11 @@ static int s6x0_i2c_transfer(struct i2c_
 		}
 		}
 	}
+	ret = num;
 
+unlock:
 	mutex_unlock(&d->i2c_mutex);
-	return num;
+	return ret;
 }
 
 static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
@@ -630,6 +752,13 @@ static int su3000_i2c_transfer(struct i2
 			msg[0].buf[0] = ibuf[1];
 			break;
 		default:
+			if (3 + msg[0].len > sizeof(obuf)) {
+				warn("i2c wr: len=%d is too big!\n",
+				     msg[0].len);
+				num = -EOPNOTSUPP;
+				break;
+			}
+
 			/* always i2c write*/
 			obuf[0] = 0x08;
 			obuf[1] = msg[0].addr;
@@ -645,6 +774,19 @@ static int su3000_i2c_transfer(struct i2
 		break;
 	case 2:
 		/* always i2c read */
+		if (4 + msg[0].len > sizeof(obuf)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[0].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+		if (1 + msg[1].len > sizeof(obuf)) {
+			warn("i2c rd: len=%d is too big!\n",
+			     msg[1].len);
+			num = -EOPNOTSUPP;
+			break;
+		}
+
 		obuf[0] = 0x09;
 		obuf[1] = msg[0].len;
 		obuf[2] = msg[1].len;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/dvb/dvb-usb/ttusb2.c linux-libre-3.2.92-gnu1/drivers/media/dvb/dvb-usb/ttusb2.c
--- linux-libre-3.2.91-gnu1/drivers/media/dvb/dvb-usb/ttusb2.c	2017-07-18 16:20:22.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/dvb/dvb-usb/ttusb2.c	2017-08-26 10:03:40.000000000 -0400
@@ -75,10 +75,21 @@ static int ttusb2_msg(struct dvb_usb_dev
 		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
 {
 	struct ttusb2_state *st = d->priv;
-	u8 s[wlen+4],r[64] = { 0 };
+	u8 *s, *r = NULL;
 	int ret = 0;
 
-	memset(s,0,wlen+4);
+	if (4 + rlen > 64)
+		return -EIO;
+
+	s = kzalloc(wlen+4, GFP_KERNEL);
+	if (!s)
+		return -ENOMEM;
+
+	r = kzalloc(64, GFP_KERNEL);
+	if (!r) {
+		kfree(s);
+		return -ENOMEM;
+	}
 
 	s[0] = 0xaa;
 	s[1] = ++st->id;
@@ -94,12 +105,17 @@ static int ttusb2_msg(struct dvb_usb_dev
 		r[2] != cmd ||
 		(rlen > 0 && r[3] != rlen)) {
 		warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
+		kfree(s);
+		kfree(r);
 		return -EIO;
 	}
 
 	if (rlen > 0)
 		memcpy(rbuf, &r[4], rlen);
 
+	kfree(s);
+	kfree(r);
+
 	return 0;
 }
 
@@ -368,6 +384,22 @@ static int ttusb2_i2c_xfer(struct i2c_ad
 		write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
 		read = msg[i].flags & I2C_M_RD;
 
+		if (3 + msg[i].len > sizeof(obuf)) {
+			err("i2c wr len=%d too high", msg[i].len);
+			break;
+		}
+		if (write_read) {
+			if (3 + msg[i+1].len > sizeof(ibuf)) {
+				err("i2c rd len=%d too high", msg[i+1].len);
+				break;
+			}
+		} else if (read) {
+			if (3 + msg[i].len > sizeof(ibuf)) {
+				err("i2c rd len=%d too high", msg[i].len);
+				break;
+			}
+		}
+
 		obuf[0] = (msg[i].addr << 1) | (write_read | read);
 		if (read)
 			obuf[1] = 0;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/rc/mceusb.c linux-libre-3.2.92-gnu1/drivers/media/rc/mceusb.c
--- linux-libre-3.2.91-gnu1/drivers/media/rc/mceusb.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/rc/mceusb.c	2017-08-25 21:14:07.000000000 -0400
@@ -1301,8 +1301,8 @@ static int __devinit mceusb_dev_probe(st
 				"found\n");
 		}
 	}
-	if (ep_in == NULL) {
-		mce_dbg(&intf->dev, "inbound and/or endpoint not found\n");
+	if (!ep_in || !ep_out) {
+		mce_dbg(&intf->dev, "required endpoints not found\n");
 		return -ENODEV;
 	}
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c linux-libre-3.2.92-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/cx231xx/cx231xx-audio.c	2017-08-25 21:14:07.000000000 -0400
@@ -652,10 +652,8 @@ static int cx231xx_audio_init(struct cx2
 
 	spin_lock_init(&adev->slock);
 	err = snd_pcm_new(card, "Cx231xx Audio", 0, 0, 1, &pcm);
-	if (err < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if (err < 0)
+		goto err_free_card;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
 			&snd_cx231xx_pcm_capture);
@@ -670,10 +668,9 @@ static int cx231xx_audio_init(struct cx2
 	INIT_WORK(&dev->wq_trigger, audio_trigger);
 
 	err = snd_card_register(card);
-	if (err < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if (err < 0)
+		goto err_free_card;
+
 	adev->sndcard = card;
 	adev->udev = dev->udev;
 
@@ -683,6 +680,11 @@ static int cx231xx_audio_init(struct cx2
 					    hs_config_info[0].interface_info.
 					    audio_index + 1];
 
+	if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
+		err = -ENODEV;
+		goto err_free_card;
+	}
+
 	adev->end_point_addr =
 	    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
 			bEndpointAddress);
@@ -691,15 +693,21 @@ static int cx231xx_audio_init(struct cx2
 	cx231xx_info("EndPoint Addr 0x%x, Alternate settings: %i\n",
 		     adev->end_point_addr, adev->num_alt);
 	adev->alt_max_pkt_size = kmalloc(32 * adev->num_alt, GFP_KERNEL);
-
-	if (adev->alt_max_pkt_size == NULL) {
+	if (!adev->alt_max_pkt_size) {
 		cx231xx_errdev("out of memory!\n");
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_free_card;
 	}
 
 	for (i = 0; i < adev->num_alt; i++) {
-		u16 tmp =
-		    le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
+		u16 tmp;
+
+		if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
+			err = -ENODEV;
+			goto err_free_pkt_size;
+		}
+
+		tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.
 				wMaxPacketSize);
 		adev->alt_max_pkt_size[i] =
 		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -708,6 +716,13 @@ static int cx231xx_audio_init(struct cx2
 	}
 
 	return 0;
+
+err_free_pkt_size:
+	kfree(adev->alt_max_pkt_size);
+err_free_card:
+	snd_card_free(card);
+
+	return err;
 }
 
 static int cx231xx_audio_fini(struct cx231xx *dev)
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c linux-libre-3.2.92-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2017-07-18 16:18:40.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/cx231xx/cx231xx-cards.c	2017-08-26 10:02:35.000000000 -0400
@@ -863,7 +863,6 @@ static int cx231xx_init_dev(struct cx231
 {
 	struct cx231xx *dev = *devhandle;
 	int retval = -ENOMEM;
-	int errCode;
 	unsigned int maxh, maxw;
 
 	dev->udev = udev;
@@ -899,8 +898,8 @@ static int cx231xx_init_dev(struct cx231
 	/* Cx231xx pre card setup */
 	cx231xx_pre_card_setup(dev);
 
-	errCode = cx231xx_config(dev);
-	if (errCode) {
+	retval = cx231xx_config(dev);
+	if (retval) {
 		cx231xx_errdev("error configuring device\n");
 		return -ENOMEM;
 	}
@@ -909,12 +908,11 @@ static int cx231xx_init_dev(struct cx231
 	dev->norm = dev->board.norm;
 
 	/* register i2c bus */
-	errCode = cx231xx_dev_init(dev);
-	if (errCode < 0) {
-		cx231xx_dev_uninit(dev);
+	retval = cx231xx_dev_init(dev);
+	if (retval) {
 		cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
-			       __func__, errCode);
-		return errCode;
+			       __func__, retval);
+		goto err_dev_init;
 	}
 
 	/* Do board specific init */
@@ -932,11 +930,11 @@ static int cx231xx_init_dev(struct cx231
 	dev->interlaced = 0;
 	dev->video_input = 0;
 
-	errCode = cx231xx_config(dev);
-	if (errCode < 0) {
+	retval = cx231xx_config(dev);
+	if (retval) {
 		cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
-			       __func__, errCode);
-		return errCode;
+			       __func__, retval);
+		goto err_dev_init;
 	}
 
 	/* init video dma queues */
@@ -960,9 +958,9 @@ static int cx231xx_init_dev(struct cx231
 	}
 
 	retval = cx231xx_register_analog_devices(dev);
-	if (retval < 0) {
-		cx231xx_release_resources(dev);
-		return retval;
+	if (retval) {
+		cx231xx_release_analog_resources(dev);
+		goto err_analog;
 	}
 
 	cx231xx_ir_init(dev);
@@ -970,6 +968,11 @@ static int cx231xx_init_dev(struct cx231
 	cx231xx_init_extension(dev);
 
 	return 0;
+err_analog:
+	cx231xx_remove_from_devlist(dev);
+err_dev_init:
+	cx231xx_dev_uninit(dev);
+	return retval;
 }
 
 #if defined(CONFIG_MODULES) && defined(MODULE)
@@ -1019,7 +1022,6 @@ static int cx231xx_usb_probe(struct usb_
 	struct usb_interface *lif = NULL;
 	struct usb_interface_assoc_descriptor *assoc_desc;
 
-	udev = usb_get_dev(interface_to_usbdev(interface));
 	ifnum = interface->altsetting[0].desc.bInterfaceNumber;
 
 	/*
@@ -1048,6 +1050,8 @@ static int cx231xx_usb_probe(struct usb_
 		return -ENOMEM;
 	}
 
+	udev = usb_get_dev(interface_to_usbdev(interface));
+
 	snprintf(dev->name, 29, "cx231xx #%d", nr);
 	dev->devno = nr;
 	dev->model = id->driver_info;
@@ -1126,10 +1130,8 @@ static int cx231xx_usb_probe(struct usb_
 	if (assoc_desc->bFirstInterface != ifnum) {
 		cx231xx_err(DRIVER_NAME ": Not found "
 			    "matching IAD interface\n");
-		cx231xx_devused &= ~(1 << nr);
-		kfree(dev);
-		dev = NULL;
-		return -ENODEV;
+		retval = -ENODEV;
+		goto err_if;
 	}
 
 	cx231xx_info("registering interface %d\n", ifnum);
@@ -1145,27 +1147,21 @@ static int cx231xx_usb_probe(struct usb_
 	retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
 	if (retval) {
 		cx231xx_errdev("v4l2_device_register failed\n");
-		cx231xx_devused &= ~(1 << nr);
-		kfree(dev);
-		dev = NULL;
-		return -EIO;
+		retval = -EIO;
+		goto err_v4l2;
 	}
 	/* allocate device struct */
 	retval = cx231xx_init_dev(&dev, udev, nr);
-	if (retval) {
-		cx231xx_devused &= ~(1 << dev->devno);
-		v4l2_device_unregister(&dev->v4l2_dev);
-		kfree(dev);
-		dev = NULL;
-		usb_set_intfdata(lif, NULL);
-
-		return retval;
-	}
+	if (retval)
+		goto err_init;
 
 	/* compute alternate max packet sizes for video */
 	uif = udev->actconfig->interface[dev->current_pcb_config.
 		       hs_config_info[0].interface_info.video_index + 1];
 
+	if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
+		return -ENODEV;
+
 	dev->video_mode.end_point_addr = le16_to_cpu(uif->altsetting[0].
 			endpoint[isoc_pipe].desc.bEndpointAddress);
 
@@ -1178,16 +1174,17 @@ static int cx231xx_usb_probe(struct usb_
 
 	if (dev->video_mode.alt_max_pkt_size == NULL) {
 		cx231xx_errdev("out of memory!\n");
-		cx231xx_devused &= ~(1 << nr);
-		v4l2_device_unregister(&dev->v4l2_dev);
-		kfree(dev);
-		dev = NULL;
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err_video_alt;
 	}
 
 	for (i = 0; i < dev->video_mode.num_alt; i++) {
-		u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
-				desc.wMaxPacketSize);
+		u16 tmp;
+
+		if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
+			return -ENODEV;
+
+		tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize);
 		dev->video_mode.alt_max_pkt_size[i] =
 		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
 		cx231xx_info("Alternate setting %i, max size= %i\n", i,
@@ -1199,6 +1196,9 @@ static int cx231xx_usb_probe(struct usb_
 				       hs_config_info[0].interface_info.
 				       vanc_index + 1];
 
+	if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
+		return -ENODEV;
+
 	dev->vbi_mode.end_point_addr =
 	    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
 			bEndpointAddress);
@@ -1212,16 +1212,17 @@ static int cx231xx_usb_probe(struct usb_
 
 	if (dev->vbi_mode.alt_max_pkt_size == NULL) {
 		cx231xx_errdev("out of memory!\n");
-		cx231xx_devused &= ~(1 << nr);
-		v4l2_device_unregister(&dev->v4l2_dev);
-		kfree(dev);
-		dev = NULL;
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err_vbi_alt;
 	}
 
 	for (i = 0; i < dev->vbi_mode.num_alt; i++) {
-		u16 tmp =
-		    le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+		u16 tmp;
+
+		if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
+			return -ENODEV;
+
+		tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
 				desc.wMaxPacketSize);
 		dev->vbi_mode.alt_max_pkt_size[i] =
 		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -1234,6 +1235,9 @@ static int cx231xx_usb_probe(struct usb_
 				       hs_config_info[0].interface_info.
 				       hanc_index + 1];
 
+	if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1)
+		return -ENODEV;
+
 	dev->sliced_cc_mode.end_point_addr =
 	    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].desc.
 			bEndpointAddress);
@@ -1247,15 +1251,17 @@ static int cx231xx_usb_probe(struct usb_
 
 	if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
 		cx231xx_errdev("out of memory!\n");
-		cx231xx_devused &= ~(1 << nr);
-		v4l2_device_unregister(&dev->v4l2_dev);
-		kfree(dev);
-		dev = NULL;
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err_sliced_cc_alt;
 	}
 
 	for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
-		u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
+		u16 tmp;
+
+		if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1)
+			return -ENODEV;
+
+		tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].
 				desc.wMaxPacketSize);
 		dev->sliced_cc_mode.alt_max_pkt_size[i] =
 		    (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
@@ -1270,6 +1276,11 @@ static int cx231xx_usb_probe(struct usb_
 					       interface_info.
 					       ts1_index + 1];
 
+		if (uif->altsetting[0].desc.bNumEndpoints < isoc_pipe + 1) {
+			retval = -ENODEV;
+			goto err_video_alt;
+		}
+
 		dev->ts1_mode.end_point_addr =
 		    le16_to_cpu(uif->altsetting[0].endpoint[isoc_pipe].
 				desc.bEndpointAddress);
@@ -1283,15 +1294,19 @@ static int cx231xx_usb_probe(struct usb_
 
 		if (dev->ts1_mode.alt_max_pkt_size == NULL) {
 			cx231xx_errdev("out of memory!\n");
-			cx231xx_devused &= ~(1 << nr);
-			v4l2_device_unregister(&dev->v4l2_dev);
-			kfree(dev);
-			dev = NULL;
-			return -ENOMEM;
+			retval = -ENOMEM;
+			goto err_ts1_alt;
 		}
 
 		for (i = 0; i < dev->ts1_mode.num_alt; i++) {
-			u16 tmp = le16_to_cpu(uif->altsetting[i].
+			u16 tmp;
+
+			if (uif->altsetting[i].desc.bNumEndpoints < isoc_pipe + 1) {
+				retval = -ENODEV;
+				goto err_video_alt;
+			}
+
+			tmp = le16_to_cpu(uif->altsetting[i].
 						endpoint[isoc_pipe].desc.
 						wMaxPacketSize);
 			dev->ts1_mode.alt_max_pkt_size[i] =
@@ -1314,6 +1329,29 @@ static int cx231xx_usb_probe(struct usb_
 	request_modules(dev);
 
 	return 0;
+err_ts1_alt:
+	kfree(dev->sliced_cc_mode.alt_max_pkt_size);
+err_sliced_cc_alt:
+	kfree(dev->vbi_mode.alt_max_pkt_size);
+err_vbi_alt:
+	kfree(dev->video_mode.alt_max_pkt_size);
+err_video_alt:
+	/* cx231xx_uninit_dev: */
+	cx231xx_close_extension(dev);
+	cx231xx_ir_exit(dev);
+	cx231xx_release_analog_resources(dev);
+	cx231xx_417_unregister(dev);
+	cx231xx_remove_from_devlist(dev);
+	cx231xx_dev_uninit(dev);
+err_init:
+	v4l2_device_unregister(&dev->v4l2_dev);
+err_v4l2:
+	usb_set_intfdata(lif, NULL);
+err_if:
+	usb_put_dev(udev);
+	kfree(dev);
+	cx231xx_devused &= ~(1 << nr);
+	return retval;
 }
 
 /*
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/gspca/konica.c linux-libre-3.2.92-gnu1/drivers/media/video/gspca/konica.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/gspca/konica.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/gspca/konica.c	2017-08-25 21:14:07.000000000 -0400
@@ -290,6 +290,9 @@ static int sd_start(struct gspca_dev *gs
 		return -EIO;
 	}
 
+	if (alt->desc.bNumEndpoints < 2)
+		return -ENODEV;
+
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 
 	reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/ov2640.c linux-libre-3.2.92-gnu1/drivers/media/video/ov2640.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/ov2640.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/ov2640.c	2017-08-25 21:14:07.000000000 -0400
@@ -687,8 +687,10 @@ static int ov2640_s_ctrl(struct v4l2_ctr
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
-		val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
-		return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
+		val = ctrl->val ? REG04_VFLIP_IMG | REG04_VREF_EN : 0x00;
+		return ov2640_mask_set(client, REG04,
+				       REG04_VFLIP_IMG | REG04_VREF_EN, val);
+		/* NOTE: REG04_VREF_EN: 1 line shift / even/odd line swap */
 	case V4L2_CID_HFLIP:
 		val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
 		return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c linux-libre-3.2.92-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/pvrusb2/pvrusb2-eeprom.c	2017-08-25 21:14:07.000000000 -0400
@@ -123,15 +123,10 @@ int pvr2_eeprom_analyze(struct pvr2_hdw
 	memset(&tvdata,0,sizeof(tvdata));
 
 	eeprom = pvr2_eeprom_fetch(hdw);
-	if (!eeprom) return -EINVAL;
+	if (!eeprom)
+		return -EINVAL;
 
-	{
-		struct i2c_client fake_client;
-		/* Newer version expects a useless client interface */
-		fake_client.addr = hdw->eeprom_addr;
-		fake_client.adapter = &hdw->i2c_adap;
-		tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom);
-	}
+	tveeprom_hauppauge_analog(NULL, &tvdata, eeprom);
 
 	trace_eeprom("eeprom assumed v4l tveeprom module");
 	trace_eeprom("eeprom direct call results:");
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/usbvision/usbvision-video.c linux-libre-3.2.92-gnu1/drivers/media/video/usbvision/usbvision-video.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/usbvision/usbvision-video.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/usbvision/usbvision-video.c	2017-08-25 21:14:07.000000000 -0400
@@ -1564,7 +1564,14 @@ static int __devinit usbvision_probe(str
 	}
 
 	for (i = 0; i < usbvision->num_alt; i++) {
-		u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
+		u16 tmp;
+
+		if (uif->altsetting[i].desc.bNumEndpoints < 2) {
+			ret = -ENODEV;
+			goto err_pkt;
+		}
+
+		tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
 				      wMaxPacketSize);
 		usbvision->alt_max_pkt_size[i] =
 			(tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/media/video/zr364xx.c linux-libre-3.2.92-gnu1/drivers/media/video/zr364xx.c
--- linux-libre-3.2.91-gnu1/drivers/media/video/zr364xx.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/media/video/zr364xx.c	2017-08-25 21:14:07.000000000 -0400
@@ -611,6 +611,14 @@ static int zr364xx_read_video_callback(s
 	ptr = pdest = frm->lpvbits;
 
 	if (frm->ulState == ZR364XX_READ_IDLE) {
+		if (purb->actual_length < 128) {
+			/* header incomplete */
+			dev_info(&cam->udev->dev,
+				 "%s: buffer (%d bytes) too small to hold jpeg header. Discarding.\n",
+				 __func__, purb->actual_length);
+			return -EINVAL;
+		}
+
 		frm->ulState = ZR364XX_READ_FRAME;
 		frm->cur_size = 0;
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/net/ethernet/freescale/ucc_geth.c linux-libre-3.2.92-gnu1/drivers/net/ethernet/freescale/ucc_geth.c
--- linux-libre-3.2.91-gnu1/drivers/net/ethernet/freescale/ucc_geth.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/net/ethernet/freescale/ucc_geth.c	2017-08-25 21:14:07.000000000 -0400
@@ -2591,11 +2591,10 @@ static int ucc_geth_startup(struct ucc_g
 		} else if (ugeth->ug_info->uf_info.bd_mem_part ==
 			   MEM_PART_MURAM) {
 			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
-				 (u32) immrbar_virt_to_phys(ugeth->
-							    p_tx_bd_ring[i]));
+				 (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i]));
 			out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].
 				 last_bd_completed_address,
-				 (u32) immrbar_virt_to_phys(endOfRing));
+				 (u32)qe_muram_dma(endOfRing));
 		}
 	}
 
@@ -2856,8 +2855,7 @@ static int ucc_geth_startup(struct ucc_g
 		} else if (ugeth->ug_info->uf_info.bd_mem_part ==
 			   MEM_PART_MURAM) {
 			out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr,
-				 (u32) immrbar_virt_to_phys(ugeth->
-							    p_rx_bd_ring[i]));
+				 (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i]));
 		}
 		/* rest of fields handled by QE */
 	}
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/net/wireless/ath/ath9k/hif_usb.c linux-libre-3.2.92-gnu1/drivers/net/wireless/ath/ath9k/hif_usb.c
--- linux-libre-3.2.91-gnu1/drivers/net/wireless/ath/ath9k/hif_usb.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/net/wireless/ath/ath9k/hif_usb.c	2017-08-25 21:14:07.000000000 -0400
@@ -38,7 +38,10 @@ static struct usb_device_id ath9k_hif_us
 	{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
 	{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
 	{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
+	{ USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
 	{ USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
+	{ USB_DEVICE(0x0471, 0x209e) }, /* Philips (or NXP) PTA01 */
+	{ USB_DEVICE(0x1eda, 0x2315) }, /* AirTies */
 
 	{ USB_DEVICE(0x0cf3, 0x7015),
 	  .driver_info = AR9287_USB },  /* Atheros */
@@ -53,6 +56,12 @@ static struct usb_device_id ath9k_hif_us
 	  .driver_info = AR9280_USB },  /* SMC Networks */
 	{ USB_DEVICE(0x0411, 0x017f),
 	  .driver_info = AR9280_USB },  /* Sony UWA-BR100 */
+	{ USB_DEVICE(0x0411, 0x0197),
+	  .driver_info = AR9280_USB },  /* Buffalo WLI-UV-AG300P */
+	{ USB_DEVICE(0x04da, 0x3904),
+	  .driver_info = AR9280_USB },
+	{ USB_DEVICE(0x0930, 0x0a08),
+	  .driver_info = AR9280_USB },  /* Toshiba WLM-20U2 and GN-1080 */
 
 	{ USB_DEVICE(0x0cf3, 0x20ff),
 	  .driver_info = STORAGE_DEVICE },
@@ -1095,6 +1104,9 @@ static int send_eject_command(struct usb
 	u8 bulk_out_ep;
 	int r;
 
+	if (iface_desc->desc.bNumEndpoints < 2)
+		return -ENODEV;
+
 	/* Find bulk out endpoint */
 	for (r = 1; r >= 0; r--) {
 		endpoint = &iface_desc->endpoint[r].desc;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c linux-libre-3.2.92-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c
--- linux-libre-3.2.91-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c	2017-07-18 16:32:12.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/net/wireless/zd1211rw/zd_usb.c	2017-08-26 10:11:26.000000000 -0400
@@ -1276,6 +1276,9 @@ static int eject_installer(struct usb_in
 	u8 bulk_out_ep;
 	int r;
 
+	if (iface_desc->desc.bNumEndpoints < 2)
+		return -ENODEV;
+
 	/* Find bulk out endpoint */
 	for (r = 1; r >= 0; r--) {
 		endpoint = &iface_desc->endpoint[r].desc;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/pci/pci.c linux-libre-3.2.92-gnu1/drivers/pci/pci.c
--- linux-libre-3.2.91-gnu1/drivers/pci/pci.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/pci/pci.c	2017-08-25 21:14:07.000000000 -0400
@@ -1478,8 +1478,8 @@ static void pci_pme_list_scan(struct wor
 			}
 		}
 		if (!list_empty(&pci_pme_list))
-			schedule_delayed_work(&pci_pme_work,
-					      msecs_to_jiffies(PME_TIMEOUT));
+			queue_delayed_work(system_freezable_wq, &pci_pme_work,
+					   msecs_to_jiffies(PME_TIMEOUT));
 	}
 	mutex_unlock(&pci_pme_list_mutex);
 }
@@ -1528,8 +1528,9 @@ void pci_pme_active(struct pci_dev *dev,
 			mutex_lock(&pci_pme_list_mutex);
 			list_add(&pme_dev->list, &pci_pme_list);
 			if (list_is_singular(&pci_pme_list))
-				schedule_delayed_work(&pci_pme_work,
-						      msecs_to_jiffies(PME_TIMEOUT));
+				queue_delayed_work(system_freezable_wq,
+						   &pci_pme_work,
+						   msecs_to_jiffies(PME_TIMEOUT));
 			mutex_unlock(&pci_pme_list_mutex);
 		} else {
 			mutex_lock(&pci_pme_list_mutex);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/pci/pci-sysfs.c linux-libre-3.2.92-gnu1/drivers/pci/pci-sysfs.c
--- linux-libre-3.2.91-gnu1/drivers/pci/pci-sysfs.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/pci/pci-sysfs.c	2017-08-25 21:14:07.000000000 -0400
@@ -772,15 +772,19 @@ void pci_remove_legacy_files(struct pci_
 int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
 		  enum pci_mmap_api mmap_api)
 {
-	unsigned long nr, start, size, pci_start;
+	unsigned long nr, start, size;
+	resource_size_t pci_start = 0, pci_end;
 
 	if (pci_resource_len(pdev, resno) == 0)
 		return 0;
 	nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 	start = vma->vm_pgoff;
 	size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
-	pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
-			pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
+	if (mmap_api == PCI_MMAP_PROCFS) {
+		pci_resource_to_user(pdev, resno, &pdev->resource[resno],
+				     &pci_start, &pci_end);
+		pci_start >>= PAGE_SHIFT;
+	}
 	if (start >= pci_start && start < pci_start + size &&
 			start + nr <= pci_start + size)
 		return 1;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/pci/proc.c linux-libre-3.2.92-gnu1/drivers/pci/proc.c
--- linux-libre-3.2.91-gnu1/drivers/pci/proc.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/pci/proc.c	2017-08-25 21:14:07.000000000 -0400
@@ -249,23 +249,35 @@ static int proc_bus_pci_mmap(struct file
 	const struct proc_dir_entry *dp = PDE(inode);
 	struct pci_dev *dev = dp->data;
 	struct pci_filp_private *fpriv = file->private_data;
-	int i, ret;
+	int i, ret, write_combine = 0, res_bit;
 
 	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
 
+	if (fpriv->mmap_state == pci_mmap_io)
+		res_bit = IORESOURCE_IO;
+	else
+		res_bit = IORESOURCE_MEM;
+
 	/* Make sure the caller is mapping a real resource for this device */
 	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
-		if (pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
+		if (dev->resource[i].flags & res_bit &&
+		    pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
 			break;
 	}
 
 	if (i >= PCI_ROM_RESOURCE)
 		return -ENODEV;
 
+	if (fpriv->mmap_state == pci_mmap_mem &&
+	    fpriv->write_combine) {
+		if (dev->resource[i].flags & IORESOURCE_PREFETCH)
+			write_combine = 1;
+		else
+			return -EINVAL;
+	}
 	ret = pci_mmap_page_range(dev, vma,
-				  fpriv->mmap_state,
-				  fpriv->write_combine);
+				  fpriv->mmap_state, write_combine);
 	if (ret < 0)
 		return ret;
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/pci/quirks.c linux-libre-3.2.92-gnu1/drivers/pci/quirks.c
--- linux-libre-3.2.91-gnu1/drivers/pci/quirks.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/pci/quirks.c	2017-08-25 21:14:07.000000000 -0400
@@ -1733,6 +1733,29 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	0x260b, quirk_intel_pcie_pm);
 
 #ifdef CONFIG_X86_IO_APIC
+static int dmi_disable_ioapicreroute(const struct dmi_system_id *d)
+{
+	noioapicreroute = 1;
+	pr_info("%s detected: disable boot interrupt reroute\n", d->ident);
+
+	return 0;
+}
+
+static struct dmi_system_id boot_interrupt_dmi_table[] = {
+	/*
+	 * Systems to exclude from boot interrupt reroute quirks
+	 */
+	{
+		.callback = dmi_disable_ioapicreroute,
+		.ident = "ASUSTek Computer INC. M2N-LR",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "M2N-LR"),
+		},
+	},
+	{}
+};
+
 /*
  * Boot interrupts on some chipsets cannot be turned off. For these chipsets,
  * remap the original interrupt in the linux kernel to the boot interrupt, so
@@ -1741,6 +1764,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
  */
 static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
 {
+	dmi_check_system(boot_interrupt_dmi_table);
 	if (noioapicquirk || noioapicreroute)
 		return;
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/power/pda_power.c linux-libre-3.2.92-gnu1/drivers/power/pda_power.c
--- linux-libre-3.2.91-gnu1/drivers/power/pda_power.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/power/pda_power.c	2017-08-25 21:14:07.000000000 -0400
@@ -33,9 +33,9 @@ static inline unsigned int get_irq_flags
 static struct device *dev;
 static struct pda_power_pdata *pdata;
 static struct resource *ac_irq, *usb_irq;
-static struct timer_list charger_timer;
-static struct timer_list supply_timer;
-static struct timer_list polling_timer;
+static struct delayed_work charger_work;
+static struct delayed_work polling_work;
+static struct delayed_work supply_work;
 static int polling;
 
 #ifdef CONFIG_USB_OTG_UTILS
@@ -144,7 +144,7 @@ static void update_charger(void)
 	}
 }
 
-static void supply_timer_func(unsigned long unused)
+static void supply_work_func(struct work_struct *work)
 {
 	if (ac_status == PDA_PSY_TO_CHANGE) {
 		ac_status = new_ac_status;
@@ -165,11 +165,12 @@ static void psy_changed(void)
 	 * Okay, charger set. Now wait a bit before notifying supplicants,
 	 * charge power should stabilize.
 	 */
-	mod_timer(&supply_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_charger));
+	cancel_delayed_work(&supply_work);
+	schedule_delayed_work(&supply_work,
+			      msecs_to_jiffies(pdata->wait_for_charger));
 }
 
-static void charger_timer_func(unsigned long unused)
+static void charger_work_func(struct work_struct *work)
 {
 	update_status();
 	psy_changed();
@@ -188,13 +189,14 @@ static irqreturn_t power_changed_isr(int
 	 * Wait a bit before reading ac/usb line status and setting charger,
 	 * because ac/usb status readings may lag from irq.
 	 */
-	mod_timer(&charger_timer,
-		  jiffies + msecs_to_jiffies(pdata->wait_for_status));
+	cancel_delayed_work(&charger_work);
+	schedule_delayed_work(&charger_work,
+			      msecs_to_jiffies(pdata->wait_for_status));
 
 	return IRQ_HANDLED;
 }
 
-static void polling_timer_func(unsigned long unused)
+static void polling_work_func(struct work_struct *work)
 {
 	int changed = 0;
 
@@ -215,8 +217,9 @@ static void polling_timer_func(unsigned
 	if (changed)
 		psy_changed();
 
-	mod_timer(&polling_timer,
-		  jiffies + msecs_to_jiffies(pdata->polling_interval));
+	cancel_delayed_work(&polling_work);
+	schedule_delayed_work(&polling_work,
+			      msecs_to_jiffies(pdata->polling_interval));
 }
 
 #ifdef CONFIG_USB_OTG_UTILS
@@ -262,8 +265,8 @@ static int pda_power_probe(struct platfo
 	if (!pdata->ac_max_uA)
 		pdata->ac_max_uA = 500000;
 
-	setup_timer(&charger_timer, charger_timer_func, 0);
-	setup_timer(&supply_timer, supply_timer_func, 0);
+	INIT_DELAYED_WORK(&charger_work, charger_work_func);
+	INIT_DELAYED_WORK(&supply_work, supply_work_func);
 
 	ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac");
 	usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb");
@@ -333,9 +336,10 @@ static int pda_power_probe(struct platfo
 
 	if (polling) {
 		dev_dbg(dev, "will poll for status\n");
-		setup_timer(&polling_timer, polling_timer_func, 0);
-		mod_timer(&polling_timer,
-			  jiffies + msecs_to_jiffies(pdata->polling_interval));
+		INIT_DELAYED_WORK(&polling_work, polling_work_func);
+		cancel_delayed_work(&polling_work);
+		schedule_delayed_work(&polling_work,
+				      msecs_to_jiffies(pdata->polling_interval));
 	}
 
 	if (ac_irq || usb_irq)
@@ -376,9 +380,9 @@ static int pda_power_remove(struct platf
 		free_irq(ac_irq->start, &pda_psy_ac);
 
 	if (polling)
-		del_timer_sync(&polling_timer);
-	del_timer_sync(&charger_timer);
-	del_timer_sync(&supply_timer);
+		cancel_delayed_work_sync(&polling_work);
+	cancel_delayed_work_sync(&charger_work);
+	cancel_delayed_work_sync(&supply_work);
 
 	if (pdata->is_usb_online)
 		power_supply_unregister(&pda_psy_usb);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/tty/serial/sh-sci.c linux-libre-3.2.92-gnu1/drivers/tty/serial/sh-sci.c
--- linux-libre-3.2.91-gnu1/drivers/tty/serial/sh-sci.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/tty/serial/sh-sci.c	2017-08-25 21:14:07.000000000 -0400
@@ -1579,11 +1579,13 @@ static int sci_startup(struct uart_port
 
 	sci_port_enable(s);
 
+	sci_request_dma(port);
+
 	ret = sci_request_irq(s);
-	if (unlikely(ret < 0))
+	if (unlikely(ret < 0)) {
+		sci_free_dma(port);
 		return ret;
-
-	sci_request_dma(port);
+	}
 
 	sci_start_tx(port);
 	sci_start_rx(port);
@@ -1600,8 +1602,8 @@ static void sci_shutdown(struct uart_por
 	sci_stop_rx(port);
 	sci_stop_tx(port);
 
-	sci_free_dma(port);
 	sci_free_irq(s);
+	sci_free_dma(port);
 
 	sci_port_disable(s);
 }
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/usb/class/cdc-acm.c linux-libre-3.2.92-gnu1/drivers/usb/class/cdc-acm.c
--- linux-libre-3.2.91-gnu1/drivers/usb/class/cdc-acm.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/usb/class/cdc-acm.c	2017-08-25 21:14:07.000000000 -0400
@@ -293,6 +293,12 @@ static void acm_ctrl_irq(struct urb *urb
 		break;
 
 	case USB_CDC_NOTIFY_SERIAL_STATE:
+		if (le16_to_cpu(dr->wLength) != 2) {
+			dev_dbg(&acm->control->dev,
+				"%s - malformed serial state\n", __func__);
+			break;
+		}
+
 		tty = tty_port_tty_get(&acm->port);
 		newctrl = get_unaligned_le16(data);
 
@@ -323,11 +329,10 @@ static void acm_ctrl_irq(struct urb *urb
 
 	default:
 		dev_dbg(&acm->control->dev,
-			"%s - unknown notification %d received: index %d "
-			"len %d data0 %d data1 %d\n",
+			"%s - unknown notification %d received: index %d len %d\n",
 			__func__,
-			dr->bNotificationType, dr->wIndex,
-			dr->wLength, data[0], data[1]);
+			dr->bNotificationType, dr->wIndex, dr->wLength);
+
 		break;
 	}
 exit:
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/usb/core/driver.c linux-libre-3.2.92-gnu1/drivers/usb/core/driver.c
--- linux-libre-3.2.91-gnu1/drivers/usb/core/driver.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/usb/core/driver.c	2017-08-25 21:14:07.000000000 -0400
@@ -1218,6 +1218,24 @@ static int usb_suspend_both(struct usb_d
 		 */
 		if (udev->parent && !PMSG_IS_AUTO(msg))
 			status = 0;
+
+		/*
+		 * If the device is inaccessible, don't try to resume
+		 * suspended interfaces and just return the error.
+		 */
+		if (status && status != -EBUSY) {
+			int err;
+			u16 devstat;
+
+			err = usb_get_status(udev, USB_RECIP_DEVICE, 0,
+					     &devstat);
+			if (err) {
+				dev_err(&udev->dev,
+					"Failed to suspend device, error %d\n",
+					status);
+				goto done;
+			}
+		}
 	}
 
 	/* If the suspend failed, resume interfaces that did get suspended */
@@ -1631,6 +1649,9 @@ static int autosuspend_check(struct usb_
 	int			w, i;
 	struct usb_interface	*intf;
 
+	if (udev->state == USB_STATE_NOTATTACHED)
+		return -ENODEV;
+
 	/* Fail if autosuspend is disabled, or any interfaces are in use, or
 	 * any interface drivers require remote wakeup but it isn't available.
 	 */
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/usb/core/file.c linux-libre-3.2.92-gnu1/drivers/usb/core/file.c
--- linux-libre-3.2.91-gnu1/drivers/usb/core/file.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/usb/core/file.c	2017-08-25 21:14:07.000000000 -0400
@@ -26,6 +26,7 @@
 #define MAX_USB_MINORS	256
 static const struct file_operations *usb_minors[MAX_USB_MINORS];
 static DECLARE_RWSEM(minor_rwsem);
+static DEFINE_MUTEX(init_usb_class_mutex);
 
 static int usb_open(struct inode * inode, struct file * file)
 {
@@ -116,8 +117,9 @@ static void release_usb_class(struct kre
 
 static void destroy_usb_class(void)
 {
-	if (usb_class)
-		kref_put(&usb_class->kref, release_usb_class);
+	mutex_lock(&init_usb_class_mutex);
+	kref_put(&usb_class->kref, release_usb_class);
+	mutex_unlock(&init_usb_class_mutex);
 }
 
 int usb_major_init(void)
@@ -179,7 +181,10 @@ int usb_register_dev(struct usb_interfac
 	if (intf->minor >= 0)
 		return -EADDRINUSE;
 
+	mutex_lock(&init_usb_class_mutex);
 	retval = init_usb_class();
+	mutex_unlock(&init_usb_class_mutex);
+
 	if (retval)
 		return retval;
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/usb/core/hub.c linux-libre-3.2.92-gnu1/drivers/usb/core/hub.c
--- linux-libre-3.2.91-gnu1/drivers/usb/core/hub.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/usb/core/hub.c	2017-08-25 21:14:07.000000000 -0400
@@ -884,6 +884,9 @@ static void hub_activate(struct usb_hub
 
 		portstatus = portchange = 0;
 		status = hub_port_status(hub, port1, &portstatus, &portchange);
+		if (status)
+			goto abort;
+
 		if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
 			dev_dbg(hub->intfdev,
 					"port %d: status %04x change %04x\n",
@@ -1011,7 +1014,7 @@ static void hub_activate(struct usb_hub
 
 	/* Scan all ports that need attention */
 	kick_khubd(hub);
-
+ abort:
 	/* Allow autosuspend if it was suppressed */
 	if (type <= HUB_INIT3)
 		usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
@@ -1778,6 +1781,12 @@ void usb_disconnect(struct usb_device **
 	dev_info(&udev->dev, "USB disconnect, device number %d\n",
 			udev->devnum);
 
+	/*
+	 * Ensure that the pm runtime code knows that the USB device
+	 * is in the process of being disconnected.
+	 */
+	pm_runtime_barrier(&udev->dev);
+
 	usb_lock_device(udev);
 
 	/* Free up all the children before we remove this device */
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/usb/host/xhci-mem.c linux-libre-3.2.92-gnu1/drivers/usb/host/xhci-mem.c
--- linux-libre-3.2.91-gnu1/drivers/usb/host/xhci-mem.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/usb/host/xhci-mem.c	2017-08-25 21:14:07.000000000 -0400
@@ -2321,7 +2321,7 @@ int xhci_mem_init(struct xhci_hcd *xhci,
 	val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
 		(xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) |
 		xhci->cmd_ring->cycle_state;
-	xhci_dbg(xhci, "// Setting command ring address to 0x%x\n", val);
+	xhci_dbg(xhci, "// Setting command ring address to 0x%016llx\n", val_64);
 	xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
 	xhci_dbg_cmd_ptrs(xhci);
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/video/Kconfig linux-libre-3.2.92-gnu1/drivers/video/Kconfig
--- linux-libre-3.2.91-gnu1/drivers/video/Kconfig	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/video/Kconfig	2017-08-25 21:14:07.000000000 -0400
@@ -683,8 +683,6 @@ config FB_STI
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select STI_CONSOLE
-	select VT
 	default y
 	---help---
 	  STI refers to the HP "Standard Text Interface" which is a set of
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/drivers/video/Makefile linux-libre-3.2.92-gnu1/drivers/video/Makefile
--- linux-libre-3.2.91-gnu1/drivers/video/Makefile	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/drivers/video/Makefile	2017-08-25 21:14:07.000000000 -0400
@@ -12,6 +12,7 @@ fb-y                              := fbm
 fb-objs                           := $(fb-y)
 
 obj-$(CONFIG_VT)		  += console/
+obj-$(CONFIG_FB_STI)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/ display/
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/fs/cifs/cifssmb.c linux-libre-3.2.92-gnu1/fs/cifs/cifssmb.c
--- linux-libre-3.2.91-gnu1/fs/cifs/cifssmb.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/fs/cifs/cifssmb.c	2017-08-25 21:14:07.000000000 -0400
@@ -764,6 +764,9 @@ CIFSSMBEcho(struct TCP_Server_Info *serv
 	if (rc)
 		return rc;
 
+	if (server->capabilities & CAP_UNICODE)
+		smb->hdr.Flags2 |= SMBFLG2_UNICODE;
+
 	/* set up echo request */
 	smb->hdr.Tid = 0xffff;
 	smb->hdr.WordCount = 1;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/fs/cifs/netmisc.c linux-libre-3.2.92-gnu1/fs/cifs/netmisc.c
--- linux-libre-3.2.91-gnu1/fs/cifs/netmisc.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/fs/cifs/netmisc.c	2017-08-25 21:14:07.000000000 -0400
@@ -974,10 +974,10 @@ struct timespec cnvrtDosUnixTm(__le16 le
 		cERROR(1, "illegal hours %d", st->Hours);
 	days = sd->Day;
 	month = sd->Month;
-	if ((days > 31) || (month > 12)) {
+	if (days < 1 || days > 31 || month < 1 || month > 12) {
 		cERROR(1, "illegal date, month %d day: %d", month, days);
-		if (month > 12)
-			month = 12;
+		days = clamp(days, 1, 31);
+		month = clamp(month, 1, 12);
 	}
 	month -= 1;
 	days += total_days_of_prev_months[month];
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/fs/timerfd.c linux-libre-3.2.92-gnu1/fs/timerfd.c
--- linux-libre-3.2.91-gnu1/fs/timerfd.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/fs/timerfd.c	2017-08-25 21:14:07.000000000 -0400
@@ -34,6 +34,7 @@ struct timerfd_ctx {
 	int clockid;
 	struct rcu_head rcu;
 	struct list_head clist;
+	spinlock_t cancel_lock;
 	bool might_cancel;
 };
 
@@ -86,7 +87,7 @@ void timerfd_clock_was_set(void)
 	rcu_read_unlock();
 }
 
-static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
+static void __timerfd_remove_cancel(struct timerfd_ctx *ctx)
 {
 	if (ctx->might_cancel) {
 		ctx->might_cancel = false;
@@ -96,6 +97,13 @@ static void timerfd_remove_cancel(struct
 	}
 }
 
+static void timerfd_remove_cancel(struct timerfd_ctx *ctx)
+{
+	spin_lock(&ctx->cancel_lock);
+	__timerfd_remove_cancel(ctx);
+	spin_unlock(&ctx->cancel_lock);
+}
+
 static bool timerfd_canceled(struct timerfd_ctx *ctx)
 {
 	if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX)
@@ -106,6 +114,7 @@ static bool timerfd_canceled(struct time
 
 static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags)
 {
+	spin_lock(&ctx->cancel_lock);
 	if (ctx->clockid == CLOCK_REALTIME && (flags & TFD_TIMER_ABSTIME) &&
 	    (flags & TFD_TIMER_CANCEL_ON_SET)) {
 		if (!ctx->might_cancel) {
@@ -114,9 +123,10 @@ static void timerfd_setup_cancel(struct
 			list_add_rcu(&ctx->clist, &cancel_list);
 			spin_unlock(&cancel_lock);
 		}
-	} else if (ctx->might_cancel) {
-		timerfd_remove_cancel(ctx);
+	} else {
+		__timerfd_remove_cancel(ctx);
 	}
+	spin_unlock(&ctx->cancel_lock);
 }
 
 static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx)
@@ -268,6 +278,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clo
 		return -ENOMEM;
 
 	init_waitqueue_head(&ctx->wqh);
+	spin_lock_init(&ctx->cancel_lock);
 	ctx->clockid = clockid;
 	hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
 	ctx->moffs = ktime_get_monotonic_offset();
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/include/linux/netfilter/nf_conntrack_common.h linux-libre-3.2.92-gnu1/include/linux/netfilter/nf_conntrack_common.h
--- linux-libre-3.2.91-gnu1/include/linux/netfilter/nf_conntrack_common.h	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/include/linux/netfilter/nf_conntrack_common.h	2017-08-25 21:14:07.000000000 -0400
@@ -83,6 +83,15 @@ enum ip_conntrack_status {
 	/* Conntrack is a fake untracked entry */
 	IPS_UNTRACKED_BIT = 12,
 	IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
+
+	/* Be careful here, modifying these bits can make things messy,
+	 * so don't let users modify them directly.
+	 */
+	IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK |
+				 IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING |
+				 IPS_SEQ_ADJUST | IPS_TEMPLATE),
+
+	__IPS_MAX_BIT = 13,
 };
 
 /* Connection tracking event types */
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/ipc/mqueue.c linux-libre-3.2.92-gnu1/ipc/mqueue.c
--- linux-libre-3.2.91-gnu1/ipc/mqueue.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/ipc/mqueue.c	2017-08-25 21:14:07.000000000 -0400
@@ -1095,8 +1095,10 @@ retry:
 
 			timeo = MAX_SCHEDULE_TIMEOUT;
 			ret = netlink_attachskb(sock, nc, &timeo, NULL);
-			if (ret == 1)
+			if (ret == 1) {
+				sock = NULL;
 				goto retry;
+			}
 			if (ret) {
 				sock = NULL;
 				nc = NULL;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/kernel/padata.c linux-libre-3.2.92-gnu1/kernel/padata.c
--- linux-libre-3.2.91-gnu1/kernel/padata.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/kernel/padata.c	2017-08-25 21:14:07.000000000 -0400
@@ -369,7 +369,7 @@ static int padata_setup_cpumasks(struct
 
 	cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_active_mask);
 	if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
-		free_cpumask_var(pd->cpumask.cbcpu);
+		free_cpumask_var(pd->cpumask.pcpu);
 		return -ENOMEM;
 	}
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/Makefile linux-libre-3.2.92-gnu1/Makefile
--- linux-libre-3.2.91-gnu1/Makefile	2017-07-18 16:15:12.000000000 -0400
+++ linux-libre-3.2.92-gnu1/Makefile	2017-08-26 09:58:10.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 91
+SUBLEVEL = 92
 EXTRAVERSION =-gnu1
 NAME = Saber-toothed Squirrel
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/bluetooth/hci_sock.c linux-libre-3.2.92-gnu1/net/bluetooth/hci_sock.c
--- linux-libre-3.2.91-gnu1/net/bluetooth/hci_sock.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/bluetooth/hci_sock.c	2017-08-25 21:14:07.000000000 -0400
@@ -477,7 +477,8 @@ static int hci_sock_sendmsg(struct kiocb
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
 
-	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
+	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE|
+			       MSG_CMSG_COMPAT))
 		return -EINVAL;
 
 	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/ipv4/tcp_lp.c linux-libre-3.2.92-gnu1/net/ipv4/tcp_lp.c
--- linux-libre-3.2.91-gnu1/net/ipv4/tcp_lp.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/ipv4/tcp_lp.c	2017-08-25 21:14:07.000000000 -0400
@@ -264,13 +264,15 @@ static void tcp_lp_pkts_acked(struct soc
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct lp *lp = inet_csk_ca(sk);
+	u32 delta;
 
 	if (rtt_us > 0)
 		tcp_lp_rtt_sample(sk, rtt_us);
 
 	/* calc inference */
-	if (tcp_time_stamp > tp->rx_opt.rcv_tsecr)
-		lp->inference = 3 * (tcp_time_stamp - tp->rx_opt.rcv_tsecr);
+	delta = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+	if ((s32)delta > 0)
+		lp->inference = 3 * delta;
 
 	/* test if within inference */
 	if (lp->last_drop && (tcp_time_stamp - lp->last_drop < lp->inference))
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/ipv6/exthdrs.c linux-libre-3.2.92-gnu1/net/ipv6/exthdrs.c
--- linux-libre-3.2.91-gnu1/net/ipv6/exthdrs.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/ipv6/exthdrs.c	2017-08-25 21:14:07.000000000 -0400
@@ -723,13 +723,13 @@ void ipv6_push_nfrag_opts(struct sk_buff
 		ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
 }
 
-EXPORT_SYMBOL(ipv6_push_nfrag_opts);
 
 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
 {
 	if (opt->dst1opt)
 		ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
 }
+EXPORT_SYMBOL(ipv6_push_frag_opts);
 
 struct ipv6_txoptions *
 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/ipv6/ip6_output.c linux-libre-3.2.92-gnu1/net/ipv6/ip6_output.c
--- linux-libre-3.2.91-gnu1/net/ipv6/ip6_output.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/ipv6/ip6_output.c	2017-08-25 21:14:07.000000000 -0400
@@ -561,13 +561,14 @@ static void ip6_copy_metadata(struct sk_
 
 int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 {
-	u16 offset = sizeof(struct ipv6hdr);
+	unsigned int offset = sizeof(struct ipv6hdr);
 	unsigned int packet_len = skb->tail - skb->network_header;
 	int found_rhdr = 0;
 	*nexthdr = &ipv6_hdr(skb)->nexthdr;
 
 	while (offset <= packet_len) {
 		struct ipv6_opt_hdr *exthdr;
+		unsigned int len;
 
 		switch (**nexthdr) {
 
@@ -593,7 +594,10 @@ int ip6_find_1stfragopt(struct sk_buff *
 
 		exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
 						 offset);
-		offset += ipv6_optlen(exthdr);
+		len = ipv6_optlen(exthdr);
+		if (len + offset >= IPV6_MAXPLEN)
+			return -EINVAL;
+		offset += len;
 		*nexthdr = &exthdr->nexthdr;
 	}
 
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/ipv6/ip6_tunnel.c linux-libre-3.2.92-gnu1/net/ipv6/ip6_tunnel.c
--- linux-libre-3.2.91-gnu1/net/ipv6/ip6_tunnel.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/ipv6/ip6_tunnel.c	2017-08-25 21:14:07.000000000 -0400
@@ -818,7 +818,7 @@ static void init_tel_txopt(struct ipv6_t
 	opt->dst_opt[5] = IPV6_TLV_PADN;
 	opt->dst_opt[6] = 1;
 
-	opt->ops.dst0opt = (struct ipv6_opt_hdr *) opt->dst_opt;
+	opt->ops.dst1opt = (struct ipv6_opt_hdr *) opt->dst_opt;
 	opt->ops.opt_nflen = 8;
 }
 
@@ -989,7 +989,7 @@ static int ip6_tnl_xmit2(struct sk_buff
 	proto = fl6->flowi6_proto;
 	if (encap_limit >= 0) {
 		init_tel_txopt(&opt, encap_limit);
-		ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
+		ipv6_push_frag_opts(skb, &opt.ops, &proto);
 	}
 	skb_push(skb, sizeof(struct ipv6hdr));
 	skb_reset_network_header(skb);
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/netfilter/nf_conntrack_netlink.c linux-libre-3.2.92-gnu1/net/netfilter/nf_conntrack_netlink.c
--- linux-libre-3.2.91-gnu1/net/netfilter/nf_conntrack_netlink.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/netfilter/nf_conntrack_netlink.c	2017-08-25 21:14:07.000000000 -0400
@@ -1053,6 +1053,24 @@ ctnetlink_parse_nat_setup(struct nf_conn
 }
 #endif
 
+static void
+__ctnetlink_change_status(struct nf_conn *ct, unsigned long on,
+			  unsigned long off)
+{
+	unsigned int bit;
+
+	/* Ignore these unchangable bits */
+	on &= ~IPS_UNCHANGEABLE_MASK;
+	off &= ~IPS_UNCHANGEABLE_MASK;
+
+	for (bit = 0; bit < __IPS_MAX_BIT; bit++) {
+		if (on & (1 << bit))
+			set_bit(bit, &ct->status);
+		else if (off & (1 << bit))
+			clear_bit(bit, &ct->status);
+	}
+}
+
 static int
 ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
 {
@@ -1072,10 +1090,7 @@ ctnetlink_change_status(struct nf_conn *
 		/* ASSURED bit can only be set */
 		return -EBUSY;
 
-	/* Be careful here, modifying NAT bits can screw up things,
-	 * so don't let users modify them directly if they don't pass
-	 * nf_nat_range. */
-	ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
+	__ctnetlink_change_status(ct, status, 0);
 	return 0;
 }
 
@@ -1258,7 +1273,7 @@ ctnetlink_change_nat_seq_adj(struct nf_c
 		if (ret < 0)
 			return ret;
 
-		ct->status |= IPS_SEQ_ADJUST;
+		set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
 	}
 
 	if (cda[CTA_NAT_SEQ_ADJ_REPLY]) {
@@ -1267,7 +1282,7 @@ ctnetlink_change_nat_seq_adj(struct nf_c
 		if (ret < 0)
 			return ret;
 
-		ct->status |= IPS_SEQ_ADJUST;
+		set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
 	}
 
 	return 0;
diff -druNp --no-dereference linux-libre-3.2.91-gnu1/net/packet/af_packet.c linux-libre-3.2.92-gnu1/net/packet/af_packet.c
--- linux-libre-3.2.91-gnu1/net/packet/af_packet.c	2017-07-18 13:38:46.000000000 -0400
+++ linux-libre-3.2.92-gnu1/net/packet/af_packet.c	2017-08-25 21:14:07.000000000 -0400
@@ -3132,14 +3132,19 @@ packet_setsockopt(struct socket *sock, i
 
 		if (optlen != sizeof(val))
 			return -EINVAL;
-		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
-			return -EBUSY;
 		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
 		if (val > INT_MAX)
 			return -EINVAL;
-		po->tp_reserve = val;
-		return 0;
+		lock_sock(sk);
+		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+			ret = -EBUSY;
+		} else {
+			po->tp_reserve = val;
+			ret = 0;
+		}
+		release_sock(sk);
+		return ret;
 	}
 	case PACKET_LOSS:
 	{
