diff -druNp --no-dereference linux-libre-3.12.68-gnu/arch/sparc/kernel/signal_32.c linux-libre-3.12.69-gnu/arch/sparc/kernel/signal_32.c
--- linux-libre-3.12.68-gnu/arch/sparc/kernel/signal_32.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/arch/sparc/kernel/signal_32.c	2016-12-13 14:52:06.000000000 -0500
@@ -88,7 +88,7 @@ asmlinkage void do_sigreturn(struct pt_r
 	sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
 
 	/* 1. Make sure we are not getting garbage from the user */
-	if (!invalid_frame_pointer(sf, sizeof(*sf)))
+	if (invalid_frame_pointer(sf, sizeof(*sf)))
 		goto segv_and_exit;
 
 	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
@@ -149,7 +149,7 @@ asmlinkage void do_rt_sigreturn(struct p
 
 	synchronize_user_stack();
 	sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
-	if (!invalid_frame_pointer(sf, sizeof(*sf)))
+	if (invalid_frame_pointer(sf, sizeof(*sf)))
 		goto segv;
 
 	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
diff -druNp --no-dereference linux-libre-3.12.68-gnu/arch/sparc/mm/init_64.c linux-libre-3.12.69-gnu/arch/sparc/mm/init_64.c
--- linux-libre-3.12.68-gnu/arch/sparc/mm/init_64.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/arch/sparc/mm/init_64.c	2016-12-13 14:52:06.000000000 -0500
@@ -807,8 +807,10 @@ struct mdesc_mblock {
 };
 static struct mdesc_mblock *mblocks;
 static int num_mblocks;
+static int find_numa_node_for_addr(unsigned long pa,
+				   struct node_mem_mask *pnode_mask);
 
-static unsigned long ra_to_pa(unsigned long addr)
+static unsigned long __init ra_to_pa(unsigned long addr)
 {
 	int i;
 
@@ -824,8 +826,11 @@ static unsigned long ra_to_pa(unsigned l
 	return addr;
 }
 
-static int find_node(unsigned long addr)
+static int __init find_node(unsigned long addr)
 {
+	static bool search_mdesc = true;
+	static struct node_mem_mask last_mem_mask = { ~0UL, ~0UL };
+	static int last_index;
 	int i;
 
 	addr = ra_to_pa(addr);
@@ -835,13 +840,30 @@ static int find_node(unsigned long addr)
 		if ((addr & p->mask) == p->val)
 			return i;
 	}
-	/* The following condition has been observed on LDOM guests.*/
-	WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node"
-		" rule. Some physical memory will be owned by node 0.");
-	return 0;
+	/* The following condition has been observed on LDOM guests because
+	 * node_masks only contains the best latency mask and value.
+	 * LDOM guest's mdesc can contain a single latency group to
+	 * cover multiple address range. Print warning message only if the
+	 * address cannot be found in node_masks nor mdesc.
+	 */
+	if ((search_mdesc) &&
+	    ((addr & last_mem_mask.mask) != last_mem_mask.val)) {
+		/* find the available node in the mdesc */
+		last_index = find_numa_node_for_addr(addr, &last_mem_mask);
+		numadbg("find_node: latency group for address 0x%lx is %d\n",
+			addr, last_index);
+		if ((last_index < 0) || (last_index >= num_node_masks)) {
+			/* WARN_ONCE() and use default group 0 */
+			WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node rule. Some physical memory will be owned by node 0.");
+			search_mdesc = false;
+			last_index = 0;
+		}
+	}
+
+	return last_index;
 }
 
-static u64 memblock_nid_range(u64 start, u64 end, int *nid)
+static u64 __init memblock_nid_range(u64 start, u64 end, int *nid)
 {
 	*nid = find_node(start);
 	start += PAGE_SIZE;
@@ -1150,6 +1172,41 @@ static struct mdesc_mlgroup * __init fin
 	return NULL;
 }
 
+static int find_numa_node_for_addr(unsigned long pa,
+				   struct node_mem_mask *pnode_mask)
+{
+	struct mdesc_handle *md = mdesc_grab();
+	u64 node, arc;
+	int i = 0;
+
+	node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
+	if (node == MDESC_NODE_NULL)
+		goto out;
+
+	mdesc_for_each_node_by_name(md, node, "group") {
+		mdesc_for_each_arc(arc, md, node, MDESC_ARC_TYPE_FWD) {
+			u64 target = mdesc_arc_target(md, arc);
+			struct mdesc_mlgroup *m = find_mlgroup(target);
+
+			if (!m)
+				continue;
+			if ((pa & m->mask) == m->match) {
+				if (pnode_mask) {
+					pnode_mask->mask = m->mask;
+					pnode_mask->val = m->match;
+				}
+				mdesc_release(md);
+				return i;
+			}
+		}
+		i++;
+	}
+
+out:
+	mdesc_release(md);
+	return -1;
+}
+
 static int __init numa_attach_mlgroup(struct mdesc_handle *md, u64 grp,
 				      int index)
 {
diff -druNp --no-dereference linux-libre-3.12.68-gnu/arch/tile/kernel/time.c linux-libre-3.12.69-gnu/arch/tile/kernel/time.c
--- linux-libre-3.12.68-gnu/arch/tile/kernel/time.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/arch/tile/kernel/time.c	2016-12-13 14:52:06.000000000 -0500
@@ -216,8 +216,8 @@ void do_timer_interrupt(struct pt_regs *
  */
 unsigned long long sched_clock(void)
 {
-	return clocksource_cyc2ns(get_cycles(),
-				  sched_clock_mult, SCHED_CLOCK_SHIFT);
+	return mult_frac(get_cycles(),
+			 sched_clock_mult, 1ULL << SCHED_CLOCK_SHIFT);
 }
 
 int setup_profiling_timer(unsigned int multiplier)
diff -druNp --no-dereference linux-libre-3.12.68-gnu/arch/x86/kernel/head_32.S linux-libre-3.12.69-gnu/arch/x86/kernel/head_32.S
--- linux-libre-3.12.68-gnu/arch/x86/kernel/head_32.S	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/arch/x86/kernel/head_32.S	2016-12-13 14:52:06.000000000 -0500
@@ -564,7 +564,7 @@ early_idt_handler_common:
 	movl %eax,%ds
 	movl %eax,%es
 
-	cmpl $(__KERNEL_CS),32(%esp)
+	cmpw $(__KERNEL_CS),32(%esp)
 	jne 10f
 
 	leal 28(%esp),%eax	# Pointer to %eip
diff -druNp --no-dereference linux-libre-3.12.68-gnu/arch/x86/kernel/process.c linux-libre-3.12.69-gnu/arch/x86/kernel/process.c
--- linux-libre-3.12.68-gnu/arch/x86/kernel/process.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/arch/x86/kernel/process.c	2016-12-13 14:52:06.000000000 -0500
@@ -428,6 +428,7 @@ static int prefer_mwait_c1_over_halt(con
 static void mwait_idle(void)
 {
 	if (!current_set_polling_and_test()) {
+		trace_cpu_idle_rcuidle(1, smp_processor_id());
 		if (static_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) {
 			mb();
 			clflush((void *)&current_thread_info()->flags);
@@ -439,6 +440,7 @@ static void mwait_idle(void)
 			__sti_mwait(0, 0);
 		else
 			local_irq_enable();
+		trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
 	} else
 		local_irq_enable();
 	__current_clr_polling();
diff -druNp --no-dereference linux-libre-3.12.68-gnu/arch/x86/kvm/emulate.c linux-libre-3.12.69-gnu/arch/x86/kvm/emulate.c
--- linux-libre-3.12.68-gnu/arch/x86/kvm/emulate.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/arch/x86/kvm/emulate.c	2016-12-13 14:52:06.000000000 -0500
@@ -1985,14 +1985,8 @@ static int em_iret(struct x86_emulate_ct
 static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
 {
 	int rc;
-	unsigned short sel, old_sel;
-	struct desc_struct old_desc, new_desc;
-	const struct x86_emulate_ops *ops = ctxt->ops;
-
-	/* Assignment of RIP may only fail in 64-bit mode */
-	if (ctxt->mode == X86EMUL_MODE_PROT64)
-		ops->get_segment(ctxt, &old_sel, &old_desc, NULL,
-				 VCPU_SREG_CS);
+	unsigned short sel;
+	struct desc_struct new_desc;
 
 	memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
 
@@ -2001,12 +1995,10 @@ static int em_jmp_far(struct x86_emulate
 		return rc;
 
 	rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
-	if (rc != X86EMUL_CONTINUE) {
-		WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
-		/* assigning eip failed; restore the old cs */
-		ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS);
-		return rc;
-	}
+	/* Error handling is not implemented. */
+	if (rc != X86EMUL_CONTINUE)
+		return X86EMUL_UNHANDLEABLE;
+
 	return rc;
 }
 
@@ -2063,14 +2055,8 @@ static int em_ret_far(struct x86_emulate
 {
 	int rc;
 	unsigned long eip, cs;
-	u16 old_cs;
 	int cpl = ctxt->ops->cpl(ctxt);
-	struct desc_struct old_desc, new_desc;
-	const struct x86_emulate_ops *ops = ctxt->ops;
-
-	if (ctxt->mode == X86EMUL_MODE_PROT64)
-		ops->get_segment(ctxt, &old_cs, &old_desc, NULL,
-				 VCPU_SREG_CS);
+	struct desc_struct new_desc;
 
 	rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
 	if (rc != X86EMUL_CONTINUE)
@@ -2085,10 +2071,10 @@ static int em_ret_far(struct x86_emulate
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	rc = assign_eip_far(ctxt, eip, new_desc.l);
-	if (rc != X86EMUL_CONTINUE) {
-		WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
-		ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
-	}
+	/* Error handling is not implemented. */
+	if (rc != X86EMUL_CONTINUE)
+		return X86EMUL_UNHANDLEABLE;
+
 	return rc;
 }
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/gpu/drm/radeon/atombios_crtc.c linux-libre-3.12.69-gnu/drivers/gpu/drm/radeon/atombios_crtc.c
--- linux-libre-3.12.68-gnu/drivers/gpu/drm/radeon/atombios_crtc.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/gpu/drm/radeon/atombios_crtc.c	2016-12-13 14:52:06.000000000 -0500
@@ -277,6 +277,8 @@ void atombios_crtc_dpms(struct drm_crtc
 			atombios_enable_crtc_memreq(crtc, ATOM_ENABLE);
 		atombios_blank_crtc(crtc, ATOM_DISABLE);
 		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+		/* Make sure vblank interrupt is still enabled if needed */
+		radeon_irq_set(rdev);
 		radeon_crtc_load_lut(crtc);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/gpu/drm/radeon/radeon_legacy_crtc.c linux-libre-3.12.69-gnu/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
--- linux-libre-3.12.68-gnu/drivers/gpu/drm/radeon/radeon_legacy_crtc.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/gpu/drm/radeon/radeon_legacy_crtc.c	2016-12-13 14:52:06.000000000 -0500
@@ -331,6 +331,8 @@ static void radeon_crtc_dpms(struct drm_
 			WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
 		}
 		drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
+		/* Make sure vblank interrupt is still enabled if needed */
+		radeon_irq_set(rdev);
 		radeon_crtc_load_lut(crtc);
 		break;
 	case DRM_MODE_DPMS_STANDBY:
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/i2c/busses/i2c-at91.c linux-libre-3.12.69-gnu/drivers/i2c/busses/i2c-at91.c
--- linux-libre-3.12.68-gnu/drivers/i2c/busses/i2c-at91.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/i2c/busses/i2c-at91.c	2016-12-13 14:52:06.000000000 -0500
@@ -370,19 +370,57 @@ static irqreturn_t atmel_twi_interrupt(i
 
 	if (!irqstatus)
 		return IRQ_NONE;
-	else if (irqstatus & AT91_TWI_RXRDY)
-		at91_twi_read_next_byte(dev);
-	else if (irqstatus & AT91_TWI_TXRDY)
-		at91_twi_write_next_byte(dev);
-
-	/* catch error flags */
-	dev->transfer_status |= status;
 
+	/*
+	 * When a NACK condition is detected, the I2C controller sets the NACK,
+	 * TXCOMP and TXRDY bits all together in the Status Register (SR).
+	 *
+	 * 1 - Handling NACK errors with CPU write transfer.
+	 *
+	 * In such case, we should not write the next byte into the Transmit
+	 * Holding Register (THR) otherwise the I2C controller would start a new
+	 * transfer and the I2C slave is likely to reply by another NACK.
+	 *
+	 * 2 - Handling NACK errors with DMA write transfer.
+	 *
+	 * By setting the TXRDY bit in the SR, the I2C controller also triggers
+	 * the DMA controller to write the next data into the THR. Then the
+	 * result depends on the hardware version of the I2C controller.
+	 *
+	 * 2a - Without support of the Alternative Command mode.
+	 *
+	 * This is the worst case: the DMA controller is triggered to write the
+	 * next data into the THR, hence starting a new transfer: the I2C slave
+	 * is likely to reply by another NACK.
+	 * Concurrently, this interrupt handler is likely to be called to manage
+	 * the first NACK before the I2C controller detects the second NACK and
+	 * sets once again the NACK bit into the SR.
+	 * When handling the first NACK, this interrupt handler disables the I2C
+	 * controller interruptions, especially the NACK interrupt.
+	 * Hence, the NACK bit is pending into the SR. This is why we should
+	 * read the SR to clear all pending interrupts at the beginning of
+	 * at91_do_twi_transfer() before actually starting a new transfer.
+	 *
+	 * 2b - With support of the Alternative Command mode.
+	 *
+	 * When a NACK condition is detected, the I2C controller also locks the
+	 * THR (and sets the LOCK bit in the SR): even though the DMA controller
+	 * is triggered by the TXRDY bit to write the next data into the THR,
+	 * this data actually won't go on the I2C bus hence a second NACK is not
+	 * generated.
+	 */
 	if (irqstatus & (AT91_TWI_TXCOMP | AT91_TWI_NACK)) {
 		at91_disable_twi_interrupts(dev);
 		complete(&dev->cmd_complete);
+	} else if (irqstatus & AT91_TWI_RXRDY) {
+		at91_twi_read_next_byte(dev);
+	} else if (irqstatus & AT91_TWI_TXRDY) {
+		at91_twi_write_next_byte(dev);
 	}
 
+	/* catch error flags */
+	dev->transfer_status |= status;
+
 	return IRQ_HANDLED;
 }
 
@@ -390,6 +428,7 @@ static int at91_do_twi_transfer(struct a
 {
 	int ret;
 	bool has_unre_flag = dev->pdata->has_unre_flag;
+	unsigned sr;
 
 	/*
 	 * WARNING: the TXCOMP bit in the Status Register is NOT a clear on
@@ -425,13 +464,16 @@ static int at91_do_twi_transfer(struct a
 	INIT_COMPLETION(dev->cmd_complete);
 	dev->transfer_status = 0;
 
+	/* Clear pending interrupts, such as NACK. */
+	sr = at91_twi_read(dev, AT91_TWI_SR);
+
 	if (!dev->buf_len) {
 		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
 		at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
 	} else if (dev->msg->flags & I2C_M_RD) {
 		unsigned start_flags = AT91_TWI_START;
 
-		if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
+		if (sr & AT91_TWI_RXRDY) {
 			dev_err(dev->dev, "RXRDY still set!");
 			at91_twi_read(dev, AT91_TWI_RHR);
 		}
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/mtd/mtd_blkdevs.c linux-libre-3.12.69-gnu/drivers/mtd/mtd_blkdevs.c
--- linux-libre-3.12.68-gnu/drivers/mtd/mtd_blkdevs.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/mtd/mtd_blkdevs.c	2016-12-13 14:52:06.000000000 -0500
@@ -198,8 +198,8 @@ static int blktrans_open(struct block_de
 	if (!dev)
 		return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
 
-	mutex_lock(&dev->lock);
 	mutex_lock(&mtd_table_mutex);
+	mutex_lock(&dev->lock);
 
 	if (dev->open)
 		goto unlock;
@@ -223,8 +223,8 @@ static int blktrans_open(struct block_de
 
 unlock:
 	dev->open++;
-	mutex_unlock(&mtd_table_mutex);
 	mutex_unlock(&dev->lock);
+	mutex_unlock(&mtd_table_mutex);
 	blktrans_dev_put(dev);
 	return ret;
 
@@ -234,8 +234,8 @@ error_release:
 error_put:
 	module_put(dev->tr->owner);
 	kref_put(&dev->ref, blktrans_dev_release);
-	mutex_unlock(&mtd_table_mutex);
 	mutex_unlock(&dev->lock);
+	mutex_unlock(&mtd_table_mutex);
 	blktrans_dev_put(dev);
 	return ret;
 }
@@ -247,8 +247,8 @@ static void blktrans_release(struct gend
 	if (!dev)
 		return;
 
-	mutex_lock(&dev->lock);
 	mutex_lock(&mtd_table_mutex);
+	mutex_lock(&dev->lock);
 
 	if (--dev->open)
 		goto unlock;
@@ -262,8 +262,8 @@ static void blktrans_release(struct gend
 		__put_mtd_device(dev->mtd);
 	}
 unlock:
-	mutex_unlock(&mtd_table_mutex);
 	mutex_unlock(&dev->lock);
+	mutex_unlock(&mtd_table_mutex);
 	blktrans_dev_put(dev);
 }
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/net/ethernet/marvell/sky2.c linux-libre-3.12.69-gnu/drivers/net/ethernet/marvell/sky2.c
--- linux-libre-3.12.68-gnu/drivers/net/ethernet/marvell/sky2.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/net/ethernet/marvell/sky2.c	2016-12-13 14:52:06.000000000 -0500
@@ -5197,6 +5197,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sk
 
 static void sky2_shutdown(struct pci_dev *pdev)
 {
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	int port;
+
+	for (port = 0; port < hw->ports; port++) {
+		struct net_device *ndev = hw->dev[port];
+
+		rtnl_lock();
+		if (netif_running(ndev)) {
+			dev_close(ndev);
+			netif_device_detach(ndev);
+		}
+		rtnl_unlock();
+	}
 	sky2_suspend(&pdev->dev);
 	pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
 	pci_set_power_state(pdev, PCI_D3hot);
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/net/macvtap.c linux-libre-3.12.69-gnu/drivers/net/macvtap.c
--- linux-libre-3.12.68-gnu/drivers/net/macvtap.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/net/macvtap.c	2016-12-13 14:52:06.000000000 -0500
@@ -67,7 +67,7 @@ static struct cdev macvtap_cdev;
 static const struct proto_ops macvtap_socket_ops;
 
 #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
-		      NETIF_F_TSO6)
+		      NETIF_F_TSO6 | NETIF_F_UFO)
 #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
 #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG | NETIF_F_FRAGLIST)
 
@@ -566,8 +566,6 @@ static int macvtap_skb_from_vnet_hdr(str
 			gso_type = SKB_GSO_TCPV6;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
-			pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
-				     current->comm);
 			gso_type = SKB_GSO_UDP;
 			if (skb->protocol == htons(ETH_P_IPV6))
 				ipv6_proxy_select_ident(skb);
@@ -615,6 +613,8 @@ static int macvtap_skb_to_vnet_hdr(const
 			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (sinfo->gso_type & SKB_GSO_TCPV6)
 			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+		else if (sinfo->gso_type & SKB_GSO_UDP)
+			vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
 		if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -962,6 +962,9 @@ static int set_offload(struct macvtap_qu
 			if (arg & TUN_F_TSO6)
 				feature_mask |= NETIF_F_TSO6;
 		}
+
+		if (arg & TUN_F_UFO)
+			feature_mask |= NETIF_F_UFO;
 	}
 
 	/* tun/tap driver inverts the usage for TSO offloads, where
@@ -972,7 +975,7 @@ static int set_offload(struct macvtap_qu
 	 * When user space turns off TSO, we turn off GSO/LRO so that
 	 * user-space will not receive TSO frames.
 	 */
-	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
+	if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
 		features |= RX_OFFLOADS;
 	else
 		features &= ~RX_OFFLOADS;
@@ -1073,7 +1076,7 @@ static long macvtap_ioctl(struct file *f
 	case TUNSETOFFLOAD:
 		/* let the user check for future flags */
 		if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
-			    TUN_F_TSO_ECN))
+			    TUN_F_TSO_ECN | TUN_F_UFO))
 			return -EINVAL;
 
 		rtnl_lock();
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/net/tun.c linux-libre-3.12.69-gnu/drivers/net/tun.c
--- linux-libre-3.12.68-gnu/drivers/net/tun.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/net/tun.c	2016-12-13 14:52:06.000000000 -0500
@@ -173,7 +173,7 @@ struct tun_struct {
 	struct net_device	*dev;
 	netdev_features_t	set_features;
 #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
-			  NETIF_F_TSO6)
+			  NETIF_F_TSO6|NETIF_F_UFO)
 
 	int			vnet_hdr_sz;
 	int			sndbuf;
@@ -1113,20 +1113,10 @@ static ssize_t tun_get_user(struct tun_s
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
-		{
-			static bool warned;
-
-			if (!warned) {
-				warned = true;
-				netdev_warn(tun->dev,
-					    "%s: using disabled UFO feature; please fix this program\n",
-					    current->comm);
-			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 			if (skb->protocol == htons(ETH_P_IPV6))
 				ipv6_proxy_select_ident(skb);
 			break;
-		}
 		default:
 			tun->dev->stats.rx_frame_errors++;
 			kfree_skb(skb);
@@ -1230,6 +1220,8 @@ static ssize_t tun_put_user(struct tun_s
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 			else if (sinfo->gso_type & SKB_GSO_TCPV6)
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+			else if (sinfo->gso_type & SKB_GSO_UDP)
+				gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 			else {
 				pr_err("unexpected GSO type: "
 				       "0x%x, gso_size %d, hdr_len %d\n",
@@ -1758,6 +1750,11 @@ static int set_offload(struct tun_struct
 				features |= NETIF_F_TSO6;
 			arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
 		}
+
+		if (arg & TUN_F_UFO) {
+			features |= NETIF_F_UFO;
+			arg &= ~TUN_F_UFO;
+		}
 	}
 
 	/* This gives the user a way to test for new features in future by
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/net/virtio_net.c linux-libre-3.12.69-gnu/drivers/net/virtio_net.c
--- linux-libre-3.12.68-gnu/drivers/net/virtio_net.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/net/virtio_net.c	2016-12-13 14:52:06.000000000 -0500
@@ -438,17 +438,8 @@ static void receive_buf(struct receive_q
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
 			break;
 		case VIRTIO_NET_HDR_GSO_UDP:
-		{
-			static bool warned;
-
-			if (!warned) {
-				warned = true;
-				netdev_warn(dev,
-					    "host using disabled UFO feature; please fix it\n");
-			}
 			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
 			break;
-		}
 		case VIRTIO_NET_HDR_GSO_TCPV6:
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
@@ -763,6 +754,8 @@ static int xmit_skb(struct send_queue *s
 			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 		else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
 			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+		else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+			hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 		else
 			BUG();
 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
@@ -1579,7 +1572,7 @@ static int virtnet_probe(struct virtio_d
 			dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
 
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
-			dev->hw_features |= NETIF_F_TSO
+			dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
 				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
 		}
 		/* Individual feature bits: what can host handle? */
@@ -1589,9 +1582,11 @@ static int virtnet_probe(struct virtio_d
 			dev->hw_features |= NETIF_F_TSO6;
 		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
 			dev->hw_features |= NETIF_F_TSO_ECN;
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+			dev->hw_features |= NETIF_F_UFO;
 
 		if (gso)
-			dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
+			dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
 		/* (!csum && gso) case will be fixed by register_netdev() */
 	}
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
@@ -1626,7 +1621,8 @@ static int virtnet_probe(struct virtio_d
 	/* If we can receive ANY GSO packets, we must allocate large ones. */
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
 	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
-	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
+	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
 		vi->big_packets = true;
 
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
@@ -1812,9 +1808,9 @@ static struct virtio_device_id id_table[
 static unsigned int features[] = {
 	VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
 	VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
-	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
+	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
 	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
-	VIRTIO_NET_F_GUEST_ECN,
+	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
 	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
 	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 	VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/net/wireless/mwifiex/cfg80211.c linux-libre-3.12.69-gnu/drivers/net/wireless/mwifiex/cfg80211.c
--- linux-libre-3.12.68-gnu/drivers/net/wireless/mwifiex/cfg80211.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/net/wireless/mwifiex/cfg80211.c	2016-12-13 14:52:06.000000000 -0500
@@ -1693,8 +1693,9 @@ done:
 			is_scanning_required = 1;
 		} else {
 			dev_dbg(priv->adapter->dev,
-				"info: trying to associate to '%s' bssid %pM\n",
-				(char *) req_ssid.ssid, bss->bssid);
+				"info: trying to associate to '%.*s' bssid %pM\n",
+				req_ssid.ssid_len, (char *)req_ssid.ssid,
+				bss->bssid);
 			memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
 			break;
 		}
@@ -1735,8 +1736,8 @@ mwifiex_cfg80211_connect(struct wiphy *w
 		return -EINVAL;
 	}
 
-	wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
-		  (char *) sme->ssid, sme->bssid);
+	wiphy_dbg(wiphy, "info: Trying to associate to %.*s and bssid %pM\n",
+		  (int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
 
 	ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
 				     priv->bss_mode, sme->channel, sme, 0);
@@ -1859,8 +1860,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy
 		goto done;
 	}
 
-	wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
-		  (char *) params->ssid, params->bssid);
+	wiphy_dbg(wiphy, "info: trying to join to %.*s and bssid %pM\n",
+		  params->ssid_len, (char *)params->ssid, params->bssid);
 
 	mwifiex_set_ibss_params(priv, params);
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/pci/access.c linux-libre-3.12.69-gnu/drivers/pci/access.c
--- linux-libre-3.12.68-gnu/drivers/pci/access.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/pci/access.c	2016-12-13 14:52:06.000000000 -0500
@@ -362,7 +362,8 @@ static const struct pci_vpd_ops pci_vpd_
 static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
 			       void *arg)
 {
-	struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
+	struct pci_dev *tdev = pci_get_slot(dev->bus,
+					    PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
 	ssize_t ret;
 
 	if (!tdev)
@@ -376,7 +377,8 @@ static ssize_t pci_vpd_f0_read(struct pc
 static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
 				const void *arg)
 {
-	struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
+	struct pci_dev *tdev = pci_get_slot(dev->bus,
+					    PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
 	ssize_t ret;
 
 	if (!tdev)
@@ -393,22 +395,6 @@ static const struct pci_vpd_ops pci_vpd_
 	.release = pci_vpd_pci22_release,
 };
 
-static int pci_vpd_f0_dev_check(struct pci_dev *dev)
-{
-	struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn));
-	int ret = 0;
-
-	if (!tdev)
-		return -ENODEV;
-	if (!tdev->vpd || !tdev->multifunction ||
-	    dev->class != tdev->class || dev->vendor != tdev->vendor ||
-	    dev->device != tdev->device)
-		ret = -ENODEV;
-
-	pci_dev_put(tdev);
-	return ret;
-}
-
 int pci_vpd_pci22_init(struct pci_dev *dev)
 {
 	struct pci_vpd_pci22 *vpd;
@@ -417,12 +403,7 @@ int pci_vpd_pci22_init(struct pci_dev *d
 	cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
 	if (!cap)
 		return -ENODEV;
-	if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) {
-		int ret = pci_vpd_f0_dev_check(dev);
 
-		if (ret)
-			return ret;
-	}
 	vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
 	if (!vpd)
 		return -ENOMEM;
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/pci/pcie/aer/aer_inject.c linux-libre-3.12.69-gnu/drivers/pci/pcie/aer/aer_inject.c
--- linux-libre-3.12.68-gnu/drivers/pci/pcie/aer/aer_inject.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/pci/pcie/aer/aer_inject.c	2016-12-13 14:52:06.000000000 -0500
@@ -283,20 +283,6 @@ out:
 	return 0;
 }
 
-static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
-{
-	while (1) {
-		if (!pci_is_pcie(dev))
-			break;
-		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
-			return dev;
-		if (!dev->bus->self)
-			break;
-		dev = dev->bus->self;
-	}
-	return NULL;
-}
-
 static int find_aer_device_iter(struct device *device, void *data)
 {
 	struct pcie_device **result = data;
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/pci/quirks.c linux-libre-3.12.69-gnu/drivers/pci/quirks.c
--- linux-libre-3.12.68-gnu/drivers/pci/quirks.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/pci/quirks.c	2016-12-13 14:52:06.000000000 -0500
@@ -1894,11 +1894,27 @@ static void quirk_netmos(struct pci_dev
 DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
 			 PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
 
+/*
+ * Quirk non-zero PCI functions to route VPD access through function 0 for
+ * devices that share VPD resources between functions.  The functions are
+ * expected to be identical devices.
+ */
 static void quirk_f0_vpd_link(struct pci_dev *dev)
 {
-	if (!dev->multifunction || !PCI_FUNC(dev->devfn))
+	struct pci_dev *f0;
+
+	if (!PCI_FUNC(dev->devfn))
 		return;
-	dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+
+	f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+	if (!f0)
+		return;
+
+	if (f0->vpd && dev->class == f0->class &&
+	    dev->vendor == f0->vendor && dev->device == f0->device)
+		dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+
+	pci_dev_put(f0);
 }
 DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
 			      PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/pwm/sysfs.c linux-libre-3.12.69-gnu/drivers/pwm/sysfs.c
--- linux-libre-3.12.68-gnu/drivers/pwm/sysfs.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/pwm/sysfs.c	2016-12-13 14:52:06.000000000 -0500
@@ -364,6 +364,8 @@ void pwmchip_sysfs_unexport_children(str
 		if (test_bit(PWMF_EXPORTED, &pwm->flags))
 			pwm_unexport_child(parent, pwm);
 	}
+
+	put_device(parent);
 }
 
 static int __init pwm_sysfs_init(void)
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c linux-libre-3.12.69-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c
--- linux-libre-3.12.68-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/scsi/mpt3sas/mpt3sas_scsih.c	2016-12-13 14:52:06.000000000 -0500
@@ -3516,6 +3516,10 @@ _scsih_eedp_error_handling(struct scsi_c
 	    SAM_STAT_CHECK_CONDITION;
 }
 
+static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
+{
+	return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
+}
 
 /**
  * _scsih_qcmd_lck - main scsi request entry point
@@ -3544,6 +3548,13 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd,
 		scsi_print_command(scmd);
 #endif
 
+	/*
+	 * Lock the device for any subsequent command until command is
+	 * done.
+	 */
+	if (ata_12_16_cmd(scmd))
+		scsi_internal_device_block(scmd->device);
+
 	scmd->scsi_done = done;
 	sas_device_priv_data = scmd->device->hostdata;
 	if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
@@ -4047,6 +4058,9 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *i
 	if (scmd == NULL)
 		return 1;
 
+	if (ata_12_16_cmd(scmd))
+		scsi_internal_device_unblock(scmd->device, SDEV_RUNNING);
+
 	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
 
 	if (mpi_reply == NULL) {
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/tty/n_tty.c linux-libre-3.12.69-gnu/drivers/tty/n_tty.c
--- linux-libre-3.12.68-gnu/drivers/tty/n_tty.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/tty/n_tty.c	2016-12-13 14:52:06.000000000 -0500
@@ -192,7 +192,7 @@ static inline int tty_copy_to_user(struc
 {
 	struct n_tty_data *ldata = tty->disc_data;
 
-	tty_audit_add_data(tty, to, n, ldata->icanon);
+	tty_audit_add_data(tty, from, n, ldata->icanon);
 	return copy_to_user(to, from, n);
 }
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/tty/tty_audit.c linux-libre-3.12.69-gnu/drivers/tty/tty_audit.c
--- linux-libre-3.12.68-gnu/drivers/tty/tty_audit.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/tty/tty_audit.c	2016-12-13 14:52:06.000000000 -0500
@@ -264,7 +264,7 @@ static struct tty_audit_buf *tty_audit_b
  *
  *	Audit @data of @size from @tty, if necessary.
  */
-void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
+void tty_audit_add_data(struct tty_struct *tty, const void *data,
 			size_t size, unsigned icanon)
 {
 	struct tty_audit_buf *buf;
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/usb/chipidea/core.c linux-libre-3.12.69-gnu/drivers/usb/chipidea/core.c
--- linux-libre-3.12.68-gnu/drivers/usb/chipidea/core.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/usb/chipidea/core.c	2016-12-13 14:52:06.000000000 -0500
@@ -491,6 +491,7 @@ static int ci_hdrc_probe(struct platform
 		return -ENOMEM;
 	}
 
+	spin_lock_init(&ci->lock);
 	ci->dev = dev;
 	ci->platdata = dev->platform_data;
 	if (ci->platdata->phy)
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/usb/chipidea/udc.c linux-libre-3.12.69-gnu/drivers/usb/chipidea/udc.c
--- linux-libre-3.12.68-gnu/drivers/usb/chipidea/udc.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/usb/chipidea/udc.c	2016-12-13 14:52:06.000000000 -0500
@@ -1777,8 +1777,6 @@ static int udc_start(struct ci_hdrc *ci)
 	struct device *dev = ci->dev;
 	int retval = 0;
 
-	spin_lock_init(&ci->lock);
-
 	ci->gadget.ops          = &usb_gadget_ops;
 	ci->gadget.speed        = USB_SPEED_UNKNOWN;
 	ci->gadget.max_speed    = USB_SPEED_HIGH;
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/usb/serial/cp210x.c linux-libre-3.12.69-gnu/drivers/usb/serial/cp210x.c
--- linux-libre-3.12.68-gnu/drivers/usb/serial/cp210x.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/usb/serial/cp210x.c	2016-12-13 14:52:06.000000000 -0500
@@ -130,6 +130,7 @@ static const struct usb_device_id id_tab
 	{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
 	{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
+	{ USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */
 	{ USB_DEVICE(0x10C4, 0x8977) },	/* CEL MeshWorks DevKit Device */
 	{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
 	{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/usb/serial/ftdi_sio.c linux-libre-3.12.69-gnu/drivers/usb/serial/ftdi_sio.c
--- linux-libre-3.12.68-gnu/drivers/usb/serial/ftdi_sio.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/usb/serial/ftdi_sio.c	2016-12-13 14:52:06.000000000 -0500
@@ -1026,6 +1026,8 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
 	{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
+	{ USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ }					/* Terminating entry */
 };
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/usb/serial/ftdi_sio_ids.h linux-libre-3.12.69-gnu/drivers/usb/serial/ftdi_sio_ids.h
--- linux-libre-3.12.68-gnu/drivers/usb/serial/ftdi_sio_ids.h	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/usb/serial/ftdi_sio_ids.h	2016-12-13 14:52:06.000000000 -0500
@@ -596,6 +596,12 @@
 #define STK541_PID		0x2109 /* Zigbee Controller */
 
 /*
+ * Texas Instruments
+ */
+#define TI_VID			0x0451
+#define TI_CC3200_LAUNCHPAD_PID	0xC32A /* SimpleLink Wi-Fi CC3200 LaunchPad */
+
+/*
  * Blackfin gnICE JTAG
  * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice
  */
diff -druNp --no-dereference linux-libre-3.12.68-gnu/drivers/usb/storage/transport.c linux-libre-3.12.69-gnu/drivers/usb/storage/transport.c
--- linux-libre-3.12.68-gnu/drivers/usb/storage/transport.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/drivers/usb/storage/transport.c	2016-12-13 14:52:06.000000000 -0500
@@ -919,10 +919,15 @@ int usb_stor_CB_transport(struct scsi_cm
 
 	/* COMMAND STAGE */
 	/* let's send the command via the control pipe */
+	/*
+	 * Command is sometime (f.e. after scsi_eh_prep_cmnd) on the stack.
+	 * Stack may be vmallocated.  So no DMA for us.  Make a copy.
+	 */
+	memcpy(us->iobuf, srb->cmnd, srb->cmd_len);
 	result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
 				      US_CBI_ADSC, 
 				      USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 
-				      us->ifnum, srb->cmnd, srb->cmd_len);
+				      us->ifnum, us->iobuf, srb->cmd_len);
 
 	/* check the return code for the command */
 	usb_stor_dbg(us, "Call to usb_stor_ctrl_transfer() returned %d\n",
diff -druNp --no-dereference linux-libre-3.12.68-gnu/include/linux/pci.h linux-libre-3.12.69-gnu/include/linux/pci.h
--- linux-libre-3.12.68-gnu/include/linux/pci.h	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/include/linux/pci.h	2016-12-13 14:52:06.000000000 -0500
@@ -1787,6 +1787,20 @@ static inline int pci_pcie_type(const st
 	return (pcie_caps_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4;
 }
 
+static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+{
+	while (1) {
+		if (!pci_is_pcie(dev))
+			break;
+		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+			return dev;
+		if (!dev->bus->self)
+			break;
+		dev = dev->bus->self;
+	}
+	return NULL;
+}
+
 void pci_request_acs(void);
 bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
 bool pci_acs_path_enabled(struct pci_dev *start,
diff -druNp --no-dereference linux-libre-3.12.68-gnu/include/linux/tty.h linux-libre-3.12.69-gnu/include/linux/tty.h
--- linux-libre-3.12.68-gnu/include/linux/tty.h	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/include/linux/tty.h	2016-12-13 14:52:06.000000000 -0500
@@ -578,7 +578,7 @@ extern void n_tty_inherit_ops(struct tty
 
 /* tty_audit.c */
 #ifdef CONFIG_AUDIT
-extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data,
+extern void tty_audit_add_data(struct tty_struct *tty, const void *data,
 			       size_t size, unsigned icanon);
 extern void tty_audit_exit(void);
 extern void tty_audit_fork(struct signal_struct *sig);
@@ -586,8 +586,8 @@ extern void tty_audit_tiocsti(struct tty
 extern void tty_audit_push(struct tty_struct *tty);
 extern int tty_audit_push_current(void);
 #else
-static inline void tty_audit_add_data(struct tty_struct *tty,
-		unsigned char *data, size_t size, unsigned icanon)
+static inline void tty_audit_add_data(struct tty_struct *tty, const void *data,
+				      size_t size, unsigned icanon)
 {
 }
 static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch)
diff -druNp --no-dereference linux-libre-3.12.68-gnu/kernel/panic.c linux-libre-3.12.69-gnu/kernel/panic.c
--- linux-libre-3.12.68-gnu/kernel/panic.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/kernel/panic.c	2016-12-13 14:52:06.000000000 -0500
@@ -138,8 +138,11 @@ void panic(const char *fmt, ...)
 	 * We may have ended up stopping the CPU holding the lock (in
 	 * smp_send_stop()) while still having some valuable data in the console
 	 * buffer.  Try to acquire the lock then release it regardless of the
-	 * result.  The release will also print the buffers out.
+	 * result.  The release will also print the buffers out.  Locks debug
+	 * should be disabled to avoid reporting bad unlock balance when
+	 * panic() is not being callled from OOPS.
 	 */
+	debug_locks_off();
 	console_flush_on_panic();
 
 	if (!panic_blink)
diff -druNp --no-dereference linux-libre-3.12.68-gnu/kernel/rcutree_plugin.h linux-libre-3.12.69-gnu/kernel/rcutree_plugin.h
--- linux-libre-3.12.68-gnu/kernel/rcutree_plugin.h	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/kernel/rcutree_plugin.h	2016-12-13 14:52:06.000000000 -0500
@@ -2274,6 +2274,7 @@ static int rcu_nocb_kthread(void *arg)
 				cl++;
 			c++;
 			local_bh_enable();
+			cond_resched();
 			list = next;
 		}
 		trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1);
diff -druNp --no-dereference linux-libre-3.12.68-gnu/lib/mpi/mpi-pow.c linux-libre-3.12.69-gnu/lib/mpi/mpi-pow.c
--- linux-libre-3.12.68-gnu/lib/mpi/mpi-pow.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/lib/mpi/mpi-pow.c	2016-12-13 14:52:06.000000000 -0500
@@ -64,8 +64,13 @@ int mpi_powm(MPI res, MPI base, MPI exp,
 	if (!esize) {
 		/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
 		 * depending on if MOD equals 1.  */
-		rp[0] = 1;
 		res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+		if (res->nlimbs) {
+			if (mpi_resize(res, 1) < 0)
+				goto enomem;
+			rp = res->d;
+			rp[0] = 1;
+		}
 		res->sign = 0;
 		goto leave;
 	}
diff -druNp --no-dereference linux-libre-3.12.68-gnu/Makefile linux-libre-3.12.69-gnu/Makefile
--- linux-libre-3.12.68-gnu/Makefile	2016-11-30 19:51:49.000000000 -0500
+++ linux-libre-3.12.69-gnu/Makefile	2016-12-18 07:32:38.000000000 -0500
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 12
-SUBLEVEL = 68
+SUBLEVEL = 69
 EXTRAVERSION =-gnu
 NAME = One Giant Leap for Frogkind
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/core/sock.c linux-libre-3.12.69-gnu/net/core/sock.c
--- linux-libre-3.12.68-gnu/net/core/sock.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/core/sock.c	2016-12-13 14:52:06.000000000 -0500
@@ -728,7 +728,7 @@ int sock_setsockopt(struct socket *sock,
 		val = min_t(u32, val, sysctl_wmem_max);
 set_sndbuf:
 		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
-		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
+		sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
 		/* Wake up sending tasks if we upped the value. */
 		sk->sk_write_space(sk);
 		break;
@@ -764,7 +764,7 @@ set_rcvbuf:
 		 * returning the value we actually used in getsockopt
 		 * is the most desirable behavior.
 		 */
-		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
+		sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
 		break;
 
 	case SO_RCVBUFFORCE:
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/dccp/ipv4.c linux-libre-3.12.69-gnu/net/dccp/ipv4.c
--- linux-libre-3.12.68-gnu/net/dccp/ipv4.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/dccp/ipv4.c	2016-12-13 14:52:06.000000000 -0500
@@ -742,6 +742,7 @@ int dccp_invalid_packet(struct sk_buff *
 {
 	const struct dccp_hdr *dh;
 	unsigned int cscov;
+	u8 dccph_doff;
 
 	if (skb->pkt_type != PACKET_HOST)
 		return 1;
@@ -763,18 +764,19 @@ int dccp_invalid_packet(struct sk_buff *
 	/*
 	 * If P.Data Offset is too small for packet type, drop packet and return
 	 */
-	if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
-		DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
+	dccph_doff = dh->dccph_doff;
+	if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
+		DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff);
 		return 1;
 	}
 	/*
 	 * If P.Data Offset is too too large for packet, drop packet and return
 	 */
-	if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
-		DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
+	if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
+		DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff);
 		return 1;
 	}
-
+	dh = dccp_hdr(skb);
 	/*
 	 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
 	 * has short sequence numbers), drop packet and return
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/ipv4/ip_output.c linux-libre-3.12.69-gnu/net/ipv4/ip_output.c
--- linux-libre-3.12.68-gnu/net/ipv4/ip_output.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/ipv4/ip_output.c	2016-12-13 14:52:06.000000000 -0500
@@ -97,6 +97,9 @@ int __ip_local_out(struct sk_buff *skb)
 
 	iph->tot_len = htons(skb->len);
 	ip_send_check(iph);
+
+	skb->protocol = htons(ETH_P_IP);
+
 	return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
 		       skb_dst(skb)->dev, dst_output);
 }
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/ipv4/ping.c linux-libre-3.12.69-gnu/net/ipv4/ping.c
--- linux-libre-3.12.68-gnu/net/ipv4/ping.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/ipv4/ping.c	2016-12-13 14:52:06.000000000 -0500
@@ -655,6 +655,10 @@ int ping_common_sendmsg(int family, stru
 	if (len > 0xFFFF)
 		return -EMSGSIZE;
 
+	/* Must have at least a full ICMP header. */
+	if (len < icmph_len)
+		return -EINVAL;
+
 	/*
 	 *	Check the flags.
 	 */
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/ipv6/ip6_tunnel.c linux-libre-3.12.69-gnu/net/ipv6/ip6_tunnel.c
--- linux-libre-3.12.68-gnu/net/ipv6/ip6_tunnel.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/ipv6/ip6_tunnel.c	2016-12-13 14:52:06.000000000 -0500
@@ -950,12 +950,21 @@ static int ip6_tnl_xmit2(struct sk_buff
 	struct ipv6_tel_txoption opt;
 	struct dst_entry *dst = NULL, *ndst = NULL;
 	struct net_device *tdev;
+	bool use_cache = false;
 	int mtu;
 	unsigned int max_headroom = sizeof(struct ipv6hdr);
 	u8 proto;
 	int err = -1;
 
-	if (!fl6->flowi6_mark)
+	if (!(t->parms.flags &
+		     (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) {
+		/* enable the cache only only if the routing decision does
+		 * not depend on the current inner header value
+		 */
+		use_cache = true;
+	}
+
+	if (use_cache)
 		dst = ip6_tnl_dst_check(t);
 	if (!dst) {
 		ndst = ip6_route_output(net, NULL, fl6);
@@ -1013,7 +1022,7 @@ static int ip6_tnl_xmit2(struct sk_buff
 		consume_skb(skb);
 		skb = new_skb;
 	}
-	if (fl6->flowi6_mark) {
+	if (!use_cache) {
 		skb_dst_set(skb, dst);
 		ndst = NULL;
 	} else {
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/ipv6/output_core.c linux-libre-3.12.69-gnu/net/ipv6/output_core.c
--- linux-libre-3.12.68-gnu/net/ipv6/output_core.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/ipv6/output_core.c	2016-12-13 14:52:06.000000000 -0500
@@ -117,6 +117,8 @@ int __ip6_local_out(struct sk_buff *skb)
 		len = 0;
 	ipv6_hdr(skb)->payload_len = htons(len);
 
+	skb->protocol = htons(ETH_P_IPV6);
+
 	return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
 		       skb_dst(skb)->dev, dst_output);
 }
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/l2tp/l2tp_ip6.c linux-libre-3.12.69-gnu/net/l2tp/l2tp_ip6.c
--- linux-libre-3.12.68-gnu/net/l2tp/l2tp_ip6.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/l2tp/l2tp_ip6.c	2016-12-13 14:52:06.000000000 -0500
@@ -266,8 +266,6 @@ static int l2tp_ip6_bind(struct sock *sk
 	int addr_type;
 	int err;
 
-	if (!sock_flag(sk, SOCK_ZAPPED))
-		return -EINVAL;
 	if (addr->l2tp_family != AF_INET6)
 		return -EINVAL;
 	if (addr_len < sizeof(*addr))
@@ -293,6 +291,9 @@ static int l2tp_ip6_bind(struct sock *sk
 	lock_sock(sk);
 
 	err = -EINVAL;
+	if (!sock_flag(sk, SOCK_ZAPPED))
+		goto out_unlock;
+
 	if (sk->sk_state != TCP_CLOSE)
 		goto out_unlock;
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/l2tp/l2tp_ip.c linux-libre-3.12.69-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-3.12.68-gnu/net/l2tp/l2tp_ip.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/l2tp/l2tp_ip.c	2016-12-13 14:52:06.000000000 -0500
@@ -251,8 +251,6 @@ static int l2tp_ip_bind(struct sock *sk,
 	int ret;
 	int chk_addr_ret;
 
-	if (!sock_flag(sk, SOCK_ZAPPED))
-		return -EINVAL;
 	if (addr_len < sizeof(struct sockaddr_l2tpip))
 		return -EINVAL;
 	if (addr->l2tp_family != AF_INET)
@@ -267,6 +265,9 @@ static int l2tp_ip_bind(struct sock *sk,
 	read_unlock_bh(&l2tp_ip_lock);
 
 	lock_sock(sk);
+	if (!sock_flag(sk, SOCK_ZAPPED))
+		goto out;
+
 	if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip))
 		goto out;
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/packet/af_packet.c linux-libre-3.12.69-gnu/net/packet/af_packet.c
--- linux-libre-3.12.68-gnu/net/packet/af_packet.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/packet/af_packet.c	2016-12-13 14:52:06.000000000 -0500
@@ -3115,19 +3115,25 @@ 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;
 		switch (val) {
 		case TPACKET_V1:
 		case TPACKET_V2:
 		case TPACKET_V3:
-			po->tp_version = val;
-			return 0;
+			break;
 		default:
 			return -EINVAL;
 		}
+		lock_sock(sk);
+		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+			ret = -EBUSY;
+		} else {
+			po->tp_version = val;
+			ret = 0;
+		}
+		release_sock(sk);
+		return ret;
 	}
 	case PACKET_RESERVE:
 	{
@@ -3584,6 +3590,7 @@ static int packet_set_ring(struct sock *
 	/* Added to avoid minimal code churn */
 	struct tpacket_req *req = &req_u->req;
 
+	lock_sock(sk);
 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
 		WARN(1, "Tx-ring is not supported.\n");
@@ -3665,7 +3672,6 @@ static int packet_set_ring(struct sock *
 			goto out;
 	}
 
-	lock_sock(sk);
 
 	/* Detach socket from network */
 	spin_lock(&po->bind_lock);
@@ -3714,11 +3720,11 @@ static int packet_set_ring(struct sock *
 		if (!tx_ring)
 			prb_shutdown_retire_blk_timer(po, tx_ring, rb_queue);
 	}
-	release_sock(sk);
 
 	if (pg_vec)
 		free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
+	release_sock(sk);
 	return err;
 }
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/sched/act_pedit.c linux-libre-3.12.69-gnu/net/sched/act_pedit.c
--- linux-libre-3.12.68-gnu/net/sched/act_pedit.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/sched/act_pedit.c	2016-12-13 14:52:06.000000000 -0500
@@ -124,6 +124,17 @@ static int tcf_pedit_cleanup(struct tc_a
 	return 0;
 }
 
+static bool offset_valid(struct sk_buff *skb, int offset)
+{
+	if (offset > 0 && offset > skb->len)
+		return false;
+
+	if  (offset < 0 && -offset > skb_headroom(skb))
+		return false;
+
+	return true;
+}
+
 static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
 		     struct tcf_result *res)
 {
@@ -150,6 +161,11 @@ static int tcf_pedit(struct sk_buff *skb
 			if (tkey->offmask) {
 				char *d, _d;
 
+				if (!offset_valid(skb, off + tkey->at)) {
+					pr_info("tc filter pedit 'at' offset %d out of bounds\n",
+						off + tkey->at);
+					goto bad;
+				}
 				d = skb_header_pointer(skb, off + tkey->at, 1,
 						       &_d);
 				if (!d)
@@ -162,10 +178,10 @@ static int tcf_pedit(struct sk_buff *skb
 					" offset must be on 32 bit boundaries\n");
 				goto bad;
 			}
-			if (offset > 0 && offset > skb->len) {
-				pr_info("tc filter pedit"
-					" offset %d can't exceed pkt length %d\n",
-				       offset, skb->len);
+
+			if (!offset_valid(skb, off + offset)) {
+				pr_info("tc filter pedit offset %d out of bounds\n",
+					offset);
 				goto bad;
 			}
 
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/wireless/core.h linux-libre-3.12.69-gnu/net/wireless/core.h
--- linux-libre-3.12.68-gnu/net/wireless/core.h	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/wireless/core.h	2016-12-13 14:52:06.000000000 -0500
@@ -61,6 +61,7 @@ struct cfg80211_registered_device {
 	struct list_head bss_list;
 	struct rb_root bss_tree;
 	u32 bss_generation;
+	u32 bss_entries;
 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
 	struct cfg80211_sched_scan_request *sched_scan_req;
 	unsigned long suspend_at;
diff -druNp --no-dereference linux-libre-3.12.68-gnu/net/wireless/scan.c linux-libre-3.12.69-gnu/net/wireless/scan.c
--- linux-libre-3.12.68-gnu/net/wireless/scan.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/net/wireless/scan.c	2016-12-13 14:52:06.000000000 -0500
@@ -55,6 +55,19 @@
  * also linked into the probe response struct.
  */
 
+/*
+ * Limit the number of BSS entries stored in mac80211. Each one is
+ * a bit over 4k at most, so this limits to roughly 4-5M of memory.
+ * If somebody wants to really attack this though, they'd likely
+ * use small beacons, and only one type of frame, limiting each of
+ * the entries to a much smaller size (in order to generate more
+ * entries in total, so overhead is bigger.)
+ */
+static int bss_entries_limit = 1000;
+module_param(bss_entries_limit, int, 0644);
+MODULE_PARM_DESC(bss_entries_limit,
+                 "limit to number of scan BSS entries (per wiphy, default 1000)");
+
 #define IEEE80211_SCAN_RESULT_EXPIRE	(30 * HZ)
 
 static void bss_free(struct cfg80211_internal_bss *bss)
@@ -135,6 +148,10 @@ static bool __cfg80211_unlink_bss(struct
 
 	list_del_init(&bss->list);
 	rb_erase(&bss->rbn, &dev->bss_tree);
+	dev->bss_entries--;
+	WARN_ONCE((dev->bss_entries == 0) ^ list_empty(&dev->bss_list),
+		  "rdev bss entries[%d]/list[empty:%d] corruption\n",
+		  dev->bss_entries, list_empty(&dev->bss_list));
 	bss_ref_put(dev, bss);
 	return true;
 }
@@ -339,6 +356,40 @@ void cfg80211_bss_expire(struct cfg80211
 	__cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
 }
 
+static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
+{
+	struct cfg80211_internal_bss *bss, *oldest = NULL;
+	bool ret;
+
+	lockdep_assert_held(&rdev->bss_lock);
+
+	list_for_each_entry(bss, &rdev->bss_list, list) {
+		if (atomic_read(&bss->hold))
+			continue;
+
+		if (!list_empty(&bss->hidden_list) &&
+		    !bss->pub.hidden_beacon_bss)
+			continue;
+
+		if (oldest && time_before(oldest->ts, bss->ts))
+			continue;
+		oldest = bss;
+	}
+
+	if (WARN_ON(!oldest))
+		return false;
+
+	/*
+	 * The callers make sure to increase rdev->bss_generation if anything
+	 * gets removed (and a new entry added), so there's no need to also do
+	 * it here.
+	 */
+
+	ret = __cfg80211_unlink_bss(rdev, oldest);
+	WARN_ON(!ret);
+	return ret;
+}
+
 const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
 {
 	while (len > 2 && ies[0] != eid) {
@@ -620,6 +671,7 @@ static bool cfg80211_combine_bsses(struc
 	const u8 *ie;
 	int i, ssidlen;
 	u8 fold = 0;
+	u32 n_entries = 0;
 
 	ies = rcu_access_pointer(new->pub.beacon_ies);
 	if (WARN_ON(!ies))
@@ -643,6 +695,12 @@ static bool cfg80211_combine_bsses(struc
 	/* This is the bad part ... */
 
 	list_for_each_entry(bss, &dev->bss_list, list) {
+		/*
+		 * we're iterating all the entries anyway, so take the
+		 * opportunity to validate the list length accounting
+		 */
+		n_entries++;
+
 		if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
 			continue;
 		if (bss->pub.channel != new->pub.channel)
@@ -674,6 +732,10 @@ static bool cfg80211_combine_bsses(struc
 				   new->pub.beacon_ies);
 	}
 
+	WARN_ONCE(n_entries != dev->bss_entries,
+		  "rdev bss entries[%d]/list[len:%d] corruption\n",
+		  dev->bss_entries, n_entries);
+
 	return true;
 }
 
@@ -819,7 +881,14 @@ cfg80211_bss_update(struct cfg80211_regi
 			}
 		}
 
+		if (dev->bss_entries >= bss_entries_limit &&
+		    !cfg80211_bss_expire_oldest(dev)) {
+			kfree(new);
+			goto drop;
+		}
+
 		list_add_tail(&new->list, &dev->bss_list);
+		dev->bss_entries++;
 		rb_insert_bss(dev, new);
 		found = new;
 	}
diff -druNp --no-dereference linux-libre-3.12.68-gnu/security/apparmor/domain.c linux-libre-3.12.69-gnu/security/apparmor/domain.c
--- linux-libre-3.12.68-gnu/security/apparmor/domain.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/security/apparmor/domain.c	2016-12-13 14:52:06.000000000 -0500
@@ -629,8 +629,8 @@ int aa_change_hat(const char *hats[], in
 	/* released below */
 	cred = get_current_cred();
 	cxt = cred_cxt(cred);
-	profile = aa_cred_profile(cred);
-	previous_profile = cxt->previous;
+	profile = aa_get_newest_profile(aa_cred_profile(cred));
+	previous_profile = aa_get_newest_profile(cxt->previous);
 
 	if (unconfined(profile)) {
 		info = "unconfined";
@@ -726,6 +726,8 @@ audit:
 out:
 	aa_put_profile(hat);
 	kfree(name);
+	aa_put_profile(profile);
+	aa_put_profile(previous_profile);
 	put_cred(cred);
 
 	return error;
diff -druNp --no-dereference linux-libre-3.12.68-gnu/sound/core/pcm_lib.c linux-libre-3.12.69-gnu/sound/core/pcm_lib.c
--- linux-libre-3.12.68-gnu/sound/core/pcm_lib.c	2016-11-28 16:22:53.000000000 -0500
+++ linux-libre-3.12.69-gnu/sound/core/pcm_lib.c	2016-12-13 14:52:06.000000000 -0500
@@ -1857,10 +1857,10 @@ void snd_pcm_period_elapsed(struct snd_p
 	if (substream->timer_running)
 		snd_timer_interrupt(substream->timer, 1);
  _end:
+	kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
 	snd_pcm_stream_unlock_irqrestore(substream, flags);
 	if (runtime->transfer_ack_end)
 		runtime->transfer_ack_end(substream);
-	kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
 }
 
 EXPORT_SYMBOL(snd_pcm_period_elapsed);
