Skip to contentSkip to conversation

3.3.7-stable review

PATCH New Greg KH 1 participant 48 messages May 18, 2012

Subsystems (41)
lore
Share & tools
lore

Greg KH

author maintainer
#0 lore raw

cover 3.3.7-stable review

This is the start of the stable review cycle for the 3.3.7 release. There are 47 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Sun May 20 21:26:47 UTC 2012. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.3.7-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------

 Makefile                                      |    4 +-
 arch/arm/mm/fault.c                           |    4 +-
 arch/arm/vfp/vfpmodule.c                      |   10 ++--
 arch/sparc/kernel/central.c                   |    2 +-
 arch/sparc/mm/ultra.S                         |    6 +-
 arch/tile/kernel/compat_signal.c              |   12 ++--
 drivers/char/virtio_console.c                 |    7 +++
 drivers/crypto/Kconfig                        |    1 +
 drivers/i2c/busses/i2c-eg20t.c                |    2 +-
 drivers/md/dm-mpath.c                         |    4 +-
 drivers/md/md.c                               |    2 +
 drivers/media/dvb/dvb-core/dvb_frontend.c     |    4 ++
 drivers/media/rc/ene_ir.c                     |   32 +++++-----
 drivers/media/rc/fintek-cir.c                 |   20 +++----
 drivers/media/rc/ite-cir.c                    |   20 +++----
 drivers/media/rc/nuvoton-cir.c                |   36 ++++++------
 drivers/media/rc/winbond-cir.c                |   78 ++++++++++++-------------
 drivers/media/video/marvell-ccic/mmp-driver.c |    1 -
 drivers/media/video/s5p-fimc/fimc-capture.c   |    2 +-
 drivers/mtd/mtdchar.c                         |    2 +-
 drivers/net/ethernet/dlink/dl2k.c             |   52 +++--------------
 drivers/net/ethernet/dlink/dl2k.h             |    7 ---
 drivers/net/ethernet/intel/e1000/e1000_main.c |    6 +-
 drivers/net/usb/cdc_ether.c                   |   30 +++++++++-
 drivers/net/usb/usbnet.c                      |   54 ++++++++++++-----
 drivers/spi/spi-topcliff-pch.c                |   78 +++++++++++++++++++++----
 drivers/target/target_core_file.c             |   22 +++++--
 drivers/target/target_core_pr.c               |    3 +
 drivers/target/target_core_tpg.c              |   22 -------
 drivers/video/omap2/dss/venc.c                |    5 ++
 fs/cifs/cifsfs.c                              |    2 +-
 fs/ext4/xattr.c                               |    7 ++-
 fs/jffs2/gc.c                                 |    2 +-
 fs/nfs/nfs4proc.c                             |   28 ++++-----
 fs/nfs/nfs4xdr.c                              |   18 +++---
 include/linux/usb/usbnet.h                    |    3 +-
 init/do_mounts.c                              |    2 +-
 kernel/compat.c                               |   63 ++++++++++++++------
 kernel/fork.c                                 |    3 +
 mm/hugetlb.c                                  |    1 -
 mm/memcontrol.c                               |    6 ++
 mm/nobootmem.c                                |    3 +-
 mm/percpu.c                                   |   12 ++++
 net/ipv4/tcp.c                                |    3 +-
 sound/pci/echoaudio/echoaudio_dsp.c           |    2 +-
 sound/pci/hda/hda_intel.c                     |    6 +-
 sound/pci/hda/patch_realtek.c                 |    1 +
 sound/pci/hda/patch_sigmatel.c                |    6 +-
 sound/soc/codecs/cs42l73.c                    |   16 ++---
 sound/soc/codecs/wm8994.c                     |    2 +-
 50 files changed, 424 insertions(+), 290 deletions(-)
author maintainer
#1 lore raw

PATCH 1/47 ALSA: echoaudio: Remove incorrect part of assertion

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mark Hills <[email protected]>

commit c914f55f7cdfafe9d7d5b248751902c7ab57691e upstream.

This assertion seems to imply that chip->dsp_code_to_load is a pointer. It's actually an integer handle on the actual firmware, and 0 has no special meaning.

The assertion prevents initialisation of a Darla20 card, but would also affect other models. It seems it was introduced in commit dd7b254d.

ALSA sound/pci/echoaudio/echoaudio.c:2061 Echoaudio driver starting...
ALSA sound/pci/echoaudio/echoaudio.c:1969 chip=ebe4e000
ALSA sound/pci/echoaudio/echoaudio.c:2007 pci=ed568000 irq=19 subdev=0010 Init hardware...
ALSA sound/pci/echoaudio/darla20_dsp.c:36 init_hw() - Darla20
------------[ cut here ]------------
WARNING: at sound/pci/echoaudio/echoaudio_dsp.c:478 init_hw+0x1d1/0x86c [snd_darla20]()
Hardware name: Dell DM051

BUG? (!chip->dsp_code_to_load || !chip->comm_page)

---
 sound/pci/echoaudio/echoaudio_dsp.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/pci/echoaudio/echoaudio_dsp.c +1 -1
@@ -475,7 +475,7 @@ static int load_firmware(struct echoaudi
 	const struct firmware *fw;
 	int box_type, err;
 
-	if (snd_BUG_ON(!chip->dsp_code_to_load || !chip->comm_page))
+	if (snd_BUG_ON(!chip->comm_page))
 		return -EPERM;
 
 	/* See if the ASIC is present and working - only if the DSP is already loaded */
author maintainer
#2 lore raw

PATCH 2/47 ALSA: HDA: Lessen CPU usage when waiting for chip to respond

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Henningsson <[email protected]>

commit 32cf4023e689ad5b3a81a749d8cc99d7f184cb99 upstream.

When an IRQ for some reason gets lost, we wait up to a second using udelay, which is CPU intensive. This patch improves the situation by waiting about 30 ms in the CPU intensive mode, then stepping down to using msleep(2) instead. In essence, we trade some granularity in exchange for less CPU consumption when the waiting time is a bit longer.

As a result, PulseAudio should no longer be killed by the kernel for taking up to much RT-prio CPU time. At least not for *this* reason.

---
 sound/pci/hda/hda_intel.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
sound/pci/hda/hda_intel.c +4 -2
@@ -779,11 +779,13 @@ static unsigned int azx_rirb_get_respons
 {
 	struct azx *chip = bus->private_data;
 	unsigned long timeout;
+	unsigned long loopcounter;
 	int do_poll = 0;
 
  again:
 	timeout = jiffies + msecs_to_jiffies(1000);
-	for (;;) {
+
+	for (loopcounter = 0;; loopcounter++) {
 		if (chip->polling_mode || do_poll) {
 			spin_lock_irq(&chip->reg_lock);
 			azx_update_rirb(chip);
@@ -799,7 +801,7 @@ static unsigned int azx_rirb_get_respons
 		}
 		if (time_after(jiffies, timeout))
 			break;
-		if (bus->needs_damn_long_delay)
+		if (bus->needs_damn_long_delay || loopcounter > 3000)
 			msleep(2); /* temporary workaround */
 		else {
 			udelay(10);
author maintainer
#3 lore raw

PATCH 3/47 ALSA: hda/realtek - Add missing CD-input pin for MSI-7350 mobo

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit bca40138558f0b39357fd1ca477868e4f52f4b1e upstream.

---
 sound/pci/hda/patch_realtek.c |    1 +
 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -4665,6 +4665,7 @@ static const struct snd_pci_quirk alc882
 	SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
 
 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
+	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
 	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
 	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD),
 	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
author maintainer
#4 lore raw

PATCH 4/47 ALSA: hda/idt - Fix power-map for speaker-pins with some HP laptops

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <[email protected]>

commit b0791dda813c179e539b0fc1ecd3f5f30f2571e2 upstream.

BIOS on some HP laptops don't set the speaker-pins as fixed but expose as jacks, and this confuses the driver as if these pins are jack-detectable. As a result, the machine doesn't get sounds from speakers because the driver prepares the power-map update via jack unsol events which never come up in reality. The bug was introduced in some time in 3.2 for enabling the power-mapping feature.

This patch fixes the problem by replacing the check of the persistent power-map bits with a proper is_jack_detectable() call.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=43240

---
 sound/pci/hda/patch_sigmatel.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
sound/pci/hda/patch_sigmatel.c +3 -3
@@ -4394,9 +4394,9 @@ static int stac92xx_init(struct hda_code
 		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_COMPLEX) {
-			if (def_conf != AC_JACK_PORT_NONE)
-				stac_toggle_power_map(codec, nid, 1);
+		if (def_conf != AC_JACK_PORT_NONE &&
+		    !is_jack_detectable(codec, nid)) {
+			stac_toggle_power_map(codec, nid, 1);
 			continue;
 		}
 		if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) {
author maintainer
#5 lore raw

PATCH 5/47 usbnet: fix skb traversing races during unlink(v2)

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Ming Lei <[email protected]>

commit 5b6e9bcdeb65634b4ad604eb4536404bbfc62cfa upstream.

Commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d(net/usbnet: avoid recursive locking in usbnet_stop()) fixes the recursive locking problem by releasing the skb queue lock before unlink, but may cause skb traversing races:
- after URB is unlinked and the queue lock is released, the refered skb and skb->next may be moved to done queue, even be released
- in skb_queue_walk_safe, the next skb is still obtained by next pointer of the last skb
- so maybe trigger oops or other problems

This patch extends the usage of entry->state to describe 'start_unlink' state, so always holding the queue(rx/tx) lock to change the state if the referd skb is in rx or tx queue because we need to know if the refered urb has been started unlinking in unlink_urbs.

The other part of this patch is based on Huajun's patch:
always traverse from head of the tx/rx queue to get skb which is to be unlinked but not been started unlinking.

---
 drivers/net/usb/usbnet.c   |   54 +++++++++++++++++++++++++++++++--------------
 include/linux/usb/usbnet.h |    3 +-
 2 files changed, 40 insertions(+), 17 deletions(-)
drivers/net/usb/usbnet.c +38 -16
@@ -281,17 +281,32 @@ int usbnet_change_mtu (struct net_device
 }
 EXPORT_SYMBOL_GPL(usbnet_change_mtu);
 
+/* The caller must hold list->lock */
+static void __usbnet_queue_skb(struct sk_buff_head *list,
+			struct sk_buff *newsk, enum skb_state state)
+{
+	struct skb_data *entry = (struct skb_data *) newsk->cb;
+
+	__skb_queue_tail(list, newsk);
+	entry->state = state;
+}
+
 /*-------------------------------------------------------------------------*/
 
 /* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from
  * completion callbacks.  2.5 should have fixed those bugs...
  */
 
-static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
+static enum skb_state defer_bh(struct usbnet *dev, struct sk_buff *skb,
+		struct sk_buff_head *list, enum skb_state state)
 {
 	unsigned long		flags;
+	enum skb_state 		old_state;
+	struct skb_data *entry = (struct skb_data *) skb->cb;
 
 	spin_lock_irqsave(&list->lock, flags);
+	old_state = entry->state;
+	entry->state = state;
 	__skb_unlink(skb, list);
 	spin_unlock(&list->lock);
 	spin_lock(&dev->done.lock);
@@ -299,6 +314,7 @@ static void defer_bh(struct usbnet *dev,
 	if (dev->done.qlen == 1)
 		tasklet_schedule(&dev->bh);
 	spin_unlock_irqrestore(&dev->done.lock, flags);
+	return old_state;
 }
 
 /* some work can't be done in tasklets, so we use keventd
@@ -339,7 +355,6 @@ static int rx_submit (struct usbnet *dev
 	entry = (struct skb_data *) skb->cb;
 	entry->urb = urb;
 	entry->dev = dev;
-	entry->state = rx_start;
 	entry->length = 0;
 
 	usb_fill_bulk_urb (urb, dev->udev, dev->in,
@@ -371,7 +386,7 @@ static int rx_submit (struct usbnet *dev
 			tasklet_schedule (&dev->bh);
 			break;
 		case 0:
-			__skb_queue_tail (&dev->rxq, skb);
+			__usbnet_queue_skb(&dev->rxq, skb, rx_start);
 		}
 	} else {
 		netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
@@ -422,16 +437,17 @@ static void rx_complete (struct urb *urb
 	struct skb_data		*entry = (struct skb_data *) skb->cb;
 	struct usbnet		*dev = entry->dev;
 	int			urb_status = urb->status;
+	enum skb_state		state;
 
 	skb_put (skb, urb->actual_length);
-	entry->state = rx_done;
+	state = rx_done;
 	entry->urb = NULL;
 
 	switch (urb_status) {
 	/* success */
 	case 0:
 		if (skb->len < dev->net->hard_header_len) {
-			entry->state = rx_cleanup;
+			state = rx_cleanup;
 			dev->net->stats.rx_errors++;
 			dev->net->stats.rx_length_errors++;
 			netif_dbg(dev, rx_err, dev->net,
@@ -470,7 +486,7 @@ static void rx_complete (struct urb *urb
 				  "rx throttle %d\n", urb_status);
 		}
 block:
-		entry->state = rx_cleanup;
+		state = rx_cleanup;
 		entry->urb = urb;
 		urb = NULL;
 		break;
@@ -481,17 +497,18 @@ block:
 		// FALLTHROUGH
 
 	default:
-		entry->state = rx_cleanup;
+		state = rx_cleanup;
 		dev->net->stats.rx_errors++;
 		netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status);
 		break;
 	}
 
-	defer_bh(dev, skb, &dev->rxq);
+	state = defer_bh(dev, skb, &dev->rxq, state);
 
 	if (urb) {
 		if (netif_running (dev->net) &&
-		    !test_bit (EVENT_RX_HALT, &dev->flags)) {
+		    !test_bit (EVENT_RX_HALT, &dev->flags) &&
+		    state != unlink_start) {
 			rx_submit (dev, urb, GFP_ATOMIC);
 			return;
 		}
@@ -577,16 +594,23 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rx
 static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
 {
 	unsigned long		flags;
-	struct sk_buff		*skb, *skbnext;
+	struct sk_buff		*skb;
 	int			count = 0;
 
 	spin_lock_irqsave (&q->lock, flags);
-	skb_queue_walk_safe(q, skb, skbnext) {
+	while (!skb_queue_empty(q)) {
 		struct skb_data		*entry;
 		struct urb		*urb;
 		int			retval;
 
-		entry = (struct skb_data *) skb->cb;
+		skb_queue_walk(q, skb) {
+			entry = (struct skb_data *) skb->cb;
+			if (entry->state != unlink_start)
+				goto found;
+		}
+		break;
+found:
+		entry->state = unlink_start;
 		urb = entry->urb;
 
 		/*
@@ -1037,8 +1061,7 @@ static void tx_complete (struct urb *urb
 	}
 
 	usb_autopm_put_interface_async(dev->intf);
-	entry->state = tx_done;
-	defer_bh(dev, skb, &dev->txq);
+	(void) defer_bh(dev, skb, &dev->txq, tx_done);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1094,7 +1117,6 @@ netdev_tx_t usbnet_start_xmit (struct sk
 	entry = (struct skb_data *) skb->cb;
 	entry->urb = urb;
 	entry->dev = dev;
-	entry->state = tx_start;
 	entry->length = length;
 
 	usb_fill_bulk_urb (urb, dev->udev, dev->out,
@@ -1153,7 +1175,7 @@ netdev_tx_t usbnet_start_xmit (struct sk
 		break;
 	case 0:
 		net->trans_start = jiffies;
-		__skb_queue_tail (&dev->txq, skb);
+		__usbnet_queue_skb(&dev->txq, skb, tx_start);
 		if (dev->txq.qlen >= TX_QLEN (dev))
 			netif_stop_queue (net);
 	}
include/linux/usb/usbnet.h +2 -1
@@ -191,7 +191,8 @@ extern void usbnet_cdc_status(struct usb
 enum skb_state {
 	illegal = 0,
 	tx_start, tx_done,
-	rx_start, rx_done, rx_cleanup
+	rx_start, rx_done, rx_cleanup,
+	unlink_start
 };
 
 struct skb_data {	/* skb->cb is one of these */
author maintainer
#6 lore raw

PATCH 6/47 namespaces, pid_ns: fix leakage on fork() failure

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mike Galbraith <[email protected]>

commit 5e2bf0142231194d36fdc9596b36a261ed2b9fe7 upstream.

Fork() failure post namespace creation for a child cloned with CLONE_NEWPID leaks pid_namespace/mnt_cache due to proc being mounted during creation, but not unmounted during cleanup. Call pid_ns_release_proc() during cleanup.

---
 kernel/fork.c |    3 +++
 1 file changed, 3 insertions(+)
kernel/fork.c +3 -0
@@ -47,6 +47,7 @@
 #include <linux/audit.h>
 #include <linux/memcontrol.h>
 #include <linux/ftrace.h>
+#include <linux/proc_fs.h>
 #include <linux/profile.h>
 #include <linux/rmap.h>
 #include <linux/ksm.h>
@@ -1438,6 +1439,8 @@ bad_fork_cleanup_io:
 	if (p->io_context)
 		exit_io_context(p);
 bad_fork_cleanup_namespaces:
+	if (unlikely(clone_flags & CLONE_NEWPID))
+		pid_ns_release_proc(p->nsproxy->pid_ns);
 	exit_task_namespaces(p);
 bad_fork_cleanup_mm:
 	if (p->mm)
author maintainer
#7 lore raw

PATCH 7/47 sparc64: Do not clobber %g2 in xcall_fetch_glob_regs().

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: "David S. Miller" <[email protected]>

[ Upstream commit a5a737e090e25981e99d69f01400e3a80356581c ]

%g2 is meant to hold the CPUID number throughout this routine, since at the very beginning, and at the very end, we use %g2 to calculate indexes into per-cpu arrays.

However we erroneously clobber it in order to hold the %cwp register value mid-stream.

Fix this code to use %g3 for the %cwp read and related calulcations instead.

---
 arch/sparc/kernel/central.c |    2 +-
 arch/sparc/mm/ultra.S       |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/sparc/kernel/central.c +1 -1
@@ -269,4 +269,4 @@ static int __init sunfire_init(void)
 	return 0;
 }
 
-subsys_initcall(sunfire_init);
+fs_initcall(sunfire_init);
arch/sparc/mm/ultra.S +3 -3
@@ -495,11 +495,11 @@ xcall_fetch_glob_regs:
 	stx		%o7, [%g1 + GR_SNAP_O7]
 	stx		%i7, [%g1 + GR_SNAP_I7]
 	/* Don't try this at home kids... */
-	rdpr		%cwp, %g2
-	sub		%g2, 1, %g7
+	rdpr		%cwp, %g3
+	sub		%g3, 1, %g7
 	wrpr		%g7, %cwp
 	mov		%i7, %g7
-	wrpr		%g2, %cwp
+	wrpr		%g3, %cwp
 	stx		%g7, [%g1 + GR_SNAP_RPC]
 	sethi		%hi(trap_block), %g7
 	or		%g7, %lo(trap_block), %g7
author maintainer
#8 lore raw

PATCH 8/47 media: marvell-cam: fix an ARM build error

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jonathan Corbet <[email protected]>

commit 9967232f1be5bab10c7b7a8dcf51ff5c3c1a6d77 upstream.

One of the OLPC changes lost a little in its translation to mainline, leading to build errors on the ARM architecture. Remove the offending line, and all will be well.

---
 drivers/media/video/marvell-ccic/mmp-driver.c |    1 -
 1 file changed, 1 deletion(-)
drivers/media/video/marvell-ccic/mmp-driver.c +0 -1
@@ -176,7 +176,6 @@ static int mmpcam_probe(struct platform_
 	INIT_LIST_HEAD(&cam->devlist);
 
 	mcam = &cam->mcam;
-	mcam->platform = MHP_Armada610;
 	mcam->plat_power_up = mmpcam_power_up;
 	mcam->plat_power_down = mmpcam_power_down;
 	mcam->dev = &pdev->dev;
author maintainer
#9 lore raw

PATCH 9/47 ARM: 7417/1: vfp: ensure preemption is disabled when enabling VFP access

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Will Deacon <[email protected]>

commit 998de4acb2ba188d20768d1065658377a2e7d29b upstream.

The vfp_enable function enables access to the VFP co-processor register space (cp10 and cp11) on the current CPU and must be called with preemption disabled. Unfortunately, the vfp_init late initcall does not disable preemption and can lead to an oops during boot if thread migration occurs at the wrong time and we end up attempting to access the FPSID on a CPU with VFP access disabled.

This patch fixes the initcall to call vfp_enable from a non-preemptible context on each CPU and adds a BUG_ON(preemptible) to ensure that any similar problems are easily spotted in the future.

---
 arch/arm/vfp/vfpmodule.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
arch/arm/vfp/vfpmodule.c +6 -4
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <linux/cpu.h>
 #include <linux/cpu_pm.h>
+#include <linux/hardirq.h>
 #include <linux/kernel.h>
 #include <linux/notifier.h>
 #include <linux/signal.h>
@@ -428,7 +429,10 @@ void VFP_bounce(u32 trigger, u32 fpexc,
 
 static void vfp_enable(void *unused)
 {
-	u32 access = get_copro_access();
+	u32 access;
+
+	BUG_ON(preemptible());
+	access = get_copro_access();
 
 	/*
 	 * Enable full access to VFP (cp10 and cp11)
@@ -556,7 +560,7 @@ static int __init vfp_init(void)
 	unsigned int cpu_arch = cpu_architecture();
 
 	if (cpu_arch >= CPU_ARCH_ARMv6)
-		vfp_enable(NULL);
+		on_each_cpu(vfp_enable, NULL, 1);
 
 	/*
 	 * First check that there is a VFP that we can use.
@@ -577,8 +581,6 @@ static int __init vfp_init(void)
 	} else {
 		hotcpu_notifier(vfp_hotplug, 0);
 
-		smp_call_function(vfp_enable, NULL, 1);
-
 		VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT;  /* Extract the architecture version */
 		printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
 			(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
author maintainer
#10 lore raw

PATCH 10/47 ARM: prevent VM_GROWSDOWN mmaps extending below FIRST_USER_ADDRESS

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Russell King <[email protected]>

commit 9b61a4d1b2064dbd0c9e61754305ac852170509f upstream.

---
 arch/arm/mm/fault.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm/mm/fault.c +3 -1
@@ -245,7 +245,9 @@ good_area:
 	return handle_mm_fault(mm, vma, addr & PAGE_MASK, flags);
 
 check_stack:
-	if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
+	/* Don't allow expansion below FIRST_USER_ADDRESS */
+	if (vma->vm_flags & VM_GROWSDOWN &&
+	    addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr))
 		goto good_area;
 out:
 	return fault;
author maintainer
#11 lore raw

PATCH 11/47 media: s5p-fimc: Fix locking in subdev set_crop op

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sylwester Nawrocki <[email protected]>

commit e985dbf7d93e2a3e114b4525413e50f83613e0cb upstream.

When setting TRY crop on the sub-device the mutex was erroneously acquired rather than released on exit path. This bug is present in kernels starting from v3.2.

---
 drivers/media/video/s5p-fimc/fimc-capture.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/video/s5p-fimc/fimc-capture.c +1 -1
@@ -1316,7 +1316,7 @@ static int fimc_subdev_set_crop(struct v
 	fimc_capture_try_crop(ctx, r, crop->pad);
 
 	if (crop->which == V4L2_SUBDEV_FORMAT_TRY) {
-		mutex_lock(&fimc->lock);
+		mutex_unlock(&fimc->lock);
 		*v4l2_subdev_get_try_crop(fh, crop->pad) = *r;
 		return 0;
 	}
author maintainer
#12 lore raw

PATCH 12/47 media: rc: Postpone ISR registration

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Luis Henriques <[email protected]>

commit 9ef449c6b31bb6a8e6dedc24de475a3b8c79be20 upstream.

An early registration of an ISR was causing a crash to several users (for example, with the ite-cir driver: http://bugs.launchpad.net/bugs/972723).
The reason was that IRQs were being triggered before a driver initialisation was completed.

This patch fixes this by moving the invocation to request_irq() and to request_region() to a later stage on the driver probe function.

---
 drivers/media/rc/ene_ir.c      |   32 ++++++++--------
 drivers/media/rc/fintek-cir.c  |   20 +++++-----
 drivers/media/rc/ite-cir.c     |   20 +++++-----
 drivers/media/rc/nuvoton-cir.c |   36 +++++++++---------
 drivers/media/rc/winbond-cir.c |   78 ++++++++++++++++++++---------------------
 5 files changed, 93 insertions(+), 93 deletions(-)
drivers/media/rc/ene_ir.c +16 -16
@@ -1018,22 +1018,6 @@ static int ene_probe(struct pnp_dev *pnp
 
 	spin_lock_init(&dev->hw_lock);
 
-	/* claim the resources */
-	error = -EBUSY;
-	dev->hw_io = pnp_port_start(pnp_dev, 0);
-	if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
-		dev->hw_io = -1;
-		dev->irq = -1;
-		goto error;
-	}
-
-	dev->irq = pnp_irq(pnp_dev, 0);
-	if (request_irq(dev->irq, ene_isr,
-			IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
-		dev->irq = -1;
-		goto error;
-	}
-
 	pnp_set_drvdata(pnp_dev, dev);
 	dev->pnp_dev = pnp_dev;
 
@@ -1086,6 +1070,22 @@ static int ene_probe(struct pnp_dev *pnp
 	device_set_wakeup_capable(&pnp_dev->dev, true);
 	device_set_wakeup_enable(&pnp_dev->dev, true);
 
+	/* claim the resources */
+	error = -EBUSY;
+	dev->hw_io = pnp_port_start(pnp_dev, 0);
+	if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
+		dev->hw_io = -1;
+		dev->irq = -1;
+		goto error;
+	}
+
+	dev->irq = pnp_irq(pnp_dev, 0);
+	if (request_irq(dev->irq, ene_isr,
+			IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
+		dev->irq = -1;
+		goto error;
+	}
+
 	error = rc_register_device(rdev);
 	if (error < 0)
 		goto error;
drivers/media/rc/fintek-cir.c +10 -10
@@ -504,16 +504,6 @@ static int fintek_probe(struct pnp_dev *
 
 	spin_lock_init(&fintek->fintek_lock);
 
-	ret = -EBUSY;
-	/* now claim resources */
-	if (!request_region(fintek->cir_addr,
-			    fintek->cir_port_len, FINTEK_DRIVER_NAME))
-		goto failure;
-
-	if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
-			FINTEK_DRIVER_NAME, (void *)fintek))
-		goto failure;
-
 	pnp_set_drvdata(pdev, fintek);
 	fintek->pdev = pdev;
 
@@ -548,6 +538,16 @@ static int fintek_probe(struct pnp_dev *
 	/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
 	rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
 
+	ret = -EBUSY;
+	/* now claim resources */
+	if (!request_region(fintek->cir_addr,
+			    fintek->cir_port_len, FINTEK_DRIVER_NAME))
+		goto failure;
+
+	if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
+			FINTEK_DRIVER_NAME, (void *)fintek))
+		goto failure;
+
 	ret = rc_register_device(rdev);
 	if (ret)
 		goto failure;
drivers/media/rc/ite-cir.c +10 -10
@@ -1515,16 +1515,6 @@ static int ite_probe(struct pnp_dev *pde
 	/* initialize raw event */
 	init_ir_raw_event(&itdev->rawir);
 
-	ret = -EBUSY;
-	/* now claim resources */
-	if (!request_region(itdev->cir_addr,
-				dev_desc->io_region_size, ITE_DRIVER_NAME))
-		goto failure;
-
-	if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
-			ITE_DRIVER_NAME, (void *)itdev))
-		goto failure;
-
 	/* set driver data into the pnp device */
 	pnp_set_drvdata(pdev, itdev);
 	itdev->pdev = pdev;
@@ -1600,6 +1590,16 @@ static int ite_probe(struct pnp_dev *pde
 	rdev->driver_name = ITE_DRIVER_NAME;
 	rdev->map_name = RC_MAP_RC6_MCE;
 
+	ret = -EBUSY;
+	/* now claim resources */
+	if (!request_region(itdev->cir_addr,
+				dev_desc->io_region_size, ITE_DRIVER_NAME))
+		goto failure;
+
+	if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
+			ITE_DRIVER_NAME, (void *)itdev))
+		goto failure;
+
 	ret = rc_register_device(rdev);
 	if (ret)
 		goto failure;
drivers/media/rc/nuvoton-cir.c +18 -18
@@ -1021,24 +1021,6 @@ static int nvt_probe(struct pnp_dev *pde
 	spin_lock_init(&nvt->nvt_lock);
 	spin_lock_init(&nvt->tx.lock);
 
-	ret = -EBUSY;
-	/* now claim resources */
-	if (!request_region(nvt->cir_addr,
-			    CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
-		goto failure;
-
-	if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED,
-			NVT_DRIVER_NAME, (void *)nvt))
-		goto failure;
-
-	if (!request_region(nvt->cir_wake_addr,
-			    CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
-		goto failure;
-
-	if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED,
-			NVT_DRIVER_NAME, (void *)nvt))
-		goto failure;
-
 	pnp_set_drvdata(pdev, nvt);
 	nvt->pdev = pdev;
 
@@ -1085,6 +1067,24 @@ static int nvt_probe(struct pnp_dev *pde
 	rdev->tx_resolution = XYZ;
 #endif
 
+	ret = -EBUSY;
+	/* now claim resources */
+	if (!request_region(nvt->cir_addr,
+			    CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
+		goto failure;
+
+	if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED,
+			NVT_DRIVER_NAME, (void *)nvt))
+		goto failure;
+
+	if (!request_region(nvt->cir_wake_addr,
+			    CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
+		goto failure;
+
+	if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED,
+			NVT_DRIVER_NAME, (void *)nvt))
+		goto failure;
+
 	ret = rc_register_device(rdev);
 	if (ret)
 		goto failure;
drivers/media/rc/winbond-cir.c +39 -39

107 lines not on this page · raw message

author maintainer
#13 lore raw

PATCH 13/47 media: dvb_frontend: fix a regression with DVB-S zig-zag

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mauro Carvalho Chehab <[email protected]>

commit 910a5f2e9642d5be373beae3d29e1c4a3bc7d83b upstream.

Changeset 5bfaadde broke zig-zag for DVB-S drivers that don't implement get_tune_settings() callback.

Fix the code, in order to allow it to work as before, otherwise some channels may not be tuned anymore.

Fix Fedora Bugzilla:

	https://bugzilla.redhat.com/show_bug.cgi?id=814404
---
 drivers/media/dvb/dvb-core/dvb_frontend.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/media/dvb/dvb-core/dvb_frontend.c +4 -0
@@ -1921,6 +1921,10 @@ static int dtv_set_frontend(struct dvb_f
 	} else {
 		/* default values */
 		switch (c->delivery_system) {
+		case SYS_DVBS:
+		case SYS_DVBS2:
+		case SYS_ISDBS:
+		case SYS_TURBO:
 		case SYS_DVBC_ANNEX_A:
 		case SYS_DVBC_ANNEX_C:
 			fepriv->min_delay = HZ / 20;
author maintainer
#14 lore raw

PATCH 14/47 ASoC: cs42l73: Sync digital mixer kcontrols to allow for 0dB

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Brian Austin <[email protected]>

commit 5807c3bf68eb489032ca8ff70b3d3c833fd8172b upstream.

Some of the Digital mixer kcontrol max values were off by 1 not allowing a max of 0dB.

---
 sound/soc/codecs/cs42l73.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
sound/soc/codecs/cs42l73.c +8 -8
@@ -568,22 +568,22 @@ static const struct snd_kcontrol_new cs4
 			attn_tlv),
 
 	SOC_SINGLE_TLV("SPK-IP Mono Volume",
-			CS42L73_SPKMIPMA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_SPKMIPMA, 0, 0x3F, 1, attn_tlv),
 	SOC_SINGLE_TLV("SPK-XSP Mono Volume",
-			CS42L73_SPKMXSPA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_SPKMXSPA, 0, 0x3F, 1, attn_tlv),
 	SOC_SINGLE_TLV("SPK-ASP Mono Volume",
-			CS42L73_SPKMASPA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_SPKMASPA, 0, 0x3F, 1, attn_tlv),
 	SOC_SINGLE_TLV("SPK-VSP Mono Volume",
-			CS42L73_SPKMVSPMA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_SPKMVSPMA, 0, 0x3F, 1, attn_tlv),
 
 	SOC_SINGLE_TLV("ESL-IP Mono Volume",
-			CS42L73_ESLMIPMA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_ESLMIPMA, 0, 0x3F, 1, attn_tlv),
 	SOC_SINGLE_TLV("ESL-XSP Mono Volume",
-			CS42L73_ESLMXSPA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_ESLMXSPA, 0, 0x3F, 1, attn_tlv),
 	SOC_SINGLE_TLV("ESL-ASP Mono Volume",
-			CS42L73_ESLMASPA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_ESLMASPA, 0, 0x3F, 1, attn_tlv),
 	SOC_SINGLE_TLV("ESL-VSP Mono Volume",
-			CS42L73_ESLMVSPMA, 0, 0x3E, 1, attn_tlv),
+			CS42L73_ESLMVSPMA, 0, 0x3F, 1, attn_tlv),
 
 	SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum),
 
author maintainer
#15 lore raw

PATCH 15/47 ASoC: wm8994: Fix AIF2ADC power down

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mark Brown <[email protected]>

commit c7f5f2389377b66028bc129890aa653deafe8d39 upstream.

---
 sound/soc/codecs/wm8994.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/wm8994.c +1 -1
@@ -1073,7 +1073,7 @@ static int aif2clk_ev(struct snd_soc_dap
 		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
 				    WM8994_AIF2DACL_ENA |
 				    WM8994_AIF2DACR_ENA, 0);
-		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
+		snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4,
 				    WM8994_AIF2ADCL_ENA |
 				    WM8994_AIF2ADCR_ENA, 0);
 
author maintainer
#16 lore raw

PATCH 16/47 cdc_ether: Ignore bogus union descriptor for RNDIS devices

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bjørn Mork <[email protected]>

commit 6eddcb4c82883451aec3be1240f17793370fa62f upstream.

Some RNDIS devices include a bogus CDC Union descriptor pointing to non-existing interfaces. The RNDIS code is already prepared to handle devices without a CDC Union descriptor by hardwiring the driver to use interfaces 0 and 1, which is correct for the devices with the bogus descriptor as well. So we can reuse the existing workaround.

Cc Markus Kolb <[email protected]>
Cc Iker Salmón San Millán <[email protected]>
Cc Jonathan Nieder <[email protected]>
Cc Oliver Neukum <[email protected]>
---
 drivers/net/usb/cdc_ether.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/net/usb/cdc_ether.c +12 -2
@@ -83,6 +83,7 @@ int usbnet_generic_cdc_bind(struct usbne
 	struct cdc_state		*info = (void *) &dev->data;
 	int				status;
 	int				rndis;
+	bool				android_rndis_quirk = false;
 	struct usb_driver		*driver = driver_of(intf);
 	struct usb_cdc_mdlm_desc	*desc = NULL;
 	struct usb_cdc_mdlm_detail_desc *detail = NULL;
@@ -195,6 +196,11 @@ int usbnet_generic_cdc_bind(struct usbne
 					info->control,
 					info->u->bSlaveInterface0,
 					info->data);
+				/* fall back to hard-wiring for RNDIS */
+				if (rndis) {
+					android_rndis_quirk = true;
+					goto next_desc;
+				}
 				goto bad_desc;
 			}
 			if (info->control != intf) {
@@ -271,11 +277,15 @@ next_desc:
 	/* Microsoft ActiveSync based and some regular RNDIS devices lack the
 	 * CDC descriptors, so we'll hard-wire the interfaces and not check
 	 * for descriptors.
+	 *
+	 * Some Android RNDIS devices have a CDC Union descriptor pointing
+	 * to non-existing interfaces.  Ignore that and attempt the same
+	 * hard-wired 0 and 1 interfaces.
 	 */
-	if (rndis && !info->u) {
+	if (rndis && (!info->u || android_rndis_quirk)) {
 		info->control = usb_ifnum_to_if(dev->udev, 0);
 		info->data = usb_ifnum_to_if(dev->udev, 1);
-		if (!info->control || !info->data) {
+		if (!info->control || !info->data || info->control != intf) {
 			dev_dbg(&intf->dev,
 				"rndis: master #0/%p slave #1/%p\n",
 				info->control,
author maintainer
#17 lore raw

PATCH 17/47 cdc_ether: add Novatel USB551L device IDs for FLAG_WWAN

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Williams <[email protected]>

commit 4e6304b8420aba5311ba21fd68dab2924ae4d91a upstream.

Needs to be tagged with FLAG_WWAN, which since it has generic descriptors, won't happen if we don't override the generic driver info.

---
 drivers/net/usb/cdc_ether.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/net/usb/cdc_ether.c +16 -0
@@ -485,6 +485,7 @@ static const struct driver_info wwan_inf
 /*-------------------------------------------------------------------------*/
 
 #define HUAWEI_VENDOR_ID	0x12D1
+#define NOVATEL_VENDOR_ID	0x1410
 
 static const struct usb_device_id	products [] = {
 /*
@@ -602,6 +603,21 @@ static const struct usb_device_id	produc
  * because of bugs/quirks in a given product (like Zaurus, above).
  */
 {
+	/* Novatel USB551L */
+	/* This match must come *before* the generic CDC-ETHER match so that
+	 * we get FLAG_WWAN set on the device, since it's descriptors are
+	 * generic CDC-ETHER.
+	 */
+	.match_flags    =   USB_DEVICE_ID_MATCH_VENDOR
+		 | USB_DEVICE_ID_MATCH_PRODUCT
+		 | USB_DEVICE_ID_MATCH_INT_INFO,
+	.idVendor               = NOVATEL_VENDOR_ID,
+	.idProduct		= 0xB001,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= USB_CDC_SUBCLASS_ETHERNET,
+	.bInterfaceProtocol	= USB_CDC_PROTO_NONE,
+	.driver_info = (unsigned long)&wwan_info,
+}, {
 	USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET,
 			USB_CDC_PROTO_NONE),
 	.driver_info = (unsigned long) &cdc_info,
author maintainer
#18 lore raw

PATCH 18/47 percpu: pcpu_embed_first_chunk() should free unused parts after all allocs are complete

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tejun Heo <[email protected]>

commit 42b64281453249dac52861f9b97d18552a7ec62b upstream.

pcpu_embed_first_chunk() allocates memory for each node, copies percpu data and frees unused portions of it before proceeding to the next group. This assumes that allocations for different nodes doesn't overlap; however, depending on memory topology, the bootmem allocator may end up allocating memory from a different node than the requested one which may overlap with the portion freed from one of the previous percpu areas. This leads to percpu groups for different nodes overlapping which is a serious bug.

This patch separates out copy & partial free from the allocation loop such that all allocations are complete before partial frees happen.

This also fixes overlapping frees which could happen on allocation failure path - out_free_areas path frees whole groups but the groups could have portions freed at that point.

LKML-Reference: <[email protected]>

---
 mm/percpu.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
mm/percpu.c +10 -0
@@ -1650,6 +1650,16 @@ int __init pcpu_embed_first_chunk(size_t
 		areas[group] = ptr;
 
 		base = min(ptr, base);
+	}
+
+	/*
+	 * Copy data and free unused parts.  This should happen after all
+	 * allocations are complete; otherwise, we may end up with
+	 * overlapping groups.
+	 */
+	for (group = 0; group < ai->nr_groups; group++) {
+		struct pcpu_group_info *gi = &ai->groups[group];
+		void *ptr = areas[group];
 
 		for (i = 0; i < gi->nr_units; i++, ptr += ai->unit_size) {
 			if (gi->cpu_map[i] == NR_CPUS) {
author maintainer
#19 lore raw

PATCH 19/47 kmemleak: Fix the kmemleak tracking of the percpu areas with !SMP

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Catalin Marinas <[email protected]>

commit 100d13c3b5b9410f604b86f5e0a34da64b8cf659 upstream.

Kmemleak tracks the percpu allocations via a specific API and the originally allocated areas must be removed from kmemleak (via kmemleak_free). The code was already doing this for SMP systems.

---
 mm/percpu.c |    2 ++
 1 file changed, 2 insertions(+)
mm/percpu.c +2 -0
@@ -1895,6 +1895,8 @@ void __init setup_per_cpu_areas(void)
 	fc = __alloc_bootmem(unit_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
 	if (!ai || !fc)
 		panic("Failed to allocate memory for percpu areas.");
+	/* kmemleak tracks the percpu allocations separately */
+	kmemleak_free(fc);
 
 	ai->dyn_size = unit_size;
 	ai->unit_size = unit_size;
author maintainer
#20 lore raw

PATCH 20/47 mtd: fix oops in dataflash driver

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Will Newton <[email protected]>

commit 7a84477c4acebf6299b6a8bd6a1d5894eb838ffa upstream.

I'm seeing an oops in mtd_dataflash.c with Linux 3.3. What appears to be happening is that otp_select_filemode calls mtd_read_fact_prot_reg with -1 for offset and length and a NULL buffer to test if OTP operations are supported. This finds its way down to otp_read in mtd_dataflash.c and causes an oops when memcpying the returned data into the NULL buf.

None of the checks in otp_read catches the negative length and offset. Changing the length of the dummy read to 0 prevents the oops.

---
 drivers/mtd/mtdchar.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/mtdchar.c +1 -1
@@ -369,7 +369,7 @@ static int otp_select_filemode(struct mt
 	 * Make a fake call to mtd_read_fact_prot_reg() to check if OTP
 	 * operations are supported.
 	 */
-	if (mtd_read_fact_prot_reg(mtd, -1, -1, &retlen, NULL) == -EOPNOTSUPP)
+	if (mtd_read_fact_prot_reg(mtd, -1, 0, &retlen, NULL) == -EOPNOTSUPP)
 		return -EOPNOTSUPP;
 
 	switch (mode) {
author maintainer
#21 lore raw

PATCH 21/47 hugetlb: prevent BUG_ON in hugetlb_fault() -> hugetlb_cow()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chris Metcalf <[email protected]>

commit 4998a6c0edce7fae9c0a5463f6ec3fa585258ee7 upstream.

Commit 66aebce747eaf ("hugetlb: fix race condition in hugetlb_fault()") added code to avoid a race condition by elevating the page refcount in hugetlb_fault() while calling hugetlb_cow().

However, one code path in hugetlb_cow() includes an assertion that the page count is 1, whereas it may now also have the value 2 in this path.

The consensus is that this BUG_ON has served its purpose, so rather than extending it to cover both cases, we just remove it.

---
 mm/hugetlb.c |    1 -
 1 file changed, 1 deletion(-)
mm/hugetlb.c +0 -1
@@ -2486,7 +2486,6 @@ retry_avoidcopy:
 		if (outside_reserve) {
 			BUG_ON(huge_pte_none(pte));
 			if (unmap_ref_private(mm, vma, old_page, address)) {
-				BUG_ON(page_count(old_page) != 1);
 				BUG_ON(huge_pte_none(pte));
 				spin_lock(&mm->page_table_lock);
 				ptep = huge_pte_offset(mm, address & huge_page_mask(h));
author maintainer
#22 lore raw

PATCH 22/47 mm: nobootmem: fix sign extend problem in __free_pages_memory()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Russ Anderson <[email protected]>

commit 6bc2e853c6b46a6041980d58200ad9b0a73a60ff upstream.

Systems with 8 TBytes of memory or greater can hit a problem where only the the first 8 TB of memory shows up. This is due to "int i" being smaller than "unsigned long start_aligned", causing the high bits to be dropped.

The fix is to change `i' to unsigned long to match start_aligned and end_aligned.

Thanks to Jack Steiner for assistance tracking this down.

---
 mm/nobootmem.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
mm/nobootmem.c +1 -2
@@ -82,8 +82,7 @@ void __init free_bootmem_late(unsigned l
 
 static void __init __free_pages_memory(unsigned long start, unsigned long end)
 {
-	int i;
-	unsigned long start_aligned, end_aligned;
+	unsigned long i, start_aligned, end_aligned;
 	int order = ilog2(BITS_PER_LONG);
 
 	start_aligned = (start + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1);
author maintainer
#23 lore raw

PATCH 23/47 jffs2: Fix lock acquisition order bug in gc path

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josh Cartwright <[email protected]>

commit 226bb7df3d22bcf4a1c0fe8206c80cc427498eae upstream.

The locking policy is such that the erase_complete_block spinlock is nested within the alloc_sem mutex. This fixes a case in which the acquisition order was erroneously reversed. This issue was caught by the following lockdep splat:

=======================================================
[ INFO: possible circular locking dependency detected ] 3.0.5 #1
-------------------------------------------------------
jffs2_gcd_mtd6/299 is trying to acquire lock:

    (&c->alloc_sem){+.+.+.}, at: [<c01f7714>] jffs2_garbage_collect_pass+0x314/0x890

but task is already holding lock:

    (&(&c->erase_completion_lock)->rlock){+.+...}, at: [<c01f7708>] jffs2_garbage_collect_pass+0x308/0x890

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #1 (&(&c->erase_completion_lock)->rlock){+.+...}:

          [<c008bec4>] validate_chain+0xe6c/0x10bc
          [<c008c660>] __lock_acquire+0x54c/0xba4
          [<c008d240>] lock_acquire+0xa4/0x114
          [<c046780c>] _raw_spin_lock+0x3c/0x4c
          [<c01f744c>] jffs2_garbage_collect_pass+0x4c/0x890
          [<c01f937c>] jffs2_garbage_collect_thread+0x1b4/0x1cc
          [<c0071a68>] kthread+0x98/0xa0
          [<c000f264>] kernel_thread_exit+0x0/0x8

-> #0 (&c->alloc_sem){+.+.+.}:

          [<c008ad2c>] print_circular_bug+0x70/0x2c4
          [<c008c08c>] validate_chain+0x1034/0x10bc
          [<c008c660>] __lock_acquire+0x54c/0xba4
          [<c008d240>] lock_acquire+0xa4/0x114
          [<c0466628>] mutex_lock_nested+0x74/0x33c
          [<c01f7714>] jffs2_garbage_collect_pass+0x314/0x890
          [<c01f937c>] jffs2_garbage_collect_thread+0x1b4/0x1cc
          [<c0071a68>] kthread+0x98/0xa0
          [<c000f264>] kernel_thread_exit+0x0/0x8

other info that might help us debug this:

    Possible unsafe locking scenario:
          CPU0                    CPU1
          ----                    ----
     lock(&(&c->erase_completion_lock)->rlock);
                                  lock(&c->alloc_sem);
                                  lock(&(&c->erase_completion_lock)->rlock);
     lock(&c->alloc_sem);

    *** DEADLOCK ***

1 lock held by jffs2_gcd_mtd6/299:

    #0:  (&(&c->erase_completion_lock)->rlock){+.+...}, at: [<c01f7708>] jffs2_garbage_collect_pass+0x308/0x890
   stack backtrace:
   [<c00155dc>] (unwind_backtrace+0x0/0x100) from [<c0463dc0>] (dump_stack+0x20/0x24)
   [<c0463dc0>] (dump_stack+0x20/0x24) from [<c008ae84>] (print_circular_bug+0x1c8/0x2c4)
   [<c008ae84>] (print_circular_bug+0x1c8/0x2c4) from [<c008c08c>] (validate_chain+0x1034/0x10bc)
   [<c008c08c>] (validate_chain+0x1034/0x10bc) from [<c008c660>] (__lock_acquire+0x54c/0xba4)
   [<c008c660>] (__lock_acquire+0x54c/0xba4) from [<c008d240>] (lock_acquire+0xa4/0x114)
   [<c008d240>] (lock_acquire+0xa4/0x114) from [<c0466628>] (mutex_lock_nested+0x74/0x33c)
   [<c0466628>] (mutex_lock_nested+0x74/0x33c) from [<c01f7714>] (jffs2_garbage_collect_pass+0x314/0x890)
   [<c01f7714>] (jffs2_garbage_collect_pass+0x314/0x890) from [<c01f937c>] (jffs2_garbage_collect_thread+0x1b4/0x1cc)
   [<c01f937c>] (jffs2_garbage_collect_thread+0x1b4/0x1cc) from [<c0071a68>] (kthread+0x98/0xa0)
   [<c0071a68>] (kthread+0x98/0xa0) from [<c000f264>] (kernel_thread_exit+0x0/0x8)

This was introduce in '81cfc9f jffs2: Fix serious write stall due to erase'.

---
 fs/jffs2/gc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/jffs2/gc.c +1 -1
@@ -225,8 +225,8 @@ int jffs2_garbage_collect_pass(struct jf
 			return 0;
 
 		D1(printk(KERN_DEBUG "No progress from erasing blocks; doing GC anyway\n"));
-		spin_lock(&c->erase_completion_lock);
 		mutex_lock(&c->alloc_sem);
+		spin_lock(&c->erase_completion_lock);
 	}
 
 	/* First, work out which block we're garbage-collecting */
author maintainer
#24 lore raw

PATCH 24/47 arch/tile: apply commit 74fca9da0 to the compat signal handling as well

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Chris Metcalf <[email protected]>

commit a134d228298c6aa9007205c6b81cae0cac0acb5d upstream.

This passes siginfo and mcontext to tilegx32 signal handlers that don't have SA_SIGINFO set just as we have been doing for tilegx64.

---
 arch/tile/kernel/compat_signal.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
arch/tile/kernel/compat_signal.c +5 -7
@@ -403,19 +403,17 @@ int compat_setup_rt_frame(int sig, struc
 	 * Set up registers for signal handler.
 	 * Registers that we don't modify keep the value they had from
 	 * user-space at the time we took the signal.
+	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
+	 * since some things rely on this (e.g. glibc's debug/segfault.c).
 	 */
 	regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
 	regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
 	regs->sp = ptr_to_compat_reg(frame);
 	regs->lr = restorer;
 	regs->regs[0] = (unsigned long) usig;
-
-	if (ka->sa.sa_flags & SA_SIGINFO) {
-		/* Need extra arguments, so mark to restore caller-saves. */
-		regs->regs[1] = ptr_to_compat_reg(&frame->info);
-		regs->regs[2] = ptr_to_compat_reg(&frame->uc);
-		regs->flags |= PT_FLAGS_CALLER_SAVES;
-	}
+	regs->regs[1] = ptr_to_compat_reg(&frame->info);
+	regs->regs[2] = ptr_to_compat_reg(&frame->uc);
+	regs->flags |= PT_FLAGS_CALLER_SAVES;
 
 	/*
 	 * Notify any tracer that was single-stepping it.
author maintainer
#25 lore raw

PATCH 25/47 crypto: mv_cesa requires on CRYPTO_HASH to build

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alexander Clouter <[email protected]>

commit 1ebfefcf37a6e308266a8d786e8cfea0a454058c upstream.

Without CRYPTO_HASH being selected, mv_cesa has a lot of hooks into undefined exports.
----
MODPOST 81 modules
Kernel: arch/arm/boot/Image is ready

  AS      arch/arm/boot/compressed/head.o
  GZIP    arch/arm/boot/compressed/piggy.gzip
  CC      arch/arm/boot/compressed/misc.o
  CC      arch/arm/boot/compressed/decompress.o

ERROR: "crypto_ahash_type" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_shash_final" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_register_ahash" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_unregister_ahash" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_shash_update" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_shash_digest" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_shash_setkey" [drivers/crypto/mv_cesa.ko] undefined!
ERROR: "crypto_alloc_shash" [drivers/crypto/mv_cesa.ko] undefined! make[1]: *** [__modpost] Error 1
make: *** [modules] Error 2
make: *** Waiting for unfinished jobs....
----

---
 drivers/crypto/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/crypto/Kconfig +1 -0
@@ -173,6 +173,7 @@ config CRYPTO_DEV_MV_CESA
 	select CRYPTO_ALGAPI
 	select CRYPTO_AES
 	select CRYPTO_BLKCIPHER2
+	select CRYPTO_HASH
 	help
 	  This driver allows you to utilize the Cryptographic Engines and
 	  Security Accelerator (CESA) which can be found on the Marvell Orion
author maintainer
#26 lore raw

PATCH 26/47 target: Drop incorrect se_lun_acl release for dynamic -> explict ACL conversion

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nicholas Bellinger <[email protected]>

commit cfebf8f42f47327fa54cf05c19b98f4bd5236a26 upstream.

This patch removes some potentially problematic legacy code within core_clear_initiator_node_from_tpg() that was originally intended to release left over se_lun_acl setup during dynamic NodeACL+MappedLUN generate when running with TPG demo-mode operation.

Since we now only ever expect to allocate and release se_lun_acl from within target_core_fabric_configfs.c:target_fabric_make_mappedlun() and target_fabric_drop_mappedlun() context respectively, this code for demo-mode release is incorrect and needs to be removed.

---
 drivers/target/target_core_tpg.c |   22 ----------------------
 1 file changed, 22 deletions(-)
drivers/target/target_core_tpg.c +0 -22
@@ -60,7 +60,6 @@ static void core_clear_initiator_node_fr
 	int i;
 	struct se_dev_entry *deve;
 	struct se_lun *lun;
-	struct se_lun_acl *acl, *acl_tmp;
 
 	spin_lock_irq(&nacl->device_list_lock);
 	for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
@@ -81,28 +80,7 @@ static void core_clear_initiator_node_fr
 		core_update_device_list_for_node(lun, NULL, deve->mapped_lun,
 			TRANSPORT_LUNFLAGS_NO_ACCESS, nacl, tpg, 0);
 
-		spin_lock(&lun->lun_acl_lock);
-		list_for_each_entry_safe(acl, acl_tmp,
-					&lun->lun_acl_list, lacl_list) {
-			if (!strcmp(acl->initiatorname, nacl->initiatorname) &&
-			    (acl->mapped_lun == deve->mapped_lun))
-				break;
-		}
-
-		if (!acl) {
-			pr_err("Unable to locate struct se_lun_acl for %s,"
-				" mapped_lun: %u\n", nacl->initiatorname,
-				deve->mapped_lun);
-			spin_unlock(&lun->lun_acl_lock);
-			spin_lock_irq(&nacl->device_list_lock);
-			continue;
-		}
-
-		list_del(&acl->lacl_list);
-		spin_unlock(&lun->lun_acl_lock);
-
 		spin_lock_irq(&nacl->device_list_lock);
-		kfree(acl);
 	}
 	spin_unlock_irq(&nacl->device_list_lock);
 }
author maintainer
#27 lore raw

PATCH 27/47 target: Fix SPC-2 RELEASE bug for multi-session iSCSI client setups

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bernhard Kohl <[email protected]>

commit edc318d9fea6854df752ec8c645b960b0d5a1d23 upstream.

This patch addresses a bug in a special case for target core SPC-2 RELEASE logic where the same physical client (eg: iSCSI InitiatorName) with differing iSCSI session identifiers (ISID) is allowed to incorrectly release the same client's SPC-2 reservation from the non reservation holding path.

Note this bug is specific to iscsi-target w/ SPC-2 reservations, and with the default enforce_pr_isids=1 device attr setting in target-core controls if a InitiatorName + different ISID reservations are handled the same as a single iSCSI client entity.

---
 drivers/target/target_core_pr.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/target/target_core_pr.c +3 -0
@@ -220,6 +220,9 @@ int target_scsi2_reservation_release(str
 	if (dev->dev_reserved_node_acl != sess->se_node_acl)
 		goto out_unlock;
 
+	if (dev->dev_res_bin_isid != sess->sess_bin_isid)
+		goto out_unlock;
+
 	dev->dev_reserved_node_acl = NULL;
 	dev->dev_flags &= ~DF_SPC2_RESERVATIONS;
 	if (dev->dev_flags & DF_SPC2_RESERVATIONS_WITH_ISID) {
author maintainer
#28 lore raw

PATCH 28/47 target: Fix bug in handling of FILEIO + block_device resize ops

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nicholas Bellinger <[email protected]>

commit cd9323fd68aee3c1c6b5b21e5746c9d1b586fb58 upstream.

This patch fixes a bug in the handling of FILEIO w/ underlying block_device resize operations where the original fd_dev->fd_dev_size was incorrectly being used in fd_get_blocks() for READ_CAPACITY response payloads.

This patch avoids using fd_dev->fd_dev_size for FILEIO devices with an underlying block_device, and instead changes fd_get_blocks() to get the sector count directly from i_size_read() as recommended by hch.

---
 drivers/target/target_core_file.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/target/target_core_file.c +16 -6
@@ -169,6 +169,7 @@ static struct se_device *fd_create_virtd
 	inode = file->f_mapping->host;
 	if (S_ISBLK(inode->i_mode)) {
 		struct request_queue *q;
+		unsigned long long dev_size;
 		/*
 		 * Setup the local scope queue_limits from struct request_queue->limits
 		 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
@@ -183,13 +184,12 @@ static struct se_device *fd_create_virtd
 		 * one (1) logical sector from underlying struct block_device
 		 */
 		fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
-		fd_dev->fd_dev_size = (i_size_read(file->f_mapping->host) -
+		dev_size = (i_size_read(file->f_mapping->host) -
 				       fd_dev->fd_block_size);
 
 		pr_debug("FILEIO: Using size: %llu bytes from struct"
 			" block_device blocks: %llu logical_block_size: %d\n",
-			fd_dev->fd_dev_size,
-			div_u64(fd_dev->fd_dev_size, fd_dev->fd_block_size),
+			dev_size, div_u64(dev_size, fd_dev->fd_block_size),
 			fd_dev->fd_block_size);
 	} else {
 		if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) {
@@ -605,10 +605,20 @@ static u32 fd_get_device_type(struct se_
 static sector_t fd_get_blocks(struct se_device *dev)
 {
 	struct fd_dev *fd_dev = dev->dev_ptr;
-	unsigned long long blocks_long = div_u64(fd_dev->fd_dev_size,
-			dev->se_sub_dev->se_dev_attrib.block_size);
+	struct file *f = fd_dev->fd_file;
+	struct inode *i = f->f_mapping->host;
+	unsigned long long dev_size;
+	/*
+	 * When using a file that references an underlying struct block_device,
+	 * ensure dev_size is always based on the current inode size in order
+	 * to handle underlying block_device resize operations.
+	 */
+	if (S_ISBLK(i->i_mode))
+		dev_size = (i_size_read(i) - fd_dev->fd_block_size);
+	else
+		dev_size = fd_dev->fd_dev_size;
 
-	return blocks_long;
+	return div_u64(dev_size, dev->se_sub_dev->se_dev_attrib.block_size);
 }
 
 static struct se_subsystem_api fileio_template = {
author maintainer
#29 lore raw

PATCH 29/47 virtio: console: tell host of open ports after resume from s3/s4

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Amit Shah <[email protected]>

commit fa8b66ccd2d200b64496cfedcce90bf54fe7d6e9 upstream.

If a port was open before going into one of the sleep states, the port can continue normal operation after restore. However, the host has to be told that the guest side of the connection is open to restore pre-suspend state.

This wasn't noticed so far due to a bug in qemu that was fixed recently (which marked the guest-side connection as always open).

---
 drivers/char/virtio_console.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/char/virtio_console.c +7 -0
@@ -1901,6 +1901,13 @@ static int virtcons_restore(struct virti
 
 		/* Get port open/close status on the host */
 		send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1);
+
+		/*
+		 * If a port was open at the time of suspending, we
+		 * have to let the host know that it's still open.
+		 */
+		if (port->guest_connected)
+			send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
 	}
 	return 0;
 }
author maintainer
#30 lore raw

PATCH 30/47 dm mpath: check if scsi_dh module already loaded before trying to load

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mike Snitzer <[email protected]>

commit 510193a2d3d2e03ae53b95c0ae4f33cdff02cbf8 upstream.

If the requested scsi_dh module is already loaded then skip request_module().

Multipath table loads can hang in an unnecessary __request_module.

---
 drivers/md/dm-mpath.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/dm-mpath.c +2 -2
@@ -698,8 +698,8 @@ static int parse_hw_handler(struct dm_ar
 		return 0;
 
 	m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL);
-	request_module("scsi_dh_%s", m->hw_handler_name);
-	if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
+	if (!try_then_request_module(scsi_dh_handler_exist(m->hw_handler_name),
+				     "scsi_dh_%s", m->hw_handler_name)) {
 		ti->error = "unknown hardware handler type";
 		ret = -EINVAL;
 		goto fail;
author maintainer
#31 lore raw

PATCH 31/47 e1000: Prevent reset task killing itself.

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tushar Dave <[email protected]>

commit 8ce6909f77ba1b7bcdea65cc2388fd1742b6d669 upstream.

Killing reset task while adapter is resetting causes deadlock. Only kill reset task if adapter is not resetting. Ref bug #43132 on bugzilla.kernel.org

---
 drivers/net/ethernet/intel/e1000/e1000_main.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/ethernet/intel/e1000/e1000_main.c +5 -1
@@ -492,7 +492,11 @@ out:
 static void e1000_down_and_stop(struct e1000_adapter *adapter)
 {
 	set_bit(__E1000_DOWN, &adapter->flags);
-	cancel_work_sync(&adapter->reset_task);
+
+	/* Only kill reset task if adapter is not resetting */
+	if (!test_bit(__E1000_RESETTING, &adapter->flags))
+		cancel_work_sync(&adapter->reset_task);
+
 	cancel_delayed_work_sync(&adapter->watchdog_task);
 	cancel_delayed_work_sync(&adapter->phy_info_task);
 	cancel_delayed_work_sync(&adapter->fifo_stall_task);
author maintainer
#32 lore raw

PATCH 32/47 MD: Add del_timer_sync to mddev_suspend (fix nasty panic)

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jonathan Brassow <[email protected]>

commit 0d9f4f135eb6dea06bdcb7065b1e4ff78274a5e9 upstream.

Use del_timer_sync to remove timer before mddev_suspend finishes.

We don't want a timer going off after an mddev_suspend is called. This is especially true with device-mapper, since it can call the destructor function immediately following a suspend. This results in the removal (kfree) of the structures upon which the timer depends - resulting in a very ugly panic. Therefore, we add a del_timer_sync to mddev_suspend to prevent this.

---
 drivers/md/md.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/md/md.c +2 -0
@@ -391,6 +391,8 @@ void mddev_suspend(struct mddev *mddev)
 	synchronize_rcu();
 	wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
 	mddev->pers->quiesce(mddev, 1);
+
+	del_timer_sync(&mddev->safemode_timer);
 }
 EXPORT_SYMBOL_GPL(mddev_suspend);
 
author maintainer
#33 lore raw

PATCH 33/47 tcp: do_tcp_sendpages() must try to push data out on oom conditions

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Willy Tarreau <[email protected]>

commit bad115cfe5b509043b684d3a007ab54b80090aa1 upstream.

Since recent changes on TCP splicing (starting with commits 2f533844 "tcp: allow splice() to build full TSO packets" and 35f9c09f "tcp:
tcp_sendpages() should call tcp_push() once"), I started seeing massive stalls when forwarding traffic between two sockets using splice() when pipe buffers were larger than socket buffers.

Latest changes (net: netdev_alloc_skb() use build_skb()) made the problem even more apparent.

The reason seems to be that if do_tcp_sendpages() fails on out of memory condition without being able to send at least one byte, tcp_push() is not called and the buffers cannot be flushed.

After applying the attached patch, I cannot reproduce the stalls at all and the data rate it perfectly stable and steady under any condition which previously caused the problem to be permanent.

The issue seems to have been there since before the kernel migrated to git, which makes me think that the stalls I occasionally experienced with tux during stress-tests years ago were probably related to the same issue.

This issue was first encountered on 3.0.31 and 3.2.17, so please backport to -stable.

---
 net/ipv4/tcp.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
net/ipv4/tcp.c +1 -2
@@ -849,8 +849,7 @@ new_segment:
 wait_for_sndbuf:
 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 wait_for_memory:
-		if (copied)
-			tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
+		tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH);
 
 		if ((err = sk_stream_wait_memory(sk, &timeo)) != 0)
 			goto do_error;
author maintainer
#34 lore raw

PATCH 34/47 init: dont try mounting device as nfs root unless type fully matches

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sasha Levin <[email protected]>

commit 377485f6244af255b04d662cf19cddbbc4ae4310 upstream.

Currently, we'll try mounting any device who's major device number is UNNAMED_MAJOR as NFS root. This would happen for non-NFS devices as well (such as 9p devices) but it wouldn't cause any issues since mounting the device as NFS would fail quickly and the code proceeded to doing the proper mount:

       [  101.522716] VFS: Unable to mount root fs via NFS, trying floppy.
       [  101.534499] VFS: Mounted root (9p filesystem) on device 0:18.

Commit 6829a048102a ("NFS: Retry mounting NFSROOT") introduced retries when mounting NFS root, which means that now we don't immediately fail and instead it takes an additional 90+ seconds until we stop retrying, which has revealed the issue this patch fixes.

This meant that it would take an additional 90 seconds to boot when we're not using a device type which gets detected in order before NFS.

This patch modifies the NFS type check to require device type to be 'Root_NFS' instead of requiring the device to have an UNNAMED_MAJOR major. This makes boot process cleaner since we now won't go through the NFS mounting code at all when the device isn't an NFS root ("/dev/nfs").

---
 init/do_mounts.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
init/do_mounts.c +1 -1
@@ -472,7 +472,7 @@ void __init change_floppy(char *fmt, ...
 void __init mount_root(void)
 {
 #ifdef CONFIG_ROOT_NFS
-	if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
+	if (ROOT_DEV == Root_NFS) {
 		if (mount_nfs_root())
 			return;
 
author maintainer
#35 lore raw

PATCH 35/47 ext4: avoid deadlock on sync-mounted FS w/o journal

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Sandeen <[email protected]>

commit c1bb05a657fb3d8c6179a4ef7980261fae4521d7 upstream.

Processes hang forever on a sync-mounted ext2 file system that is mounted with the ext4 module (default in Fedora 16).

I can reproduce this reliably by mounting an ext2 partition with "-o sync" and opening a new file an that partition with vim. vim will hang in "D" state forever. The same happens on ext4 without a journal.

I am attaching a small patch here that solves this issue for me. In the sync mounted case without a journal, ext4_handle_dirty_metadata() may call sync_dirty_buffer(), which can't be called with buffer lock held.

Also move mb_cache_entry_release inside lock to avoid race fixed previously by 8a2bfdcb ext[34]: EA block reference count racing fix Note too that ext2 fixed this same problem in 2006 with b2f49033 [PATCH] fix deadlock in ext2

Signed-off-by [email protected]
[[email protected]: move mb_cache_entry_release before unlock, edit commit msg]
---
 fs/ext4/xattr.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
fs/ext4/xattr.c +4 -3
@@ -487,18 +487,19 @@ ext4_xattr_release_block(handle_t *handl
 		ext4_free_blocks(handle, inode, bh, 0, 1,
 				 EXT4_FREE_BLOCKS_METADATA |
 				 EXT4_FREE_BLOCKS_FORGET);
+		unlock_buffer(bh);
 	} else {
 		le32_add_cpu(&BHDR(bh)->h_refcount, -1);
+		if (ce)
+			mb_cache_entry_release(ce);
+		unlock_buffer(bh);
 		error = ext4_handle_dirty_metadata(handle, inode, bh);
 		if (IS_SYNC(inode))
 			ext4_handle_sync(handle);
 		dquot_free_block(inode, 1);
 		ea_bdebug(bh, "refcount now=%d; releasing",
 			  le32_to_cpu(BHDR(bh)->h_refcount));
-		if (ce)
-			mb_cache_entry_release(ce);
 	}
-	unlock_buffer(bh);
 out:
 	ext4_std_error(inode->i_sb, error);
 	return;
author maintainer
#36 lore raw

PATCH 36/47 memcg: free spare array to avoid memory leak

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sha Zhengju <[email protected]>

commit 8c7577637ca31385e92769a77e2ab5b428e8b99c upstream.

When the last event is unregistered, there is no need to keep the spare array anymore. So free it to avoid memory leak.

---
 mm/memcontrol.c |    6 ++++++
 1 file changed, 6 insertions(+)
mm/memcontrol.c +6 -0
@@ -4480,6 +4480,12 @@ static void mem_cgroup_usage_unregister_
 swap_buffers:
 	/* Swap primary and spare array */
 	thresholds->spare = thresholds->primary;
+	/* If all events are unregistered, free the spare array */
+	if (!new) {
+		kfree(thresholds->spare);
+		thresholds->spare = NULL;
+	}
+
 	rcu_assign_pointer(thresholds->primary, new);
 
 	/* To be sure that nobody uses thresholds */
author maintainer
#37 lore raw

PATCH 37/47 cifs: fix revalidation test in cifs_llseek()

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dan Carpenter <[email protected]>

commit 48a5730e5b71201e226ff06e245bf308feba5f10 upstream.

This test is always true so it means we revalidate the length every time, which generates more network traffic. When it is SEEK_SET or SEEK_CUR, then we don't need to revalidate.

---
 fs/cifs/cifsfs.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cifs/cifsfs.c +1 -1
@@ -703,7 +703,7 @@ static loff_t cifs_llseek(struct file *f
 	 * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
 	 * the cached file length
 	 */
-	if (origin != SEEK_SET || origin != SEEK_CUR) {
+	if (origin != SEEK_SET && origin != SEEK_CUR) {
 		int rc;
 		struct inode *inode = file->f_path.dentry->d_inode;
 
author maintainer
#38 lore raw

PATCH 38/47 compat: Fix RT signal mask corruption via sigprocmask

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jan Kiszka <[email protected]>

commit b7dafa0ef3145c31d7753be0a08b3cbda51f0209 upstream.

compat_sys_sigprocmask reads a smaller signal mask from userspace than sigprogmask accepts for setting. So the high word of blocked.sig[0] will be cleared, releasing any potentially blocked RT signal.

This was discovered via userspace code that relies on get/setcontext. glibc's i386 versions of those functions use sigprogmask instead of rt_sigprogmask to save/restore signal mask and caused RT signal unblocking this way.

As suggested by Linus, this replaces the sys_sigprocmask based compat version with one that open-codes the required logic, including the merge of the existing blocked set with the new one provided on SIG_SETMASK.

---
 kernel/compat.c |   65 ++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 47 insertions(+), 18 deletions(-)
kernel/compat.c +47 -18
@@ -320,25 +320,54 @@ asmlinkage long compat_sys_sigpending(co
 
 #ifdef __ARCH_WANT_SYS_SIGPROCMASK
 
-asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set,
-		compat_old_sigset_t __user *oset)
+/*
+ * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
+ * blocked set of signals to the supplied signal set
+ */
+static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
 {
-	old_sigset_t s;
-	long ret;
-	mm_segment_t old_fs;
-
-	if (set && get_user(s, set))
-		return -EFAULT;
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = sys_sigprocmask(how,
-			      set ? (old_sigset_t __user *) &s : NULL,
-			      oset ? (old_sigset_t __user *) &s : NULL);
-	set_fs(old_fs);
-	if (ret == 0)
-		if (oset)
-			ret = put_user(s, oset);
-	return ret;
+	memcpy(blocked->sig, &set, sizeof(set));
+}
+
+asmlinkage long compat_sys_sigprocmask(int how,
+				       compat_old_sigset_t __user *nset,
+				       compat_old_sigset_t __user *oset)
+{
+	old_sigset_t old_set, new_set;
+	sigset_t new_blocked;
+
+	old_set = current->blocked.sig[0];
+
+	if (nset) {
+		if (get_user(new_set, nset))
+			return -EFAULT;
+		new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
+
+		new_blocked = current->blocked;
+
+		switch (how) {
+		case SIG_BLOCK:
+			sigaddsetmask(&new_blocked, new_set);
+			break;
+		case SIG_UNBLOCK:
+			sigdelsetmask(&new_blocked, new_set);
+			break;
+		case SIG_SETMASK:
+			compat_sig_setmask(&new_blocked, new_set);
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		set_current_blocked(&new_blocked);
+	}
+
+	if (oset) {
+		if (put_user(old_set, oset))
+			return -EFAULT;
+	}
+
+	return 0;
 }
 
 #endif
author maintainer
#39 lore raw

PATCH 39/47 dl2k: Clean up rio_ioctl

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jeff Mahoney <[email protected]>

commit 1bb57e940e1958e40d51f2078f50c3a96a9b2d75 upstream.

The dl2k driver's rio_ioctl call has a few issues:
- No permissions checking
- Implements SIOCGMIIREG and SIOCGMIIREG using the SIOCDEVPRIVATE numbers
- Has a few ioctls that may have been used for debugging at one point but have no place in the kernel proper.

This patch removes all but the MII ioctls, renumbers them to use the standard ones, and adds the proper permission check for SIOCSMIIREG.

We can also get rid of the dl2k-specific struct mii_data in favor of the generic struct mii_ioctl_data.

Since we have the phyid on hand, we can add the SIOCGMIIPHY ioctl too.

Most of the MII code for the driver could probably be converted to use the generic MII library but I don't have a device to test the results.

---
 drivers/net/ethernet/dlink/dl2k.c |   52 ++++++--------------------------------
 drivers/net/ethernet/dlink/dl2k.h |    7 -----
 2 files changed, 9 insertions(+), 50 deletions(-)
drivers/net/ethernet/dlink/dl2k.c +9 -43
@@ -1259,55 +1259,21 @@ rio_ioctl (struct net_device *dev, struc
 {
 	int phy_addr;
 	struct netdev_private *np = netdev_priv(dev);
-	struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
-
-	struct netdev_desc *desc;
-	int i;
+	struct mii_ioctl_data *miidata = if_mii(rq);
 
 	phy_addr = np->phy_addr;
 	switch (cmd) {
-	case SIOCDEVPRIVATE:
-		break;
-
-	case SIOCDEVPRIVATE + 1:
-		miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
-		break;
-	case SIOCDEVPRIVATE + 2:
-		mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
-		break;
-	case SIOCDEVPRIVATE + 3:
+	case SIOCGMIIPHY:
+		miidata->phy_id = phy_addr;
 		break;
-	case SIOCDEVPRIVATE + 4:
+	case SIOCGMIIREG:
+		miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num);
 		break;
-	case SIOCDEVPRIVATE + 5:
-		netif_stop_queue (dev);
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in);
 		break;
-	case SIOCDEVPRIVATE + 6:
-		netif_wake_queue (dev);
-		break;
-	case SIOCDEVPRIVATE + 7:
-		printk
-		    ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
-		     netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
-		     np->old_rx);
-		break;
-	case SIOCDEVPRIVATE + 8:
-		printk("TX ring:\n");
-		for (i = 0; i < TX_RING_SIZE; i++) {
-			desc = &np->tx_ring[i];
-			printk
-			    ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
-			     i,
-			     (u32) (np->tx_ring_dma + i * sizeof (*desc)),
-			     (u32)le64_to_cpu(desc->next_desc),
-			     (u32)le64_to_cpu(desc->status),
-			     (u32)(le64_to_cpu(desc->fraginfo) >> 32),
-			     (u32)le64_to_cpu(desc->fraginfo));
-			printk ("\n");
-		}
-		printk ("\n");
-		break;
-
 	default:
 		return -EOPNOTSUPP;
 	}
drivers/net/ethernet/dlink/dl2k.h +0 -7
@@ -365,13 +365,6 @@ struct ioctl_data {
 	char *data;
 };
 
-struct mii_data {
-	__u16 reserved;
-	__u16 reg_num;
-	__u16 in_value;
-	__u16 out_value;
-};
-
 /* The Rx and Tx buffer descriptors. */
 struct netdev_desc {
 	__le64 next_desc;
author maintainer
#40 lore raw

PATCH 40/47 OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on OMAP4

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Danny Kukawka <[email protected]>

commit cc1d3e032df53d83d0ca4d537d8eb67eb5b3e808 upstream.

Commit ba02fa37de80bea10d706f39f076dd848348320a disabled the venc driver registration on OMAP4. Since the driver never gets probed/initialised your get a dereferenceed NULL pointer if you try to get info from /sys/kernel/debug/omapdss/venc

Return info message about disabled venc if venc_dump_regs() gets called.

---
 drivers/video/omap2/dss/venc.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/video/omap2/dss/venc.c +5 -0
@@ -699,6 +699,11 @@ void venc_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
+	if (cpu_is_omap44xx()) {
+		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
+		return;
+	}
+
 	if (venc_runtime_get())
 		return;
 
author maintainer
#41 lore raw

PATCH 41/47 i2c-eg20t: change timeout value 50msec to 1000msec

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tomoya MORINAGA <[email protected]>

commit 8a52f9f347da721b199b7f9dcc0168bbe7d0baae upstream.

Currently, during i2c works alone, wait-event timeout is not occurred. However, as CPU load increases, timeout occurs frequently. So, I modified like this patch.
Modifying like this patch, I've never seen the timeout event with high load test.

---
 drivers/i2c/busses/i2c-eg20t.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-eg20t.c +1 -1
@@ -318,7 +318,7 @@ static s32 pch_i2c_wait_for_xfer_complet
 {
 	long ret;
 	ret = wait_event_timeout(pch_event,
-			(adap->pch_event_flag != 0), msecs_to_jiffies(50));
+			(adap->pch_event_flag != 0), msecs_to_jiffies(1000));
 
 	if (ret == 0) {
 		pch_err(adap, "timeout: %x\n", adap->pch_event_flag);
author maintainer
#42 lore raw

PATCH 42/47 spi-topcliff-pch: Modify pci-bus number dynamically to get DMA device info

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tomoya MORINAGA <[email protected]>

commit ee2ece5261a639b89f194d141444b03b4c923179 upstream.

---
 drivers/spi/spi-topcliff-pch.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/spi/spi-topcliff-pch.c +2 -1
@@ -924,7 +924,8 @@ static void pch_spi_request_dma(struct p
 	dma_cap_set(DMA_SLAVE, mask);
 
 	/* Get DMA's dev information */
-	dma_dev = pci_get_bus_and_slot(2, PCI_DEVFN(12, 0));
+	dma_dev = pci_get_bus_and_slot(data->board_dat->pdev->bus->number,
+				       PCI_DEVFN(12, 0));
 
 	/* Set Tx DMA */
 	param = &dma->param_tx;
author maintainer
#43 lore raw

PATCH 43/47 spi-topcliff-pch: Fix issue for transmitting over 4KByte

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tomoya MORINAGA <[email protected]>

commit 7d05b3e868ee0f9231baf40cb77be3df5dd1f18c upstream.

Currently, when spi-topcliff-pch receives transmit request over 4KByte, this driver can't process correctly. This driver needs to divide the data into 4Kbyte unit.
This patch fixes the issue.

---
 drivers/spi/spi-topcliff-pch.c |   66 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 55 insertions(+), 11 deletions(-)
drivers/spi/spi-topcliff-pch.c +55 -11
@@ -196,6 +196,7 @@ struct pch_spi_data {
 	struct pch_spi_dma_ctrl dma;
 	int use_dma;
 	u8 irq_reg_sts;
+	int save_total_len;
 };
 
 /**
@@ -823,11 +824,13 @@ static void pch_spi_copy_rx_data_for_dma
 		rx_dma_buf = data->dma.rx_buf_virt;
 		for (j = 0; j < data->bpw_len; j++)
 			*rx_buf++ = *rx_dma_buf++ & 0xFF;
+		data->cur_trans->rx_buf = rx_buf;
 	} else {
 		rx_sbuf = data->cur_trans->rx_buf;
 		rx_dma_sbuf = data->dma.rx_buf_virt;
 		for (j = 0; j < data->bpw_len; j++)
 			*rx_sbuf++ = *rx_dma_sbuf++;
+		data->cur_trans->rx_buf = rx_sbuf;
 	}
 }
 
@@ -853,6 +856,9 @@ static int pch_spi_start_transfer(struct
 	rtn = wait_event_interruptible_timeout(data->wait,
 					       data->transfer_complete,
 					       msecs_to_jiffies(2 * HZ));
+	if (!rtn)
+		dev_err(&data->master->dev,
+			"%s wait-event timeout\n", __func__);
 
 	dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent,
 			    DMA_FROM_DEVICE);
@@ -989,6 +995,7 @@ static void pch_spi_handle_dma(struct pc
 	int i;
 	int size;
 	int rem;
+	int head;
 	unsigned long flags;
 	struct pch_spi_dma_ctrl *dma;
 
@@ -1017,6 +1024,11 @@ static void pch_spi_handle_dma(struct pc
 	}
 	data->bpw_len = data->cur_trans->len / (*bpw / 8);
 
+	if (data->bpw_len > PCH_BUF_SIZE) {
+		data->bpw_len = PCH_BUF_SIZE;
+		data->cur_trans->len -= PCH_BUF_SIZE;
+	}
+
 	/* copy Tx Data */
 	if (data->cur_trans->tx_buf != NULL) {
 		if (*bpw == 8) {
@@ -1031,10 +1043,17 @@ static void pch_spi_handle_dma(struct pc
 				*tx_dma_sbuf++ = *tx_sbuf++;
 		}
 	}
+
+	/* Calculate Rx parameter for DMA transmitting */
 	if (data->bpw_len > PCH_DMA_TRANS_SIZE) {
-		num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1;
+		if (data->bpw_len % PCH_DMA_TRANS_SIZE) {
+			num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1;
+			rem = data->bpw_len % PCH_DMA_TRANS_SIZE;
+		} else {
+			num = data->bpw_len / PCH_DMA_TRANS_SIZE;
+			rem = PCH_DMA_TRANS_SIZE;
+		}
 		size = PCH_DMA_TRANS_SIZE;
-		rem = data->bpw_len % PCH_DMA_TRANS_SIZE;
 	} else {
 		num = 1;
 		size = data->bpw_len;
@@ -1094,15 +1113,23 @@ static void pch_spi_handle_dma(struct pc
 	dma->nent = num;
 	dma->desc_rx = desc_rx;
 
-	/* TX */
-	if (data->bpw_len > PCH_DMA_TRANS_SIZE) {
-		num = data->bpw_len / PCH_DMA_TRANS_SIZE;
+	/* Calculate Tx parameter for DMA transmitting */
+	if (data->bpw_len > PCH_MAX_FIFO_DEPTH) {
+		head = PCH_MAX_FIFO_DEPTH - PCH_DMA_TRANS_SIZE;
+		if (data->bpw_len % PCH_DMA_TRANS_SIZE > 4) {
+			num = data->bpw_len / PCH_DMA_TRANS_SIZE + 1;
+			rem = data->bpw_len % PCH_DMA_TRANS_SIZE - head;
+		} else {
+			num = data->bpw_len / PCH_DMA_TRANS_SIZE;
+			rem = data->bpw_len % PCH_DMA_TRANS_SIZE +
+			      PCH_DMA_TRANS_SIZE - head;
+		}
 		size = PCH_DMA_TRANS_SIZE;
-		rem = 16;
 	} else {
 		num = 1;
 		size = data->bpw_len;
 		rem = data->bpw_len;
+		head = 0;
 	}
 
 	dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC);
@@ -1112,11 +1139,17 @@ static void pch_spi_handle_dma(struct pc
 	for (i = 0; i < num; i++, sg++) {
 		if (i == 0) {
 			sg->offset = 0;
+			sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size + head,
+				    sg->offset);
+			sg_dma_len(sg) = size + head;
+		} else if (i == (num - 1)) {
+			sg->offset = head + size * i;
+			sg->offset = sg->offset * (*bpw / 8);
 			sg_set_page(sg, virt_to_page(dma->tx_buf_virt), rem,
 				    sg->offset);
 			sg_dma_len(sg) = rem;
 		} else {
-			sg->offset = rem + size * (i - 1);
+			sg->offset = head + size * i;
 			sg->offset = sg->offset * (*bpw / 8);
 			sg_set_page(sg, virt_to_page(dma->tx_buf_virt), size,
 				    sg->offset);
@@ -1204,6 +1237,7 @@ static void pch_spi_process_messages(str
 				    data->current_msg->spi->bits_per_word);
 	pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL);
 	do {
+		int cnt;
 		/* If we are already processing a message get the next
 		transfer structure from the message otherwise retrieve
 		the 1st transfer request from the message. */
@@ -1223,11 +1257,20 @@ static void pch_spi_process_messages(str
 		}
 		spin_unlock(&data->lock);
 
+		if (!data->cur_trans->len)
+			goto out;
+		cnt = (data->cur_trans->len - 1) / PCH_BUF_SIZE + 1;
+		data->save_total_len = data->cur_trans->len;
 		if (data->use_dma) {
-			pch_spi_handle_dma(data, &bpw);
-			if (!pch_spi_start_transfer(data))
-				goto out;
-			pch_spi_copy_rx_data_for_dma(data, bpw);
+			int i;
+			char *save_rx_buf = data->cur_trans->rx_buf;
+			for (i = 0; i < cnt; i ++) {
+				pch_spi_handle_dma(data, &bpw);
+				if (!pch_spi_start_transfer(data))
+					goto out;
+				pch_spi_copy_rx_data_for_dma(data, bpw);
+			}
+			data->cur_trans->rx_buf = save_rx_buf;
 		} else {
 			pch_spi_set_tx(data, &bpw);
 			pch_spi_set_ir(data);
@@ -1238,6 +1281,7 @@ static void pch_spi_process_messages(str
 			data->pkt_tx_buff = NULL;
 		}
 		/* increment message count */
+		data->cur_trans->len = data->save_total_len;
 		data->current_msg->actual_length += data->cur_trans->len;
 
 		dev_dbg(&data->master->dev,
author maintainer
#44 lore raw

PATCH 44/47 spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tomoya MORINAGA <[email protected]>

commit f258b44e22e07f5e98ac2260c70acff5784791b6 upstream.

This patch supports a spi mode setup and bit order setup by IO control.
spi mode: mode 0 to mode 3
bit order: LSB first, MSB first

---
 drivers/spi/spi-topcliff-pch.c |    1 +
 1 file changed, 1 insertion(+)
drivers/spi/spi-topcliff-pch.c +1 -0
@@ -1434,6 +1434,7 @@ static int __devinit pch_spi_pd_probe(st
 	master->num_chipselect = PCH_MAX_CS;
 	master->setup = pch_spi_setup;
 	master->transfer = pch_spi_transfer;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
 
 	data->board_dat = board_dat;
 	data->plat_dev = plat_dev;
author maintainer
#45 lore raw

PATCH 45/47 spi-topcliff-pch: add recovery processing in case wait-event timeout

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tomoya MORINAGA <[email protected]>

commit 0f57e168aa109775430c76cc663fb64909813d84 upstream.

Currently, pch_spi_start_transfer failure is not anticipated. This patch adds the processing.

---
 drivers/spi/spi-topcliff-pch.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/spi/spi-topcliff-pch.c +9 -1
@@ -1266,8 +1266,16 @@ static void pch_spi_process_messages(str
 			char *save_rx_buf = data->cur_trans->rx_buf;
 			for (i = 0; i < cnt; i ++) {
 				pch_spi_handle_dma(data, &bpw);
-				if (!pch_spi_start_transfer(data))
+				if (!pch_spi_start_transfer(data)) {
+					data->transfer_complete = true;
+					data->current_msg->status = -EIO;
+					data->current_msg->complete
+						   (data->current_msg->context);
+					data->bcurrent_msg_processing = false;
+					data->current_msg = NULL;
+					data->cur_trans = NULL;
 					goto out;
+				}
 				pch_spi_copy_rx_data_for_dma(data, bpw);
 			}
 			data->cur_trans->rx_buf = save_rx_buf;
author maintainer
#46 lore raw

PATCH 46/47 Avoid beyond bounds copy while caching ACL

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sachin Prabhu <[email protected]>

commit 5794d21ef4639f0e33440927bb903f9598c21e92 upstream.

When attempting to cache ACLs returned from the server, if the bitmap size + the ACL size is greater than a PAGE_SIZE but the ACL size itself is smaller than a PAGE_SIZE, we can read past the buffer page boundary.

---
 fs/nfs/nfs4proc.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
fs/nfs/nfs4proc.c +5 -7
@@ -3532,16 +3532,16 @@ out:
 	return ret;
 }
 
-static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len)
+static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len)
 {
 	struct nfs4_cached_acl *acl;
 
-	if (buf && acl_len <= PAGE_SIZE) {
+	if (pages && acl_len <= PAGE_SIZE) {
 		acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
 		if (acl == NULL)
 			goto out;
 		acl->cached = 1;
-		memcpy(acl->data, buf, acl_len);
+		_copy_from_pages(acl->data, pages, pgbase, acl_len);
 	} else {
 		acl = kmalloc(sizeof(*acl), GFP_KERNEL);
 		if (acl == NULL)
@@ -3574,7 +3574,6 @@ static ssize_t __nfs4_get_acl_uncached(s
 	struct nfs_getaclres res = {
 		.acl_len = buflen,
 	};
-	void *resp_buf;
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
 		.rpc_argp = &args,
@@ -3605,7 +3604,6 @@ static ssize_t __nfs4_get_acl_uncached(s
 	 * the page we send as a guess */
 	if (buf == NULL)
 		res.acl_flags |= NFS4_ACL_LEN_REQUEST;
-	resp_buf = page_address(pages[0]);
 
 	dprintk("%s  buf %p buflen %zu npages %d args.acl_len %zu\n",
 		__func__, buf, buflen, npages, args.acl_len);
@@ -3616,9 +3614,9 @@ static ssize_t __nfs4_get_acl_uncached(s
 
 	acl_len = res.acl_len - res.acl_data_offset;
 	if (acl_len > args.acl_len)
-		nfs4_write_cached_acl(inode, NULL, acl_len);
+		nfs4_write_cached_acl(inode, NULL, 0, acl_len);
 	else
-		nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset,
+		nfs4_write_cached_acl(inode, pages, res.acl_data_offset,
 				      acl_len);
 	if (buf) {
 		ret = -ERANGE;
author maintainer
#47 lore raw

PATCH 47/47 Avoid reading past buffer when calling GETACL

In reply to Greg KH

3.3-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sachin Prabhu <[email protected]>

commit 5a00689930ab975fdd1b37b034475017e460cf2a upstream.

Bug noticed in commit
bf118a342f10dafe44b14451a1392c3254629a1f

When calling GETACL, if the size of the bitmap array, the length attribute and the acl returned by the server is greater than the allocated buffer(args.acl_len), we can Oops with a General Protection fault at _copy_from_pages() when we attempt to read past the pages allocated.

This patch allocates an extra PAGE for the bitmap and checks to see that the bitmap + attribute_length + ACLs don't exceed the buffer space allocated to it.

[Trond: Fixed a size_t vs unsigned int printk() warning]
---
 fs/nfs/nfs4proc.c |   16 ++++++++++------
 fs/nfs/nfs4xdr.c  |   18 +++++++++++-------
 2 files changed, 21 insertions(+), 13 deletions(-)
fs/nfs/nfs4proc.c +10 -6
@@ -3587,19 +3587,23 @@ static ssize_t __nfs4_get_acl_uncached(s
 	if (npages == 0)
 		npages = 1;
 
+	/* Add an extra page to handle the bitmap returned */
+	npages++;
+
 	for (i = 0; i < npages; i++) {
 		pages[i] = alloc_page(GFP_KERNEL);
 		if (!pages[i])
 			goto out_free;
 	}
-	if (npages > 1) {
-		/* for decoding across pages */
-		res.acl_scratch = alloc_page(GFP_KERNEL);
-		if (!res.acl_scratch)
-			goto out_free;
-	}
+
+	/* for decoding across pages */
+	res.acl_scratch = alloc_page(GFP_KERNEL);
+	if (!res.acl_scratch)
+		goto out_free;
+
 	args.acl_len = npages * PAGE_SIZE;
 	args.acl_pgbase = 0;
+
 	/* Let decode_getfacl know not to fail if the ACL data is larger than
 	 * the page we send as a guess */
 	if (buf == NULL)
fs/nfs/nfs4xdr.c +11 -7
@@ -4975,11 +4975,19 @@ static int decode_getacl(struct xdr_stre
 		 bitmap[3] = {0};
 	struct kvec *iov = req->rq_rcv_buf.head;
 	int status;
+	size_t page_len = xdr->buf->page_len;
 
 	res->acl_len = 0;
 	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
 		goto out;
+
 	bm_p = xdr->p;
+	res->acl_data_offset = be32_to_cpup(bm_p) + 2;
+	res->acl_data_offset <<= 2;
+	/* Check if the acl data starts beyond the allocated buffer */
+	if (res->acl_data_offset > page_len)
+		return -ERANGE;
+
 	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
 		goto out;
 	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
@@ -4989,28 +4997,24 @@ static int decode_getacl(struct xdr_stre
 		return -EIO;
 	if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
 		size_t hdrlen;
-		u32 recvd;
 
 		/* The bitmap (xdr len + bitmaps) and the attr xdr len words
 		 * are stored with the acl data to handle the problem of
 		 * variable length bitmaps.*/
 		xdr->p = bm_p;
-		res->acl_data_offset = be32_to_cpup(bm_p) + 2;
-		res->acl_data_offset <<= 2;
 
 		/* We ignore &savep and don't do consistency checks on
 		 * the attr length.  Let userspace figure it out.... */
 		hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
 		attrlen += res->acl_data_offset;
-		recvd = req->rq_rcv_buf.len - hdrlen;
-		if (attrlen > recvd) {
+		if (attrlen > page_len) {
 			if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
 				/* getxattr interface called with a NULL buf */
 				res->acl_len = attrlen;
 				goto out;
 			}
-			dprintk("NFS: acl reply: attrlen %u > recvd %u\n",
-					attrlen, recvd);
+			dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
+					attrlen, page_len);
 			return -EINVAL;
 		}
 		xdr_read_pages(xdr, attrlen);