diff -druN linux-libre-3.2.22-gnu/arch/arm/kernel/smp.c linux-libre-3.2.23-gnu/arch/arm/kernel/smp.c
--- linux-libre-3.2.22-gnu/arch/arm/kernel/smp.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/arch/arm/kernel/smp.c	2012-07-11 23:32:21.000000000 -0400
@@ -471,9 +471,7 @@
 static void ipi_timer(void)
 {
 	struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
-	irq_enter();
 	evt->event_handler(evt);
-	irq_exit();
 }
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
@@ -572,7 +570,9 @@
 
 	switch (ipinr) {
 	case IPI_TIMER:
+		irq_enter();
 		ipi_timer();
+		irq_exit();
 		break;
 
 	case IPI_RESCHEDULE:
@@ -580,15 +580,21 @@
 		break;
 
 	case IPI_CALL_FUNC:
+		irq_enter();
 		generic_smp_call_function_interrupt();
+		irq_exit();
 		break;
 
 	case IPI_CALL_FUNC_SINGLE:
+		irq_enter();
 		generic_smp_call_function_single_interrupt();
+		irq_exit();
 		break;
 
 	case IPI_CPU_STOP:
+		irq_enter();
 		ipi_cpu_stop(cpu);
+		irq_exit();
 		break;
 
 	default:
diff -druN linux-libre-3.2.22-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S linux-libre-3.2.23-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S
--- linux-libre-3.2.22-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/arch/powerpc/kvm/book3s_hv_rmhandlers.S	2012-07-11 23:32:21.000000000 -0400
@@ -763,7 +763,7 @@
 	lwz	r3,VCORE_NAPPING_THREADS(r5)
 	lwz	r4,VCPU_PTID(r9)
 	li	r0,1
-	sldi	r0,r0,r4
+	sld	r0,r0,r4
 	andc.	r3,r3,r0		/* no sense IPI'ing ourselves */
 	beq	43f
 	mulli	r4,r4,PACA_SIZE		/* get paca for thread 0 */
diff -druN linux-libre-3.2.22-gnu/arch/powerpc/xmon/xmon.c linux-libre-3.2.23-gnu/arch/powerpc/xmon/xmon.c
--- linux-libre-3.2.22-gnu/arch/powerpc/xmon/xmon.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/arch/powerpc/xmon/xmon.c	2012-07-11 23:32:21.000000000 -0400
@@ -975,7 +975,7 @@
 		/* print cpus waiting or in xmon */
 		printf("cpus stopped:");
 		count = 0;
-		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+		for_each_possible_cpu(cpu) {
 			if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
 				if (count == 0)
 					printf(" %x", cpu);
diff -druN linux-libre-3.2.22-gnu/drivers/block/umem.c linux-libre-3.2.23-gnu/drivers/block/umem.c
--- linux-libre-3.2.22-gnu/drivers/block/umem.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/block/umem.c	2012-07-11 23:32:21.000000000 -0400
@@ -513,6 +513,44 @@
 	}
 }
 
+struct mm_plug_cb {
+	struct blk_plug_cb cb;
+	struct cardinfo *card;
+};
+
+static void mm_unplug(struct blk_plug_cb *cb)
+{
+	struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb);
+
+	spin_lock_irq(&mmcb->card->lock);
+	activate(mmcb->card);
+	spin_unlock_irq(&mmcb->card->lock);
+	kfree(mmcb);
+}
+
+static int mm_check_plugged(struct cardinfo *card)
+{
+	struct blk_plug *plug = current->plug;
+	struct mm_plug_cb *mmcb;
+
+	if (!plug)
+		return 0;
+
+	list_for_each_entry(mmcb, &plug->cb_list, cb.list) {
+		if (mmcb->cb.callback == mm_unplug && mmcb->card == card)
+			return 1;
+	}
+	/* Not currently on the callback list */
+	mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC);
+	if (!mmcb)
+		return 0;
+
+	mmcb->card = card;
+	mmcb->cb.callback = mm_unplug;
+	list_add(&mmcb->cb.list, &plug->cb_list);
+	return 1;
+}
+
 static void mm_make_request(struct request_queue *q, struct bio *bio)
 {
 	struct cardinfo *card = q->queuedata;
@@ -523,6 +561,8 @@
 	*card->biotail = bio;
 	bio->bi_next = NULL;
 	card->biotail = &bio->bi_next;
+	if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card))
+		activate(card);
 	spin_unlock_irq(&card->lock);
 
 	return;
diff -druN linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_dma.c linux-libre-3.2.23-gnu/drivers/gpu/drm/i915/i915_dma.c
--- linux-libre-3.2.22-gnu/drivers/gpu/drm/i915/i915_dma.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/gpu/drm/i915/i915_dma.c	2012-07-11 23:32:21.000000000 -0400
@@ -1890,6 +1890,27 @@
 	}
 }
 
+static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
+{
+	struct apertures_struct *ap;
+	struct pci_dev *pdev = dev_priv->dev->pdev;
+	bool primary;
+
+	ap = alloc_apertures(1);
+	if (!ap)
+		return;
+
+	ap->ranges[0].base = dev_priv->dev->agp->base;
+	ap->ranges[0].size =
+		dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
+	primary =
+		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
+
+	remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
+
+	kfree(ap);
+}
+
 /**
  * i915_driver_load - setup chip and create an initial config
  * @dev: DRM device
@@ -1927,6 +1948,15 @@
 		goto free_priv;
 	}
 
+	dev_priv->mm.gtt = intel_gtt_get();
+	if (!dev_priv->mm.gtt) {
+		DRM_ERROR("Failed to initialize GTT\n");
+		ret = -ENODEV;
+		goto put_bridge;
+	}
+
+	i915_kick_out_firmware_fb(dev_priv);
+
 	/* overlay on gen2 is broken and can't address above 1G */
 	if (IS_GEN2(dev))
 		dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
@@ -1950,13 +1980,6 @@
 		goto put_bridge;
 	}
 
-	dev_priv->mm.gtt = intel_gtt_get();
-	if (!dev_priv->mm.gtt) {
-		DRM_ERROR("Failed to initialize GTT\n");
-		ret = -ENODEV;
-		goto out_rmmap;
-	}
-
 	agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT;
 
 	dev_priv->mm.gtt_mapping =
diff -druN linux-libre-3.2.22-gnu/drivers/md/persistent-data/dm-space-map-checker.c linux-libre-3.2.23-gnu/drivers/md/persistent-data/dm-space-map-checker.c
--- linux-libre-3.2.22-gnu/drivers/md/persistent-data/dm-space-map-checker.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/md/persistent-data/dm-space-map-checker.c	2012-07-11 23:32:21.000000000 -0400
@@ -8,6 +8,7 @@
 
 #include <linux/device-mapper.h>
 #include <linux/export.h>
+#include <linux/vmalloc.h>
 
 #ifdef CONFIG_DM_DEBUG_SPACE_MAPS
 
@@ -89,13 +90,23 @@
 
 	ca->nr = nr_blocks;
 	ca->nr_free = nr_blocks;
-	ca->counts = kzalloc(sizeof(*ca->counts) * nr_blocks, GFP_KERNEL);
-	if (!ca->counts)
-		return -ENOMEM;
+
+	if (!nr_blocks)
+		ca->counts = NULL;
+	else {
+		ca->counts = vzalloc(sizeof(*ca->counts) * nr_blocks);
+		if (!ca->counts)
+			return -ENOMEM;
+	}
 
 	return 0;
 }
 
+static void ca_destroy(struct count_array *ca)
+{
+	vfree(ca->counts);
+}
+
 static int ca_load(struct count_array *ca, struct dm_space_map *sm)
 {
 	int r;
@@ -126,12 +137,14 @@
 static int ca_extend(struct count_array *ca, dm_block_t extra_blocks)
 {
 	dm_block_t nr_blocks = ca->nr + extra_blocks;
-	uint32_t *counts = kzalloc(sizeof(*counts) * nr_blocks, GFP_KERNEL);
+	uint32_t *counts = vzalloc(sizeof(*counts) * nr_blocks);
 	if (!counts)
 		return -ENOMEM;
 
-	memcpy(counts, ca->counts, sizeof(*counts) * ca->nr);
-	kfree(ca->counts);
+	if (ca->counts) {
+		memcpy(counts, ca->counts, sizeof(*counts) * ca->nr);
+		ca_destroy(ca);
+	}
 	ca->nr = nr_blocks;
 	ca->nr_free += extra_blocks;
 	ca->counts = counts;
@@ -151,11 +164,6 @@
 	return 0;
 }
 
-static void ca_destroy(struct count_array *ca)
-{
-	kfree(ca->counts);
-}
-
 /*----------------------------------------------------------------*/
 
 struct sm_checker {
@@ -343,25 +351,25 @@
 	int r;
 	struct sm_checker *smc;
 
-	if (!sm)
-		return NULL;
+	if (IS_ERR_OR_NULL(sm))
+		return ERR_PTR(-EINVAL);
 
 	smc = kmalloc(sizeof(*smc), GFP_KERNEL);
 	if (!smc)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	memcpy(&smc->sm, &ops_, sizeof(smc->sm));
 	r = ca_create(&smc->old_counts, sm);
 	if (r) {
 		kfree(smc);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	r = ca_create(&smc->counts, sm);
 	if (r) {
 		ca_destroy(&smc->old_counts);
 		kfree(smc);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	smc->real_sm = sm;
@@ -371,7 +379,7 @@
 		ca_destroy(&smc->counts);
 		ca_destroy(&smc->old_counts);
 		kfree(smc);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	r = ca_commit(&smc->old_counts, &smc->counts);
@@ -379,7 +387,7 @@
 		ca_destroy(&smc->counts);
 		ca_destroy(&smc->old_counts);
 		kfree(smc);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	return &smc->sm;
@@ -391,25 +399,25 @@
 	int r;
 	struct sm_checker *smc;
 
-	if (!sm)
-		return NULL;
+	if (IS_ERR_OR_NULL(sm))
+		return ERR_PTR(-EINVAL);
 
 	smc = kmalloc(sizeof(*smc), GFP_KERNEL);
 	if (!smc)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	memcpy(&smc->sm, &ops_, sizeof(smc->sm));
 	r = ca_create(&smc->old_counts, sm);
 	if (r) {
 		kfree(smc);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	r = ca_create(&smc->counts, sm);
 	if (r) {
 		ca_destroy(&smc->old_counts);
 		kfree(smc);
-		return NULL;
+		return ERR_PTR(r);
 	}
 
 	smc->real_sm = sm;
diff -druN linux-libre-3.2.22-gnu/drivers/md/persistent-data/dm-space-map-disk.c linux-libre-3.2.23-gnu/drivers/md/persistent-data/dm-space-map-disk.c
--- linux-libre-3.2.22-gnu/drivers/md/persistent-data/dm-space-map-disk.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/md/persistent-data/dm-space-map-disk.c	2012-07-11 23:32:21.000000000 -0400
@@ -290,7 +290,16 @@
 				       dm_block_t nr_blocks)
 {
 	struct dm_space_map *sm = dm_sm_disk_create_real(tm, nr_blocks);
-	return dm_sm_checker_create_fresh(sm);
+	struct dm_space_map *smc;
+
+	if (IS_ERR_OR_NULL(sm))
+		return sm;
+
+	smc = dm_sm_checker_create_fresh(sm);
+	if (IS_ERR(smc))
+		dm_sm_destroy(sm);
+
+	return smc;
 }
 EXPORT_SYMBOL_GPL(dm_sm_disk_create);
 
diff -druN linux-libre-3.2.22-gnu/drivers/md/persistent-data/dm-transaction-manager.c linux-libre-3.2.23-gnu/drivers/md/persistent-data/dm-transaction-manager.c
--- linux-libre-3.2.22-gnu/drivers/md/persistent-data/dm-transaction-manager.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/md/persistent-data/dm-transaction-manager.c	2012-07-11 23:32:21.000000000 -0400
@@ -138,6 +138,9 @@
 
 void dm_tm_destroy(struct dm_transaction_manager *tm)
 {
+	if (!tm->is_clone)
+		wipe_shadow_table(tm);
+
 	kfree(tm);
 }
 EXPORT_SYMBOL_GPL(dm_tm_destroy);
@@ -342,8 +345,10 @@
 		}
 
 		*sm = dm_sm_checker_create(inner);
-		if (!*sm)
+		if (IS_ERR(*sm)) {
+			r = PTR_ERR(*sm);
 			goto bad2;
+		}
 
 	} else {
 		r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location,
@@ -362,8 +367,10 @@
 		}
 
 		*sm = dm_sm_checker_create(inner);
-		if (!*sm)
+		if (IS_ERR(*sm)) {
+			r = PTR_ERR(*sm);
 			goto bad2;
+		}
 	}
 
 	return 0;
diff -druN linux-libre-3.2.22-gnu/drivers/md/raid10.c linux-libre-3.2.23-gnu/drivers/md/raid10.c
--- linux-libre-3.2.22-gnu/drivers/md/raid10.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/md/raid10.c	2012-07-11 23:32:21.000000000 -0400
@@ -1919,7 +1919,7 @@
 			if (r10_sync_page_io(rdev,
 					     r10_bio->devs[sl].addr +
 					     sect,
-					     s<<9, conf->tmppage, WRITE)
+					     s, conf->tmppage, WRITE)
 			    == 0) {
 				/* Well, this device is dead */
 				printk(KERN_NOTICE
@@ -1956,7 +1956,7 @@
 			switch (r10_sync_page_io(rdev,
 					     r10_bio->devs[sl].addr +
 					     sect,
-					     s<<9, conf->tmppage,
+					     s, conf->tmppage,
 						 READ)) {
 			case 0:
 				/* Well, this device is dead */
@@ -2119,7 +2119,7 @@
 	rdev = conf->mirrors[mirror].rdev;
 	printk_ratelimited(
 		KERN_ERR
-		"md/raid10:%s: %s: redirecting"
+		"md/raid10:%s: %s: redirecting "
 		"sector %llu to another mirror\n",
 		mdname(mddev),
 		bdevname(rdev->bdev, b),
@@ -2436,6 +2436,12 @@
 			/* want to reconstruct this device */
 			rb2 = r10_bio;
 			sect = raid10_find_virt(conf, sector_nr, i);
+			if (sect >= mddev->resync_max_sectors) {
+				/* last stripe is not complete - don't
+				 * try to recover this sector.
+				 */
+				continue;
+			}
 			/* Unless we are doing a full sync, we only need
 			 * to recover the block if it is set in the bitmap
 			 */
diff -druN linux-libre-3.2.22-gnu/drivers/md/raid5.c linux-libre-3.2.23-gnu/drivers/md/raid5.c
--- linux-libre-3.2.22-gnu/drivers/md/raid5.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/md/raid5.c	2012-07-11 23:32:21.000000000 -0400
@@ -542,6 +542,12 @@
 					 * a chance*/
 					md_check_recovery(conf->mddev);
 				}
+				/*
+				 * Because md_wait_for_blocked_rdev
+				 * will dec nr_pending, we must
+				 * increment it first.
+				 */
+				atomic_inc(&rdev->nr_pending);
 				md_wait_for_blocked_rdev(rdev, conf->mddev);
 			} else {
 				/* Acknowledged bad block - skip the write */
@@ -3621,7 +3627,6 @@
 		raid_bio->bi_next = (void*)rdev;
 		align_bi->bi_bdev =  rdev->bdev;
 		align_bi->bi_flags &= ~(1 << BIO_SEG_VALID);
-		align_bi->bi_sector += rdev->data_offset;
 
 		if (!bio_fits_rdev(align_bi) ||
 		    is_badblock(rdev, align_bi->bi_sector, align_bi->bi_size>>9,
@@ -3632,6 +3637,9 @@
 			return 0;
 		}
 
+		/* No reshape active, so we can trust rdev->data_offset */
+		align_bi->bi_sector += rdev->data_offset;
+
 		spin_lock_irq(&conf->device_lock);
 		wait_event_lock_irq(conf->wait_for_stripe,
 				    conf->quiesce == 0,
diff -druN linux-libre-3.2.22-gnu/drivers/mtd/nand/cafe_nand.c linux-libre-3.2.23-gnu/drivers/mtd/nand/cafe_nand.c
--- linux-libre-3.2.22-gnu/drivers/mtd/nand/cafe_nand.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/mtd/nand/cafe_nand.c	2012-07-11 23:32:21.000000000 -0400
@@ -102,7 +102,7 @@
 static int cafe_device_ready(struct mtd_info *mtd)
 {
 	struct cafe_priv *cafe = mtd->priv;
-	int result = !!(cafe_readl(cafe, NAND_STATUS) | 0x40000000);
+	int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000);
 	uint32_t irqs = cafe_readl(cafe, NAND_IRQ);
 
 	cafe_writel(cafe, irqs, NAND_IRQ);
diff -druN linux-libre-3.2.22-gnu/drivers/net/bonding/bond_main.c linux-libre-3.2.23-gnu/drivers/net/bonding/bond_main.c
--- linux-libre-3.2.22-gnu/drivers/net/bonding/bond_main.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/bonding/bond_main.c	2012-07-11 23:32:21.000000000 -0400
@@ -77,6 +77,7 @@
 #include <net/route.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
+#include <net/pkt_sched.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 #include "bond_alb.h"
@@ -382,8 +383,6 @@
 	return next;
 }
 
-#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb))
-
 /**
  * bond_dev_queue_xmit - Prepare skb for xmit.
  *
@@ -396,7 +395,9 @@
 {
 	skb->dev = slave_dev;
 
-	skb->queue_mapping = bond_queue_mapping(skb);
+	BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
+		     sizeof(qdisc_skb_cb(skb)->bond_queue_mapping));
+	skb->queue_mapping = qdisc_skb_cb(skb)->bond_queue_mapping;
 
 	if (unlikely(netpoll_tx_running(slave_dev)))
 		bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
@@ -4151,7 +4152,7 @@
 	/*
 	 * Save the original txq to restore before passing to the driver
 	 */
-	bond_queue_mapping(skb) = skb->queue_mapping;
+	qdisc_skb_cb(skb)->bond_queue_mapping = skb->queue_mapping;
 
 	if (unlikely(txq >= dev->real_num_tx_queues)) {
 		do {
diff -druN linux-libre-3.2.22-gnu/drivers/net/dummy.c linux-libre-3.2.23-gnu/drivers/net/dummy.c
--- linux-libre-3.2.22-gnu/drivers/net/dummy.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/dummy.c	2012-07-11 23:32:21.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/rtnetlink.h>
 #include <net/rtnetlink.h>
 #include <linux/u64_stats_sync.h>
+#include <linux/sched.h>
 
 static int numdummies = 1;
 
@@ -186,8 +187,10 @@
 	rtnl_lock();
 	err = __rtnl_link_register(&dummy_link_ops);
 
-	for (i = 0; i < numdummies && !err; i++)
+	for (i = 0; i < numdummies && !err; i++) {
 		err = dummy_init_one();
+		cond_resched();
+	}
 	if (err < 0)
 		__rtnl_link_unregister(&dummy_link_ops);
 	rtnl_unlock();
diff -druN linux-libre-3.2.22-gnu/drivers/net/ethernet/emulex/benet/be_main.c linux-libre-3.2.23-gnu/drivers/net/ethernet/emulex/benet/be_main.c
--- linux-libre-3.2.22-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/ethernet/emulex/benet/be_main.c	2012-07-11 23:32:21.000000000 -0400
@@ -696,6 +696,8 @@
 
 	copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb);
 	if (copied) {
+		int gso_segs = skb_shinfo(skb)->gso_segs;
+
 		/* record the sent skb in the sent_skb table */
 		BUG_ON(txo->sent_skb_list[start]);
 		txo->sent_skb_list[start] = skb;
@@ -713,8 +715,7 @@
 
 		be_txq_notify(adapter, txq->id, wrb_cnt);
 
-		be_tx_stats_update(txo, wrb_cnt, copied,
-				skb_shinfo(skb)->gso_segs, stopped);
+		be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped);
 	} else {
 		txq->head = start;
 		dev_kfree_skb_any(skb);
diff -druN linux-libre-3.2.22-gnu/drivers/net/ethernet/marvell/sky2.c linux-libre-3.2.23-gnu/drivers/net/ethernet/marvell/sky2.c
--- linux-libre-3.2.22-gnu/drivers/net/ethernet/marvell/sky2.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/ethernet/marvell/sky2.c	2012-07-11 23:32:21.000000000 -0400
@@ -4361,10 +4361,12 @@
 	struct sky2_port *sky2 = netdev_priv(dev);
 	u32 changed = dev->features ^ features;
 
-	if (changed & NETIF_F_RXCSUM) {
-		u32 on = features & NETIF_F_RXCSUM;
-		sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-			     on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+	if ((changed & NETIF_F_RXCSUM) &&
+	    !(sky2->hw->flags & SKY2_HW_NEW_LE)) {
+		sky2_write32(sky2->hw,
+			     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+			     (features & NETIF_F_RXCSUM)
+			     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
 	}
 
 	if (changed & NETIF_F_RXHASH)
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/hw.c linux-libre-3.2.23-gnu/drivers/net/wireless/ath/ath9k/hw.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/hw.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/ath/ath9k/hw.c	2012-07-11 23:32:21.000000000 -0400
@@ -557,7 +557,7 @@
 
 	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
 		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
-		    ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
+		    ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) &&
 		     !ah->is_pciexpress)) {
 			ah->config.serialize_regmode =
 				SER_REG_MODE_ON;
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/recv.c linux-libre-3.2.23-gnu/drivers/net/wireless/ath/ath9k/recv.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath9k/recv.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/ath/ath9k/recv.c	2012-07-11 23:32:21.000000000 -0400
@@ -829,7 +829,8 @@
 	 * descriptor does contain a valid key index. This has been observed
 	 * mostly with CCMP encryption.
 	 */
-	if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID)
+	if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID ||
+	    !test_bit(rx_stats->rs_keyix, common->ccmp_keymap))
 		rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS;
 
 	if (!rx_stats->rs_datalen)
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath.h linux-libre-3.2.23-gnu/drivers/net/wireless/ath/ath.h
--- linux-libre-3.2.22-gnu/drivers/net/wireless/ath/ath.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/ath/ath.h	2012-07-11 23:32:21.000000000 -0400
@@ -143,6 +143,7 @@
 	u32 keymax;
 	DECLARE_BITMAP(keymap, ATH_KEYMAX);
 	DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
+	DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX);
 	enum ath_crypt_caps crypt_caps;
 
 	unsigned int clockrate;
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/ath/key.c linux-libre-3.2.23-gnu/drivers/net/wireless/ath/key.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/ath/key.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/ath/key.c	2012-07-11 23:32:21.000000000 -0400
@@ -556,6 +556,9 @@
 		return -EIO;
 
 	set_bit(idx, common->keymap);
+	if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
+		set_bit(idx, common->ccmp_keymap);
+
 	if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
 		set_bit(idx + 64, common->keymap);
 		set_bit(idx, common->tkip_keymap);
@@ -582,6 +585,7 @@
 		return;
 
 	clear_bit(key->hw_key_idx, common->keymap);
+	clear_bit(key->hw_key_idx, common->ccmp_keymap);
 	if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
 		return;
 
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.c linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.c	2012-07-11 23:32:21.000000000 -0400
@@ -267,7 +267,8 @@
 	else
 		last_seq = priv->rx_seq[tid];
 
-	if (last_seq >= new_node->start_win)
+	if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
+	    last_seq >= new_node->start_win)
 		new_node->start_win = last_seq + 1;
 
 	new_node->win_size = win_size;
@@ -611,5 +612,5 @@
 	spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
 
 	INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
-	memset(priv->rx_seq, 0, sizeof(priv->rx_seq));
+	mwifiex_reset_11n_rx_seq_num(priv);
 }
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.h linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.h
--- linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/11n_rxreorder.h	2012-07-11 23:32:21.000000000 -0400
@@ -37,6 +37,13 @@
 
 #define ADDBA_RSP_STATUS_ACCEPT 0
 
+#define MWIFIEX_DEF_11N_RX_SEQ_NUM	0xffff
+
+static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv)
+{
+	memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq));
+}
+
 int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
 			       u16 seqNum,
 			       u16 tid, u8 *ta,
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/cfg80211.c linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/cfg80211.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/cfg80211.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/cfg80211.c	2012-07-11 23:32:21.000000000 -0400
@@ -1177,11 +1177,11 @@
 	void *mdev_priv;
 
 	if (!priv)
-		return NULL;
+		return ERR_PTR(-EFAULT);
 
 	adapter = priv->adapter;
 	if (!adapter)
-		return NULL;
+		return ERR_PTR(-EFAULT);
 
 	switch (type) {
 	case NL80211_IFTYPE_UNSPECIFIED:
@@ -1190,7 +1190,7 @@
 		if (priv->bss_mode) {
 			wiphy_err(wiphy, "cannot create multiple"
 					" station/adhoc interfaces\n");
-			return NULL;
+			return ERR_PTR(-EINVAL);
 		}
 
 		if (type == NL80211_IFTYPE_UNSPECIFIED)
@@ -1208,14 +1208,15 @@
 		break;
 	default:
 		wiphy_err(wiphy, "type not supported\n");
-		return NULL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name,
 			      ether_setup, 1);
 	if (!dev) {
 		wiphy_err(wiphy, "no memory available for netdevice\n");
-		goto error;
+		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
+		return ERR_PTR(-ENOMEM);
 	}
 
 	dev_net_set(dev, wiphy_net(wiphy));
@@ -1240,7 +1241,9 @@
 	/* Register network device */
 	if (register_netdevice(dev)) {
 		wiphy_err(wiphy, "cannot register virtual network device\n");
-		goto error;
+		free_netdev(dev);
+		priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
+		return ERR_PTR(-EFAULT);
 	}
 
 	sema_init(&priv->async_sem, 1);
@@ -1252,12 +1255,6 @@
 	mwifiex_dev_debugfs_init(priv);
 #endif
 	return dev;
-error:
-	if (dev && (dev->reg_state == NETREG_UNREGISTERED))
-		free_netdev(dev);
-	priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-
-	return NULL;
 }
 EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
 
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/wmm.c linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/wmm.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/mwifiex/wmm.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/mwifiex/wmm.c	2012-07-11 23:32:21.000000000 -0400
@@ -406,6 +406,8 @@
 		priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
 		priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
 
+		mwifiex_reset_11n_rx_seq_num(priv);
+
 		atomic_set(&priv->wmm.tx_pkts_queued, 0);
 		atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
 	}
@@ -1209,10 +1211,12 @@
 		return 0;
 	}
 
-	if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid)
-	    || ((priv->sec_info.wpa_enabled
-		  || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)
-		) {
+	if (!ptr->is_11n_enabled ||
+	    mwifiex_is_ba_stream_setup(priv, ptr, tid) ||
+	    priv->wps.session_enable ||
+	    ((priv->sec_info.wpa_enabled ||
+	      priv->sec_info.wpa2_enabled) &&
+	     !priv->wpa_is_gtk_set)) {
 		mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
 		/* ra_list_spinlock has been freed in
 		   mwifiex_send_single_packet() */
diff -druN linux-libre-3.2.22-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c linux-libre-3.2.23-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
--- linux-libre-3.2.22-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2012-07-04 19:05:19.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2012-07-13 12:32:53.000000000 -0400
@@ -311,9 +311,11 @@
 	{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
 	{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
 	{RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/
+	{RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
 	{RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
 	{RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
 	{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
+	{RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/
 	/* HP - Lite-On ,8188CUS Slim Combo */
 	{RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)},
 	{RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */
@@ -355,6 +357,7 @@
 	{RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/
 	{RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/
 	{RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
+	{RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/
 	{RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/
 	{RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/
 	{RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/
diff -druN linux-libre-3.2.22-gnu/drivers/target/tcm_fc/tfc_sess.c linux-libre-3.2.23-gnu/drivers/target/tcm_fc/tfc_sess.c
--- linux-libre-3.2.22-gnu/drivers/target/tcm_fc/tfc_sess.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/drivers/target/tcm_fc/tfc_sess.c	2012-07-11 23:32:21.000000000 -0400
@@ -61,7 +61,8 @@
 	struct ft_tport *tport;
 	int i;
 
-	tport = rcu_dereference(lport->prov[FC_TYPE_FCP]);
+	tport = rcu_dereference_protected(lport->prov[FC_TYPE_FCP],
+					  lockdep_is_held(&ft_lport_lock));
 	if (tport && tport->tpg)
 		return tport;
 
diff -druN linux-libre-3.2.22-gnu/fs/btrfs/tree-log.c linux-libre-3.2.23-gnu/fs/btrfs/tree-log.c
--- linux-libre-3.2.22-gnu/fs/btrfs/tree-log.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/fs/btrfs/tree-log.c	2012-07-11 23:32:21.000000000 -0400
@@ -692,6 +692,8 @@
 	kfree(name);
 
 	iput(inode);
+
+	btrfs_run_delayed_items(trans, root);
 	return ret;
 }
 
@@ -897,6 +899,7 @@
 				ret = btrfs_unlink_inode(trans, root, dir,
 							 inode, victim_name,
 							 victim_name_len);
+				btrfs_run_delayed_items(trans, root);
 			}
 			kfree(victim_name);
 			ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
@@ -1477,6 +1480,9 @@
 			ret = btrfs_unlink_inode(trans, root, dir, inode,
 						 name, name_len);
 			BUG_ON(ret);
+
+			btrfs_run_delayed_items(trans, root);
+
 			kfree(name);
 			iput(inode);
 
diff -druN linux-libre-3.2.22-gnu/fs/cifs/connect.c linux-libre-3.2.23-gnu/fs/cifs/connect.c
--- linux-libre-3.2.22-gnu/fs/cifs/connect.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/fs/cifs/connect.c	2012-07-11 23:32:21.000000000 -0400
@@ -2975,18 +2975,15 @@
 	 * MS-CIFS indicates that servers are only limited by the client's
 	 * bufsize for reads, testing against win98se shows that it throws
 	 * INVALID_PARAMETER errors if you try to request too large a read.
+	 * OS/2 just sends back short reads.
 	 *
-	 * If the server advertises a MaxBufferSize of less than one page,
-	 * assume that it also can't satisfy reads larger than that either.
-	 *
-	 * FIXME: Is there a better heuristic for this?
+	 * If the server doesn't advertise CAP_LARGE_READ_X, then assume that
+	 * it can't handle a read request larger than its MaxBufferSize either.
 	 */
 	if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
 		defsize = CIFS_DEFAULT_IOSIZE;
 	else if (server->capabilities & CAP_LARGE_READ_X)
 		defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
-	else if (server->maxBuf >= PAGE_CACHE_SIZE)
-		defsize = CIFSMaxBufSize;
 	else
 		defsize = server->maxBuf - sizeof(READ_RSP);
 
diff -druN linux-libre-3.2.22-gnu/fs/ocfs2/file.c linux-libre-3.2.23-gnu/fs/ocfs2/file.c
--- linux-libre-3.2.22-gnu/fs/ocfs2/file.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/fs/ocfs2/file.c	2012-07-11 23:32:21.000000000 -0400
@@ -2422,8 +2422,10 @@
 		unaligned_dio = 0;
 	}
 
-	if (unaligned_dio)
+	if (unaligned_dio) {
+		ocfs2_iocb_clear_unaligned_aio(iocb);
 		atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio);
+	}
 
 out:
 	if (rw_level != -1)
diff -druN linux-libre-3.2.22-gnu/fs/open.c linux-libre-3.2.23-gnu/fs/open.c
--- linux-libre-3.2.22-gnu/fs/open.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/fs/open.c	2012-07-11 23:32:21.000000000 -0400
@@ -396,10 +396,10 @@
 {
 	struct file *file;
 	struct inode *inode;
-	int error;
+	int error, fput_needed;
 
 	error = -EBADF;
-	file = fget(fd);
+	file = fget_raw_light(fd, &fput_needed);
 	if (!file)
 		goto out;
 
@@ -413,7 +413,7 @@
 	if (!error)
 		set_fs_pwd(current->fs, &file->f_path);
 out_putf:
-	fput(file);
+	fput_light(file, fput_needed);
 out:
 	return error;
 }
diff -druN linux-libre-3.2.22-gnu/fs/splice.c linux-libre-3.2.23-gnu/fs/splice.c
--- linux-libre-3.2.22-gnu/fs/splice.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/fs/splice.c	2012-07-11 23:32:21.000000000 -0400
@@ -274,13 +274,16 @@
  * Check if we need to grow the arrays holding pages and partial page
  * descriptions.
  */
-int splice_grow_spd(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
+int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc *spd)
 {
-	if (pipe->buffers <= PIPE_DEF_BUFFERS)
+	unsigned int buffers = ACCESS_ONCE(pipe->buffers);
+
+	spd->nr_pages_max = buffers;
+	if (buffers <= PIPE_DEF_BUFFERS)
 		return 0;
 
-	spd->pages = kmalloc(pipe->buffers * sizeof(struct page *), GFP_KERNEL);
-	spd->partial = kmalloc(pipe->buffers * sizeof(struct partial_page), GFP_KERNEL);
+	spd->pages = kmalloc(buffers * sizeof(struct page *), GFP_KERNEL);
+	spd->partial = kmalloc(buffers * sizeof(struct partial_page), GFP_KERNEL);
 
 	if (spd->pages && spd->partial)
 		return 0;
@@ -290,10 +293,9 @@
 	return -ENOMEM;
 }
 
-void splice_shrink_spd(struct pipe_inode_info *pipe,
-		       struct splice_pipe_desc *spd)
+void splice_shrink_spd(struct splice_pipe_desc *spd)
 {
-	if (pipe->buffers <= PIPE_DEF_BUFFERS)
+	if (spd->nr_pages_max <= PIPE_DEF_BUFFERS)
 		return;
 
 	kfree(spd->pages);
@@ -316,6 +318,7 @@
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.partial = partial,
+		.nr_pages_max = PIPE_DEF_BUFFERS,
 		.flags = flags,
 		.ops = &page_cache_pipe_buf_ops,
 		.spd_release = spd_release_page,
@@ -327,7 +330,7 @@
 	index = *ppos >> PAGE_CACHE_SHIFT;
 	loff = *ppos & ~PAGE_CACHE_MASK;
 	req_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	nr_pages = min(req_pages, pipe->buffers);
+	nr_pages = min(req_pages, spd.nr_pages_max);
 
 	/*
 	 * Lookup the (hopefully) full range of pages we need.
@@ -498,7 +501,7 @@
 	if (spd.nr_pages)
 		error = splice_to_pipe(pipe, &spd);
 
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 	return error;
 }
 
@@ -599,6 +602,7 @@
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.partial = partial,
+		.nr_pages_max = PIPE_DEF_BUFFERS,
 		.flags = flags,
 		.ops = &default_pipe_buf_ops,
 		.spd_release = spd_release_page,
@@ -609,8 +613,8 @@
 
 	res = -ENOMEM;
 	vec = __vec;
-	if (pipe->buffers > PIPE_DEF_BUFFERS) {
-		vec = kmalloc(pipe->buffers * sizeof(struct iovec), GFP_KERNEL);
+	if (spd.nr_pages_max > PIPE_DEF_BUFFERS) {
+		vec = kmalloc(spd.nr_pages_max * sizeof(struct iovec), GFP_KERNEL);
 		if (!vec)
 			goto shrink_ret;
 	}
@@ -618,7 +622,7 @@
 	offset = *ppos & ~PAGE_CACHE_MASK;
 	nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
-	for (i = 0; i < nr_pages && i < pipe->buffers && len; i++) {
+	for (i = 0; i < nr_pages && i < spd.nr_pages_max && len; i++) {
 		struct page *page;
 
 		page = alloc_page(GFP_USER);
@@ -666,7 +670,7 @@
 shrink_ret:
 	if (vec != __vec)
 		kfree(vec);
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 	return res;
 
 err:
@@ -1616,6 +1620,7 @@
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.partial = partial,
+		.nr_pages_max = PIPE_DEF_BUFFERS,
 		.flags = flags,
 		.ops = &user_page_pipe_buf_ops,
 		.spd_release = spd_release_page,
@@ -1631,13 +1636,13 @@
 
 	spd.nr_pages = get_iovec_page_array(iov, nr_segs, spd.pages,
 					    spd.partial, flags & SPLICE_F_GIFT,
-					    pipe->buffers);
+					    spd.nr_pages_max);
 	if (spd.nr_pages <= 0)
 		ret = spd.nr_pages;
 	else
 		ret = splice_to_pipe(pipe, &spd);
 
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 	return ret;
 }
 
diff -druN linux-libre-3.2.22-gnu/fs/udf/super.c linux-libre-3.2.23-gnu/fs/udf/super.c
--- linux-libre-3.2.22-gnu/fs/udf/super.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/fs/udf/super.c	2012-07-11 23:32:21.000000000 -0400
@@ -56,6 +56,7 @@
 #include <linux/seq_file.h>
 #include <linux/bitmap.h>
 #include <linux/crc-itu-t.h>
+#include <linux/log2.h>
 #include <asm/byteorder.h>
 
 #include "udf_sb.h"
@@ -1217,16 +1218,65 @@
 	return ret;
 }
 
+static int udf_load_sparable_map(struct super_block *sb,
+				 struct udf_part_map *map,
+				 struct sparablePartitionMap *spm)
+{
+	uint32_t loc;
+	uint16_t ident;
+	struct sparingTable *st;
+	struct udf_sparing_data *sdata = &map->s_type_specific.s_sparing;
+	int i;
+	struct buffer_head *bh;
+
+	map->s_partition_type = UDF_SPARABLE_MAP15;
+	sdata->s_packet_len = le16_to_cpu(spm->packetLength);
+	if (!is_power_of_2(sdata->s_packet_len)) {
+		udf_err(sb, "error loading logical volume descriptor: "
+			"Invalid packet length %u\n",
+			(unsigned)sdata->s_packet_len);
+		return -EIO;
+	}
+	if (spm->numSparingTables > 4) {
+		udf_err(sb, "error loading logical volume descriptor: "
+			"Too many sparing tables (%d)\n",
+			(int)spm->numSparingTables);
+		return -EIO;
+	}
+
+	for (i = 0; i < spm->numSparingTables; i++) {
+		loc = le32_to_cpu(spm->locSparingTable[i]);
+		bh = udf_read_tagged(sb, loc, loc, &ident);
+		if (!bh)
+			continue;
+
+		st = (struct sparingTable *)bh->b_data;
+		if (ident != 0 ||
+		    strncmp(st->sparingIdent.ident, UDF_ID_SPARING,
+			    strlen(UDF_ID_SPARING)) ||
+		    sizeof(*st) + le16_to_cpu(st->reallocationTableLen) >
+							sb->s_blocksize) {
+			brelse(bh);
+			continue;
+		}
+
+		sdata->s_spar_map[i] = bh;
+	}
+	map->s_partition_func = udf_get_pblock_spar15;
+	return 0;
+}
+
 static int udf_load_logicalvol(struct super_block *sb, sector_t block,
 			       struct kernel_lb_addr *fileset)
 {
 	struct logicalVolDesc *lvd;
-	int i, j, offset;
+	int i, offset;
 	uint8_t type;
 	struct udf_sb_info *sbi = UDF_SB(sb);
 	struct genericPartitionMap *gpm;
 	uint16_t ident;
 	struct buffer_head *bh;
+	unsigned int table_len;
 	int ret = 0;
 
 	bh = udf_read_tagged(sb, block, block, &ident);
@@ -1234,15 +1284,20 @@
 		return 1;
 	BUG_ON(ident != TAG_IDENT_LVD);
 	lvd = (struct logicalVolDesc *)bh->b_data;
-
-	i = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
-	if (i != 0) {
-		ret = i;
+	table_len = le32_to_cpu(lvd->mapTableLength);
+	if (sizeof(*lvd) + table_len > sb->s_blocksize) {
+		udf_err(sb, "error loading logical volume descriptor: "
+			"Partition table too long (%u > %lu)\n", table_len,
+			sb->s_blocksize - sizeof(*lvd));
 		goto out_bh;
 	}
 
+	ret = udf_sb_alloc_partition_maps(sb, le32_to_cpu(lvd->numPartitionMaps));
+	if (ret)
+		goto out_bh;
+
 	for (i = 0, offset = 0;
-	     i < sbi->s_partitions && offset < le32_to_cpu(lvd->mapTableLength);
+	     i < sbi->s_partitions && offset < table_len;
 	     i++, offset += gpm->partitionMapLength) {
 		struct udf_part_map *map = &sbi->s_partmaps[i];
 		gpm = (struct genericPartitionMap *)
@@ -1277,38 +1332,9 @@
 			} else if (!strncmp(upm2->partIdent.ident,
 						UDF_ID_SPARABLE,
 						strlen(UDF_ID_SPARABLE))) {
-				uint32_t loc;
-				struct sparingTable *st;
-				struct sparablePartitionMap *spm =
-					(struct sparablePartitionMap *)gpm;
-
-				map->s_partition_type = UDF_SPARABLE_MAP15;
-				map->s_type_specific.s_sparing.s_packet_len =
-						le16_to_cpu(spm->packetLength);
-				for (j = 0; j < spm->numSparingTables; j++) {
-					struct buffer_head *bh2;
-
-					loc = le32_to_cpu(
-						spm->locSparingTable[j]);
-					bh2 = udf_read_tagged(sb, loc, loc,
-							     &ident);
-					map->s_type_specific.s_sparing.
-							s_spar_map[j] = bh2;
-
-					if (bh2 == NULL)
-						continue;
-
-					st = (struct sparingTable *)bh2->b_data;
-					if (ident != 0 || strncmp(
-						st->sparingIdent.ident,
-						UDF_ID_SPARING,
-						strlen(UDF_ID_SPARING))) {
-						brelse(bh2);
-						map->s_type_specific.s_sparing.
-							s_spar_map[j] = NULL;
-					}
-				}
-				map->s_partition_func = udf_get_pblock_spar15;
+				if (udf_load_sparable_map(sb, map,
+				    (struct sparablePartitionMap *)gpm) < 0)
+					goto out_bh;
 			} else if (!strncmp(upm2->partIdent.ident,
 						UDF_ID_METADATA,
 						strlen(UDF_ID_METADATA))) {
diff -druN linux-libre-3.2.22-gnu/include/linux/aio.h linux-libre-3.2.23-gnu/include/linux/aio.h
--- linux-libre-3.2.22-gnu/include/linux/aio.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/include/linux/aio.h	2012-07-11 23:32:21.000000000 -0400
@@ -140,6 +140,7 @@
 		(x)->ki_dtor = NULL;			\
 		(x)->ki_obj.tsk = tsk;			\
 		(x)->ki_user_data = 0;                  \
+		(x)->private = NULL;			\
 	} while (0)
 
 #define AIO_RING_MAGIC			0xa10a10a1
diff -druN linux-libre-3.2.22-gnu/include/linux/splice.h linux-libre-3.2.23-gnu/include/linux/splice.h
--- linux-libre-3.2.22-gnu/include/linux/splice.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/include/linux/splice.h	2012-07-11 23:32:21.000000000 -0400
@@ -51,7 +51,8 @@
 struct splice_pipe_desc {
 	struct page **pages;		/* page map */
 	struct partial_page *partial;	/* pages[] may not be contig */
-	int nr_pages;			/* number of pages in map */
+	int nr_pages;			/* number of populated pages in map */
+	unsigned int nr_pages_max;	/* pages[] & partial[] arrays size */
 	unsigned int flags;		/* splice flags */
 	const struct pipe_buf_operations *ops;/* ops associated with output pipe */
 	void (*spd_release)(struct splice_pipe_desc *, unsigned int);
@@ -85,9 +86,8 @@
 /*
  * for dynamic pipe sizing
  */
-extern int splice_grow_spd(struct pipe_inode_info *, struct splice_pipe_desc *);
-extern void splice_shrink_spd(struct pipe_inode_info *,
-				struct splice_pipe_desc *);
+extern int splice_grow_spd(const struct pipe_inode_info *, struct splice_pipe_desc *);
+extern void splice_shrink_spd(struct splice_pipe_desc *);
 extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
 
 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
diff -druN linux-libre-3.2.22-gnu/include/net/cipso_ipv4.h linux-libre-3.2.23-gnu/include/net/cipso_ipv4.h
--- linux-libre-3.2.22-gnu/include/net/cipso_ipv4.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/include/net/cipso_ipv4.h	2012-07-11 23:32:21.000000000 -0400
@@ -42,6 +42,7 @@
 #include <net/netlabel.h>
 #include <net/request_sock.h>
 #include <linux/atomic.h>
+#include <asm/unaligned.h>
 
 /* known doi values */
 #define CIPSO_V4_DOI_UNKNOWN          0x00000000
@@ -285,7 +286,33 @@
 static inline int cipso_v4_validate(const struct sk_buff *skb,
 				    unsigned char **option)
 {
-	return -ENOSYS;
+	unsigned char *opt = *option;
+	unsigned char err_offset = 0;
+	u8 opt_len = opt[1];
+	u8 opt_iter;
+
+	if (opt_len < 8) {
+		err_offset = 1;
+		goto out;
+	}
+
+	if (get_unaligned_be32(&opt[2]) == 0) {
+		err_offset = 2;
+		goto out;
+	}
+
+	for (opt_iter = 6; opt_iter < opt_len;) {
+		if (opt[opt_iter + 1] > (opt_len - opt_iter)) {
+			err_offset = opt_iter + 1;
+			goto out;
+		}
+		opt_iter += opt[opt_iter + 1];
+	}
+
+out:
+	*option = opt + err_offset;
+	return err_offset;
+
 }
 #endif /* CONFIG_NETLABEL */
 
diff -druN linux-libre-3.2.22-gnu/include/net/sch_generic.h linux-libre-3.2.23-gnu/include/net/sch_generic.h
--- linux-libre-3.2.22-gnu/include/net/sch_generic.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/include/net/sch_generic.h	2012-07-11 23:32:21.000000000 -0400
@@ -220,13 +220,16 @@
 
 struct qdisc_skb_cb {
 	unsigned int		pkt_len;
-	unsigned char		data[24];
+	u16			bond_queue_mapping;
+	u16			_pad;
+	unsigned char		data[20];
 };
 
 static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
 {
 	struct qdisc_skb_cb *qcb;
-	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(unsigned int) + sz);
+
+	BUILD_BUG_ON(sizeof(skb->cb) < offsetof(struct qdisc_skb_cb, data) + sz);
 	BUILD_BUG_ON(sizeof(qcb->data) < sz);
 }
 
diff -druN linux-libre-3.2.22-gnu/kernel/relay.c linux-libre-3.2.23-gnu/kernel/relay.c
--- linux-libre-3.2.22-gnu/kernel/relay.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/kernel/relay.c	2012-07-11 23:32:21.000000000 -0400
@@ -1235,6 +1235,7 @@
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.nr_pages = 0,
+		.nr_pages_max = PIPE_DEF_BUFFERS,
 		.partial = partial,
 		.flags = flags,
 		.ops = &relay_pipe_buf_ops,
@@ -1302,8 +1303,8 @@
                 ret += padding;
 
 out:
-	splice_shrink_spd(pipe, &spd);
-        return ret;
+	splice_shrink_spd(&spd);
+	return ret;
 }
 
 static ssize_t relay_file_splice_read(struct file *in,
diff -druN linux-libre-3.2.22-gnu/kernel/trace/trace.c linux-libre-3.2.23-gnu/kernel/trace/trace.c
--- linux-libre-3.2.22-gnu/kernel/trace/trace.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/kernel/trace/trace.c	2012-07-11 23:32:21.000000000 -0400
@@ -2541,10 +2541,12 @@
 		if (cpumask_test_cpu(cpu, tracing_cpumask) &&
 				!cpumask_test_cpu(cpu, tracing_cpumask_new)) {
 			atomic_inc(&global_trace.data[cpu]->disabled);
+			ring_buffer_record_disable_cpu(global_trace.buffer, cpu);
 		}
 		if (!cpumask_test_cpu(cpu, tracing_cpumask) &&
 				cpumask_test_cpu(cpu, tracing_cpumask_new)) {
 			atomic_dec(&global_trace.data[cpu]->disabled);
+			ring_buffer_record_enable_cpu(global_trace.buffer, cpu);
 		}
 	}
 	arch_spin_unlock(&ftrace_max_lock);
@@ -3456,6 +3458,7 @@
 		.pages		= pages_def,
 		.partial	= partial_def,
 		.nr_pages	= 0, /* This gets updated below. */
+		.nr_pages_max	= PIPE_DEF_BUFFERS,
 		.flags		= flags,
 		.ops		= &tracing_pipe_buf_ops,
 		.spd_release	= tracing_spd_release_pipe,
@@ -3527,7 +3530,7 @@
 
 	ret = splice_to_pipe(pipe, &spd);
 out:
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 	return ret;
 
 out_err:
@@ -4017,6 +4020,7 @@
 	struct splice_pipe_desc spd = {
 		.pages		= pages_def,
 		.partial	= partial_def,
+		.nr_pages_max	= PIPE_DEF_BUFFERS,
 		.flags		= flags,
 		.ops		= &buffer_pipe_buf_ops,
 		.spd_release	= buffer_spd_release,
@@ -4104,7 +4108,7 @@
 	}
 
 	ret = splice_to_pipe(pipe, &spd);
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 out:
 	return ret;
 }
diff -druN linux-libre-3.2.22-gnu/Makefile linux-libre-3.2.23-gnu/Makefile
--- linux-libre-3.2.22-gnu/Makefile	2012-07-04 18:56:06.000000000 -0400
+++ linux-libre-3.2.23-gnu/Makefile	2012-07-13 12:24:00.000000000 -0400
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 2
-SUBLEVEL = 22
+SUBLEVEL = 23
 EXTRAVERSION =-gnu
 NAME = Saber-toothed Squirrel
 
diff -druN linux-libre-3.2.22-gnu/mm/madvise.c linux-libre-3.2.23-gnu/mm/madvise.c
--- linux-libre-3.2.22-gnu/mm/madvise.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/mm/madvise.c	2012-07-11 23:32:21.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/hugetlb.h>
 #include <linux/sched.h>
 #include <linux/ksm.h>
+#include <linux/file.h>
 
 /*
  * Any behaviour which results in changes to the vma->vm_flags needs to
@@ -197,14 +198,16 @@
 	struct address_space *mapping;
 	loff_t offset, endoff;
 	int error;
+	struct file *f;
 
 	*prev = NULL;	/* tell sys_madvise we drop mmap_sem */
 
 	if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
 		return -EINVAL;
 
-	if (!vma->vm_file || !vma->vm_file->f_mapping
-		|| !vma->vm_file->f_mapping->host) {
+	f = vma->vm_file;
+
+	if (!f || !f->f_mapping || !f->f_mapping->host) {
 			return -EINVAL;
 	}
 
@@ -218,9 +221,16 @@
 	endoff = (loff_t)(end - vma->vm_start - 1)
 			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
 
-	/* vmtruncate_range needs to take i_mutex */
+	/*
+	 * vmtruncate_range may need to take i_mutex.  We need to
+	 * explicitly grab a reference because the vma (and hence the
+	 * vma's reference to the file) can go away as soon as we drop
+	 * mmap_sem.
+	 */
+	get_file(f);
 	up_read(&current->mm->mmap_sem);
 	error = vmtruncate_range(mapping->host, offset, endoff);
+	fput(f);
 	down_read(&current->mm->mmap_sem);
 	return error;
 }
diff -druN linux-libre-3.2.22-gnu/mm/shmem.c linux-libre-3.2.23-gnu/mm/shmem.c
--- linux-libre-3.2.22-gnu/mm/shmem.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/mm/shmem.c	2012-07-11 23:32:21.000000000 -0400
@@ -1359,6 +1359,7 @@
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.partial = partial,
+		.nr_pages_max = PIPE_DEF_BUFFERS,
 		.flags = flags,
 		.ops = &page_cache_pipe_buf_ops,
 		.spd_release = spd_release_page,
@@ -1447,7 +1448,7 @@
 	if (spd.nr_pages)
 		error = splice_to_pipe(pipe, &spd);
 
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 
 	if (error > 0) {
 		*ppos += error;
diff -druN linux-libre-3.2.22-gnu/net/bridge/br_if.c linux-libre-3.2.23-gnu/net/bridge/br_if.c
--- linux-libre-3.2.22-gnu/net/bridge/br_if.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/bridge/br_if.c	2012-07-11 23:32:21.000000000 -0400
@@ -240,6 +240,7 @@
 		return -ENOMEM;
 
 	dev_net_set(dev, net);
+	dev->rtnl_link_ops = &br_link_ops;
 
 	res = register_netdev(dev);
 	if (res)
diff -druN linux-libre-3.2.22-gnu/net/bridge/br_netlink.c linux-libre-3.2.23-gnu/net/bridge/br_netlink.c
--- linux-libre-3.2.22-gnu/net/bridge/br_netlink.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/bridge/br_netlink.c	2012-07-11 23:32:21.000000000 -0400
@@ -211,7 +211,7 @@
 	return 0;
 }
 
-static struct rtnl_link_ops br_link_ops __read_mostly = {
+struct rtnl_link_ops br_link_ops __read_mostly = {
 	.kind		= "bridge",
 	.priv_size	= sizeof(struct net_bridge),
 	.setup		= br_dev_setup,
diff -druN linux-libre-3.2.22-gnu/net/bridge/br_private.h linux-libre-3.2.23-gnu/net/bridge/br_private.h
--- linux-libre-3.2.22-gnu/net/bridge/br_private.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/bridge/br_private.h	2012-07-11 23:32:21.000000000 -0400
@@ -536,6 +536,7 @@
 #endif
 
 /* br_netlink.c */
+extern struct rtnl_link_ops br_link_ops;
 extern int br_netlink_init(void);
 extern void br_netlink_fini(void);
 extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
diff -druN linux-libre-3.2.22-gnu/net/core/ethtool.c linux-libre-3.2.23-gnu/net/core/ethtool.c
--- linux-libre-3.2.22-gnu/net/core/ethtool.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/core/ethtool.c	2012-07-11 23:32:21.000000000 -0400
@@ -1672,6 +1672,7 @@
 	case ETHTOOL_GRXCSUM:
 	case ETHTOOL_GTXCSUM:
 	case ETHTOOL_GSG:
+	case ETHTOOL_GSSET_INFO:
 	case ETHTOOL_GSTRINGS:
 	case ETHTOOL_GTSO:
 	case ETHTOOL_GPERMADDR:
diff -druN linux-libre-3.2.22-gnu/net/core/netpoll.c linux-libre-3.2.23-gnu/net/core/netpoll.c
--- linux-libre-3.2.22-gnu/net/core/netpoll.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/core/netpoll.c	2012-07-11 23:32:21.000000000 -0400
@@ -351,22 +351,23 @@
 
 void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
 {
-	int total_len, eth_len, ip_len, udp_len;
+	int total_len, ip_len, udp_len;
 	struct sk_buff *skb;
 	struct udphdr *udph;
 	struct iphdr *iph;
 	struct ethhdr *eth;
 
 	udp_len = len + sizeof(*udph);
-	ip_len = eth_len = udp_len + sizeof(*iph);
-	total_len = eth_len + ETH_HLEN + NET_IP_ALIGN;
+	ip_len = udp_len + sizeof(*iph);
+	total_len = ip_len + LL_RESERVED_SPACE(np->dev);
 
-	skb = find_skb(np, total_len, total_len - len);
+	skb = find_skb(np, total_len + np->dev->needed_tailroom,
+		       total_len - len);
 	if (!skb)
 		return;
 
 	skb_copy_to_linear_data(skb, msg, len);
-	skb->len += len;
+	skb_put(skb, len);
 
 	skb_push(skb, sizeof(*udph));
 	skb_reset_transport_header(skb);
diff -druN linux-libre-3.2.22-gnu/net/core/skbuff.c linux-libre-3.2.23-gnu/net/core/skbuff.c
--- linux-libre-3.2.22-gnu/net/core/skbuff.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/core/skbuff.c	2012-07-11 23:32:21.000000000 -0400
@@ -1663,6 +1663,7 @@
 	struct splice_pipe_desc spd = {
 		.pages = pages,
 		.partial = partial,
+		.nr_pages_max = MAX_SKB_FRAGS,
 		.flags = flags,
 		.ops = &sock_pipe_buf_ops,
 		.spd_release = sock_spd_release,
@@ -1709,7 +1710,7 @@
 		lock_sock(sk);
 	}
 
-	splice_shrink_spd(pipe, &spd);
+	splice_shrink_spd(&spd);
 	return ret;
 }
 
diff -druN linux-libre-3.2.22-gnu/net/core/sock.c linux-libre-3.2.23-gnu/net/core/sock.c
--- linux-libre-3.2.22-gnu/net/core/sock.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/core/sock.c	2012-07-11 23:32:21.000000000 -0400
@@ -1497,6 +1497,11 @@
 	gfp_t gfp_mask;
 	long timeo;
 	int err;
+	int npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+
+	err = -EMSGSIZE;
+	if (npages > MAX_SKB_FRAGS)
+		goto failure;
 
 	gfp_mask = sk->sk_allocation;
 	if (gfp_mask & __GFP_WAIT)
@@ -1515,14 +1520,12 @@
 		if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) {
 			skb = alloc_skb(header_len, gfp_mask);
 			if (skb) {
-				int npages;
 				int i;
 
 				/* No pages, we're done... */
 				if (!data_len)
 					break;
 
-				npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 				skb->truesize += data_len;
 				skb_shinfo(skb)->nr_frags = npages;
 				for (i = 0; i < npages; i++) {
diff -druN linux-libre-3.2.22-gnu/net/ipv6/route.c linux-libre-3.2.23-gnu/net/ipv6/route.c
--- linux-libre-3.2.22-gnu/net/ipv6/route.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/ipv6/route.c	2012-07-11 23:32:21.000000000 -0400
@@ -2881,10 +2881,6 @@
 	net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
 	net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
 
-#ifdef CONFIG_PROC_FS
-	proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
-	proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
-#endif
 	net->ipv6.ip6_rt_gc_expire = 30*HZ;
 
 	ret = 0;
@@ -2905,10 +2901,6 @@
 
 static void __net_exit ip6_route_net_exit(struct net *net)
 {
-#ifdef CONFIG_PROC_FS
-	proc_net_remove(net, "ipv6_route");
-	proc_net_remove(net, "rt6_stats");
-#endif
 	kfree(net->ipv6.ip6_null_entry);
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 	kfree(net->ipv6.ip6_prohibit_entry);
@@ -2917,11 +2909,33 @@
 	dst_entries_destroy(&net->ipv6.ip6_dst_ops);
 }
 
+static int __net_init ip6_route_net_init_late(struct net *net)
+{
+#ifdef CONFIG_PROC_FS
+	proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
+	proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
+#endif
+	return 0;
+}
+
+static void __net_exit ip6_route_net_exit_late(struct net *net)
+{
+#ifdef CONFIG_PROC_FS
+	proc_net_remove(net, "ipv6_route");
+	proc_net_remove(net, "rt6_stats");
+#endif
+}
+
 static struct pernet_operations ip6_route_net_ops = {
 	.init = ip6_route_net_init,
 	.exit = ip6_route_net_exit,
 };
 
+static struct pernet_operations ip6_route_net_late_ops = {
+	.init = ip6_route_net_init_late,
+	.exit = ip6_route_net_exit_late,
+};
+
 static struct notifier_block ip6_route_dev_notifier = {
 	.notifier_call = ip6_route_dev_notify,
 	.priority = 0,
@@ -2971,19 +2985,25 @@
 	if (ret)
 		goto xfrm6_init;
 
+	ret = register_pernet_subsys(&ip6_route_net_late_ops);
+	if (ret)
+		goto fib6_rules_init;
+
 	ret = -ENOBUFS;
 	if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) ||
 	    __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) ||
 	    __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL))
-		goto fib6_rules_init;
+		goto out_register_late_subsys;
 
 	ret = register_netdevice_notifier(&ip6_route_dev_notifier);
 	if (ret)
-		goto fib6_rules_init;
+		goto out_register_late_subsys;
 
 out:
 	return ret;
 
+out_register_late_subsys:
+	unregister_pernet_subsys(&ip6_route_net_late_ops);
 fib6_rules_init:
 	fib6_rules_cleanup();
 xfrm6_init:
@@ -3002,6 +3022,7 @@
 void ip6_route_cleanup(void)
 {
 	unregister_netdevice_notifier(&ip6_route_dev_notifier);
+	unregister_pernet_subsys(&ip6_route_net_late_ops);
 	fib6_rules_cleanup();
 	xfrm6_fini();
 	fib6_gc_cleanup();
diff -druN linux-libre-3.2.22-gnu/net/l2tp/l2tp_eth.c linux-libre-3.2.23-gnu/net/l2tp/l2tp_eth.c
--- linux-libre-3.2.22-gnu/net/l2tp/l2tp_eth.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/l2tp/l2tp_eth.c	2012-07-11 23:32:21.000000000 -0400
@@ -167,6 +167,7 @@
 		if (dev) {
 			unregister_netdev(dev);
 			spriv->dev = NULL;
+			module_put(THIS_MODULE);
 		}
 	}
 }
@@ -254,6 +255,7 @@
 	if (rc < 0)
 		goto out_del_dev;
 
+	__module_get(THIS_MODULE);
 	/* Must be done after register_netdev() */
 	strlcpy(session->ifname, dev->name, IFNAMSIZ);
 
diff -druN linux-libre-3.2.22-gnu/net/l2tp/l2tp_ip.c linux-libre-3.2.23-gnu/net/l2tp/l2tp_ip.c
--- linux-libre-3.2.22-gnu/net/l2tp/l2tp_ip.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/l2tp/l2tp_ip.c	2012-07-11 23:32:21.000000000 -0400
@@ -515,10 +515,12 @@
 					   sk->sk_bound_dev_if);
 		if (IS_ERR(rt))
 			goto no_route;
-		if (connected)
+		if (connected) {
 			sk_setup_caps(sk, &rt->dst);
-		else
-			dst_release(&rt->dst); /* safe since we hold rcu_read_lock */
+		} else {
+			skb_dst_set(skb, &rt->dst);
+			goto xmit;
+		}
 	}
 
 	/* We dont need to clone dst here, it is guaranteed to not disappear.
@@ -526,6 +528,7 @@
 	 */
 	skb_dst_set_noref(skb, &rt->dst);
 
+xmit:
 	/* Queue the packet to IP for output */
 	rc = ip_queue_xmit(skb, &inet->cork.fl);
 	rcu_read_unlock();
diff -druN linux-libre-3.2.22-gnu/net/mac80211/rx.c linux-libre-3.2.23-gnu/net/mac80211/rx.c
--- linux-libre-3.2.22-gnu/net/mac80211/rx.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/mac80211/rx.c	2012-07-11 23:32:21.000000000 -0400
@@ -2389,7 +2389,7 @@
 	 * frames that we didn't handle, including returning unknown
 	 * ones. For all other modes we will return them to the sender,
 	 * setting the 0x80 bit in the action category, as required by
-	 * 802.11-2007 7.3.1.11.
+	 * 802.11-2012 9.24.4.
 	 * Newer versions of hostapd shall also use the management frame
 	 * registration mechanisms, but older ones still use cooked
 	 * monitor interfaces so push all frames there.
@@ -2399,6 +2399,9 @@
 	     sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
 		return RX_DROP_MONITOR;
 
+	if (is_multicast_ether_addr(mgmt->da))
+		return RX_DROP_MONITOR;
+
 	/* do not return rejected action frames */
 	if (mgmt->u.action.category & 0x80)
 		return RX_DROP_UNUSABLE;
diff -druN linux-libre-3.2.22-gnu/net/nfc/nci/ntf.c linux-libre-3.2.23-gnu/net/nfc/nci/ntf.c
--- linux-libre-3.2.22-gnu/net/nfc/nci/ntf.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/nfc/nci/ntf.c	2012-07-11 23:32:21.000000000 -0400
@@ -86,7 +86,7 @@
 	nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data));
 	data += 2;
 
-	nfca_poll->nfcid1_len = *data++;
+	nfca_poll->nfcid1_len = min_t(__u8, *data++, sizeof(nfca_poll->nfcid1));
 
 	nfc_dbg("sens_res 0x%x, nfcid1_len %d",
 		nfca_poll->sens_res,
@@ -111,7 +111,7 @@
 
 	switch (ntf->rf_interface_type) {
 	case NCI_RF_INTERFACE_ISO_DEP:
-		nfca_poll_iso_dep->rats_res_len = *data++;
+		nfca_poll_iso_dep->rats_res_len = min_t(__u8, *data++, 20);
 		if (nfca_poll_iso_dep->rats_res_len > 0) {
 			memcpy(nfca_poll_iso_dep->rats_res,
 				data,
diff -druN linux-libre-3.2.22-gnu/net/nfc/rawsock.c linux-libre-3.2.23-gnu/net/nfc/rawsock.c
--- linux-libre-3.2.22-gnu/net/nfc/rawsock.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/net/nfc/rawsock.c	2012-07-11 23:32:21.000000000 -0400
@@ -52,7 +52,10 @@
 {
 	struct sock *sk = sock->sk;
 
-	nfc_dbg("sock=%p", sock);
+	nfc_dbg("sock=%p sk=%p", sock, sk);
+
+	if (!sk)
+		return 0;
 
 	sock_orphan(sk);
 	sock_put(sk);
diff -druN linux-libre-3.2.22-gnu/sound/pci/hda/patch_sigmatel.c linux-libre-3.2.23-gnu/sound/pci/hda/patch_sigmatel.c
--- linux-libre-3.2.22-gnu/sound/pci/hda/patch_sigmatel.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/sound/pci/hda/patch_sigmatel.c	2012-07-11 23:32:21.000000000 -0400
@@ -4457,7 +4457,7 @@
 					 AC_PINCTL_IN_EN);
 	for (i = 0; i < spec->num_pwrs; i++)  {
 		hda_nid_t nid = spec->pwr_nids[i];
-		int pinctl, def_conf;
+		unsigned int pinctl, def_conf;
 
 		/* power on when no jack detection is available */
 		/* or when the VREF is used for controlling LED */
@@ -4484,7 +4484,7 @@
 		def_conf = get_defcfg_connect(def_conf);
 		/* skip any ports that don't have jacks since presence
  		 * detection is useless */
-		if (def_conf != AC_JACK_PORT_NONE &&
+		if (def_conf != AC_JACK_PORT_COMPLEX ||
 		    !is_jack_detectable(codec, nid)) {
 			stac_toggle_power_map(codec, nid, 1);
 			continue;
diff -druN linux-libre-3.2.22-gnu/sound/soc/codecs/tlv320aic3x.c linux-libre-3.2.23-gnu/sound/soc/codecs/tlv320aic3x.c
--- linux-libre-3.2.22-gnu/sound/soc/codecs/tlv320aic3x.c	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/sound/soc/codecs/tlv320aic3x.c	2012-07-11 23:32:21.000000000 -0400
@@ -963,9 +963,7 @@
 	}
 
 found:
-	data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
-	snd_soc_write(codec, AIC3X_PLL_PROGA_REG,
-		      data | (pll_p << PLLP_SHIFT));
+	snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
 	snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
 		      pll_r << PLLR_SHIFT);
 	snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
diff -druN linux-libre-3.2.22-gnu/sound/soc/codecs/tlv320aic3x.h linux-libre-3.2.23-gnu/sound/soc/codecs/tlv320aic3x.h
--- linux-libre-3.2.22-gnu/sound/soc/codecs/tlv320aic3x.h	2012-07-04 00:44:35.000000000 -0400
+++ linux-libre-3.2.23-gnu/sound/soc/codecs/tlv320aic3x.h	2012-07-11 23:32:21.000000000 -0400
@@ -166,6 +166,7 @@
 
 /* PLL registers bitfields */
 #define PLLP_SHIFT		0
+#define PLLP_MASK		7
 #define PLLQ_SHIFT		3
 #define PLLR_SHIFT		0
 #define PLLJ_SHIFT		2
