Skip to contentSkip to conversation

3.0.16-stable review

PATCH In review Greg KH 3 participants 82 messages Jan 3, 2012 – Jan 5, 2012

Subsystems (51)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

cover 3.0.16-stable review

This is the start of the stable review cycle for the 3.0.16 release. There are 67 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 us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.

Responses should be made by Friday, January 6, 2012, 20:00:00 UTC. 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.0.16-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

 Makefile                                     |    4 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
 arch/arm/oprofile/common.c                   |    2 +-
 arch/arm/plat-mxc/pwm.c                      |   16 +-
 arch/s390/oprofile/init.c                    |    2 +-
 arch/sh/oprofile/common.c                    |    4 +-
 arch/sparc/include/asm/pgtable_32.h          |   20 +-
 arch/sparc/include/asm/pgtable_64.h          |   20 +-
 arch/sparc/kernel/entry.h                    |    7 +
 arch/sparc/kernel/module.c                   |   27 +
 arch/sparc/kernel/pci_sun4v.c                |    4 +-
 arch/sparc/kernel/setup_64.c                 |   48 +-
 arch/sparc/kernel/signal32.c                 |   18 +-
 arch/sparc/kernel/signal_32.c                |   30 +-
 arch/sparc/kernel/signal_64.c                |   42 +-
 arch/sparc/kernel/visemul.c                  |   32 +-
 arch/sparc/lib/memcpy.S                      |  804 ++++----------------------
 arch/sparc/mm/Makefile                       |    1 -
 arch/sparc/mm/btfixup.c                      |    3 +-
 arch/sparc/mm/generic_32.c                   |   98 ----
 arch/sparc/mm/generic_64.c                   |  164 ------
 arch/x86/net/bpf_jit_comp.c                  |    4 +-
 block/blk-core.c                             |   14 +-
 block/cfq-iosched.c                          |   16 +-
 drivers/gpu/drm/i915/i915_dma.c              |   10 +
 drivers/gpu/drm/i915/i915_drv.h              |    1 +
 drivers/gpu/drm/radeon/evergreen.c           |   12 +
 drivers/input/mouse/synaptics.c              |   11 +
 drivers/media/video/s5p-fimc/fimc-core.c     |    2 +-
 drivers/mfd/twl-core.c                       |   16 +-
 drivers/mfd/twl4030-madc.c                   |   35 +-
 drivers/mmc/host/mmci.c                      |   14 +-
 drivers/mmc/host/vub300.c                    |    2 +-
 drivers/net/pptp.c                           |    4 +-
 drivers/net/wireless/ath/ath9k/rc.c          |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c  |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn-tx.c    |   10 +-
 drivers/oprofile/oprofile_files.c            |    7 +-
 drivers/oprofile/oprofilefs.c                |   11 +-
 drivers/rtc/interface.c                      |    6 +
 drivers/rtc/rtc-m41t80.c                     |    9 +
 drivers/s390/scsi/zfcp_scsi.c                |    4 +
 drivers/scsi/fcoe/fcoe.c                     |    1 +
 drivers/scsi/mpt2sas/mpt2sas_base.c          |    6 +-
 drivers/scsi/mpt2sas/mpt2sas_base.h          |    2 +-
 drivers/scsi/mpt2sas/mpt2sas_scsih.c         |    2 +-
 drivers/ssb/driver_pcicore.c                 |    8 +-
 drivers/watchdog/hpwdt.c                     |    5 +-
 drivers/xen/swiotlb-xen.c                    |    2 +-
 fs/nfs/nfs4state.c                           |    8 +-
 fs/nilfs2/ioctl.c                            |   13 +
 include/linux/blkdev.h                       |    3 -
 include/linux/i2c/twl4030-madc.h             |    4 +
 include/linux/lglock.h                       |   36 +-
 include/net/sctp/structs.h                   |    4 +
 kernel/cgroup.c                              |    5 -
 kernel/futex.c                               |   28 +-
 kernel/sysctl_binary.c                       |    2 +-
 mm/filemap.c                                 |    7 +-
 mm/hugetlb.c                                 |    2 +-
 mm/memcontrol.c                              |    3 +-
 mm/oom_kill.c                                |    2 +-
 mm/percpu.c                                  |    6 +-
 net/ipv4/devinet.c                           |    5 +
 net/ipv4/ipconfig.c                          |    4 +
 net/ipv4/ipip.c                              |    7 +-
 net/ipv4/route.c                             |  107 ++++
 net/ipv6/sit.c                               |    7 +-
 net/llc/af_llc.c                             |   14 +-
 net/mac80211/agg-tx.c                        |   86 ++--
 net/sched/sch_gred.c                         |    2 +-
 net/sched/sch_mqprio.c                       |    2 +-
 net/sctp/associola.c                         |    2 +-
 net/sctp/output.c                            |    8 +-
 net/sctp/outqueue.c                          |    6 +-
 net/sctp/protocol.c                          |    3 +
 net/sctp/socket.c                            |    2 -
 net/sctp/sysctl.c                            |   13 +
 security/selinux/netport.c                   |    4 +-
 79 files changed, 752 insertions(+), 1213 deletions(-)
author
#1 lore raw

PATCH 1/67 ARM: OMAP: rx51: fix USB

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

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

From: Felipe Contreras <[email protected]>

commit e5fe29c7198a1f6616286dfc8602a69da165cb3f upstream.

Commit 10299e2e4e3ed3b16503d4e04edd48b33083f4e2 (ARM: RX-51:
Enable isp1704 power on/off) added power management for isp1704.

However, the transceiver should be powered on by default, otherwise USB doesn't work at all for networking during boot.

All kernels after v3.0 are affected.

---
 arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-omap2/board-rx51-peripherals.c +1 -1
@@ -133,7 +133,7 @@ static struct platform_device rx51_charg
 static void __init rx51_charger_init(void)
 {
 	WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO,
-		GPIOF_OUT_INIT_LOW, "isp1704_reset"));
+		GPIOF_OUT_INIT_HIGH, "isp1704_reset"));
 
 	platform_device_register(&rx51_charger_device);
 }
author
#2 lore raw

PATCH 2/67 ipip, sit: copy parms.name after register_netdevice

In reply to Greg KH

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

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

From: Ted Feng <[email protected]>

commit 72b36015ba43a3cca5303f5534d2c3e1899eae29 upstream.

Same fix as 731abb9cb2 for ipip and sit tunnel.
Commit 1c5cae815d removed an explicit call to dev_alloc_name in ipip_tunnel_locate and ipip6_tunnel_locate, because register_netdevice will now create a valid name, however the tunnel keeps a copy of the name in the private parms structure. Fix this by copying the name back after register_netdevice has successfully returned.

This shows up if you do a simple tunnel add, followed by a tunnel show:

$ sudo ip tunnel add mode ipip remote 10.2.20.211
$ ip tunnel
tunl0: ip/ip  remote any  local any  ttl inherit  nopmtudisc
tunl%d: ip/ip  remote 10.2.20.211  local any  ttl inherit
$ sudo ip tunnel add mode sit remote 10.2.20.212
$ ip tunnel
sit0: ipv6/ip  remote any  local any  ttl 64  nopmtudisc 6rd-prefix 2002::/16
sit%d: ioctl 89f8 failed: No such device
sit%d: ipv6/ip  remote 10.2.20.212  local any  ttl inherit
---
 net/ipv4/ipip.c |    7 ++++++-
 net/ipv6/sit.c  |    7 ++++++-
 2 files changed, 12 insertions(+), 2 deletions(-)
net/ipv4/ipip.c +6 -1
@@ -285,6 +285,8 @@ static struct ip_tunnel * ipip_tunnel_lo
 	if (register_netdevice(dev) < 0)
 		goto failed_free;
 
+	strcpy(nt->parms.name, dev->name);
+
 	dev_hold(dev);
 	ipip_tunnel_link(ipn, nt);
 	return nt;
@@ -759,7 +761,6 @@ static int ipip_tunnel_init(struct net_d
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 
 	tunnel->dev = dev;
-	strcpy(tunnel->parms.name, dev->name);
 
 	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
 	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@ -825,6 +826,7 @@ static void ipip_destroy_tunnels(struct
 static int __net_init ipip_init_net(struct net *net)
 {
 	struct ipip_net *ipn = net_generic(net, ipip_net_id);
+	struct ip_tunnel *t;
 	int err;
 
 	ipn->tunnels[0] = ipn->tunnels_wc;
@@ -848,6 +850,9 @@ static int __net_init ipip_init_net(stru
 	if ((err = register_netdev(ipn->fb_tunnel_dev)))
 		goto err_reg_dev;
 
+	t = netdev_priv(ipn->fb_tunnel_dev);
+
+	strcpy(t->parms.name, ipn->fb_tunnel_dev->name);
 	return 0;
 
 err_reg_dev:
net/ipv6/sit.c +6 -1
@@ -263,6 +263,8 @@ static struct ip_tunnel *ipip6_tunnel_lo
 	if (register_netdevice(dev) < 0)
 		goto failed_free;
 
+	strcpy(nt->parms.name, dev->name);
+
 	dev_hold(dev);
 
 	ipip6_tunnel_link(sitn, nt);
@@ -1141,7 +1143,6 @@ static int ipip6_tunnel_init(struct net_
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 
 	tunnel->dev = dev;
-	strcpy(tunnel->parms.name, dev->name);
 
 	memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
 	memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@ -1204,6 +1205,7 @@ static void __net_exit sit_destroy_tunne
 static int __net_init sit_init_net(struct net *net)
 {
 	struct sit_net *sitn = net_generic(net, sit_net_id);
+	struct ip_tunnel *t;
 	int err;
 
 	sitn->tunnels[0] = sitn->tunnels_wc;
@@ -1228,6 +1230,9 @@ static int __net_init sit_init_net(struc
 	if ((err = register_netdev(sitn->fb_tunnel_dev)))
 		goto err_reg_dev;
 
+	t = netdev_priv(sitn->fb_tunnel_dev);
+
+	strcpy(t->parms.name, sitn->fb_tunnel_dev->name);
 	return 0;
 
 err_reg_dev:
author
#3 lore raw

PATCH 3/67 rtc: Expire alarms after the time is set.

In reply to Greg KH

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

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

From: NeilBrown <[email protected]>

commit 93b2ec0128c431148b216b8f7337c1a52131ef03 upstream.

If the alarm time programming in the rtc is ever in the past, it won't fire, and any other alarm will be queued after it so they won't fire either.

So any time that the alarm might be in the past, we need to trigger the irq handler to ensure the old alarm is cleared and the timer queue is fully in the future.

This can happen:
- when we first initialise the alarm
- when we set the time in the rtc.

so follow both of these by scheduling the timer work function.

[Also catch set_mmss case -jstultz]
---
 drivers/rtc/interface.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/rtc/interface.c +6 -0
@@ -72,6 +72,8 @@ int rtc_set_time(struct rtc_device *rtc,
 		err = -EINVAL;
 
 	mutex_unlock(&rtc->ops_lock);
+	/* A timer might have just expired */
+	schedule_work(&rtc->irqwork);
 	return err;
 }
 EXPORT_SYMBOL_GPL(rtc_set_time);
@@ -111,6 +113,8 @@ int rtc_set_mmss(struct rtc_device *rtc,
 		err = -EINVAL;
 
 	mutex_unlock(&rtc->ops_lock);
+	/* A timer might have just expired */
+	schedule_work(&rtc->irqwork);
 
 	return err;
 }
@@ -402,6 +406,8 @@ int rtc_initialize_alarm(struct rtc_devi
 		timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
 	}
 	mutex_unlock(&rtc->ops_lock);
+	/* maybe that was in the past.*/
+	schedule_work(&rtc->irqwork);
 	return err;
 }
 EXPORT_SYMBOL_GPL(rtc_initialize_alarm);
#4 lore raw

Re: [03/67] rtc: Expire alarms after the time is set.

Quoted 1 line · Greg KH

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

This one is having problems upstream. Please hold off on it.

thanks
-john

Quoted 59 lines

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

From: NeilBrown <[email protected]>

commit 93b2ec0128c431148b216b8f7337c1a52131ef03 upstream.

If the alarm time programming in the rtc is ever in the past, it won't fire, and any other alarm will be queued after it so they won't fire either.

So any time that the alarm might be in the past, we need to trigger the irq handler to ensure the old alarm is cleared and the timer queue is fully in the future.

This can happen:
- when we first initialise the alarm
- when we set the time in the rtc.

so follow both of these by scheduling the timer work function.

[Also catch set_mmss case -jstultz]
---
 drivers/rtc/interface.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/rtc/interface.c +6 -0
@@ -72,6 +72,8 @@ int rtc_set_time(struct rtc_device *rtc,
 		err = -EINVAL;
 
 	mutex_unlock(&rtc->ops_lock);
+	/* A timer might have just expired */
+	schedule_work(&rtc->irqwork);
 	return err;
 }
 EXPORT_SYMBOL_GPL(rtc_set_time);
@@ -111,6 +113,8 @@ int rtc_set_mmss(struct rtc_device *rtc,
 		err = -EINVAL;
 
 	mutex_unlock(&rtc->ops_lock);
+	/* A timer might have just expired */
+	schedule_work(&rtc->irqwork);
 
 	return err;
 }
@@ -402,6 +406,8 @@ int rtc_initialize_alarm(struct rtc_devi
 		timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
 	}
 	mutex_unlock(&rtc->ops_lock);
+	/* maybe that was in the past.*/
+	schedule_work(&rtc->irqwork);
 	return err;
 }
 EXPORT_SYMBOL_GPL(rtc_initialize_alarm);
author
#5 lore raw

Re: [03/67] rtc: Expire alarms after the time is set.

Quoted 4 lines · John Stultz
Quoted 1 line · Greg KH

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

This one is having problems upstream. Please hold off on it.

Hold off until when? I'll just drop it for now. If it ever gets worked out, please let [email protected] know about it and I'll handle it then.

thanks,

greg k-h

#6 lore raw

Re: [03/67] rtc: Expire alarms after the time is set.

Quoted 9 lines · Greg KH
Quoted 4 lines · John Stultz
Quoted 1 line · Greg KH

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

This one is having problems upstream. Please hold off on it.

Hold off until when? I'll just drop it for now. If it ever gets worked out, please let [email protected] know about it and I'll handle it then.

Yea. I'm working on it now. As soon as we have a fix upstream I'll ping you and you can grab both this and the fix together.

thanks
-john

author
#7 lore raw

PATCH 4/67 rtc: m41t80: Workaround broken alarm functionality

In reply to Greg KH

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

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

From: John Stultz <[email protected]>

commit c3b79770e51ab1fd4201f3b54edf30113b9ce74f upstream.

The m41t80 driver can read and set the alarm, but it doesn't seem to have a functional alarm irq.

This causes failures when the generic core sees alarm functions, but then cannot use them properly for things like UIE mode.

Disabling the alarm functions allows proper error reporting, and possible fallback to emulated modes. Once someone fixes the alarm irq functionality, this can be restored.

---
 drivers/rtc/rtc-m41t80.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/rtc/rtc-m41t80.c +9 -0
@@ -357,10 +357,19 @@ static int m41t80_rtc_read_alarm(struct
 static struct rtc_class_ops m41t80_rtc_ops = {
 	.read_time = m41t80_rtc_read_time,
 	.set_time = m41t80_rtc_set_time,
+	/*
+	 * XXX - m41t80 alarm functionality is reported broken.
+	 * until it is fixed, don't register alarm functions.
+	 *
 	.read_alarm = m41t80_rtc_read_alarm,
 	.set_alarm = m41t80_rtc_set_alarm,
+	*/
 	.proc = m41t80_rtc_proc,
+	/*
+	 * See above comment on broken alarm
+	 *
 	.alarm_irq_enable = m41t80_rtc_alarm_irq_enable,
+	*/
 };
 
 #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
author
#8 lore raw

PATCH 5/67 drm/i915: prevent division by zero when asking for chipset power

In reply to Greg KH

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

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

From: Eugeni Dodonov <[email protected]>

commit 4ed0b577457eb6aeb7cdc7e7316576e63d15abb2 upstream.

This prevents an in-kernel division by zero which happens when we are asking for i915_chipset_val too quickly, or within a race condition between the power monitoring thread and userspace accesses via debugfs.

The issue can be reproduced easily via the following command:
while ``; do cat /sys/kernel/debug/dri/0/i915_emon_status; done

This is particularly dangerous because it can be triggered by a non-privileged user by just reading the debugfs entry.

This issue was also found independently by Konstantin Belousov <[email protected]>, who proposed a similar patch.

---
 drivers/gpu/drm/i915/i915_dma.c |   10 ++++++++++
 drivers/gpu/drm/i915/i915_drv.h |    1 +
 2 files changed, 11 insertions(+)
drivers/gpu/drm/i915/i915_dma.c +10 -0
@@ -1451,6 +1451,14 @@ unsigned long i915_chipset_val(struct dr
 
 	diff1 = now - dev_priv->last_time1;
 
+	/* Prevent division-by-zero if we are asking too fast.
+	 * Also, we don't get interesting results if we are polling
+	 * faster than once in 10ms, so just return the saved value
+	 * in such cases.
+	 */
+	if (diff1 <= 10)
+		return dev_priv->chipset_power;
+
 	count1 = I915_READ(DMIEC);
 	count2 = I915_READ(DDREC);
 	count3 = I915_READ(CSIEC);
@@ -1481,6 +1489,8 @@ unsigned long i915_chipset_val(struct dr
 	dev_priv->last_count1 = total_count;
 	dev_priv->last_time1 = now;
 
+	dev_priv->chipset_power = ret;
+
 	return ret;
 }
 
drivers/gpu/drm/i915/i915_drv.h +1 -0
@@ -702,6 +702,7 @@ typedef struct drm_i915_private {
 
 	u64 last_count1;
 	unsigned long last_time1;
+	unsigned long chipset_power;
 	u64 last_count2;
 	struct timespec last_time2;
 	unsigned long gfx_power;
author
#9 lore raw

PATCH 6/67 cfq-iosched: free cic_index if blkio_alloc_blkg_stats fails

In reply to Greg KH

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

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

From: majianpeng <[email protected]>

commit 2984ff38ccf6cbc02a7a996a36c7d6f69f3c6146 upstream.

If we fail allocating the blkpg stats, we free cfqd and cfgq. But we need to free the IDA cfqd->cic_index as well.

---
 block/cfq-iosched.c |    5 +++++
 1 file changed, 5 insertions(+)
block/cfq-iosched.c +5 -0
@@ -4015,6 +4015,11 @@ static void *cfq_init_queue(struct reque
 
 	if (blkio_alloc_blkg_stats(&cfqg->blkg)) {
 		kfree(cfqg);
+
+		spin_lock(&cic_index_lock);
+		ida_remove(&cic_index_ida, cfqd->cic_index);
+		spin_unlock(&cic_index_lock);
+
 		kfree(cfqd);
 		return NULL;
 	}
author
#10 lore raw

PATCH 7/67 cfq-iosched: fix cfq_cic_link() race confition

In reply to Greg KH

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

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

From: Yasuaki Ishimatsu <[email protected]>

commit 5eb46851de3904cd1be9192fdacb8d34deadc1fc upstream.

cfq_cic_link() has race condition. When some processes which shared ioc issue I/O to same block device simultaneously, cfq_cic_link() returns -EEXIST sometimes. The race condition might stop I/O by following steps:

step 1: Process A: Issue an I/O to /dev/sda
step 2: Process A: Get an ioc (iocA here) in get_io_context() which does not
linked with a cic for the device
step 3: Process A: Get a new cic for the device (cicA here) in
cfq_alloc_io_context()

step 4: Process B: Issue an I/O to /dev/sda
step 5: Process B: Get iocA in get_io_context() since process A and B share the
same ioc
step 6: Process B: Get a new cic for the device (cicB here) in
cfq_alloc_io_context() since iocA has not been linked with a cic for the device yet

step 7: Process A: Link cicA to iocA in cfq_cic_link() step 8: Process A: Dispatch I/O to driver and finish it

step 9: Process B: Try to link cicB to iocA in cfq_cic_link()
But it fails with showing "cfq: cic link failed!" kernel message, since iocA has already linked with cicA at step 7.
step 10: Process B: Wait for finishig I/O in get_request_wait()
The function does not wake up, when there is no I/O to the device.

When cfq_cic_link() returns -EEXIST, it means ioc has already linked with cic. So when cfq_cic_link() return -EEXIST, retry cfq_cic_lookup().

---
 block/cfq-iosched.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
block/cfq-iosched.c +9 -2
@@ -3169,7 +3169,7 @@ static int cfq_cic_link(struct cfq_data
 		}
 	}
 
-	if (ret)
+	if (ret && ret != -EEXIST)
 		printk(KERN_ERR "cfq: cic link failed!\n");
 
 	return ret;
@@ -3185,6 +3185,7 @@ cfq_get_io_context(struct cfq_data *cfqd
 {
 	struct io_context *ioc = NULL;
 	struct cfq_io_context *cic;
+	int ret;
 
 	might_sleep_if(gfp_mask & __GFP_WAIT);
 
@@ -3192,6 +3193,7 @@ cfq_get_io_context(struct cfq_data *cfqd
 	if (!ioc)
 		return NULL;
 
+retry:
 	cic = cfq_cic_lookup(cfqd, ioc);
 	if (cic)
 		goto out;
@@ -3200,7 +3202,12 @@ cfq_get_io_context(struct cfq_data *cfqd
 	if (cic == NULL)
 		goto err;
 
-	if (cfq_cic_link(cfqd, ioc, cic, gfp_mask))
+	ret = cfq_cic_link(cfqd, ioc, cic, gfp_mask);
+	if (ret == -EEXIST) {
+		/* someone has linked cic to ioc already */
+		cfq_cic_free(cic);
+		goto retry;
+	} else if (ret)
 		goto err_free;
 
 out:
author
#11 lore raw

PATCH 8/67 SCSI: zfcp: return early from slave_destroy if slave_alloc returned early

In reply to Greg KH

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

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

From: Steffen Maier <[email protected]>

commit 44f747fff6e9f027a4866c1a6864e26ae7c510c8 upstream.

zfcp_scsi_slave_destroy erroneously always tried to finish its task even if the corresponding previous zfcp_scsi_slave_alloc returned early. This can lead to kernel page faults on accessing uninitialized fields of struct zfcp_scsi_dev in zfcp_erp_lun_shutdown_wait. Take the port field of the struct to determine if slave_alloc returned early.

This zfcp bug is exposed by 4e6c82b (in turn fixing f7c9c6b to be compatible with 21208ae) which can call slave_destroy for a corresponding previous slave_alloc that did not finish.

This patch is based on James Bottomley's fix suggestion in
http://www.spinics.net/lists/linux-scsi/msg55449.html.

---
 drivers/s390/scsi/zfcp_scsi.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/s390/scsi/zfcp_scsi.c +4 -0
@@ -57,6 +57,10 @@ static void zfcp_scsi_slave_destroy(stru
 {
 	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
 
+	/* if previous slave_alloc returned early, there is nothing to do */
+	if (!zfcp_sdev->port)
+		return;
+
 	zfcp_erp_lun_shutdown_wait(sdev, "scssd_1");
 	put_device(&zfcp_sdev->port->dev);
 }
author
#12 lore raw

PATCH 9/67 SCSI: mpt2sas: _scsih_smart_predicted_fault uses GFP_KERNEL in interrupt context

In reply to Greg KH

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

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

From: Anton Blanchard <[email protected]>

commit f6a290b419a2675c4b77a6b0731cd2a64332365e upstream.

_scsih_smart_predicted_fault is called in an interrupt and therefore must allocate memory using GFP_ATOMIC.

---
 drivers/scsi/mpt2sas/mpt2sas_scsih.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/mpt2sas/mpt2sas_scsih.c +1 -1
@@ -4145,7 +4145,7 @@ _scsih_smart_predicted_fault(struct MPT2
 	/* insert into event log */
 	sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
 	     sizeof(Mpi2EventDataSasDeviceStatusChange_t);
-	event_reply = kzalloc(sz, GFP_KERNEL);
+	event_reply = kzalloc(sz, GFP_ATOMIC);
 	if (!event_reply) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
 		    ioc->name, __FILE__, __LINE__, __func__);
author
#13 lore raw

PATCH 10/67 SCSI: fcoe: Fix preempt count leak in fcoe_filter_frames()

In reply to Greg KH

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

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

From: Thomas Gleixner <[email protected]>

commit 7e1e7ead88dff75b11b86ee0d5232c4591be1326 upstream.

The error exit path leaks preempt count. Add the missing put_cpu().

---
 drivers/scsi/fcoe/fcoe.c |    1 +
 1 file changed, 1 insertion(+)
drivers/scsi/fcoe/fcoe.c +1 -0
@@ -1561,6 +1561,7 @@ static inline int fcoe_filter_frames(str
 	stats->InvalidCRCCount++;
 	if (stats->InvalidCRCCount < 5)
 		printk(KERN_WARNING "fcoe: dropping frame with CRC error\n");
+	put_cpu();
 	return -EINVAL;
 }
 
author
#14 lore raw

PATCH 11/67 mac80211: fix another race in aggregation start

In reply to Greg KH

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

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

From: Johannes Berg <[email protected]>

commit 15062e6a8524f5977f2cbdf6e3eb2f144262f74e upstream.

Emmanuel noticed that when mac80211 stops the queues for aggregation that can leave a packet pending. This packet will be given to the driver after the AMPDU callback, but as a non-aggregated packet which messes up the sequence number etc.

I also noticed by looking at the code that if packets are being processed while we clear the WANT_START bit, they might see it cleared already and queue up on tid_tx->pending. If the driver then rejects the new aggregation session we leak the packet.

Fix both of these issues by changing this code to not stop the queues at all. Instead, let packets queue up on the tid_tx->pending queue instead of letting them get to the driver, and add code to recover properly in case the driver rejects the session.

(The patch looks large because it has to move two functions to before their new use.)

---
 net/mac80211/agg-tx.c |   86 +++++++++++++++++++++++---------------------------
 1 file changed, 41 insertions(+), 45 deletions(-)
net/mac80211/agg-tx.c +41 -45
@@ -304,6 +304,38 @@ ieee80211_wake_queue_agg(struct ieee8021
 	__release(agg_queue);
 }
 
+/*
+ * splice packets from the STA's pending to the local pending,
+ * requires a call to ieee80211_agg_splice_finish later
+ */
+static void __acquires(agg_queue)
+ieee80211_agg_splice_packets(struct ieee80211_local *local,
+			     struct tid_ampdu_tx *tid_tx, u16 tid)
+{
+	int queue = ieee80211_ac_from_tid(tid);
+	unsigned long flags;
+
+	ieee80211_stop_queue_agg(local, tid);
+
+	if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
+			  " from the pending queue\n", tid))
+		return;
+
+	if (!skb_queue_empty(&tid_tx->pending)) {
+		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+		/* copy over remaining packets */
+		skb_queue_splice_tail_init(&tid_tx->pending,
+					   &local->pending[queue]);
+		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+	}
+}
+
+static void __releases(agg_queue)
+ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
+{
+	ieee80211_wake_queue_agg(local, tid);
+}
+
 void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
 {
 	struct tid_ampdu_tx *tid_tx;
@@ -315,19 +347,17 @@ void ieee80211_tx_ba_session_handle_star
 	tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 
 	/*
-	 * While we're asking the driver about the aggregation,
-	 * stop the AC queue so that we don't have to worry
-	 * about frames that came in while we were doing that,
-	 * which would require us to put them to the AC pending
-	 * afterwards which just makes the code more complex.
+	 * Start queuing up packets for this aggregation session.
+	 * We're going to release them once the driver is OK with
+	 * that.
 	 */
-	ieee80211_stop_queue_agg(local, tid);
-
 	clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state);
 
 	/*
-	 * make sure no packets are being processed to get
-	 * valid starting sequence number
+	 * Make sure no packets are being processed. This ensures that
+	 * we have a valid starting sequence number and that in-flight
+	 * packets have been flushed out and no packets for this TID
+	 * will go into the driver during the ampdu_action call.
 	 */
 	synchronize_net();
 
@@ -341,17 +371,15 @@ void ieee80211_tx_ba_session_handle_star
 					" tid %d\n", tid);
 #endif
 		spin_lock_bh(&sta->lock);
+		ieee80211_agg_splice_packets(local, tid_tx, tid);
 		ieee80211_assign_tid_tx(sta, tid, NULL);
+		ieee80211_agg_splice_finish(local, tid);
 		spin_unlock_bh(&sta->lock);
 
-		ieee80211_wake_queue_agg(local, tid);
 		kfree_rcu(tid_tx, rcu_head);
 		return;
 	}
 
-	/* we can take packets again now */
-	ieee80211_wake_queue_agg(local, tid);
-
 	/* activate the timer for the recipient's addBA response */
 	mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -471,38 +499,6 @@ int ieee80211_start_tx_ba_session(struct
 }
 EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
 
-/*
- * splice packets from the STA's pending to the local pending,
- * requires a call to ieee80211_agg_splice_finish later
- */
-static void __acquires(agg_queue)
-ieee80211_agg_splice_packets(struct ieee80211_local *local,
-			     struct tid_ampdu_tx *tid_tx, u16 tid)
-{
-	int queue = ieee80211_ac_from_tid(tid);
-	unsigned long flags;
-
-	ieee80211_stop_queue_agg(local, tid);
-
-	if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates"
-			  " from the pending queue\n", tid))
-		return;
-
-	if (!skb_queue_empty(&tid_tx->pending)) {
-		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-		/* copy over remaining packets */
-		skb_queue_splice_tail_init(&tid_tx->pending,
-					   &local->pending[queue]);
-		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-	}
-}
-
-static void __releases(agg_queue)
-ieee80211_agg_splice_finish(struct ieee80211_local *local, u16 tid)
-{
-	ieee80211_wake_queue_agg(local, tid);
-}
-
 static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
 					 struct sta_info *sta, u16 tid)
 {
author
#15 lore raw

PATCH 12/67 block: initialize request_queues numa node during

In reply to Greg KH

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

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

From: Mike Snitzer <[email protected]>

commit 5151412dd4338b273afdb107c3772528e9e67d92 upstream.

struct request_queue is allocated with __GFP_ZERO so its "node" field is zero before initialization. This causes an oops if node 0 is offline in the page allocator because its zonelists are not initialized. From Dave Young's dmesg:

	SRAT: Node 1 PXM 2 0-d0000000
	SRAT: Node 1 PXM 2 100000000-330000000
	SRAT: Node 0 PXM 1 330000000-630000000
	Initmem setup node 1 0000000000000000-000000000affb000
	...
	Built 1 zonelists in Node order, mobility grouping on.
	...
	BUG: unable to handle kernel paging request at 0000000000001c08
	IP: [<ffffffff8111c355>] __alloc_pages_nodemask+0xb5/0x870

and __alloc_pages_nodemask+0xb5 translates to a NULL pointer on zonelist->_zonerefs.

The fix is to initialize q->node at the time of allocation so the correct node is passed to the slab allocator later.

Since blk_init_allocated_queue_node() is no longer needed, merge it with blk_init_allocated_queue().

---
 block/blk-core.c       |   14 +++-----------
 include/linux/blkdev.h |    3 ---
 2 files changed, 3 insertions(+), 14 deletions(-)
block/blk-core.c +3 -11
@@ -418,6 +418,7 @@ struct request_queue *blk_alloc_queue_no
 	q->backing_dev_info.state = 0;
 	q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
 	q->backing_dev_info.name = "block";
+	q->node = node_id;
 
 	err = bdi_init(&q->backing_dev_info);
 	if (err) {
@@ -502,7 +503,7 @@ blk_init_queue_node(request_fn_proc *rfn
 	if (!uninit_q)
 		return NULL;
 
-	q = blk_init_allocated_queue_node(uninit_q, rfn, lock, node_id);
+	q = blk_init_allocated_queue(uninit_q, rfn, lock);
 	if (!q)
 		blk_cleanup_queue(uninit_q);
 
@@ -514,18 +515,9 @@ struct request_queue *
 blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
 			 spinlock_t *lock)
 {
-	return blk_init_allocated_queue_node(q, rfn, lock, -1);
-}
-EXPORT_SYMBOL(blk_init_allocated_queue);
-
-struct request_queue *
-blk_init_allocated_queue_node(struct request_queue *q, request_fn_proc *rfn,
-			      spinlock_t *lock, int node_id)
-{
 	if (!q)
 		return NULL;
 
-	q->node = node_id;
 	if (blk_init_free_list(q))
 		return NULL;
 
@@ -555,7 +547,7 @@ blk_init_allocated_queue_node(struct req
 
 	return NULL;
 }
-EXPORT_SYMBOL(blk_init_allocated_queue_node);
+EXPORT_SYMBOL(blk_init_allocated_queue);
 
 int blk_get_queue(struct request_queue *q)
 {
include/linux/blkdev.h +0 -3
@@ -798,9 +798,6 @@ extern void blk_unprep_request(struct re
  */
 extern struct request_queue *blk_init_queue_node(request_fn_proc *rfn,
 					spinlock_t *lock, int node_id);
-extern struct request_queue *blk_init_allocated_queue_node(struct request_queue *,
-							   request_fn_proc *,
-							   spinlock_t *, int node_id);
 extern struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *);
 extern struct request_queue *blk_init_allocated_queue(struct request_queue *,
 						      request_fn_proc *, spinlock_t *);
author
#16 lore raw

PATCH 13/67 ssb: fix init regression with SoCs

In reply to Greg KH

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

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

From: Hauke Mehrtens <[email protected]>

commit 329456d1ffb416c220813725b7363cda9975c9aa upstream.

This fixes a Data bus error on some SoCs. The first fix for this problem did not solve it on all devices.
commit 6ae8ec27868bfdbb815287bee8146acbefaee867
Author: Rafał Miłecki <[email protected]>
Date: Tue Jul 5 17:25:32 2011 +0200
ssb: fix init regression of hostmode PCI core

In ssb_pcicore_fix_sprom_core_index() the sprom on the PCI core is accessed, but the sprom only exists when the ssb bus is connected over a PCI bus to the rest of the system and not when the SSB Bus is the main system bus. SoCs sometimes have a PCI host controller and there this code will not be executed, but there are some old SoCs with an PCI controller in client mode around and ssb_pcicore_fix_sprom_core_index() should not be called on these devices too. The PCI controller on these devices are unused, but without this fix it results in an Data bus error when it gets initialized.

---
 drivers/ssb/driver_pcicore.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/ssb/driver_pcicore.c +6 -2
@@ -516,10 +516,14 @@ static void ssb_pcicore_pcie_setup_worka
 
 static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
 {
-	ssb_pcicore_fix_sprom_core_index(pc);
+	struct ssb_device *pdev = pc->dev;
+	struct ssb_bus *bus = pdev->bus;
+
+	if (bus->bustype == SSB_BUSTYPE_PCI)
+		ssb_pcicore_fix_sprom_core_index(pc);
 
 	/* Disable PCI interrupts. */
-	ssb_write32(pc->dev, SSB_INTVEC, 0);
+	ssb_write32(pdev, SSB_INTVEC, 0);
 
 	/* Additional PCIe always once-executed workarounds */
 	if (pc->dev->id.coreid == SSB_DEV_PCIE) {
author
#17 lore raw

PATCH 14/67 MXC PWM: should active during DOZE/WAIT/DBG mode

In reply to Greg KH

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

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

From: Jason Chen <[email protected]>

commit c0d96aed8c6dd925afe9ea35491a0cd458642a86 upstream.

---
 arch/arm/plat-mxc/pwm.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
arch/arm/plat-mxc/pwm.c +6 -1
@@ -32,6 +32,9 @@
 #define MX3_PWMSAR                0x0C    /* PWM Sample Register */
 #define MX3_PWMPR                 0x10    /* PWM Period Register */
 #define MX3_PWMCR_PRESCALER(x)    (((x - 1) & 0xFFF) << 4)
+#define MX3_PWMCR_DOZEEN                (1 << 24)
+#define MX3_PWMCR_WAITEN                (1 << 23)
+#define MX3_PWMCR_DBGEN			(1 << 22)
 #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
 #define MX3_PWMCR_CLKSRC_IPG      (1 << 16)
 #define MX3_PWMCR_EN              (1 << 0)
@@ -77,7 +80,9 @@ int pwm_config(struct pwm_device *pwm, i
 		writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
 		writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
 
-		cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_EN;
+		cr = MX3_PWMCR_PRESCALER(prescale) |
+			MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
+			MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
 
 		if (cpu_is_mx25())
 			cr |= MX3_PWMCR_CLKSRC_IPG;
author
#18 lore raw

PATCH 15/67 Input: synaptics - fix touchpad not working after S2R on Vostro V13

In reply to Greg KH

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

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

From: Dmitry Torokhov <[email protected]>

commit 8521478f67e95ada4e87970c7b41e504c724b2cf upstream.

Synaptics touchpads on several Dell laptops, particularly Vostro V13 systems, may not respond properly to PS/2 commands and queries immediately after resuming from suspend to RAM. This leads to unresponsive touchpad after suspend/resume cycle.

Adding a 1-second delay after resetting the device allows touchpad to finish initializing (calibrating?) and start reacting properly.

---
 drivers/input/mouse/synaptics.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/input/mouse/synaptics.c +11 -0
@@ -24,6 +24,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/input/mt.h>
 #include <linux/serio.h>
@@ -760,6 +761,16 @@ static int synaptics_reconnect(struct ps
 
 	do {
 		psmouse_reset(psmouse);
+		if (retry) {
+			/*
+			 * On some boxes, right after resuming, the touchpad
+			 * needs some time to finish initializing (I assume
+			 * it needs time to calibrate) and start responding
+			 * to Synaptics-specific queries, so let's wait a
+			 * bit.
+			 */
+			ssleep(1);
+		}
 		error = synaptics_detect(psmouse, 0);
 	} while (error && ++retry < 3);
 
author
#19 lore raw

PATCH 16/67 percpu: fix per_cpu_ptr_to_phys() handling of non-page-aligned addresses

In reply to Greg KH

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

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

From: Eugene Surovegin <[email protected]>

commit 9f57bd4d6dc69a4e3bf43044fa00fcd24dd363e3 upstream.

per_cpu_ptr_to_phys() incorrectly rounds up its result for non-kmalloc case to the page boundary, which is bogus for any non-page-aligned address.

This affects the only in-tree user of this function - sysfs handler for per-cpu 'crash_notes' physical address. The trouble is that the crash_notes per-cpu variable is not page-aligned:

crash_notes = 0xc08e8ed4
PER-CPU OFFSET VALUES:
CPU 0: 3711f000
CPU 1: 37129000
CPU 2: 37133000
CPU 3: 3713d000

So, the per-cpu addresses are:
crash_notes on CPU 0: f7a07ed4 => phys 36b57ed4
crash_notes on CPU 1: f7a11ed4 => phys 36b4ded4
crash_notes on CPU 2: f7a1bed4 => phys 36b43ed4
crash_notes on CPU 3: f7a25ed4 => phys 36b39ed4

However, /sys/devices/system/cpu/cpu*/crash_notes says:
/sys/devices/system/cpu/cpu0/crash_notes: 36b57000 /sys/devices/system/cpu/cpu1/crash_notes: 36b4d000 /sys/devices/system/cpu/cpu2/crash_notes: 36b43000 /sys/devices/system/cpu/cpu3/crash_notes: 36b39000

As you can see, all values are rounded down to a page boundary. Consequently, this is where kexec sets up the NOTE segments, and thus where the secondary kernel is looking for them. However, when the first kernel crashes, it saves the notes to the unaligned addresses, where they are not found.

Fix it by adding offset_in_page() to the translated page address.

-tj: Combined Eugene's and Petr's commit messages.

---
 mm/percpu.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
mm/percpu.c +4 -2
@@ -1011,9 +1011,11 @@ phys_addr_t per_cpu_ptr_to_phys(void *ad
 		if (!is_vmalloc_addr(addr))
 			return __pa(addr);
 		else
-			return page_to_phys(vmalloc_to_page(addr));
+			return page_to_phys(vmalloc_to_page(addr)) +
+			       offset_in_page(addr);
 	} else
-		return page_to_phys(pcpu_addr_to_page(addr));
+		return page_to_phys(pcpu_addr_to_page(addr)) +
+		       offset_in_page(addr);
 }
 
 /**
author
#20 lore raw

PATCH 17/67 binary_sysctl(): fix memory leak

In reply to Greg KH

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

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

From: Michel Lespinasse <[email protected]>

commit 3d3c8f93a237b64580c5c5e138edeb1377e98230 upstream.

binary_sysctl() calls sysctl_getname() which allocates from names_cache slab usin __getname()

The matching function to free the name is __putname(), and not putname() which should be used only to match getname() allocations.

This is because when auditing is enabled, putname() calls audit_putname *instead* (not in addition) to __putname(). Then, if a syscall is in progress, audit_putname does not release the name - instead, it expects the name to get released when the syscall completes, but that will happen only if audit_getname() was called previously, i.e. if the name was allocated with getname() rather than the naked __getname(). So, __getname() followed by putname() ends up leaking memory.

---
 kernel/sysctl_binary.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sysctl_binary.c +1 -1
@@ -1354,7 +1354,7 @@ static ssize_t binary_sysctl(const int *
 
 	fput(file);
 out_putname:
-	putname(pathname);
+	__putname(pathname);
 out:
 	return result;
 }
author
#21 lore raw

PATCH 18/67 oom: fix integer overflow of points in oom_badness

In reply to Greg KH

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

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

From: Frantisek Hrbata <[email protected]>

commit ff05b6f7ae762b6eb464183eec994b28ea09f6dd upstream.

An integer overflow will happen on 64bit archs if task's sum of rss, swapents and nr_ptes exceeds (2^31)/1000 value. This was introduced by commit

f755a04 oom: use pte pages in OOM score

where the oom score computation was divided into several steps and it's no longer computed as one expression in unsigned long(rss, swapents, nr_pte are unsigned long), where the result value assigned to points(int) is in range(1..1000). So there could be an int overflow while computing

176 points *= 1000;

and points may have negative value. Meaning the oom score for a mem hog task will be one.

196 if (points <= 0)
197 return 1;

For example:
[ 3366] 0 3366 35390480 24303939 5 0 0 oom01
Out of memory: Kill process 3366 (oom01) score 1 or sacrifice child

Here the oom1 process consumes more than 24303939(rss)*4096~=92GB physical memory, but it's oom score is one.

In this situation the mem hog task is skipped and oom killer kills another and most probably innocent task with oom score greater than one.

The points variable should be of type long instead of int to prevent the int overflow.

---
 mm/oom_kill.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/oom_kill.c +1 -1
@@ -162,7 +162,7 @@ static bool oom_unkillable_task(struct t
 unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem,
 		      const nodemask_t *nodemask, unsigned long totalpages)
 {
-	int points;
+	long points;
 
 	if (oom_unkillable_task(p, mem, nodemask))
 		return 0;
author
#22 lore raw

PATCH 19/67 oprofile: Fix uninitialized memory access when writing to writing to oprofilefs

In reply to Greg KH

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

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

From: Robert Richter <[email protected]>

commit 913050b91eb94f194392dd797b1ff3779f606ac0 upstream.

If oprofilefs_ulong_from_user() is called with count equals zero, *val remains unchanged. Depending on the implementation it might be uninitialized.

Change oprofilefs_ulong_from_user()'s interface to return count on success. Thus, we are able to return early if count equals zero which avoids using *val uninitialized. Fixing all users of oprofilefs_ulong_ from_user().

This follows write syscall implementation when count is zero:
"If count is zero ... [and if] no errors are detected, 0 will be returned without causing any other effect." (man 2 write)

---
 arch/s390/oprofile/init.c         |    2 +-
 drivers/oprofile/oprofile_files.c |    7 ++++---
 drivers/oprofile/oprofilefs.c     |   11 +++++++++--
 3 files changed, 14 insertions(+), 6 deletions(-)
arch/s390/oprofile/init.c +1 -1
@@ -90,7 +90,7 @@ static ssize_t hwsampler_write(struct fi
 		return -EINVAL;
 
 	retval = oprofilefs_ulong_from_user(&val, buf, count);
-	if (retval)
+	if (retval <= 0)
 		return retval;
 
 	if (oprofile_started)
drivers/oprofile/oprofile_files.c +4 -3
@@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file
 		return -EINVAL;
 
 	retval = oprofilefs_ulong_from_user(&val, buf, count);
-	if (retval)
+	if (retval <= 0)
 		return retval;
 
 	retval = oprofile_set_timeout(val);
@@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *
 		return -EINVAL;
 
 	retval = oprofilefs_ulong_from_user(&val, buf, count);
-	if (retval)
+	if (retval <= 0)
 		return retval;
 
 	retval = oprofile_set_ulong(&oprofile_backtrace_depth, val);
@@ -141,9 +141,10 @@ static ssize_t enable_write(struct file
 		return -EINVAL;
 
 	retval = oprofilefs_ulong_from_user(&val, buf, count);
-	if (retval)
+	if (retval <= 0)
 		return retval;
 
+	retval = 0;
 	if (val)
 		retval = oprofile_start();
 	else
drivers/oprofile/oprofilefs.c +9 -2
@@ -60,6 +60,13 @@ ssize_t oprofilefs_ulong_to_user(unsigne
 }
 
 
+/*
+ * Note: If oprofilefs_ulong_from_user() returns 0, then *val remains
+ * unchanged and might be uninitialized. This follows write syscall
+ * implementation when count is zero: "If count is zero ... [and if]
+ * no errors are detected, 0 will be returned without causing any
+ * other effect." (man 2 write)
+ */
 int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count)
 {
 	char tmpbuf[TMPBUFSIZE];
@@ -79,7 +86,7 @@ int oprofilefs_ulong_from_user(unsigned
 	spin_lock_irqsave(&oprofilefs_lock, flags);
 	*val = simple_strtoul(tmpbuf, NULL, 0);
 	spin_unlock_irqrestore(&oprofilefs_lock, flags);
-	return 0;
+	return count;
 }
 
 
@@ -99,7 +106,7 @@ static ssize_t ulong_write_file(struct f
 		return -EINVAL;
 
 	retval = oprofilefs_ulong_from_user(&value, buf, count);
-	if (retval)
+	if (retval <= 0)
 		return retval;
 
 	retval = oprofile_set_ulong(file->private_data, value);
author
#23 lore raw

PATCH 20/67 NFSv4.1: Ensure that we handle _all_ SEQUENCE status bits.

In reply to Greg KH

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

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

From: Trond Myklebust <[email protected]>

commit 111d489f0fb431f4ae85d96851fbf8d3248c09d8 upstream.

Currently, the code assumes that the SEQUENCE status bits are mutually exclusive. They are not...

---
 fs/nfs/nfs4state.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
fs/nfs/nfs4state.c +4 -4
@@ -1519,16 +1519,16 @@ void nfs41_handle_sequence_flag_errors(s
 {
 	if (!flags)
 		return;
-	else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
+	if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
 		nfs41_handle_server_reboot(clp);
-	else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
+	if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
 			    SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
 			    SEQ4_STATUS_ADMIN_STATE_REVOKED |
 			    SEQ4_STATUS_LEASE_MOVED))
 		nfs41_handle_state_revoked(clp);
-	else if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
+	if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
 		nfs41_handle_recallable_state_revoked(clp);
-	else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
+	if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
 			    SEQ4_STATUS_BACKCHANNEL_FAULT |
 			    SEQ4_STATUS_CB_PATH_DOWN_SESSION))
 		nfs41_handle_cb_path_down(clp);
author
#24 lore raw

PATCH 21/67 SELinux: Fix RCU deref check warning in sel_netport_insert()

In reply to Greg KH

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

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

From: David Howells <[email protected]>

commit 50345f1ea9cda4618d9c26e590a97ecd4bc7ac75 upstream.

Fix the following bug in sel_netport_insert() where rcu_dereference() should be rcu_dereference_protected() as sel_netport_lock is held.

===================================================
[ INFO: suspicious rcu_dereference_check() usage. ]
---------------------------------------------------
security/selinux/netport.c:127 invoked rcu_dereference_check() without protection!

other info that might help us debug this:

rcu_scheduler_active = 1, debug_locks = 0
1 lock held by ossec-rootcheck/3323:
#0: (sel_netport_lock){+.....}, at: [<ffffffff8117d775>] sel_netport_sid+0xbb/0x226

stack backtrace:
Pid: 3323, comm: ossec-rootcheck Not tainted 3.1.0-rc8-fsdevel+ #1095
Call Trace:
 [<ffffffff8105cfb7>] lockdep_rcu_dereference+0xa7/0xb0
 [<ffffffff8117d871>] sel_netport_sid+0x1b7/0x226
 [<ffffffff8117d6ba>] ? sel_netport_avc_callback+0xbc/0xbc
 [<ffffffff8117556c>] selinux_socket_bind+0x115/0x230
 [<ffffffff810a5388>] ? might_fault+0x4e/0x9e
 [<ffffffff810a53d1>] ? might_fault+0x97/0x9e
 [<ffffffff81171cf4>] security_socket_bind+0x11/0x13
 [<ffffffff812ba967>] sys_bind+0x56/0x95
 [<ffffffff81380dac>] ? sysret_check+0x27/0x62
 [<ffffffff8105b767>] ? trace_hardirqs_on_caller+0x11e/0x155
 [<ffffffff81076fcd>] ? audit_syscall_entry+0x17b/0x1ae
 [<ffffffff811b5eae>] ? trace_hardirqs_on_thunk+0x3a/0x3f
 [<ffffffff81380d7b>] system_call_fastpath+0x16/0x1b
---
 security/selinux/netport.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
security/selinux/netport.c +3 -1
@@ -139,7 +139,9 @@ static void sel_netport_insert(struct se
 	if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) {
 		struct sel_netport *tail;
 		tail = list_entry(
-			rcu_dereference(sel_netport_hash[idx].list.prev),
+			rcu_dereference_protected(
+				sel_netport_hash[idx].list.prev,
+				lockdep_is_held(&sel_netport_lock)),
 			struct sel_netport, list);
 		list_del_rcu(&tail->list);
 		call_rcu(&tail->rcu, sel_netport_free);
author
#25 lore raw

PATCH 22/67 nilfs2: unbreak compat ioctl

In reply to Greg KH

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

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

From: Thomas Meyer <[email protected]>

commit 695c60f21c69e525a89279a5f35bae4ff237afbc upstream.

commit 828b1c50ae ("nilfs2: add compat ioctl") incidentally broke all other NILFS compat ioctls. Make them work again.

---
 fs/nilfs2/ioctl.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
fs/nilfs2/ioctl.c +13 -0
@@ -842,6 +842,19 @@ long nilfs_compat_ioctl(struct file *fil
 	case FS_IOC32_GETVERSION:
 		cmd = FS_IOC_GETVERSION;
 		break;
+	case NILFS_IOCTL_CHANGE_CPMODE:
+	case NILFS_IOCTL_DELETE_CHECKPOINT:
+	case NILFS_IOCTL_GET_CPINFO:
+	case NILFS_IOCTL_GET_CPSTAT:
+	case NILFS_IOCTL_GET_SUINFO:
+	case NILFS_IOCTL_GET_SUSTAT:
+	case NILFS_IOCTL_GET_VINFO:
+	case NILFS_IOCTL_GET_BDESCS:
+	case NILFS_IOCTL_CLEAN_SEGMENTS:
+	case NILFS_IOCTL_SYNC:
+	case NILFS_IOCTL_RESIZE:
+	case NILFS_IOCTL_SET_ALLOC_RANGE:
+		break;
 	default:
 		return -ENOIOCTLCMD;
 	}
author
#26 lore raw

PATCH 23/67 mmc: vub300: fix type of firmware_rom_wait_states module parameter

In reply to Greg KH

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

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

From: Rusty Russell <[email protected]>

commit 61074287c2965edf0fc75b54ae8f4ce99f182669 upstream.

You didn't mean this to be a bool.

---
 drivers/mmc/host/vub300.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/vub300.c +1 -1
@@ -259,7 +259,7 @@ static int firmware_rom_wait_states = 0x
 static int firmware_rom_wait_states = 0x1C;
 #endif
 
-module_param(firmware_rom_wait_states, bool, 0644);
+module_param(firmware_rom_wait_states, int, 0644);
 MODULE_PARM_DESC(firmware_rom_wait_states,
 		 "ROM wait states byte=RRRIIEEE (Reserved Internal External)");
 
author
#27 lore raw

PATCH 24/67 cgroups: fix a css_set not found bug in cgroup_attach_proc

In reply to Greg KH

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

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

From: Mandeep Singh Baines <[email protected]>

commit e0197aae59e55c06db172bfbe1a1cdb8c0e1cab3 upstream.

There is a BUG when migrating a PF_EXITING proc. Since css_set_prefetch() is not called for the PF_EXITING case, find_existing_css_set() will return NULL inside cgroup_task_migrate() causing a BUG.

This bug is easy to reproduce. Create a zombie and echo its pid to cgroup.procs.

$ cat zombie.c
\#include <unistd.h>

int main()
{
if (fork())

      pause();

return 0;
}
$

We are hitting this bug pretty regularly on ChromeOS.

This bug is already fixed by Tejun Heo's cgroup patchset which is targetted for the next merge window:

https://lkml.org/lkml/2011/11/1/356

I've create a smaller patch here which just fixes this bug so that a fix can be merged into the current release and stable.

Downstream-Bug-Report: http://crosbug.com/23953

Cc containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
Cc KAMEZAWA Hiroyuki <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Oleg Nesterov <[email protected]>
Cc Andrew Morton <akpm-de/[email protected]>
Cc Paul Menage <[email protected]>
Cc Olof Johansson <[email protected]>
---
 kernel/cgroup.c |    5 -----
 1 file changed, 5 deletions(-)
kernel/cgroup.c +0 -5
@@ -2095,11 +2095,6 @@ int cgroup_attach_proc(struct cgroup *cg
 			continue;
 		/* get old css_set pointer */
 		task_lock(tsk);
-		if (tsk->flags & PF_EXITING) {
-			/* ignore this task if it's going away */
-			task_unlock(tsk);
-			continue;
-		}
 		oldcg = tsk->cgroups;
 		get_css_set(oldcg);
 		task_unlock(tsk);
author
#28 lore raw

PATCH 25/67 mfd: Fix twl-core oops while calling twl_i2c_* for unbound driver

In reply to Greg KH

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

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

From: Ilya Yanok <[email protected]>

commit 8653be1afd60d6e8c36139b487e375b70357d9ef upstream.

Check inuse variable before trying to access twl_map to prevent dereferencing of uninitialized variable.

---
 drivers/mfd/twl-core.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/mfd/twl-core.c +8 -8
@@ -362,13 +362,13 @@ int twl_i2c_write(u8 mod_no, u8 *value,
 		pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
 		return -EPERM;
 	}
-	sid = twl_map[mod_no].sid;
-	twl = &twl_modules[sid];
-
 	if (unlikely(!inuse)) {
-		pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+		pr_err("%s: not initialized\n", DRIVER_NAME);
 		return -EPERM;
 	}
+	sid = twl_map[mod_no].sid;
+	twl = &twl_modules[sid];
+
 	mutex_lock(&twl->xfer_lock);
 	/*
 	 * [MSG1]: fill the register address data
@@ -419,13 +419,13 @@ int twl_i2c_read(u8 mod_no, u8 *value, u
 		pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
 		return -EPERM;
 	}
-	sid = twl_map[mod_no].sid;
-	twl = &twl_modules[sid];
-
 	if (unlikely(!inuse)) {
-		pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+		pr_err("%s: not initialized\n", DRIVER_NAME);
 		return -EPERM;
 	}
+	sid = twl_map[mod_no].sid;
+	twl = &twl_modules[sid];
+
 	mutex_lock(&twl->xfer_lock);
 	/* [MSG1] fill the register address data */
 	msg = &twl->xfer_msg[0];
author
#29 lore raw

PATCH 26/67 vfs: __read_cache_page should use gfp argument rather than GFP_KERNEL

In reply to Greg KH

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

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

From: Dave Kleikamp <[email protected]>

commit e6f67b8c05f5e129e126f4409ddac6f25f58ffcb upstream.

lockdep reports a deadlock in jfs because a special inode's rw semaphore is taken recursively. The mapping's gfp mask is GFP_NOFS, but is not used when __read_cache_page() calls add_to_page_cache_lru().

---
 mm/filemap.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
mm/filemap.c +2 -5
@@ -1807,7 +1807,7 @@ repeat:
 		page = __page_cache_alloc(gfp | __GFP_COLD);
 		if (!page)
 			return ERR_PTR(-ENOMEM);
-		err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
+		err = add_to_page_cache_lru(page, mapping, index, gfp);
 		if (unlikely(err)) {
 			page_cache_release(page);
 			if (err == -EEXIST)
@@ -1904,10 +1904,7 @@ static struct page *wait_on_page_read(st
  * @gfp:	the page allocator flags to use if allocating
  *
  * This is the same as "read_mapping_page(mapping, index, NULL)", but with
- * any new page allocations done using the specified allocation flags. Note
- * that the Radix tree operations will still use GFP_KERNEL, so you can't
- * expect to do this atomically or anything like that - but you can pass in
- * other page requirements.
+ * any new page allocations done using the specified allocation flags.
  *
  * If the page does not get brought uptodate, return -EIO.
  */
author
#30 lore raw

PATCH 27/67 media: s5p-fimc: Use correct fourcc for RGB565 colour format

In reply to Greg KH

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

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

From: Sylwester Nawrocki <[email protected]>

commit f83f71fda27650ae43558633be93652577dbc38c upstream.

With 16-bit RGB565 colour format pixels are stored by the device in memory in the following order:

    | b3  | b2  | b1  | b0  |
   ~+-----+-----+-----+-----+
    | R5 G6 B5  | R5 G6 B5  |

This corresponds to V4L2_PIX_FMT_RGB565 fourcc, not V4L2_PIX_FMT_RGB565X. This change is required to avoid trouble when setting up video pipeline with the s5p-tv devices, so the colour formats at both devices can be properly matched.

---
 drivers/media/video/s5p-fimc/fimc-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/video/s5p-fimc/fimc-core.c +1 -1
@@ -36,7 +36,7 @@ static char *fimc_clocks[MAX_FIMC_CLOCKS
 static struct fimc_fmt fimc_formats[] = {
 	{
 		.name		= "RGB565",
-		.fourcc		= V4L2_PIX_FMT_RGB565X,
+		.fourcc		= V4L2_PIX_FMT_RGB565,
 		.depth		= { 16 },
 		.color		= S5P_FIMC_RGB565,
 		.memplanes	= 1,
author
#31 lore raw

PATCH 28/67 ath9k: fix max phy rate at rate control init

In reply to Greg KH

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

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

From: Rajkumar Manoharan <[email protected]>

commit 10636bc2d60942254bda149827b922c41f4cb4af upstream.

The stations always chooses 1Mbps for all trasmitting frames, whenever the AP is configured to lock the supported rates. As the max phy rate is always set with the 4th from highest phy rate, this assumption might be wrong if we have less than that. Fix that.

---
 drivers/net/wireless/ath/ath9k/rc.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/ath/ath9k/rc.c +3 -1
@@ -1252,7 +1252,9 @@ static void ath_rc_init(struct ath_softc
 
 	ath_rc_priv->max_valid_rate = k;
 	ath_rc_sort_validrates(rate_table, ath_rc_priv);
-	ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
+	ath_rc_priv->rate_max_phy = (k > 4) ?
+					ath_rc_priv->valid_rate_index[k-4] :
+					ath_rc_priv->valid_rate_index[k-1];
 	ath_rc_priv->rate_table = rate_table;
 
 	ath_dbg(common, ATH_DBG_CONFIG,
author
#32 lore raw

PATCH 29/67 iwlwifi: do not set the sequence control bit is not needed

In reply to Greg KH

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

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

From: Wey-Yi Guy <[email protected]>

commit 123877b80ed62c3b897c53357b622574c023b642 upstream.

Check the IEEE80211_TX_CTL_ASSIGN_SEQ flag from mac80211, then decide how to set the TX_CMD_FLG_SEQ_CTL_MSK bit. Setting the wrong bit in BAR frame whill make the firmware to increment the sequence number which is incorrect and cause unknown behavior.

---
 drivers/net/wireless/iwlwifi/iwl-agn-tx.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/iwl-agn-tx.c +4 -1
@@ -385,7 +385,10 @@ static void iwlagn_tx_cmd_build_basic(st
 		tx_cmd->tid_tspec = qc[0] & 0xf;
 		tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
 	} else {
-		tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+		if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+			tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
+		else
+			tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
 	}
 
 	priv->cfg->ops->utils->tx_cmd_protection(priv, info, fc, &tx_flags);
author
#33 lore raw

PATCH 30/67 iwlwifi: allow to switch to HT40 if not associated

In reply to Greg KH

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

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

From: Wey-Yi Guy <[email protected]>

commit 78feb35b8161acd95c33a703ed6ab6f554d29387 upstream.

My previous patch
34a5b4b6af104cf18eb50748509528b9bdbc4036 iwlwifi: do not re-configure HT40 after associated

Fix the case of HT40 after association on specified AP, but it break the association for some APs and cause not able to establish connection. We need to address HT40 before and after addociation.

---
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +2 -2
@@ -490,8 +490,8 @@ int iwlagn_mac_config(struct ieee80211_h
 			if (ctx->ht.enabled) {
 				/* if HT40 is used, it should not change
 				 * after associated except channel switch */
-				if (iwl_is_associated_ctx(ctx) &&
-				     !ctx->ht.is_40mhz)
+				if (!ctx->ht.is_40mhz ||
+						!iwl_is_associated_ctx(ctx))
 					iwlagn_config_ht40(conf, ctx);
 			} else
 				ctx->ht.is_40mhz = false;
author
#34 lore raw

PATCH 31/67 memcg: keep root group unchanged if creation fails

In reply to Greg KH

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

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

From: Hillf Danton <[email protected]>

commit a41c58a6665cc995e237303b05db42100b71b65e upstream.

If the request is to create non-root group and we fail to meet it, we should leave the root unchanged.

---
 mm/memcontrol.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
mm/memcontrol.c +1 -2
@@ -4963,9 +4963,9 @@ mem_cgroup_create(struct cgroup_subsys *
 		int cpu;
 		enable_swap_cgroup();
 		parent = NULL;
-		root_mem_cgroup = mem;
 		if (mem_cgroup_soft_limit_tree_init())
 			goto free_out;
+		root_mem_cgroup = mem;
 		for_each_possible_cpu(cpu) {
 			struct memcg_stock_pcp *stock =
 						&per_cpu(memcg_stock, cpu);
@@ -5004,7 +5004,6 @@ mem_cgroup_create(struct cgroup_subsys *
 	return &mem->css;
 free_out:
 	__mem_cgroup_free(mem);
-	root_mem_cgroup = NULL;
 	return ERR_PTR(error);
 }
 
author
#35 lore raw

PATCH 32/67 VFS: Fix race between CPU hotplug and lglocks

In reply to Greg KH

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

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

From: "Srivatsa S. Bhat" <[email protected]>

commit e30e2fdfe56288576ee9e04dbb06b4bd5f282203 upstream.

Currently, the *_global_[un]lock_online() routines are not at all synchronized with CPU hotplug. Soft-lockups detected as a consequence of this race was reported earlier at https://lkml.org/lkml/2011/8/24/185. (Thanks to Cong Meng for finding out that the root-cause of this issue is the race condition between br_write_[un]lock() and CPU hotplug, which results in the lock states getting messed up).

Fixing this race by just adding {get,put}_online_cpus() at appropriate places in *_global_[un]lock_online() is not a good option, because, then suddenly br_write_[un]lock() would become blocking, whereas they have been kept as non-blocking all this time, and we would want to keep them that way.

So, overall, we want to ensure 3 things:
1. br_write_lock() and br_write_unlock() must remain as non-blocking.
2. The corresponding lock and unlock of the per-cpu spinlocks must not happen for different sets of CPUs.
3. Either prevent any new CPU online operation in between this lock-unlock, or ensure that the newly onlined CPU does not proceed with its corresponding per-cpu spinlock unlocked.

To achieve all this:
(a) We introduce a new spinlock that is taken by the *_global_lock_online() routine and released by the *_global_unlock_online() routine.
(b) We register a callback for CPU hotplug notifications, and this callback takes the same spinlock as above.
(c) We maintain a bitmap which is close to the cpu_online_mask, and once it is initialized in the lock_init() code, all future updates to it are done in the callback, under the above spinlock.
(d) The above bitmap is used (instead of cpu_online_mask) while locking and unlocking the per-cpu locks.

The callback takes the spinlock upon the CPU_UP_PREPARE event. So, if the br_write_lock-unlock sequence is in progress, the callback keeps spinning, thus preventing the CPU online operation till the lock-unlock sequence is complete. This takes care of requirement (3).

The bitmap that we maintain remains unmodified throughout the lock-unlock sequence, since all updates to it are managed by the callback, which takes the same spinlock as the one taken by the lock code and released only by the unlock routine. Combining this with (d) above, satisfies requirement (2).

Overall, since we use a spinlock (mentioned in (a)) to prevent CPU hotplug operations from racing with br_write_lock-unlock, requirement (1) is also taken care of.

By the way, it is to be noted that a CPU offline operation can actually run in parallel with our lock-unlock sequence, because our callback doesn't react to notifications earlier than CPU_DEAD (in order to maintain our bitmap properly). And this means, since we use our own bitmap (which is stale, on purpose) during the lock-unlock sequence, we could end up unlocking the per-cpu lock of an offline CPU (because we had locked it earlier, when the CPU was online), in order to satisfy requirement (2). But this is harmless, though it looks a bit awkward.

---
 include/linux/lglock.h |   36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)
include/linux/lglock.h +32 -4
@@ -22,6 +22,7 @@
 #include <linux/spinlock.h>
 #include <linux/lockdep.h>
 #include <linux/percpu.h>
+#include <linux/cpu.h>
 
 /* can make br locks by using local lock for read side, global lock for write */
 #define br_lock_init(name)	name##_lock_init()
@@ -72,9 +73,31 @@
 
 #define DEFINE_LGLOCK(name)						\
 									\
+ DEFINE_SPINLOCK(name##_cpu_lock);					\
+ cpumask_t name##_cpus __read_mostly;					\
  DEFINE_PER_CPU(arch_spinlock_t, name##_lock);				\
  DEFINE_LGLOCK_LOCKDEP(name);						\
 									\
+ static int								\
+ name##_lg_cpu_callback(struct notifier_block *nb,			\
+				unsigned long action, void *hcpu)	\
+ {									\
+	switch (action & ~CPU_TASKS_FROZEN) {				\
+	case CPU_UP_PREPARE:						\
+		spin_lock(&name##_cpu_lock);				\
+		cpu_set((unsigned long)hcpu, name##_cpus);		\
+		spin_unlock(&name##_cpu_lock);				\
+		break;							\
+	case CPU_UP_CANCELED: case CPU_DEAD:				\
+		spin_lock(&name##_cpu_lock);				\
+		cpu_clear((unsigned long)hcpu, name##_cpus);		\
+		spin_unlock(&name##_cpu_lock);				\
+	}								\
+	return NOTIFY_OK;						\
+ }									\
+ static struct notifier_block name##_lg_cpu_notifier = {		\
+	.notifier_call = name##_lg_cpu_callback,			\
+ };									\
  void name##_lock_init(void) {						\
 	int i;								\
 	LOCKDEP_INIT_MAP(&name##_lock_dep_map, #name, &name##_lock_key, 0); \
@@ -83,6 +106,11 @@
 		lock = &per_cpu(name##_lock, i);			\
 		*lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;	\
 	}								\
+	register_hotcpu_notifier(&name##_lg_cpu_notifier);		\
+	get_online_cpus();						\
+	for_each_online_cpu(i)						\
+		cpu_set(i, name##_cpus);				\
+	put_online_cpus();						\
  }									\
  EXPORT_SYMBOL(name##_lock_init);					\
 									\
@@ -124,9 +152,9 @@
 									\
  void name##_global_lock_online(void) {					\
 	int i;								\
-	preempt_disable();						\
+	spin_lock(&name##_cpu_lock);					\
 	rwlock_acquire(&name##_lock_dep_map, 0, 0, _RET_IP_);		\
-	for_each_online_cpu(i) {					\
+	for_each_cpu(i, &name##_cpus) {					\
 		arch_spinlock_t *lock;					\
 		lock = &per_cpu(name##_lock, i);			\
 		arch_spin_lock(lock);					\
@@ -137,12 +165,12 @@
  void name##_global_unlock_online(void) {				\
 	int i;								\
 	rwlock_release(&name##_lock_dep_map, 1, _RET_IP_);		\
-	for_each_online_cpu(i) {					\
+	for_each_cpu(i, &name##_cpus) {					\
 		arch_spinlock_t *lock;					\
 		lock = &per_cpu(name##_lock, i);			\
 		arch_spin_unlock(lock);					\
 	}								\
-	preempt_enable();						\
+	spin_unlock(&name##_cpu_lock);					\
  }									\
  EXPORT_SYMBOL(name##_global_unlock_online);				\
 									\
author
#36 lore raw

PATCH 33/67 ARM:imx:fix pwm period value

In reply to Greg KH

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

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

From: Jason Chen <[email protected]>

commit 5776ac2eb33164c77cdb4d2b48feee15616eaba3 upstream.

According to imx pwm RM, the real period value should be PERIOD value in PWMPR plus 2.

PWMO (Hz) = PCLK(Hz) / (period +2)

---
 arch/arm/plat-mxc/pwm.c |    9 +++++++++
 1 file changed, 9 insertions(+)
arch/arm/plat-mxc/pwm.c +9 -0
@@ -77,6 +77,15 @@ int pwm_config(struct pwm_device *pwm, i
 		do_div(c, period_ns);
 		duty_cycles = c;
 
+		/*
+		 * according to imx pwm RM, the real period value should be
+		 * PERIOD value in PWMPR plus 2.
+		 */
+		if (period_cycles > 2)
+			period_cycles -= 2;
+		else
+			period_cycles = 0;
+
 		writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
 		writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
 
author
#37 lore raw

PATCH 34/67 ARM: 7214/1: mmc: mmci: Fixup handling of MCI_STARTBITERR

In reply to Greg KH

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

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

From: Ulf Hansson <[email protected]>

commit b63038d6f4ca5d1849ce01d9fc5bb9cb426dec73 upstream.

The interrupt was previously enabled and then correctly cleared. Now we also handle it correctly.

---
 drivers/mmc/host/mmci.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/mmc/host/mmci.c +5 -3
@@ -557,7 +557,8 @@ mmci_data_irq(struct mmci_host *host, st
 	      unsigned int status)
 {
 	/* First check for errors */
-	if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
+	if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR|
+		      MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
 		u32 remain, success;
 
 		/* Terminate the DMA transfer */
@@ -837,8 +838,9 @@ static irqreturn_t mmci_irq(int irq, voi
 		dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status);
 
 		data = host->data;
-		if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|
-			      MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND) && data)
+		if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR|
+			      MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND|
+			      MCI_DATABLOCKEND) && data)
 			mmci_data_irq(host, data, status);
 
 		cmd = host->cmd;
author
#38 lore raw

PATCH 35/67 ARM: 7220/1: mmc: mmci: Fixup error handling for dma

In reply to Greg KH

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

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

From: Ulf Hansson <[email protected]>

commit 3b6e3c73851a9a4b0e6ed9d378206341dd65e8a5 upstream.

When getting a cmd irq during an ongoing data transfer with dma, the dma job were never terminated. This is now corrected.

---
 drivers/mmc/host/mmci.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/mmc/host/mmci.c +5 -1
@@ -637,8 +637,12 @@ mmci_cmd_irq(struct mmci_host *host, str
 	}
 
 	if (!cmd->data || cmd->error) {
-		if (host->data)
+		if (host->data) {
+			/* Terminate the DMA transfer */
+			if (dma_inprogress(host))
+				mmci_dma_data_error(host);
 			mmci_stop_data(host);
+		}
 		mmci_request_end(host, cmd->mrq);
 	} else if (!(cmd->data->flags & MMC_DATA_READ)) {
 		mmci_start_data(host, cmd->data);
author
#39 lore raw

PATCH 36/67 oprofile, arm/sh: Fix oprofile_arch_exit() linkage issue

In reply to Greg KH

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

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

From: Vladimir Zapolskiy <[email protected]>

commit 55205c916e179e09773d98d290334d319f45ac6b upstream.

This change fixes a linking problem, which happens if oprofile is selected to be compiled as built-in:

oprofile_arch_exit' referenced in section .init.text' of arch/arm/oprofile/built-in.o: defined in discarded section `.exit.text' of arch/arm/oprofile/built-in.o

The problem is appeared after commit 87121ca504, which introduced oprofile_arch_exit() calls from __init function. Note that the aforementioned commit has been backported to stable branches, and the problem is known to be reproduced at least with 3.0.13 and 3.1.5 kernels.

---
 arch/arm/oprofile/common.c |    2 +-
 arch/sh/oprofile/common.c  |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
arch/arm/oprofile/common.c +1 -1
@@ -116,7 +116,7 @@ int __init oprofile_arch_init(struct opr
 	return oprofile_perf_init(ops);
 }
 
-void __exit oprofile_arch_exit(void)
+void oprofile_arch_exit(void)
 {
 	oprofile_perf_exit();
 }
arch/sh/oprofile/common.c +2 -2
@@ -49,7 +49,7 @@ int __init oprofile_arch_init(struct opr
 	return oprofile_perf_init(ops);
 }
 
-void __exit oprofile_arch_exit(void)
+void oprofile_arch_exit(void)
 {
 	oprofile_perf_exit();
 	kfree(sh_pmu_op_name);
@@ -60,5 +60,5 @@ int __init oprofile_arch_init(struct opr
 	ops->backtrace = sh_backtrace;
 	return -ENODEV;
 }
-void __exit oprofile_arch_exit(void) {}
+void oprofile_arch_exit(void) {}
 #endif /* CONFIG_HW_PERF_EVENTS */
author
#40 lore raw

PATCH 37/67 futex: Fix uninterruptible loop due to gate_area

In reply to Greg KH

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

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

From: Hugh Dickins <[email protected]>

commit e6780f7243eddb133cc20ec37fa69317c218b709 upstream.

It was found (by Sasha) that if you use a futex located in the gate area we get stuck in an uninterruptible infinite loop, much like the ZERO_PAGE issue.

While looking at this problem, PeterZ realized you'll get into similar trouble when hitting any install_special_pages() mapping. And are there still drivers setting up their own special mmaps without page->mapping, and without special VM or pte flags to make get_user_pages fail?

In most cases, if page->mapping is NULL, we do not need to retry at all:
Linus points out that even /proc/sys/vm/drop_caches poses no problem, because it ends up using remove_mapping(), which takes care not to interfere when the page reference count is raised.

But there is still one case which does need a retry: if memory pressure called shmem_writepage in between get_user_pages_fast dropping page table lock and our acquiring page lock, then the page gets switched from filecache to swapcache (and ->mapping set to NULL) whatever the refcount. Fault it back in to get the page->mapping needed for key->shared.inode.

---
 kernel/futex.c |   28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)
kernel/futex.c +20 -8
@@ -314,17 +314,29 @@ again:
 #endif
 
 	lock_page(page_head);
+
+	/*
+	 * If page_head->mapping is NULL, then it cannot be a PageAnon
+	 * page; but it might be the ZERO_PAGE or in the gate area or
+	 * in a special mapping (all cases which we are happy to fail);
+	 * or it may have been a good file page when get_user_pages_fast
+	 * found it, but truncated or holepunched or subjected to
+	 * invalidate_complete_page2 before we got the page lock (also
+	 * cases which we are happy to fail).  And we hold a reference,
+	 * so refcount care in invalidate_complete_page's remove_mapping
+	 * prevents drop_caches from setting mapping to NULL beneath us.
+	 *
+	 * The case we do have to guard against is when memory pressure made
+	 * shmem_writepage move it from filecache to swapcache beneath us:
+	 * an unlikely race, but we do need to retry for page_head->mapping.
+	 */
 	if (!page_head->mapping) {
+		int shmem_swizzled = PageSwapCache(page_head);
 		unlock_page(page_head);
 		put_page(page_head);
-		/*
-		* ZERO_PAGE pages don't have a mapping. Avoid a busy loop
-		* trying to find one. RW mapping would have COW'd (and thus
-		* have a mapping) so this page is RO and won't ever change.
-		*/
-		if ((page_head == ZERO_PAGE(address)))
-			return -EFAULT;
-		goto again;
+		if (shmem_swizzled)
+			goto again;
+		return -EFAULT;
 	}
 
 	/*
author
#41 lore raw

PATCH 38/67 watchdog: hpwdt: Changes to handle NX secure bit in 32bit path

In reply to Greg KH

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

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

From: "Mingarelli, Thomas" <[email protected]>

commit e67d668e147c3b4fec638c9e0ace04319f5ceccd upstream.

This patch makes use of the set_memory_x() kernel API in order to make necessary BIOS calls to source NMIs.

This is needed for SLES11 SP2 and the latest upstream kernel as it appears the NX Execute Disable has grown in its control.

Signed-off by: Thomas Mingarelli <[email protected]> Signed-off by: Wim Van Sebroeck <[email protected]>

---
 drivers/watchdog/hpwdt.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/watchdog/hpwdt.c +4 -1
@@ -216,6 +216,7 @@ static int __devinit cru_detect(unsigned
 
 	cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
 
+	set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE));
 	asminline_call(&cmn_regs, bios32_entrypoint);
 
 	if (cmn_regs.u1.ral != 0) {
@@ -233,8 +234,10 @@ static int __devinit cru_detect(unsigned
 		if ((physical_bios_base + physical_bios_offset)) {
 			cru_rom_addr =
 				ioremap(cru_physical_address, cru_length);
-			if (cru_rom_addr)
+			if (cru_rom_addr) {
+				set_memory_x((unsigned long)cru_rom_addr, cru_length);
 				retval = 0;
+			}
 		}
 
 		printk(KERN_DEBUG "hpwdt: CRU Base Address:   0x%lx\n",
author
#42 lore raw

PATCH 39/67 drm/radeon/kms: bail on BTC parts if MC ucode is missing

In reply to Greg KH

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

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

From: Alex Deucher <[email protected]>

commit 77e00f2ea94abee1ad13bdfde19cf7aa25992b0e upstream.

We already do this for cayman, need to also do it for BTC parts. The default memory and voltage setup is not adequate for advanced operation. Continuing will result in an unusable display.

---
 drivers/gpu/drm/radeon/evergreen.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/gpu/drm/radeon/evergreen.c +12 -0
@@ -3257,6 +3257,18 @@ int evergreen_init(struct radeon_device
 			rdev->accel_working = false;
 		}
 	}
+
+	/* Don't start up if the MC ucode is missing on BTC parts.
+	 * The default clocks and voltages before the MC ucode
+	 * is loaded are not suffient for advanced operations.
+	 */
+	if (ASIC_IS_DCE5(rdev)) {
+		if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
+			DRM_ERROR("radeon: MC ucode required for NI+.\n");
+			return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 
author
#43 lore raw

PATCH 40/67 mm: hugetlb: fix non-atomic enqueue of huge page

In reply to Greg KH

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

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

From: Hillf Danton <[email protected]>

commit b0365c8d0cb6e79eb5f21418ae61ab511f31b575 upstream.

If a huge page is enqueued under the protection of hugetlb_lock, then the operation is atomic and safe.

---
 mm/hugetlb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/hugetlb.c +1 -1
@@ -901,7 +901,6 @@ retry:
 	h->resv_huge_pages += delta;
 	ret = 0;
 
-	spin_unlock(&hugetlb_lock);
 	/* Free the needed pages to the hugetlb pool */
 	list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
 		if ((--needed) < 0)
@@ -915,6 +914,7 @@ retry:
 		VM_BUG_ON(page_count(page));
 		enqueue_huge_page(h, page);
 	}
+	spin_unlock(&hugetlb_lock);
 
 	/* Free unnecessary surplus pages to the buddy allocator */
 free:
author
#44 lore raw

PATCH 41/67 mpt2sas crashes on shutdown

In reply to Greg KH

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

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

From: David Miller <[email protected]>

[Fixed differently in 3.2]

The mpt2sas driver accesses I/O space as virtual addresses when saving and restoring the MSIX table, this only works by luck on x86.

One needs to use the appropriate {read,write}{b,w,l}() APIs.

This is fixed in v3.2.x because all of this code got rewritten for NUMA I/O support.

But both 3.0.x and 3.1.x still have this bug, and my Niagara sparc machines crash on shutdown every single time due to this bug making my -stable work more difficult than it needs to be.

---
 drivers/scsi/mpt2sas/mpt2sas_base.c |    6 +++---
 drivers/scsi/mpt2sas/mpt2sas_base.h |    2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/scsi/mpt2sas/mpt2sas_base.c +3 -3
@@ -1096,7 +1096,7 @@ _base_save_msix_table(struct MPT2SAS_ADA
 		return;
 
 	for (i = 0; i < ioc->msix_vector_count; i++)
-		ioc->msix_table_backup[i] = ioc->msix_table[i];
+		ioc->msix_table_backup[i] = readl(&ioc->msix_table[i]);
 }
 
 /**
@@ -1113,7 +1113,7 @@ _base_restore_msix_table(struct MPT2SAS_
 		return;
 
 	for (i = 0; i < ioc->msix_vector_count; i++)
-		ioc->msix_table[i] = ioc->msix_table_backup[i];
+		writel(ioc->msix_table_backup[i], &ioc->msix_table[i]);
 }
 
 /**
@@ -1144,7 +1144,7 @@ _base_check_enable_msix(struct MPT2SAS_A
 	/* get msix table  */
 	pci_read_config_dword(ioc->pdev, base + 4, &msix_table_offset);
 	msix_table_offset &= 0xFFFFFFF8;
-	ioc->msix_table = (u32 *)((void *)ioc->chip + msix_table_offset);
+	ioc->msix_table = ((void __iomem *)ioc->chip + msix_table_offset);
 
 	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, "
 	    "vector_count(%d), table_offset(0x%08x), table(%p)\n", ioc->name,
drivers/scsi/mpt2sas/mpt2sas_base.h +1 -1
@@ -768,7 +768,7 @@ struct MPT2SAS_ADAPTER {
 
 	u8		msix_enable;
 	u16		msix_vector_count;
-	u32		*msix_table;
+	u32 __iomem	*msix_table;
 	u32		*msix_table_backup;
 	u32		ioc_reset_count;
 
author
#45 lore raw

PATCH 42/67 sparc64: Fix MSIQ HV call ordering in pci_sun4v_msiq_build_irq().

In reply to Greg KH

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

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

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

[ Upstream commit 7cc8583372a21d98a23b703ad96cab03180b5030 ]

This silently was working for many years and stopped working on Niagara-T3 machines.

We need to set the MSIQ to VALID before we can set it's state to IDLE.

On Niagara-T3, setting the state to IDLE first was causing HV_EINVAL errors. The hypervisor documentation says, rather ambiguously, that the MSIQ must be "initialized" before one can set the state.

I previously understood this to mean merely that a successful setconf() operation has been performed on the MSIQ, which we have done at this point. But it seems to also mean that it has been set VALID too.

---
 arch/sparc/kernel/pci_sun4v.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/sparc/kernel/pci_sun4v.c +2 -2
@@ -848,10 +848,10 @@ static int pci_sun4v_msiq_build_irq(stru
 	if (!irq)
 		return -ENOMEM;
 
-	if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE))
-		return -EINVAL;
 	if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID))
 		return -EINVAL;
+	if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE))
+		return -EINVAL;
 
 	return irq;
 }
author
#46 lore raw

PATCH 43/67 sparc32: Be less strict in matching %lo part of relocation.

In reply to Greg KH

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

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

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

[ Upstream commit b1f44e13a525d2ffb7d5afe2273b7169d6f2222e ]

The "(insn & 0x01800000) != 0x01800000" test matches 'restore' but that is a legitimate place to see the %lo() part of a 32-bit symbol relocation, particularly in tail calls.

---
 arch/sparc/mm/btfixup.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/sparc/mm/btfixup.c +1 -2
@@ -302,8 +302,7 @@ void __init btfixup(void)
 				case 'i':	/* INT */
 					if ((insn & 0xc1c00000) == 0x01000000) /* %HI */
 						set_addr(addr, q[1], fmangled, (insn & 0xffc00000) | (p[1] >> 10));
-					else if ((insn & 0x80002000) == 0x80002000 &&
-					         (insn & 0x01800000) != 0x01800000) /* %LO */
+					else if ((insn & 0x80002000) == 0x80002000) /* %LO */
 						set_addr(addr, q[1], fmangled, (insn & 0xffffe000) | (p[1] & 0x3ff));
 					else {
 						prom_printf(insn_i, p, addr, insn);
author
#47 lore raw

PATCH 44/67 sparc64: Patch sun4v code sequences properly on module load.

In reply to Greg KH

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

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

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

[ Upstream commit 0b64120cceb86e93cb1bda0dc055f13016646907 ]

Some of the sun4v code patching occurs in inline functions visible to, and usable by, modules.

Therefore we have to patch them up during module load.

---
 arch/sparc/kernel/entry.h    |    7 ++++++
 arch/sparc/kernel/module.c   |   27 ++++++++++++++++++++++++
 arch/sparc/kernel/setup_64.c |   48 +++++++++++++++++++++++++------------------
 3 files changed, 63 insertions(+), 19 deletions(-)
arch/sparc/kernel/entry.h +7 -0
@@ -42,6 +42,9 @@ extern void fpsave(unsigned long *fpregs
 extern void fpload(unsigned long *fpregs, unsigned long *fsr);
 
 #else /* CONFIG_SPARC32 */
+
+#include <asm/trap_block.h>
+
 struct popc_3insn_patch_entry {
 	unsigned int	addr;
 	unsigned int	insns[3];
@@ -57,6 +60,10 @@ extern struct popc_6insn_patch_entry __p
 	__popc_6insn_patch_end;
 
 extern void __init per_cpu_patch(void);
+extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
+				    struct sun4v_1insn_patch_entry *);
+extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
+				    struct sun4v_2insn_patch_entry *);
 extern void __init sun4v_patch(void);
 extern void __init boot_cpu_id_too_large(int cpu);
 extern unsigned int dcache_parity_tl1_occurred;
arch/sparc/kernel/module.c +27 -0
@@ -17,6 +17,8 @@
 #include <asm/processor.h>
 #include <asm/spitfire.h>
 
+#include "entry.h"
+
 #ifdef CONFIG_SPARC64
 
 #include <linux/jump_label.h>
@@ -220,6 +222,29 @@ int apply_relocate_add(Elf_Shdr *sechdrs
 }
 
 #ifdef CONFIG_SPARC64
+static void do_patch_sections(const Elf_Ehdr *hdr,
+			      const Elf_Shdr *sechdrs)
+{
+	const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL;
+	char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+	for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+		if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name))
+			sun4v_1insn = s;
+		if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name))
+			sun4v_2insn = s;
+	}
+
+	if (sun4v_1insn && tlb_type == hypervisor) {
+		void *p = (void *) sun4v_1insn->sh_addr;
+		sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size);
+	}
+	if (sun4v_2insn && tlb_type == hypervisor) {
+		void *p = (void *) sun4v_2insn->sh_addr;
+		sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size);
+	}
+}
+
 int module_finalize(const Elf_Ehdr *hdr,
 		    const Elf_Shdr *sechdrs,
 		    struct module *me)
@@ -227,6 +252,8 @@ int module_finalize(const Elf_Ehdr *hdr,
 	/* make jump label nops */
 	jump_label_apply_nops(me);
 
+	do_patch_sections(hdr, sechdrs);
+
 	/* Cheetah's I-cache is fully coherent.  */
 	if (tlb_type == spitfire) {
 		unsigned long va;
arch/sparc/kernel/setup_64.c +29 -19

69 lines not on this page · raw message

author
#48 lore raw

PATCH 45/67 sparc: Kill custom io_remap_pfn_range().

In reply to Greg KH

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

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

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

[ Upstream commit 3e37fd3153ac95088a74f5e7c569f7567e9f993a ]

To handle the large physical addresses, just make a simple wrapper around remap_pfn_range() like MIPS does.

---
 arch/sparc/include/asm/pgtable_32.h |   20 +++-
 arch/sparc/include/asm/pgtable_64.h |   20 +++-
 arch/sparc/mm/Makefile              |    1 
 arch/sparc/mm/generic_32.c          |   98 ---------------------
 arch/sparc/mm/generic_64.c          |  164 ------------------------------------
 5 files changed, 32 insertions(+), 271 deletions(-)
 delete mode 100644 arch/sparc/mm/generic_32.c
 delete mode 100644 arch/sparc/mm/generic_64.c
arch/sparc/include/asm/pgtable_32.h +16 -4
@@ -431,10 +431,6 @@ extern unsigned long *sparc_valid_addr_b
 #define kern_addr_valid(addr) \
 	(test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))
 
-extern int io_remap_pfn_range(struct vm_area_struct *vma,
-			      unsigned long from, unsigned long pfn,
-			      unsigned long size, pgprot_t prot);
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  * its high 4 bits.  These macros/functions put it there or get it from there.
@@ -443,6 +439,22 @@ extern int io_remap_pfn_range(struct vm_
 #define GET_IOSPACE(pfn)		(pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)			(pfn & 0x0fffffffUL)
 
+extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+			   unsigned long, pgprot_t);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+				     unsigned long from, unsigned long pfn,
+				     unsigned long size, pgprot_t prot)
+{
+	unsigned long long offset, space, phys_base;
+
+	offset = ((unsigned long long) GET_PFN(pfn)) << PAGE_SHIFT;
+	space = GET_IOSPACE(pfn);
+	phys_base = offset | (space << 32ULL);
+
+	return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
+}
+
 #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
 ({									  \
arch/sparc/include/asm/pgtable_64.h +16 -4
@@ -750,10 +750,6 @@ static inline bool kern_addr_valid(unsig
 
 extern int page_in_phys_avail(unsigned long paddr);
 
-extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-			       unsigned long pfn,
-			       unsigned long size, pgprot_t prot);
-
 /*
  * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
  * its high 4 bits.  These macros/functions put it there or get it from there.
@@ -762,6 +758,22 @@ extern int io_remap_pfn_range(struct vm_
 #define GET_IOSPACE(pfn)		(pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)			(pfn & 0x0fffffffffffffffUL)
 
+extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
+			   unsigned long, pgprot_t);
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+				     unsigned long from, unsigned long pfn,
+				     unsigned long size, pgprot_t prot)
+{
+	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+	int space = GET_IOSPACE(pfn);
+	unsigned long phys_base;
+
+	phys_base = offset | (((unsigned long) space) << 32UL);
+
+	return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
+}
+
 #include <asm-generic/pgtable.h>
 
 /* We provide our own get_unmapped_area to cope with VA holes and
arch/sparc/mm/Makefile +0 -1
@@ -8,7 +8,6 @@ obj-$(CONFIG_SPARC64)   += ultra.o tlb.o
 obj-y                   += fault_$(BITS).o
 obj-y                   += init_$(BITS).o
 obj-$(CONFIG_SPARC32)   += loadmmu.o
-obj-y                   += generic_$(BITS).o
 obj-$(CONFIG_SPARC32)   += extable.o btfixup.o srmmu.o iommu.o io-unit.o
 obj-$(CONFIG_SPARC32)   += hypersparc.o viking.o tsunami.o swift.o
 obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
arch/sparc/mm/generic_32.c deleted +0 -98

98 lines not on this page · raw message

arch/sparc/mm/generic_64.c deleted +0 -164

164 lines not on this page · raw message

author
#49 lore raw

PATCH 46/67 sparc32: Remove non-kernel code from memcpy implementation.

In reply to Greg KH

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

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

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

[ Upstream commit 045b7de9ca0cf09f1adc3efa467f668b89238390 ]

---
 arch/sparc/lib/memcpy.S |  607 ------------------------------------------------
 1 file changed, 2 insertions(+), 605 deletions(-)
arch/sparc/lib/memcpy.S +2 -605
@@ -7,17 +7,12 @@
  * Copyright (C) 1996 Jakub Jelinek ([email protected])
  */
 
-#ifdef __KERNEL__
-
-#define FUNC(x) 											\
+#define FUNC(x) 		\
 	.globl	x;		\
 	.type	x,@function;	\
-	.align	4;											\
+	.align	4;		\
 x:
 
-#undef FASTER_REVERSE
-#undef FASTER_NONALIGNED
-#define FASTER_ALIGNED
 
 /* In kernel these functions don't return a value.
  * One should use macros in asm/string.h for that purpose.
@@ -26,21 +21,6 @@ x:
 #define SETUP_RETL
 #define RETL_INSN	clr	%o0
 
-#else
-
-/* libc */
-
-#include "DEFS.h"
-
-#define FASTER_REVERSE
-#define FASTER_NONALIGNED
-#define FASTER_ALIGNED
-
-#define SETUP_RETL	mov	%o0, %g6
-#define RETL_INSN	mov	%g6, %o0
-
-#endif
-
 /* Both these macros have to start with exactly the same insn */
 #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
 	ldd	[%src + (offset) + 0x00], %t0; \
@@ -164,30 +144,6 @@ x:
 	.text
 	.align	4
 
-#ifdef FASTER_REVERSE
-
-70:	/* rdword_align */
-
-	andcc		%o1, 1, %g0
-	be		4f
-	 andcc		%o1, 2, %g0
-
-	ldub		[%o1 - 1], %g2
-	sub		%o1, 1, %o1
-	stb		%g2, [%o0 - 1]
-	sub		%o2, 1, %o2
-	be		3f
-	 sub		%o0, 1, %o0
-4:
-	lduh		[%o1 - 2], %g2
-	sub		%o1, 2, %o1
-	sth		%g2, [%o0 - 2]
-	sub		%o2, 2, %o2
-	b		3f
-	 sub		%o0, 2, %o0
-
-#endif /* FASTER_REVERSE */
-
 0:
 	retl
 	 nop		! Only bcopy returns here and it retuns void...
@@ -207,8 +163,6 @@ FUNC(memmove)
 	bleu		0f
 	 andcc		%o4, 3, %o5
 
-#ifndef FASTER_REVERSE
-
 	add		%o1, %o2, %o1
 	add		%o0, %o2, %o0
 	sub		%o1, 1, %o1
@@ -226,294 +180,6 @@ FUNC(memmove)
 	retl
 	 RETL_INSN
 
-#else /* FASTER_REVERSE */
-
-	add		%o1, %o2, %o1
-	add		%o0, %o2, %o0
-	bne		77f
-	 cmp		%o2, 15
-	bleu		91f
-	 andcc		%o1, 3, %g0
-	bne		70b
-3:
-	 andcc		%o1, 4, %g0
-
-	be		2f
-	 mov		%o2, %g1
-
-	ld		[%o1 - 4], %o4
-	sub		%g1, 4, %g1
-	st		%o4, [%o0 - 4]
-	sub		%o1, 4, %o1
-	sub		%o0, 4, %o0
-2:
-	andcc		%g1, 0xffffff80, %g7
-	be		3f
-	 andcc		%o0, 4, %g0
-
-	be		74f + 4
-5:
-	RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
-	RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
-	RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
-	RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-	subcc		%g7, 128, %g7
-	sub		%o1, 128, %o1
-	bne		5b
-	 sub		%o0, 128, %o0
-3:
-	andcc		%g1, 0x70, %g7
-	be		72f
-	 andcc		%g1, 8, %g0
-
-	sethi		%hi(72f), %o5
-	srl		%g7, 1, %o4
-	add		%g7, %o4, %o4
-	sub		%o1, %g7, %o1
-	sub		%o5, %o4, %o5
-	jmpl		%o5 + %lo(72f), %g0
-	 sub		%o0, %g7, %o0
-
-71:	/* rmemcpy_table */
-	RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
-	RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
-	RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
-	RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
-	RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
-	RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
-	RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
-
-72:	/* rmemcpy_table_end */
-
-	be		73f
-	 andcc		%g1, 4, %g0
-
-	ldd		[%o1 - 0x08], %g2
-	sub		%o0, 8, %o0
-	sub		%o1, 8, %o1
-	st		%g2, [%o0]
-	st		%g3, [%o0 + 0x04]
-
-73:	/* rmemcpy_last7 */
-
-	be		1f
-	 andcc		%g1, 2, %g0
-
-	ld		[%o1 - 4], %g2
-	sub		%o1, 4, %o1
-	st		%g2, [%o0 - 4]
-	sub		%o0, 4, %o0
-1:
-	be		1f
-	 andcc		%g1, 1, %g0
-
-	lduh		[%o1 - 2], %g2
-	sub		%o1, 2, %o1
-	sth		%g2, [%o0 - 2]
-	sub		%o0, 2, %o0
-1:
-	be		1f
-	 nop
-
-	ldub		[%o1 - 1], %g2
-	stb		%g2, [%o0 - 1]
-1:
-	retl
- 	 RETL_INSN
-
-74:	/* rldd_std */
-	RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
-	RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
-	RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
-	RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-	subcc		%g7, 128, %g7
-	sub		%o1, 128, %o1
-	bne		74b
-	 sub		%o0, 128, %o0
-
-	andcc		%g1, 0x70, %g7
-	be		72b
-	 andcc		%g1, 8, %g0
-
-	sethi		%hi(72b), %o5
-	srl		%g7, 1, %o4
-	add		%g7, %o4, %o4
-	sub		%o1, %g7, %o1
-	sub		%o5, %o4, %o5
-	jmpl		%o5 + %lo(72b), %g0
-	 sub		%o0, %g7, %o0
-
-75:	/* rshort_end */
-
-	and		%o2, 0xe, %o3
-2:
-	sethi		%hi(76f), %o5
-	sll		%o3, 3, %o4
-	sub		%o0, %o3, %o0
-	sub		%o5, %o4, %o5
-	sub		%o1, %o3, %o1
-	jmpl		%o5 + %lo(76f), %g0
-	 andcc		%o2, 1, %g0
-
-	RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
-	RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
-	RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
-	RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
-	RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
-	RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
-	RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
-
-76:	/* rshort_table_end */
-
-	be		1f
-	 nop
-	ldub		[%o1 - 1], %g2
-	stb		%g2, [%o0 - 1]
-1:
-	retl
- 	 RETL_INSN
-
-91:	/* rshort_aligned_end */
-
-	bne		75b
-	 andcc		%o2, 8, %g0
-
-	be		1f
-	 andcc		%o2, 4, %g0
-
-	ld		[%o1 - 0x08], %g2
-	ld		[%o1 - 0x04], %g3
-	sub		%o1, 8, %o1
-	st		%g2, [%o0 - 0x08]
-	st		%g3, [%o0 - 0x04]
-	sub		%o0, 8, %o0
-1:
-	b		73b
-	 mov		%o2, %g1
-
-77:	/* rnon_aligned */
-	cmp		%o2, 15
-	bleu		75b
-	 andcc		%o0, 3, %g0
-	be		64f
-	 andcc		%o0, 1, %g0
-	be		63f
-	 andcc		%o0, 2, %g0
-	ldub		[%o1 - 1], %g5
-	sub		%o1, 1, %o1
-	stb		%g5, [%o0 - 1]
-	sub		%o0, 1, %o0
-	be		64f
-	 sub		%o2, 1, %o2
-63:
-	ldub		[%o1 - 1], %g5
-	sub		%o1, 2, %o1
-	stb		%g5, [%o0 - 1]
-	sub		%o0, 2, %o0
-	ldub		[%o1], %g5
-	sub		%o2, 2, %o2
-	stb		%g5, [%o0]
-64:	
-	and		%o1, 3, %g2
-	and		%o1, -4, %o1
-	and		%o2, 0xc, %g3
-	add		%o1, 4, %o1
-	cmp		%g3, 4
-	sll		%g2, 3, %g4
-	mov		32, %g2
-	be		4f
-	 sub		%g2, %g4, %g7
-
-	blu		3f
-	 cmp		%g3, 8
-
-	be		2f
-	 srl		%o2, 2, %g3
-
-	ld		[%o1 - 4], %o3
-	add		%o0, -8, %o0
-	ld		[%o1 - 8], %o4
-	add		%o1, -16, %o1
-	b		7f
-	 add		%g3, 1, %g3
-2:
-	ld		[%o1 - 4], %o4
-	add		%o0, -4, %o0
-	ld		[%o1 - 8], %g1
-	add		%o1, -12, %o1
-	b		8f
-	 add		%g3, 2, %g3
-3:
-	ld		[%o1 - 4], %o5
-	add		%o0, -12, %o0
-	ld		[%o1 - 8], %o3
-	add		%o1, -20, %o1
-	b		6f
-	 srl		%o2, 2, %g3
-4:
-	ld		[%o1 - 4], %g1
-	srl		%o2, 2, %g3
-	ld		[%o1 - 8], %o5
-	add		%o1, -24, %o1
-	add		%o0, -16, %o0
-	add		%g3, -1, %g3
-
-	ld		[%o1 + 12], %o3
-5:
-	sll		%o5, %g4, %g2
-	srl		%g1, %g7, %g5
-	or		%g2, %g5, %g2
-	st		%g2, [%o0 + 12]
-6:
-	ld		[%o1 + 8], %o4
-	sll		%o3, %g4, %g2
-	srl		%o5, %g7, %g5
-	or		%g2, %g5, %g2
-	st		%g2, [%o0 + 8]
-7:
-	ld		[%o1 + 4], %g1
-	sll		%o4, %g4, %g2
-	srl		%o3, %g7, %g5
-	or		%g2, %g5, %g2
-	st		%g2, [%o0 + 4]
-8:
-	ld		[%o1], %o5
-	sll		%g1, %g4, %g2
-	srl		%o4, %g7, %g5
-	addcc		%g3, -4, %g3
-	or		%g2, %g5, %g2
-	add		%o1, -16, %o1
-	st		%g2, [%o0]
-	add		%o0, -16, %o0
-	bne,a		5b	
-	 ld		[%o1 + 12], %o3
-	sll		%o5, %g4, %g2
-	srl		%g1, %g7, %g5
-	srl		%g4, 3, %g3
-	or		%g2, %g5, %g2
-	add		%o1, %g3, %o1
-	andcc		%o2, 2, %g0
-	st		%g2, [%o0 + 12]
-	be		1f
-	 andcc		%o2, 1, %g0
-	
-	ldub		[%o1 + 15], %g5
-	add		%o1, -2, %o1
-	stb		%g5, [%o0 + 11]
-	add		%o0, -2, %o0
-	ldub		[%o1 + 16], %g5
-	stb		%g5, [%o0 + 12]
-1:
-	be		1f
-	 nop
-	ldub		[%o1 + 15], %g5
-	stb		%g5, [%o0 + 11]
-1:
-	retl
-	 RETL_INSN
-
-#endif /* FASTER_REVERSE */
-
 /* NOTE: This code is executed just for the cases,
          where %src (=%o1) & 3 is != 0.
 	 We need to align it to 4. So, for (%src & 3)
@@ -653,22 +319,6 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	bne		82b
 	 add		%o0, 128, %o0
 
-#ifndef FASTER_ALIGNED
-
-	andcc		%g1, 0x70, %g7
-	be		80b
-	 andcc		%g1, 8, %g0
-
-	sethi		%hi(80b), %o5
-	srl		%g7, 1, %o4
-	add		%g7, %o4, %o4
-	add		%o1, %g7, %o1
-	sub		%o5, %o4, %o5
-	jmpl		%o5 + %lo(80b), %g0
-	 add		%o0, %g7, %o0
-
-#else /* FASTER_ALIGNED */
-
 	andcc		%g1, 0x70, %g7
 	be		84f
 	 andcc		%g1, 8, %g0
@@ -723,19 +373,9 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	retl
  	 RETL_INSN
 
-#endif /* FASTER_ALIGNED */
-
 86:	/* non_aligned */
 	cmp		%o2, 6
 	bleu		88f
-
-#ifdef FASTER_NONALIGNED
-
-	 cmp		%o2, 256
-	bcc		87f
-
-#endif /* FASTER_NONALIGNED */
-
 	 andcc		%o0, 3, %g0
 	be		61f
 	 andcc		%o0, 1, %g0
@@ -855,249 +495,6 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	retl
 	 RETL_INSN
 
-#ifdef FASTER_NONALIGNED
-
-87:	/* faster_nonaligned */
-
-	andcc		%o1, 3, %g0
-	be		3f
-	 andcc		%o1, 1, %g0
-
-	be		4f
-	 andcc		%o1, 2, %g0
-
-	ldub		[%o1], %g2
-	add		%o1, 1, %o1
-	stb		%g2, [%o0]
-	sub		%o2, 1, %o2
-	bne		3f
-	 add		%o0, 1, %o0
-4:
-	lduh		[%o1], %g2
-	add		%o1, 2, %o1
-	srl		%g2, 8, %g3
-	sub		%o2, 2, %o2
-	stb		%g3, [%o0]
-	add		%o0, 2, %o0
-	stb		%g2, [%o0 - 1]
-3:
-	 andcc		%o1, 4, %g0
-
-	bne		2f
-	 cmp		%o5, 1
-
-	ld		[%o1], %o4
-	srl		%o4, 24, %g2
-	stb		%g2, [%o0]
-	srl		%o4, 16, %g3
-	stb		%g3, [%o0 + 1]
-	srl		%o4, 8, %g2
-	stb		%g2, [%o0 + 2]
-	sub		%o2, 4, %o2
-	stb		%o4, [%o0 + 3]
-	add		%o1, 4, %o1
-	add		%o0, 4, %o0
-2:
-	be		33f
-	 cmp		%o5, 2
-	be		32f
-	 sub		%o2, 4, %o2
-31:
-	ld		[%o1], %g2
-	add		%o1, 4, %o1
-	srl		%g2, 24, %g3
-	and		%o0, 7, %g5
-	stb		%g3, [%o0]
-	cmp		%g5, 7
-	sll		%g2, 8, %g1
-	add		%o0, 4, %o0
-	be		41f
-	 and		%o2, 0xffffffc0, %o3
-	ld		[%o0 - 7], %o4
-4:
-	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	subcc		%o3, 64, %o3
-	add		%o1, 64, %o1
-	bne		4b
-	 add		%o0, 64, %o0
-
-	andcc		%o2, 0x30, %o3
-	be,a		1f
-	 srl		%g1, 16, %g2
-4:
-	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	subcc		%o3, 16, %o3
-	add		%o1, 16, %o1
-	bne		4b
-	 add		%o0, 16, %o0
-
-	srl		%g1, 16, %g2
-1:
-	st		%o4, [%o0 - 7]
-	sth		%g2, [%o0 - 3]
-	srl		%g1, 8, %g4
-	b		88f
-	 stb		%g4, [%o0 - 1]
-32:
-	ld		[%o1], %g2
-	add		%o1, 4, %o1
-	srl		%g2, 16, %g3
-	and		%o0, 7, %g5
-	sth		%g3, [%o0]
-	cmp		%g5, 6
-	sll		%g2, 16, %g1
-	add		%o0, 4, %o0
-	be		42f
-	 and		%o2, 0xffffffc0, %o3
-	ld		[%o0 - 6], %o4
-4:
-	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	subcc		%o3, 64, %o3
-	add		%o1, 64, %o1
-	bne		4b
-	 add		%o0, 64, %o0
-
-	andcc		%o2, 0x30, %o3
-	be,a		1f
-	 srl		%g1, 16, %g2
-4:
-	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	subcc		%o3, 16, %o3
-	add		%o1, 16, %o1
-	bne		4b
-	 add		%o0, 16, %o0
-
-	srl		%g1, 16, %g2
-1:
-	st		%o4, [%o0 - 6]
-	b		88f
-	 sth		%g2, [%o0 - 2]
-33:
-	ld		[%o1], %g2
-	sub		%o2, 4, %o2
-	srl		%g2, 24, %g3
-	and		%o0, 7, %g5
-	stb		%g3, [%o0]
-	cmp		%g5, 5
-	srl		%g2, 8, %g4
-	sll		%g2, 24, %g1
-	sth		%g4, [%o0 + 1]
-	add		%o1, 4, %o1
-	be		43f
-	 and		%o2, 0xffffffc0, %o3
-
-	ld		[%o0 - 1], %o4
-	add		%o0, 4, %o0
-4:
-	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
-	SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
-	SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
-	SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
-	subcc		%o3, 64, %o3
-	add		%o1, 64, %o1
-	bne		4b
-	 add		%o0, 64, %o0
-
-	andcc		%o2, 0x30, %o3
-	be,a		1f
-	 srl		%g1, 24, %g2
-4:
-	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
-	subcc		%o3, 16, %o3
-	add		%o1, 16, %o1
-	bne		4b
-	 add		%o0, 16, %o0
-
-	srl		%g1, 24, %g2
-1:
-	st		%o4, [%o0 - 5]
-	b		88f
-	 stb		%g2, [%o0 - 1]
-41:
-	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	subcc		%o3, 64, %o3
-	add		%o1, 64, %o1
-	bne		41b
-	 add		%o0, 64, %o0
-	 
-	andcc		%o2, 0x30, %o3
-	be,a		1f
-	 srl		%g1, 16, %g2
-4:
-	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
-	subcc		%o3, 16, %o3
-	add		%o1, 16, %o1
-	bne		4b
-	 add		%o0, 16, %o0
-
-	srl		%g1, 16, %g2
-1:
-	sth		%g2, [%o0 - 3]
-	srl		%g1, 8, %g4
-	b		88f
-	 stb		%g4, [%o0 - 1]
-43:
-	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
-	subcc		%o3, 64, %o3
-	add		%o1, 64, %o1
-	bne		43b
-	 add		%o0, 64, %o0
-
-	andcc		%o2, 0x30, %o3
-	be,a		1f
-	 srl		%g1, 24, %g2
-4:
-	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
-	subcc		%o3, 16, %o3
-	add		%o1, 16, %o1
-	bne		4b
-	 add		%o0, 16, %o0
-
-	srl		%g1, 24, %g2
-1:
-	stb		%g2, [%o0 + 3]
-	b		88f
-	 add		%o0, 4, %o0
-42:
-	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	subcc		%o3, 64, %o3
-	add		%o1, 64, %o1
-	bne		42b
-	 add		%o0, 64, %o0
-	 
-	andcc		%o2, 0x30, %o3
-	be,a		1f
-	 srl		%g1, 16, %g2
-4:
-	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
-	subcc		%o3, 16, %o3
-	add		%o1, 16, %o1
-	bne		4b
-	 add		%o0, 16, %o0
-
-	srl		%g1, 16, %g2
-1:
-	sth		%g2, [%o0 - 2]
-
-	/* Fall through */
-	 
-#endif /* FASTER_NONALIGNED */
-
 88:	/* short_end */
 
 	and		%o2, 0xe, %o3
author
#50 lore raw

PATCH 47/67 sparc32: Remove uses of %g7 in memcpy implementation.

In reply to Greg KH

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

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

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

[ Upstream commit 21f74d361dfd6a7d0e47574e315f780d8172084a ]

This is setting things up so that we can correct the return value, so that it properly returns the original destination buffer pointer.

---
 arch/sparc/lib/memcpy.S |  177 ++++++++++++++++++++++++------------------------
 1 file changed, 91 insertions(+), 86 deletions(-)
arch/sparc/lib/memcpy.S +91 -86
@@ -235,7 +235,7 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	add		%o1, 4, %o1
 	add		%o0, 4, %o0
 2:
-	andcc		%g1, 0xffffff80, %g7
+	andcc		%g1, 0xffffff80, %g0
 	be		3f
 	 andcc		%o0, 4, %g0
 
@@ -245,22 +245,23 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
 	MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
 	MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-	subcc		%g7, 128, %g7
+	sub		%g1, 128, %g1
 	add		%o1, 128, %o1
-	bne		5b
+	cmp		%g1, 128
+	bge		5b
 	 add		%o0, 128, %o0
 3:
-	andcc		%g1, 0x70, %g7
+	andcc		%g1, 0x70, %g4
 	be		80f
 	 andcc		%g1, 8, %g0
 
 	sethi		%hi(80f), %o5
-	srl		%g7, 1, %o4
-	add		%g7, %o4, %o4
-	add		%o1, %g7, %o1
+	srl		%g4, 1, %o4
+	add		%g4, %o4, %o4
+	add		%o1, %g4, %o1
 	sub		%o5, %o4, %o5
 	jmpl		%o5 + %lo(80f), %g0
-	 add		%o0, %g7, %o0
+	 add		%o0, %g4, %o0
 
 79:	/* memcpy_table */
 
@@ -314,20 +315,21 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
 	MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
 	MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
-	subcc		%g7, 128, %g7
+	subcc		%g1, 128, %g1
 	add		%o1, 128, %o1
-	bne		82b
+	cmp		%g1, 128
+	bge		82b
 	 add		%o0, 128, %o0
 
-	andcc		%g1, 0x70, %g7
+	andcc		%g1, 0x70, %g4
 	be		84f
 	 andcc		%g1, 8, %g0
 
 	sethi		%hi(84f), %o5
-	add		%o1, %g7, %o1
-	sub		%o5, %g7, %o5
+	add		%o1, %g4, %o1
+	sub		%o5, %g4, %o5
 	jmpl		%o5 + %lo(84f), %g0
-	 add		%o0, %g7, %o0
+	 add		%o0, %g4, %o0
 
 83:	/* amemcpy_table */
 
@@ -376,124 +378,127 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 86:	/* non_aligned */
 	cmp		%o2, 6
 	bleu		88f
-	 andcc		%o0, 3, %g0
+	 nop
+
+	save		%sp, -96, %sp
+	andcc		%i0, 3, %g0
 	be		61f
-	 andcc		%o0, 1, %g0
+	 andcc		%i0, 1, %g0
 	be		60f
-	 andcc		%o0, 2, %g0
+	 andcc		%i0, 2, %g0
 
-	ldub		[%o1], %g5
-	add		%o1, 1, %o1
-	stb		%g5, [%o0]
-	sub		%o2, 1, %o2
+	ldub		[%i1], %g5
+	add		%i1, 1, %i1
+	stb		%g5, [%i0]
+	sub		%i2, 1, %i2
 	bne		61f
-	 add		%o0, 1, %o0
+	 add		%i0, 1, %i0
 60:
-	ldub		[%o1], %g3
-	add		%o1, 2, %o1
-	stb		%g3, [%o0]
-	sub		%o2, 2, %o2
-	ldub		[%o1 - 1], %g3
-	add		%o0, 2, %o0
-	stb		%g3, [%o0 - 1]
+	ldub		[%i1], %g3
+	add		%i1, 2, %i1
+	stb		%g3, [%i0]
+	sub		%i2, 2, %i2
+	ldub		[%i1 - 1], %g3
+	add		%i0, 2, %i0
+	stb		%g3, [%i0 - 1]
 61:
-	and		%o1, 3, %g2
-	and		%o2, 0xc, %g3
-	and		%o1, -4, %o1
+	and		%i1, 3, %g2
+	and		%i2, 0xc, %g3
+	and		%i1, -4, %i1
 	cmp		%g3, 4
 	sll		%g2, 3, %g4
 	mov		32, %g2
 	be		4f
-	 sub		%g2, %g4, %g7
+	 sub		%g2, %g4, %l0
 	
 	blu		3f
 	 cmp		%g3, 0x8
 
 	be		2f
-	 srl		%o2, 2, %g3
+	 srl		%i2, 2, %g3
 
-	ld		[%o1], %o3
-	add		%o0, -8, %o0
-	ld		[%o1 + 4], %o4
+	ld		[%i1], %i3
+	add		%i0, -8, %i0
+	ld		[%i1 + 4], %i4
 	b		8f
 	 add		%g3, 1, %g3
 2:
-	ld		[%o1], %o4
-	add		%o0, -12, %o0
-	ld		[%o1 + 4], %o5
+	ld		[%i1], %i4
+	add		%i0, -12, %i0
+	ld		[%i1 + 4], %i5
 	add		%g3, 2, %g3
 	b		9f
-	 add		%o1, -4, %o1
+	 add		%i1, -4, %i1
 3:
-	ld		[%o1], %g1
-	add		%o0, -4, %o0
-	ld		[%o1 + 4], %o3
-	srl		%o2, 2, %g3
+	ld		[%i1], %g1
+	add		%i0, -4, %i0
+	ld		[%i1 + 4], %i3
+	srl		%i2, 2, %g3
 	b		7f
-	 add		%o1, 4, %o1
+	 add		%i1, 4, %i1
 4:
-	ld		[%o1], %o5
-	cmp		%o2, 7
-	ld		[%o1 + 4], %g1
-	srl		%o2, 2, %g3
+	ld		[%i1], %i5
+	cmp		%i2, 7
+	ld		[%i1 + 4], %g1
+	srl		%i2, 2, %g3
 	bleu		10f
-	 add		%o1, 8, %o1
+	 add		%i1, 8, %i1
 
-	ld		[%o1], %o3
+	ld		[%i1], %i3
 	add		%g3, -1, %g3
 5:
-	sll		%o5, %g4, %g2
-	srl		%g1, %g7, %g5
+	sll		%i5, %g4, %g2
+	srl		%g1, %l0, %g5
 	or		%g2, %g5, %g2
-	st		%g2, [%o0]
+	st		%g2, [%i0]
 7:
-	ld		[%o1 + 4], %o4
+	ld		[%i1 + 4], %i4
 	sll		%g1, %g4, %g2
-	srl		%o3, %g7, %g5
+	srl		%i3, %l0, %g5
 	or		%g2, %g5, %g2
-	st		%g2, [%o0 + 4]
+	st		%g2, [%i0 + 4]
 8:
-	ld		[%o1 + 8], %o5
-	sll		%o3, %g4, %g2
-	srl		%o4, %g7, %g5
+	ld		[%i1 + 8], %i5
+	sll		%i3, %g4, %g2
+	srl		%i4, %l0, %g5
 	or		%g2, %g5, %g2
-	st		%g2, [%o0 + 8]
+	st		%g2, [%i0 + 8]
 9:
-	ld		[%o1 + 12], %g1
-	sll		%o4, %g4, %g2
-	srl		%o5, %g7, %g5
+	ld		[%i1 + 12], %g1
+	sll		%i4, %g4, %g2
+	srl		%i5, %l0, %g5
 	addcc		%g3, -4, %g3
 	or		%g2, %g5, %g2
-	add		%o1, 16, %o1
-	st		%g2, [%o0 + 12]
-	add		%o0, 16, %o0
+	add		%i1, 16, %i1
+	st		%g2, [%i0 + 12]
+	add		%i0, 16, %i0
 	bne,a		5b
-	 ld		[%o1], %o3
+	 ld		[%i1], %i3
 10:
-	sll		%o5, %g4, %g2
-	srl		%g1, %g7, %g5
-	srl		%g7, 3, %g3
+	sll		%i5, %g4, %g2
+	srl		%g1, %l0, %g5
+	srl		%l0, 3, %g3
 	or		%g2, %g5, %g2
-	sub		%o1, %g3, %o1
-	andcc		%o2, 2, %g0
-	st		%g2, [%o0]
+	sub		%i1, %g3, %i1
+	andcc		%i2, 2, %g0
+	st		%g2, [%i0]
 	be		1f
-	 andcc		%o2, 1, %g0
+	 andcc		%i2, 1, %g0
 
-	ldub		[%o1], %g2
-	add		%o1, 2, %o1
-	stb		%g2, [%o0 + 4]
-	add		%o0, 2, %o0
-	ldub		[%o1 - 1], %g2
-	stb		%g2, [%o0 + 3]
+	ldub		[%i1], %g2
+	add		%i1, 2, %i1
+	stb		%g2, [%i0 + 4]
+	add		%i0, 2, %i0
+	ldub		[%i1 - 1], %g2
+	stb		%g2, [%i0 + 3]
 1:
 	be		1f
 	 nop
-	ldub		[%o1], %g2
-	stb		%g2, [%o0 + 4]
+	ldub		[%i1], %g2
+	stb		%g2, [%i0 + 4]
 1:
-	retl
-	 RETL_INSN
+	ret
+	 restore	%g0, %g0, %o0
 
 88:	/* short_end */
 
author
#51 lore raw

PATCH 48/67 sparc32: Correct the return value of memcpy.

In reply to Greg KH

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

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

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

[ Upstream commit a52312b88c8103e965979a79a07f6b34af82ca4b ]

Properly return the original destination buffer pointer.

---
 arch/sparc/lib/memcpy.S |   22 +++++++---------------
 1 file changed, 7 insertions(+), 15 deletions(-)
arch/sparc/lib/memcpy.S +7 -15
@@ -13,14 +13,6 @@
 	.align	4;		\
 x:
 
-
-/* In kernel these functions don't return a value.
- * One should use macros in asm/string.h for that purpose.
- * We return 0, so that bugs are more apparent.
- */
-#define SETUP_RETL
-#define RETL_INSN	clr	%o0
-
 /* Both these macros have to start with exactly the same insn */
 #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
 	ldd	[%src + (offset) + 0x00], %t0; \
@@ -154,7 +146,7 @@ FUNC(__memmove)
 #endif
 FUNC(memmove)
 	cmp		%o0, %o1
-	SETUP_RETL
+	mov		%o0, %g7
 	bleu		9f
 	 sub		%o0, %o1, %o4
 
@@ -178,7 +170,7 @@ FUNC(memmove)
 	 sub		%o0, 1, %o0
 
 	retl
-	 RETL_INSN
+	 mov		%g7, %o0
 
 /* NOTE: This code is executed just for the cases,
          where %src (=%o1) & 3 is != 0.
@@ -212,7 +204,7 @@ FUNC(memmove)
 FUNC(memcpy)	/* %o0=dst %o1=src %o2=len */
 
 	sub		%o0, %o1, %o4
-	SETUP_RETL
+	mov		%o0, %g7
 9:
 	andcc		%o4, 3, %o5
 0:
@@ -308,7 +300,7 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	stb		%g2, [%o0]
 1:
 	retl
- 	 RETL_INSN
+	 mov		%g7, %o0
 
 82:	/* ldd_std */
 	MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
@@ -373,7 +365,7 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	stb		%g2, [%o0]
 1:
 	retl
- 	 RETL_INSN
+	 mov		%g7, %o0
 
 86:	/* non_aligned */
 	cmp		%o2, 6
@@ -498,7 +490,7 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	stb		%g2, [%i0 + 4]
 1:
 	ret
-	 restore	%g0, %g0, %o0
+	 restore	%g7, %g0, %o0
 
 88:	/* short_end */
 
@@ -529,7 +521,7 @@ FUNC(memcpy)	/* %o0=dst %o1=src %o2=len
 	stb		%g2, [%o0]
 1:
 	retl
- 	 RETL_INSN
+	 mov		%g7, %o0
 
 90:	/* short_aligned_end */
 	bne		88b
author
#52 lore raw

PATCH 49/67 sparc64: Fix masking and shifting in VIS fpcmp emulation.

In reply to Greg KH

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

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

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

[ Upstream commit 2e8ecdc008a16b9a6c4b9628bb64d0d1c05f9f92 ]

---
 arch/sparc/kernel/visemul.c |   32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)
arch/sparc/kernel/visemul.c +16 -16
@@ -713,17 +713,17 @@ static void pcmp(struct pt_regs *regs, u
 			s16 b = (rs2 >> (i * 16)) & 0xffff;
 
 			if (a > b)
-				rd_val |= 1 << i;
+				rd_val |= 8 >> i;
 		}
 		break;
 
 	case FCMPGT32_OPF:
 		for (i = 0; i < 2; i++) {
-			s32 a = (rs1 >> (i * 32)) & 0xffff;
-			s32 b = (rs2 >> (i * 32)) & 0xffff;
+			s32 a = (rs1 >> (i * 32)) & 0xffffffff;
+			s32 b = (rs2 >> (i * 32)) & 0xffffffff;
 
 			if (a > b)
-				rd_val |= 1 << i;
+				rd_val |= 2 >> i;
 		}
 		break;
 
@@ -733,17 +733,17 @@ static void pcmp(struct pt_regs *regs, u
 			s16 b = (rs2 >> (i * 16)) & 0xffff;
 
 			if (a <= b)
-				rd_val |= 1 << i;
+				rd_val |= 8 >> i;
 		}
 		break;
 
 	case FCMPLE32_OPF:
 		for (i = 0; i < 2; i++) {
-			s32 a = (rs1 >> (i * 32)) & 0xffff;
-			s32 b = (rs2 >> (i * 32)) & 0xffff;
+			s32 a = (rs1 >> (i * 32)) & 0xffffffff;
+			s32 b = (rs2 >> (i * 32)) & 0xffffffff;
 
 			if (a <= b)
-				rd_val |= 1 << i;
+				rd_val |= 2 >> i;
 		}
 		break;
 
@@ -753,17 +753,17 @@ static void pcmp(struct pt_regs *regs, u
 			s16 b = (rs2 >> (i * 16)) & 0xffff;
 
 			if (a != b)
-				rd_val |= 1 << i;
+				rd_val |= 8 >> i;
 		}
 		break;
 
 	case FCMPNE32_OPF:
 		for (i = 0; i < 2; i++) {
-			s32 a = (rs1 >> (i * 32)) & 0xffff;
-			s32 b = (rs2 >> (i * 32)) & 0xffff;
+			s32 a = (rs1 >> (i * 32)) & 0xffffffff;
+			s32 b = (rs2 >> (i * 32)) & 0xffffffff;
 
 			if (a != b)
-				rd_val |= 1 << i;
+				rd_val |= 2 >> i;
 		}
 		break;
 
@@ -773,17 +773,17 @@ static void pcmp(struct pt_regs *regs, u
 			s16 b = (rs2 >> (i * 16)) & 0xffff;
 
 			if (a == b)
-				rd_val |= 1 << i;
+				rd_val |= 8 >> i;
 		}
 		break;
 
 	case FCMPEQ32_OPF:
 		for (i = 0; i < 2; i++) {
-			s32 a = (rs1 >> (i * 32)) & 0xffff;
-			s32 b = (rs2 >> (i * 32)) & 0xffff;
+			s32 a = (rs1 >> (i * 32)) & 0xffffffff;
+			s32 b = (rs2 >> (i * 32)) & 0xffffffff;
 
 			if (a == b)
-				rd_val |= 1 << i;
+				rd_val |= 2 >> i;
 		}
 		break;
 	}
author
#53 lore raw

PATCH 50/67 sparc: Fix handling of orig_i0 wrt. debugging when restarting syscalls.

In reply to Greg KH

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

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

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

[ A combination of upstream commits 1d299bc7732c34d85bd43ac1a8745f5a2fed2078 and
e88d2468718b0789b4c33da2f7e1cef2a1eee279 ]

Although we provide a proper way for a debugger to control whether syscall restart occurs, we run into problems because orig_i0 is not saved and restored properly.

Luckily we can solve this problem without having to make debuggers aware of the issue. Across system calls, several registers are considered volatile and can be safely clobbered.

Therefore we use the pt_regs save area of one of those registers, %g6, as a place to save and restore orig_i0.

Debuggers transparently will do the right thing because they save and restore this register already.

---
 arch/sparc/kernel/signal32.c  |   18 ++++++++++--------
 arch/sparc/kernel/signal_32.c |   30 +++++++++++++++++++++++++-----
 arch/sparc/kernel/signal_64.c |   42 ++++++++++++++++++++++++++++--------------
 3 files changed, 63 insertions(+), 27 deletions(-)
arch/sparc/kernel/signal32.c +10 -8
@@ -829,21 +829,23 @@ static inline void syscall_restart32(uns
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-void do_signal32(sigset_t *oldset, struct pt_regs * regs,
-		 int restart_syscall, unsigned long orig_i0)
+void do_signal32(sigset_t *oldset, struct pt_regs * regs)
 {
 	struct k_sigaction ka;
+	unsigned long orig_i0;
+	int restart_syscall;
 	siginfo_t info;
 	int signr;
 	
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-	/* If the debugger messes with the program counter, it clears
-	 * the "in syscall" bit, directing us to not perform a syscall
-	 * restart.
-	 */
-	if (restart_syscall && !pt_regs_is_syscall(regs))
-		restart_syscall = 0;
+	restart_syscall = 0;
+	orig_i0 = 0;
+	if (pt_regs_is_syscall(regs) &&
+	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
+		restart_syscall = 1;
+		orig_i0 = regs->u_regs[UREG_G6];
+	}
 
 	if (signr > 0) {
 		if (restart_syscall)
arch/sparc/kernel/signal_32.c +25 -5
@@ -525,10 +525,26 @@ static void do_signal(struct pt_regs *re
 	siginfo_t info;
 	int signr;
 
+	/* It's a lot of work and synchronization to add a new ptrace
+	 * register for GDB to save and restore in order to get
+	 * orig_i0 correct for syscall restarts when debugging.
+	 *
+	 * Although it should be the case that most of the global
+	 * registers are volatile across a system call, glibc already
+	 * depends upon that fact that we preserve them.  So we can't
+	 * just use any global register to save away the orig_i0 value.
+	 *
+	 * In particular %g2, %g3, %g4, and %g5 are all assumed to be
+	 * preserved across a system call trap by various pieces of
+	 * code in glibc.
+	 *
+	 * %g7 is used as the "thread register".   %g6 is not used in
+	 * any fixed manner.  %g6 is used as a scratch register and
+	 * a compiler temporary, but it's value is never used across
+	 * a system call.  Therefore %g6 is usable for orig_i0 storage.
+	 */
 	if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
-		restart_syscall = 1;
-	else
-		restart_syscall = 0;
+		regs->u_regs[UREG_G6] = orig_i0;
 
 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
 		oldset = &current->saved_sigmask;
@@ -541,8 +557,12 @@ static void do_signal(struct pt_regs *re
 	 * the software "in syscall" bit, directing us to not perform
 	 * a syscall restart.
 	 */
-	if (restart_syscall && !pt_regs_is_syscall(regs))
-		restart_syscall = 0;
+	restart_syscall = 0;
+	if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
+		restart_syscall = 1;
+		orig_i0 = regs->u_regs[UREG_G6];
+	}
+
 
 	if (signr > 0) {
 		if (restart_syscall)
arch/sparc/kernel/signal_64.c +28 -14

61 lines not on this page · raw message

author
#54 lore raw

PATCH 51/67 net: bpf_jit: fix an off-one bug in x86_64 cond jump target

In reply to Greg KH

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

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

From: Markus K�tter <[email protected]>

[ Upstream commit a03ffcf873fe0f2565386ca8ef832144c42e67fa ]

x86 jump instruction size is 2 or 5 bytes (near/long jump), not 2 or 6 bytes.

In case a conditional jump is followed by a long jump, conditional jump target is one byte past the start of target instruction.

---
 arch/x86/net/bpf_jit_comp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/net/bpf_jit_comp.c +2 -2
@@ -568,8 +568,8 @@ cond_branch:			f_offset = addrs[i + filt
 					break;
 				}
 				if (filter[i].jt != 0) {
-					if (filter[i].jf)
-						t_offset += is_near(f_offset) ? 2 : 6;
+					if (filter[i].jf && f_offset)
+						t_offset += is_near(f_offset) ? 2 : 5;
 					EMIT_COND_JMP(t_op, t_offset);
 					if (filter[i].jf)
 						EMIT_JMP(f_offset);
author
#55 lore raw

PATCH 52/67 ppp: fix pptp double release_sock in pptp_bind()

In reply to Greg KH

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

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

From: Djalal Harouni <[email protected]>

[ Upstream commit a454daceb78844a09c08b6e2d8badcb76a5d73b9 ]

---
 drivers/net/pptp.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/pptp.c +1 -3
@@ -418,10 +418,8 @@ static int pptp_bind(struct socket *sock
 	lock_sock(sk);
 
 	opt->src_addr = sp->sa_addr.pptp;
-	if (add_chan(po)) {
-		release_sock(sk);
+	if (add_chan(po))
 		error = -EBUSY;
-	}
 
 	release_sock(sk);
 	return error;
author
#56 lore raw

PATCH 53/67 llc: llc_cmsg_rcv was getting called after sk_eat_skb.

In reply to Greg KH

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

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

From: Alex Juncu <[email protected]>

[ Upstream commit 9cef310fcdee12b49b8b4c96fd8f611c8873d284 ]

Received non stream protocol packets were calling llc_cmsg_rcv that used a skb after that skb was released by sk_eat_skb. This caused received STP packets to generate kernel panics.

---
 net/llc/af_llc.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
net/llc/af_llc.c +10 -4
@@ -833,15 +833,15 @@ static int llc_ui_recvmsg(struct kiocb *
 		copied += used;
 		len -= used;
 
+		/* For non stream protcols we get one packet per recvmsg call */
+		if (sk->sk_type != SOCK_STREAM)
+			goto copy_uaddr;
+
 		if (!(flags & MSG_PEEK)) {
 			sk_eat_skb(sk, skb, 0);
 			*seq = 0;
 		}
 
-		/* For non stream protcols we get one packet per recvmsg call */
-		if (sk->sk_type != SOCK_STREAM)
-			goto copy_uaddr;
-
 		/* Partial read */
 		if (used + offset < skb->len)
 			continue;
@@ -857,6 +857,12 @@ copy_uaddr:
 	}
 	if (llc_sk(sk)->cmsg_flags)
 		llc_cmsg_rcv(msg, skb);
+
+	if (!(flags & MSG_PEEK)) {
+			sk_eat_skb(sk, skb, 0);
+			*seq = 0;
+	}
+
 	goto out;
 }
 
author
#57 lore raw

PATCH 54/67 mqprio: Avoid panic if no options are provided

In reply to Greg KH

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

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

From: Thomas Graf <[email protected]>

[ Upstream commit 7838f2ce36b6ab5c13ef20b1857e3bbd567f1759 ]

Userspace may not provide TCA_OPTIONS, in fact tc currently does so not do so if no arguments are specified on the command line. Return EINVAL instead of panicing.

---
 net/sched/sch_mqprio.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/sch_mqprio.c +1 -1
@@ -106,7 +106,7 @@ static int mqprio_init(struct Qdisc *sch
 	if (!netif_is_multiqueue(dev))
 		return -EOPNOTSUPP;
 
-	if (nla_len(opt) < sizeof(*qopt))
+	if (!opt || nla_len(opt) < sizeof(*qopt))
 		return -EINVAL;
 
 	qopt = nla_data(opt);
author
#58 lore raw

PATCH 55/67 net: have ipconfig not wait if no dev is available

In reply to Greg KH

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

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

From: Gerlando Falauto <[email protected]>

[ Upstream commit cd7816d14953c8af910af5bb92f488b0b277e29d ]

previous commit 3fb72f1e6e6165c5f495e8dc11c5bbd14c73385c makes IP-Config wait for carrier on at least one network device.

Before waiting (predefined value 120s), check that at least one device was successfully brought up. Otherwise (e.g. buggy bootloader which does not set the MAC address) there is no point in waiting for carrier.

---
 net/ipv4/ipconfig.c |    4 ++++
 1 file changed, 4 insertions(+)
net/ipv4/ipconfig.c +4 -0
@@ -252,6 +252,10 @@ static int __init ic_open_devs(void)
 		}
 	}
 
+	/* no point in waiting if we could not bring up at least one device */
+	if (!ic_first_dev)
+		goto have_carrier;
+
 	/* wait for a carrier on at least one device */
 	start = jiffies;
 	while (jiffies - start < msecs_to_jiffies(CONF_CARRIER_TIMEOUT)) {
author
#59 lore raw

PATCH 56/67 sch_gred: should not use GFP_KERNEL while holding a spinlock

In reply to Greg KH

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 3f1e6d3fd37bd4f25e5b19f1c7ca21850426c33f ]

gred_change_vq() is called under sch_tree_lock(sch).

This means a spinlock is held, and we are not allowed to sleep in this context.

We might pre-allocate memory using GFP_KERNEL before taking spinlock, but this is not suitable for stable material.

---
 net/sched/sch_gred.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sched/sch_gred.c +1 -1
@@ -385,7 +385,7 @@ static inline int gred_change_vq(struct
 	struct gred_sched_data *q;
 
 	if (table->tab[dp] == NULL) {
-		table->tab[dp] = kzalloc(sizeof(*q), GFP_KERNEL);
+		table->tab[dp] = kzalloc(sizeof(*q), GFP_ATOMIC);
 		if (table->tab[dp] == NULL)
 			return -ENOMEM;
 	}
author
#60 lore raw

PATCH 57/67 sctp: fix incorrect overflow check on autoclose

In reply to Greg KH

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

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

From: Xi Wang <[email protected]>

[ Upstream commit 2692ba61a82203404abd7dd2a027bda962861f74 ]

Commit 8ffd3208 voids the previous patches f6778aab and 810c0719 for limiting the autoclose value. If userspace passes in -1 on 32-bit platform, the overflow check didn't work and autoclose would be set to 0xffffffff.

This patch defines a max_autoclose (in seconds) for limiting the value and exposes it through sysctl, with the following intentions.

1) Avoid overflowing autoclose * HZ.

2) Keep the default autoclose bound consistent across 32- and 64-bit platforms (INT_MAX / HZ in this patch).

3) Keep the autoclose value consistent between setsockopt() and getsockopt() calls.

---
 include/net/sctp/structs.h |    4 ++++
 net/sctp/associola.c       |    2 +-
 net/sctp/protocol.c        |    3 +++
 net/sctp/socket.c          |    2 --
 net/sctp/sysctl.c          |   13 +++++++++++++
 5 files changed, 21 insertions(+), 3 deletions(-)
include/net/sctp/structs.h +4 -0
@@ -236,6 +236,9 @@ extern struct sctp_globals {
 	 * bits is an indicator of when to send and window update SACK.
 	 */
 	int rwnd_update_shift;
+
+	/* Threshold for autoclose timeout, in seconds. */
+	unsigned long max_autoclose;
 } sctp_globals;
 
 #define sctp_rto_initial		(sctp_globals.rto_initial)
@@ -271,6 +274,7 @@ extern struct sctp_globals {
 #define sctp_auth_enable		(sctp_globals.auth_enable)
 #define sctp_checksum_disable		(sctp_globals.checksum_disable)
 #define sctp_rwnd_upd_shift		(sctp_globals.rwnd_update_shift)
+#define sctp_max_autoclose		(sctp_globals.max_autoclose)
 
 /* SCTP Socket type: UDP or TCP style. */
 typedef enum {
net/sctp/associola.c +1 -1
@@ -173,7 +173,7 @@ static struct sctp_association *sctp_ass
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
-		(unsigned long)sp->autoclose * HZ;
+		min_t(unsigned long, sp->autoclose, sctp_max_autoclose) * HZ;
 
 	/* Initializes the timers */
 	for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
net/sctp/protocol.c +3 -0
@@ -1144,6 +1144,9 @@ SCTP_STATIC __init int sctp_init(void)
 	sctp_max_instreams    		= SCTP_DEFAULT_INSTREAMS;
 	sctp_max_outstreams   		= SCTP_DEFAULT_OUTSTREAMS;
 
+	/* Initialize maximum autoclose timeout. */
+	sctp_max_autoclose		= INT_MAX / HZ;
+
 	/* Initialize handle used for association ids. */
 	idr_init(&sctp_assocs_id);
 
net/sctp/socket.c +0 -2
@@ -2129,8 +2129,6 @@ static int sctp_setsockopt_autoclose(str
 		return -EINVAL;
 	if (copy_from_user(&sp->autoclose, optval, optlen))
 		return -EFAULT;
-	/* make sure it won't exceed MAX_SCHEDULE_TIMEOUT */
-	sp->autoclose = min_t(long, sp->autoclose, MAX_SCHEDULE_TIMEOUT / HZ);
 
 	return 0;
 }
net/sctp/sysctl.c +13 -0
@@ -53,6 +53,10 @@ static int sack_timer_min = 1;
 static int sack_timer_max = 500;
 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
 static int rwnd_scale_max = 16;
+static unsigned long max_autoclose_min = 0;
+static unsigned long max_autoclose_max =
+	(MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
+	? UINT_MAX : MAX_SCHEDULE_TIMEOUT / HZ;
 
 extern long sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
@@ -251,6 +255,15 @@ static ctl_table sctp_table[] = {
 		.extra1		= &one,
 		.extra2		= &rwnd_scale_max,
 	},
+	{
+		.procname	= "max_autoclose",
+		.data		= &sctp_max_autoclose,
+		.maxlen		= sizeof(unsigned long),
+		.mode		= 0644,
+		.proc_handler	= &proc_doulongvec_minmax,
+		.extra1		= &max_autoclose_min,
+		.extra2		= &max_autoclose_max,
+	},
 
 	{ /* sentinel */ }
 };
author
#61 lore raw

PATCH 58/67 sctp: Do not account for sizeof(struct sk_buff) in estimated rwnd

In reply to Greg KH

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

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

From: Thomas Graf <[email protected]>

[ Upstream commit a76c0adf60f6ca5ff3481992e4ea0383776b24d2 ]

When checking whether a DATA chunk fits into the estimated rwnd a full sizeof(struct sk_buff) is added to the needed chunk size. This quickly exhausts the available rwnd space and leads to packets being sent which are much below the PMTU limit. This can lead to much worse performance.

The reason for this behaviour was to avoid putting too much memory pressure on the receiver. The concept is not completely irational because a Linux receiver does in fact clone an skb for each DATA chunk delivered. However, Linux also reserves half the available socket buffer space for data structures therefore usage of it is already accounted for.

When proposing to change this the last time it was noted that this behaviour was introduced to solve a performance issue caused by rwnd overusage in combination with small DATA chunks.

Trying to reproduce this I found that with the sk_buff overhead removed, the performance would improve significantly unless socket buffer limits are increased.

The following numbers have been gathered using a patched iperf supporting SCTP over a live 1 Gbit ethernet network. The -l option was used to limit DATA chunk sizes. The numbers listed are based on the average of 3 test runs each. Default values have been used for sk_(r|w)mem.

Chunk
Size Unpatched No Overhead
-------------------------------------

   4    15.2 Kbit [!]   12.2 Mbit [!]
   8    35.8 Kbit [!]   26.0 Mbit [!]
  16    95.5 Kbit [!]   54.4 Mbit [!]
  32   106.7 Mbit      102.3 Mbit
  64   189.2 Mbit      188.3 Mbit
 128   331.2 Mbit      334.8 Mbit
 256   537.7 Mbit      536.0 Mbit
 512   766.9 Mbit      766.6 Mbit
1024   810.1 Mbit      808.6 Mbit
---
 net/sctp/output.c   |    8 +-------
 net/sctp/outqueue.c |    6 ++----
 2 files changed, 3 insertions(+), 11 deletions(-)
net/sctp/output.c +1 -7
@@ -697,13 +697,7 @@ static void sctp_packet_append_data(stru
 	/* Keep track of how many bytes are in flight to the receiver. */
 	asoc->outqueue.outstanding_bytes += datasize;
 
-	/* Update our view of the receiver's rwnd. Include sk_buff overhead
-	 * while updating peer.rwnd so that it reduces the chances of a
-	 * receiver running out of receive buffer space even when receive
-	 * window is still open. This can happen when a sender is sending
-	 * sending small messages.
-	 */
-	datasize += sizeof(struct sk_buff);
+	/* Update our view of the receiver's rwnd. */
 	if (datasize < rwnd)
 		rwnd -= datasize;
 	else
net/sctp/outqueue.c +2 -4
@@ -411,8 +411,7 @@ void sctp_retransmit_mark(struct sctp_ou
 					chunk->transport->flight_size -=
 							sctp_data_size(chunk);
 				q->outstanding_bytes -= sctp_data_size(chunk);
-				q->asoc->peer.rwnd += (sctp_data_size(chunk) +
-							sizeof(struct sk_buff));
+				q->asoc->peer.rwnd += sctp_data_size(chunk);
 			}
 			continue;
 		}
@@ -432,8 +431,7 @@ void sctp_retransmit_mark(struct sctp_ou
 			 * (Section 7.2.4)), add the data size of those
 			 * chunks to the rwnd.
 			 */
-			q->asoc->peer.rwnd += (sctp_data_size(chunk) +
-						sizeof(struct sk_buff));
+			q->asoc->peer.rwnd += sctp_data_size(chunk);
 			q->outstanding_bytes -= sctp_data_size(chunk);
 			if (chunk->transport)
 				transport->flight_size -= sctp_data_size(chunk);
author
#62 lore raw

PATCH 59/67 ipv4: flush route cache after change accept_local

In reply to Greg KH

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

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

From: Weiping Pan <[email protected]>

[ Upstream commit d01ff0a049f749e0bf10a35bb23edd012718c8c2 ]

After reset ipv4_devconf->data[IPV4_DEVCONF_ACCEPT_LOCAL] to 0, we should flush route cache, or it will continue receive packets with local source address, which should be dropped.

---
 net/ipv4/devinet.c |    5 +++++
 1 file changed, 5 insertions(+)
net/ipv4/devinet.c +5 -0
@@ -1490,7 +1490,9 @@ static int devinet_conf_proc(ctl_table *
 			     void __user *buffer,
 			     size_t *lenp, loff_t *ppos)
 {
+	int old_value = *(int *)ctl->data;
 	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+	int new_value = *(int *)ctl->data;
 
 	if (write) {
 		struct ipv4_devconf *cnf = ctl->extra1;
@@ -1501,6 +1503,9 @@ static int devinet_conf_proc(ctl_table *
 
 		if (cnf == net->ipv4.devconf_dflt)
 			devinet_copy_dflt_conf(net, i);
+		if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1)
+			if ((new_value == 0) && (old_value != 0))
+				rt_cache_flush(net, 0);
 	}
 
 	return ret;
author
#63 lore raw

PATCH 60/67 ipv4: reintroduce route cache garbage collector

In reply to Greg KH

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 9f28a2fc0bd77511f649c0a788c7bf9a5fd04edb ]

Commit 2c8cec5c10b (ipv4: Cache learned PMTU information in inetpeer) removed IP route cache garbage collector a bit too soon, as this gc was responsible for expired routes cleanup, releasing their neighbour reference.

As pointed out by Robert Gladewitz, recent kernels can fill and exhaust their neighbour cache.

Reintroduce the garbage collection, since we'll have to wait our neighbour lookups become refcount-less to not depend on this stuff.

---
 net/ipv4/route.c |  106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
net/ipv4/route.c +106 -0
@@ -132,6 +132,9 @@ static int ip_rt_min_pmtu __read_mostly
 static int ip_rt_min_advmss __read_mostly	= 256;
 static int rt_chain_length_max __read_mostly	= 20;
 
+static struct delayed_work expires_work;
+static unsigned long expires_ljiffies;
+
 /*
  *	Interface to generic destination cache.
  */
@@ -821,6 +824,97 @@ static int has_noalias(const struct rtab
 	return ONE;
 }
 
+static void rt_check_expire(void)
+{
+	static unsigned int rover;
+	unsigned int i = rover, goal;
+	struct rtable *rth;
+	struct rtable __rcu **rthp;
+	unsigned long samples = 0;
+	unsigned long sum = 0, sum2 = 0;
+	unsigned long delta;
+	u64 mult;
+
+	delta = jiffies - expires_ljiffies;
+	expires_ljiffies = jiffies;
+	mult = ((u64)delta) << rt_hash_log;
+	if (ip_rt_gc_timeout > 1)
+		do_div(mult, ip_rt_gc_timeout);
+	goal = (unsigned int)mult;
+	if (goal > rt_hash_mask)
+		goal = rt_hash_mask + 1;
+	for (; goal > 0; goal--) {
+		unsigned long tmo = ip_rt_gc_timeout;
+		unsigned long length;
+
+		i = (i + 1) & rt_hash_mask;
+		rthp = &rt_hash_table[i].chain;
+
+		if (need_resched())
+			cond_resched();
+
+		samples++;
+
+		if (rcu_dereference_raw(*rthp) == NULL)
+			continue;
+		length = 0;
+		spin_lock_bh(rt_hash_lock_addr(i));
+		while ((rth = rcu_dereference_protected(*rthp,
+					lockdep_is_held(rt_hash_lock_addr(i)))) != NULL) {
+			prefetch(rth->dst.rt_next);
+			if (rt_is_expired(rth)) {
+				*rthp = rth->dst.rt_next;
+				rt_free(rth);
+				continue;
+			}
+			if (rth->dst.expires) {
+				/* Entry is expired even if it is in use */
+				if (time_before_eq(jiffies, rth->dst.expires)) {
+nofree:
+					tmo >>= 1;
+					rthp = &rth->dst.rt_next;
+					/*
+					 * We only count entries on
+					 * a chain with equal hash inputs once
+					 * so that entries for different QOS
+					 * levels, and other non-hash input
+					 * attributes don't unfairly skew
+					 * the length computation
+					 */
+					length += has_noalias(rt_hash_table[i].chain, rth);
+					continue;
+				}
+			} else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
+				goto nofree;
+
+			/* Cleanup aged off entries. */
+			*rthp = rth->dst.rt_next;
+			rt_free(rth);
+		}
+		spin_unlock_bh(rt_hash_lock_addr(i));
+		sum += length;
+		sum2 += length*length;
+	}
+	if (samples) {
+		unsigned long avg = sum / samples;
+		unsigned long sd = int_sqrt(sum2 / samples - avg*avg);
+		rt_chain_length_max = max_t(unsigned long,
+					ip_rt_gc_elasticity,
+					(avg + 4*sd) >> FRACT_BITS);
+	}
+	rover = i;
+}
+
+/*
+ * rt_worker_func() is run in process context.
+ * we call rt_check_expire() to scan part of the hash table
+ */
+static void rt_worker_func(struct work_struct *work)
+{
+	rt_check_expire();
+	schedule_delayed_work(&expires_work, ip_rt_gc_interval);
+}
+
 /*
  * Perturbation of rt_genid by a small quantity [1..256]
  * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
@@ -3088,6 +3182,13 @@ static ctl_table ipv4_route_table[] = {
 		.proc_handler	= proc_dointvec_jiffies,
 	},
 	{
+		.procname	= "gc_interval",
+		.data		= &ip_rt_gc_interval,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_jiffies,
+	},
+	{
 		.procname	= "redirect_load",
 		.data		= &ip_rt_redirect_load,
 		.maxlen		= sizeof(int),
@@ -3297,6 +3398,11 @@ int __init ip_rt_init(void)
 	devinet_init();
 	ip_fib_init();
 
+	INIT_DELAYED_WORK_DEFERRABLE(&expires_work, rt_worker_func);
+	expires_ljiffies = jiffies;
+	schedule_delayed_work(&expires_work,
+		net_random() % ip_rt_gc_interval + ip_rt_gc_interval);
+
 	if (ip_rt_proc_init())
 		printk(KERN_ERR "Unable to create route proc files\n");
 #ifdef CONFIG_XFRM
author
#64 lore raw

PATCH 61/67 ipv4: using prefetch requires including prefetch.h

In reply to Greg KH

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

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

From: Stephen Rothwell <[email protected]>

[ Upstream commit b9eda06f80b0db61a73bd87c6b0eb67d8aca55ad ]

---
 net/ipv4/route.c |    1 +
 1 file changed, 1 insertion(+)
net/ipv4/route.c +1 -0
@@ -91,6 +91,7 @@
 #include <linux/rcupdate.h>
 #include <linux/times.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 #include <net/dst.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
author
#65 lore raw

PATCH 62/67 iwlwifi: update SCD BC table for all SCD queues

In reply to Greg KH

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

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

From: Emmanuel Grumbach <[email protected]>

commit 96f1f05af76b601ab21a7dc603ae0a1cea4efc3d upstream.

Since we configure all the queues as CHAINABLE, we need to update the byte count for all the queues, not only the AGGREGATABLE ones.

Not doing so can confuse the SCD and make the fw assert.

---
 drivers/net/wireless/iwlwifi/iwl-agn-tx.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/iwl-agn-tx.c +1 -4
@@ -778,10 +778,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
 	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
 	iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
 
-	/* Set up entry for this TFD in Tx byte-count array */
-	if (info->flags & IEEE80211_TX_CTL_AMPDU)
-		iwlagn_txq_update_byte_cnt_tbl(priv, txq,
-					       le16_to_cpu(tx_cmd->len));
+	iwlagn_txq_update_byte_cnt_tbl(priv, txq, le16_to_cpu(tx_cmd->len));
 
 	pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
 				       firstlen, PCI_DMA_BIDIRECTIONAL);
author
#66 lore raw

PATCH 63/67 mfd: Fix mismatch in twl4030 mutex lock-unlock

In reply to Greg KH

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

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

From: Sanjeev Premi <[email protected]>

commit e178ccb33569da17dc897a08a3865441b813bdfb upstream.

A mutex is locked on entry into twl4030_madc_conversion(). Immediate return on some error conditions leaves the mutex locked.

This patch ensures that mutex is always unlocked before leaving the function.

---
 drivers/mfd/twl4030-madc.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/mfd/twl4030-madc.c +4 -4
@@ -530,13 +530,13 @@ int twl4030_madc_conversion(struct twl40
 	if (ret) {
 		dev_err(twl4030_madc->dev,
 			"unable to write sel register 0x%X\n", method->sel + 1);
-		return ret;
+		goto out;
 	}
 	ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
 	if (ret) {
 		dev_err(twl4030_madc->dev,
 			"unable to write sel register 0x%X\n", method->sel + 1);
-		return ret;
+		goto out;
 	}
 	/* Select averaging for all channels if do_avg is set */
 	if (req->do_avg) {
@@ -546,7 +546,7 @@ int twl4030_madc_conversion(struct twl40
 			dev_err(twl4030_madc->dev,
 				"unable to write avg register 0x%X\n",
 				method->avg + 1);
-			return ret;
+			goto out;
 		}
 		ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
 				       ch_lsb, method->avg);
@@ -554,7 +554,7 @@ int twl4030_madc_conversion(struct twl40
 			dev_err(twl4030_madc->dev,
 				"unable to write sel reg 0x%X\n",
 				method->sel + 1);
-			return ret;
+			goto out;
 		}
 	}
 	if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
author
#67 lore raw

PATCH 64/67 mfd: Copy the device pointer to the twl4030-madc structure

In reply to Greg KH

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

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

From: Kyle Manna <[email protected]>

commit 66cc5b8e50af87b0bbd0f179d76d2826f4549c13 upstream.

Worst case this fixes the following error:

[   72.086212] (NULL device *): conversion timeout!

Best case it prevents a crash

---
 drivers/mfd/twl4030-madc.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/mfd/twl4030-madc.c +2 -0
@@ -706,6 +706,8 @@ static int __devinit twl4030_madc_probe(
 	if (!madc)
 		return -ENOMEM;
 
+	madc->dev = &pdev->dev;
+
 	/*
 	 * Phoenix provides 2 interrupt lines. The first one is connected to
 	 * the OMAP. The other one can be connected to the other processor such
author
#68 lore raw

PATCH 65/67 mfd: Check for twl4030-madc NULL pointer

In reply to Greg KH

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

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

From: Kyle Manna <[email protected]>

commit d0e84caeb4cd535923884735906e5730329505b4 upstream.

If the twl4030-madc device wasn't registered, and another device, such as twl4030-madc-hwmon, calls twl4030_madc_conversion() a NULL pointer is dereferenced.

---
 drivers/mfd/twl4030-madc.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/mfd/twl4030-madc.c +2 -1
@@ -510,8 +510,9 @@ int twl4030_madc_conversion(struct twl40
 	u8 ch_msb, ch_lsb;
 	int ret;
 
-	if (!req)
+	if (!req || !twl4030_madc)
 		return -EINVAL;
+
 	mutex_lock(&twl4030_madc->lock);
 	if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
 		ret = -EINVAL;
author
#69 lore raw

PATCH 66/67 mfd: Turn on the twl4030-madc MADC clock

In reply to Greg KH

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

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

From: Kyle Manna <[email protected]>

commit 3d6271f92e98094584fd1e609a9969cd33e61122 upstream.

Without turning the MADC clock on, no MADC conversions occur.

$ cat /sys/class/hwmon/hwmon0/device/in8_input
[   53.428436] twl4030_madc twl4030_madc: conversion timeout!
cat: read error: Resource temporarily unavailable
---
 drivers/mfd/twl4030-madc.c       |   22 ++++++++++++++++++++++
 include/linux/i2c/twl4030-madc.h |    4 ++++
 2 files changed, 26 insertions(+)
drivers/mfd/twl4030-madc.c +22 -0
@@ -740,6 +740,28 @@ static int __devinit twl4030_madc_probe(
 			TWL4030_BCI_BCICTL1);
 		goto err_i2c;
 	}
+
+	/* Check that MADC clock is on */
+	ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &regval, TWL4030_REG_GPBR1);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
+				TWL4030_REG_GPBR1);
+		goto err_i2c;
+	}
+
+	/* If MADC clk is not on, turn it on */
+	if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
+		dev_info(&pdev->dev, "clk disabled, enabling\n");
+		regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
+		ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
+				       TWL4030_REG_GPBR1);
+		if (ret) {
+			dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
+					TWL4030_REG_GPBR1);
+			goto err_i2c;
+		}
+	}
+
 	platform_set_drvdata(pdev, madc);
 	mutex_init(&madc->lock);
 	ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
include/linux/i2c/twl4030-madc.h +4 -0
@@ -129,6 +129,10 @@ enum sample_type {
 #define REG_BCICTL2             0x024
 #define TWL4030_BCI_ITHSENS	0x007
 
+/* Register and bits for GPBR1 register */
+#define TWL4030_REG_GPBR1		0x0c
+#define TWL4030_GPBR1_MADC_HFCLK_EN	(1 << 7)
+
 struct twl4030_madc_user_parms {
 	int channel;
 	int average;
author
#70 lore raw

PATCH 67/67 xen/swiotlb: Use page alignment for early buffer allocation.

In reply to Greg KH

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

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

From: Konrad Rzeszutek Wilk <[email protected]>

commit 63a741757d15320a25ebf5778f8651cce2ed0611 upstream.

This fixes an odd bug found on a Dell PowerEdge 1850/0RC130 (BIOS A05 01/09/2006) where all of the modules doing pci_set_dma_mask would fail with:

ata_piix 0000:00:1f.1: enabling device (0005 -> 0007) ata_piix 0000:00:1f.1: can't derive routing for PCI INT A ata_piix 0000:00:1f.1: BMDMA: failed to set dma mask, falling back to PIO

The issue was the Xen-SWIOTLB was allocated such as that the end of buffer was stradling a page (and also above 4GB). The fix was spotted by Kalev Leonid which was to piggyback on git commit e79f86b2ef9c0a8c47225217c1018b7d3d90101c "swiotlb: Use page alignment for early buffer allocation" which:

We could call free_bootmem_late() if swiotlb is not used, and it will shrink to page alignment.

So alloc them with page alignment at first, to avoid lose two pages

And doing that fixes the outstanding issue.

---
 drivers/xen/swiotlb-xen.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/xen/swiotlb-xen.c +1 -1
@@ -162,7 +162,7 @@ void __init xen_swiotlb_init(int verbose
 	/*
 	 * Get IO TLB memory from any location.
 	 */
-	xen_io_tlb_start = alloc_bootmem(bytes);
+	xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes));
 	if (!xen_io_tlb_start)
 		panic("Cannot allocate SWIOTLB buffer");
 
author
#71 lore raw
In reply to Greg KH
Quoted 6 lines · Greg KH

This is the start of the stable review cycle for the 3.0.16 release. There are 67 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 us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.

Quoted 6 lines

Responses should be made by Friday, January 6, 2012, 20:00:00 UTC. 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.0.16-rc1.gz

and the diffstat can be found below.

Due to a few noted issues in this series, and a few last-minute straggler patches being applied to the final 3.2 release, there's a new 3.0.16-rc2 release, which can be found at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.0.16-rc1.gz
and the diffstat can be found below.

thanks,

greg k-h

 Makefile                                     |    4 +-
 arch/arm/mach-omap2/board-rx51-peripherals.c |    2 +-
 arch/arm/oprofile/common.c                   |    2 +-
 arch/arm/plat-mxc/pwm.c                      |   16 +-
 arch/s390/oprofile/init.c                    |    2 +-
 arch/sh/oprofile/common.c                    |    4 +-
 arch/sparc/include/asm/pgtable_32.h          |   20 +-
 arch/sparc/include/asm/pgtable_64.h          |   20 +-
 arch/sparc/kernel/entry.h                    |    7 +
 arch/sparc/kernel/module.c                   |   27 +
 arch/sparc/kernel/pci_sun4v.c                |    4 +-
 arch/sparc/kernel/setup_64.c                 |   48 +-
 arch/sparc/kernel/signal32.c                 |   18 +-
 arch/sparc/kernel/signal_32.c                |   30 +-
 arch/sparc/kernel/signal_64.c                |   42 +-
 arch/sparc/kernel/visemul.c                  |   32 +-
 arch/sparc/lib/memcpy.S                      |  804 ++++----------------------
 arch/sparc/mm/Makefile                       |    1 -
 arch/sparc/mm/btfixup.c                      |    3 +-
 arch/sparc/mm/generic_32.c                   |   98 ----
 arch/sparc/mm/generic_64.c                   |  164 ------
 arch/x86/net/bpf_jit_comp.c                  |    4 +-
 block/blk-core.c                             |   14 +-
 block/cfq-iosched.c                          |   16 +-
 drivers/gpu/drm/i915/i915_dma.c              |   10 +
 drivers/gpu/drm/i915/i915_drv.h              |    1 +
 drivers/gpu/drm/radeon/evergreen.c           |   12 +
 drivers/gpu/drm/radeon/radeon_atombios.c     |    6 +-
 drivers/input/mouse/synaptics.c              |   11 +
 drivers/media/video/s5p-fimc/fimc-core.c     |    2 +-
 drivers/mfd/twl-core.c                       |   16 +-
 drivers/mfd/twl4030-madc.c                   |   35 +-
 drivers/mmc/host/mmci.c                      |   14 +-
 drivers/mmc/host/vub300.c                    |    2 +-
 drivers/net/pptp.c                           |    4 +-
 drivers/net/wireless/ath/ath9k/main.c        |    3 +
 drivers/net/wireless/ath/ath9k/rc.c          |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c  |    4 +-
 drivers/net/wireless/iwlwifi/iwl-agn-tx.c    |   10 +-
 drivers/oprofile/oprofile_files.c            |    7 +-
 drivers/oprofile/oprofilefs.c                |   11 +-
 drivers/rtc/interface.c                      |   44 +--
 drivers/rtc/rtc-m41t80.c                     |    9 +
 drivers/s390/scsi/zfcp_scsi.c                |    4 +
 drivers/scsi/fcoe/fcoe.c                     |    1 +
 drivers/scsi/mpt2sas/mpt2sas_base.c          |   59 +--
 drivers/scsi/mpt2sas/mpt2sas_base.h          |    4 -
 drivers/scsi/mpt2sas/mpt2sas_scsih.c         |    2 +-
 drivers/ssb/driver_pcicore.c                 |    8 +-
 drivers/watchdog/hpwdt.c                     |    5 +-
 drivers/xen/swiotlb-xen.c                    |    2 +-
 fs/nfs/nfs4state.c                           |    8 +-
 fs/nilfs2/ioctl.c                            |   13 +
 fs/xfs/linux-2.6/xfs_super.c                 |   30 +-
 fs/xfs/linux-2.6/xfs_sync.c                  |   37 ++
 fs/xfs/linux-2.6/xfs_sync.h                  |    2 +
 include/linux/blkdev.h                       |    3 -
 include/linux/i2c/twl4030-madc.h             |    4 +
 include/linux/lglock.h                       |   36 +-
 include/net/sctp/structs.h                   |    4 +
 kernel/cgroup.c                              |    5 -
 kernel/exit.c                                |    9 +-
 kernel/futex.c                               |   28 +-
 kernel/hung_task.c                           |   14 +-
 kernel/sysctl_binary.c                       |    2 +-
 mm/filemap.c                                 |    7 +-
 mm/hugetlb.c                                 |    2 +-
 mm/memcontrol.c                              |    3 +-
 mm/oom_kill.c                                |    2 +-
 mm/percpu.c                                  |    6 +-
 net/ipv4/devinet.c                           |    5 +
 net/ipv4/ipconfig.c                          |    4 +
 net/ipv4/ipip.c                              |    7 +-
 net/ipv4/route.c                             |  107 ++++
 net/ipv6/sit.c                               |    7 +-
 net/llc/af_llc.c                             |   14 +-
 net/mac80211/agg-tx.c                        |   86 ++--
 net/sched/sch_gred.c                         |    2 +-
 net/sched/sch_mqprio.c                       |    2 +-
 net/sctp/associola.c                         |    2 +-
 net/sctp/output.c                            |    8 +-
 net/sctp/outqueue.c                          |    6 +-
 net/sctp/protocol.c                          |    3 +
 net/sctp/socket.c                            |    2 -
 net/sctp/sysctl.c                            |   13 +
 security/selinux/netport.c                   |    4 +-
 86 files changed, 824 insertions(+), 1335 deletions(-)
#72 lore raw
Quoted 10 lines · Greg KH
Quoted 9 lines · Greg KH

This is the start of the stable review cycle for the 3.0.16 release. There are 67 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 us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.

Responses should be made by Friday, January 6, 2012, 20:00:00 UTC. Anything received after that time might be too late.

Quoted 8 lines
Quoted 3 lines

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

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

and the diffstat can be found below.

Due to a few noted issues in this series, and a few last-minute straggler patches being applied to the final 3.2 release, there's a new 3.0.16-rc2 release, which can be found at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.0.16-rc1.gz

Doh, that should be:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.0.16-rc2.gz

Sorry about that.

greg k-h

author
#73 lore raw
In reply to Greg KH
Quoted 14 lines · Greg KH
Quoted 6 lines · Greg KH

This is the start of the stable review cycle for the 3.0.16 release. There are 67 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 us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.

Quoted 6 lines

Responses should be made by Friday, January 6, 2012, 20:00:00 UTC. 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.0.16-rc1.gz

and the diffstat can be found below.

Quoted 5 lines

Due to a few noted issues in this series, and a few last-minute straggler patches being applied to the final 3.2 release, there's a new 3.0.16-rc2 release, which can be found at:
kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.0.16-rc1.gz
and the diffstat can be found below.

I've included the new patches as replies to this email, one was replaced, hence the 40/73 numbering, one was deleted (the developers responsible already know about that) and 7 new ones added.

thanks,

greg k-h

author
#74 lore raw

PATCH 40/73 mpt2sas: fix non-x86 crash on shutdown

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

------------------
Content-Length: 4506
Lines: 151

From: Nagalakshmi Nandigama <[email protected]>

Upstrem commit: 911ae9434f83e7355d343f6c2be3ef5b00ea7aed

There's a bug in the MSIX backup and restore routines that cause a crash on non-x86 (direct access to PCI space not via read/write). These routines are unnecessary and were removed by the above commit, so also remove them from stable to fix the crash.

---
 drivers/scsi/mpt2sas/mpt2sas_base.c |   59 +-----------------------------------
 drivers/scsi/mpt2sas/mpt2sas_base.h |    4 --
 2 files changed, 2 insertions(+), 61 deletions(-)
drivers/scsi/mpt2sas/mpt2sas_base.c +2 -57
@@ -1082,41 +1082,6 @@ _base_config_dma_addressing(struct MPT2S
 }
 
 /**
- * _base_save_msix_table - backup msix vector table
- * @ioc: per adapter object
- *
- * This address an errata where diag reset clears out the table
- */
-static void
-_base_save_msix_table(struct MPT2SAS_ADAPTER *ioc)
-{
-	int i;
-
-	if (!ioc->msix_enable || ioc->msix_table_backup == NULL)
-		return;
-
-	for (i = 0; i < ioc->msix_vector_count; i++)
-		ioc->msix_table_backup[i] = ioc->msix_table[i];
-}
-
-/**
- * _base_restore_msix_table - this restores the msix vector table
- * @ioc: per adapter object
- *
- */
-static void
-_base_restore_msix_table(struct MPT2SAS_ADAPTER *ioc)
-{
-	int i;
-
-	if (!ioc->msix_enable || ioc->msix_table_backup == NULL)
-		return;
-
-	for (i = 0; i < ioc->msix_vector_count; i++)
-		ioc->msix_table[i] = ioc->msix_table_backup[i];
-}
-
-/**
  * _base_check_enable_msix - checks MSIX capabable.
  * @ioc: per adapter object
  *
@@ -1128,7 +1093,7 @@ _base_check_enable_msix(struct MPT2SAS_A
 {
 	int base;
 	u16 message_control;
-	u32 msix_table_offset;
+
 
 	base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
 	if (!base) {
@@ -1141,14 +1106,8 @@ _base_check_enable_msix(struct MPT2SAS_A
 	pci_read_config_word(ioc->pdev, base + 2, &message_control);
 	ioc->msix_vector_count = (message_control & 0x3FF) + 1;
 
-	/* get msix table  */
-	pci_read_config_dword(ioc->pdev, base + 4, &msix_table_offset);
-	msix_table_offset &= 0xFFFFFFF8;
-	ioc->msix_table = (u32 *)((void *)ioc->chip + msix_table_offset);
-
 	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "msix is supported, "
-	    "vector_count(%d), table_offset(0x%08x), table(%p)\n", ioc->name,
-	    ioc->msix_vector_count, msix_table_offset, ioc->msix_table));
+	    "vector_count(%d)\n", ioc->name, ioc->msix_vector_count));
 	return 0;
 }
 
@@ -1162,8 +1121,6 @@ _base_disable_msix(struct MPT2SAS_ADAPTE
 {
 	if (ioc->msix_enable) {
 		pci_disable_msix(ioc->pdev);
-		kfree(ioc->msix_table_backup);
-		ioc->msix_table_backup = NULL;
 		ioc->msix_enable = 0;
 	}
 }
@@ -1189,14 +1146,6 @@ _base_enable_msix(struct MPT2SAS_ADAPTER
 	if (_base_check_enable_msix(ioc) != 0)
 		goto try_ioapic;
 
-	ioc->msix_table_backup = kcalloc(ioc->msix_vector_count,
-	    sizeof(u32), GFP_KERNEL);
-	if (!ioc->msix_table_backup) {
-		dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "allocation for "
-		    "msix_table_backup failed!!!\n", ioc->name));
-		goto try_ioapic;
-	}
-
 	memset(&entries, 0, sizeof(struct msix_entry));
 	r = pci_enable_msix(ioc->pdev, &entries, 1);
 	if (r) {
@@ -3513,9 +3462,6 @@ _base_diag_reset(struct MPT2SAS_ADAPTER
 	u32 hcb_size;
 
 	printk(MPT2SAS_INFO_FMT "sending diag reset !!\n", ioc->name);
-
-	_base_save_msix_table(ioc);
-
 	drsprintk(ioc, printk(MPT2SAS_INFO_FMT "clear interrupts\n",
 	    ioc->name));
 
@@ -3611,7 +3557,6 @@ _base_diag_reset(struct MPT2SAS_ADAPTER
 		goto out;
 	}
 
-	_base_restore_msix_table(ioc);
 	printk(MPT2SAS_INFO_FMT "diag reset: SUCCESS\n", ioc->name);
 	return 0;
 
drivers/scsi/mpt2sas/mpt2sas_base.h +0 -4
@@ -626,8 +626,6 @@ struct mpt2sas_port_facts {
  * @wait_for_port_enable_to_complete:
  * @msix_enable: flag indicating msix is enabled
  * @msix_vector_count: number msix vectors
- * @msix_table: virt address to the msix table
- * @msix_table_backup: backup msix table
  * @scsi_io_cb_idx: shost generated commands
  * @tm_cb_idx: task management commands
  * @scsih_cb_idx: scsih internal commands
@@ -768,8 +766,6 @@ struct MPT2SAS_ADAPTER {
 
 	u8		msix_enable;
 	u16		msix_vector_count;
-	u32		*msix_table;
-	u32		*msix_table_backup;
 	u32		ioc_reset_count;
 
 	/* internal commands, callback index */
author
#75 lore raw

PATCH 67/73 xfs: log the inode in ->write_inode calls for kupdate

In reply to Greg KH

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

------------------
Content-Length: 2680
Lines: 86

From: Christoph Hellwig <[email protected]>

Commit 0b8fd3033c308e4088760aa1d38ce77197b4e074 upstream.

If the writeback code writes back an inode because it has expired we currently use the non-blockin ->write_inode path. This means any inode that is pinned is skipped. With delayed logging and a workload that has very little log traffic otherwise it is very likely that an inode that gets constantly written to is always pinned, and thus we keep refusing to write it. The VM writeback code at that point redirties it and doesn't try to write it again for another 30 seconds. This means under certain scenarious time based metadata writeback never happens.

Fix this by calling into xfs_log_inode for kupdate in addition to data integrity syncs, and thus transfer the inode to the log ASAP.

---
 fs/xfs/linux-2.6/xfs_super.c |   30 +++++-------------------------
 1 file changed, 5 insertions(+), 25 deletions(-)
fs/xfs/linux-2.6/xfs_super.c +5 -25
@@ -871,27 +871,6 @@ xfs_fs_dirty_inode(
 }
 
 STATIC int
-xfs_log_inode(
-	struct xfs_inode	*ip)
-{
-	struct xfs_mount	*mp = ip->i_mount;
-	struct xfs_trans	*tp;
-	int			error;
-
-	tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
-	error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
-	if (error) {
-		xfs_trans_cancel(tp, 0);
-		return error;
-	}
-
-	xfs_ilock(ip, XFS_ILOCK_EXCL);
-	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
-	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-	return xfs_trans_commit(tp, 0);
-}
-
-STATIC int
 xfs_fs_write_inode(
 	struct inode		*inode,
 	struct writeback_control *wbc)
@@ -904,10 +883,8 @@ xfs_fs_write_inode(
 
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return -XFS_ERROR(EIO);
-	if (!ip->i_update_core)
-		return 0;
 
-	if (wbc->sync_mode == WB_SYNC_ALL) {
+	if (wbc->sync_mode == WB_SYNC_ALL || wbc->for_kupdate) {
 		/*
 		 * Make sure the inode has made it it into the log.  Instead
 		 * of forcing it all the way to stable storage using a
@@ -916,11 +893,14 @@ xfs_fs_write_inode(
 		 * of synchronous log foces dramatically.
 		 */
 		xfs_ioend_wait(ip);
-		error = xfs_log_inode(ip);
+		error = xfs_log_dirty_inode(ip, NULL, 0);
 		if (error)
 			goto out;
 		return 0;
 	} else {
+		if (!ip->i_update_core)
+			return 0;
+
 		/*
 		 * We make this non-blocking if the inode is contended, return
 		 * EAGAIN to indicate to the caller that they did not succeed.
author
#76 lore raw

PATCH 68/73 xfs: log all dirty inodes in xfs_fs_sync_fs

In reply to Greg KH

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

------------------
Content-Length: 3536
Lines: 104

From: Christoph Hellwig <[email protected]>

Commit be4f1ac828776bbc7868a68b465cd8eedb733cfd upstream.

Since Linux 2.6.36 the writeback code has introduces various measures for live lock prevention during sync(). Unfortunately some of these are actively harmful for the XFS model, where the inode gets marked dirty for metadata from the data I/O handler.

The older_than_this checks that are now more strictly enforced since

writeback: avoid livelocking WB_SYNC_ALL writeback

by only calling into __writeback_inodes_sb and thus only sampling the current cut off time once. But on a slow enough devices the previous asynchronous sync pass might not have fully completed yet, and thus XFS might mark metadata dirty only after that sampling of the cut off time for the blocking pass already happened. I have not myself reproduced this myself on a real system, but by introducing artificial delay into the XFS I/O completion workqueues it can be reproduced easily.

Fix this by iterating over all XFS inodes in ->sync_fs and log all that are dirty. This might log inode that only got redirtied after the previous pass, but given how cheap delayed logging of inodes is it isn't a major concern for performance.

---
 fs/xfs/linux-2.6/xfs_sync.c |   37 +++++++++++++++++++++++++++++++++++++
 fs/xfs/linux-2.6/xfs_sync.h |    2 ++
 2 files changed, 39 insertions(+)
fs/xfs/linux-2.6/xfs_sync.c +37 -0
@@ -336,6 +336,32 @@ xfs_sync_fsdata(
 	return xfs_bwrite(mp, bp);
 }
 
+int
+xfs_log_dirty_inode(
+	struct xfs_inode	*ip,
+	struct xfs_perag	*pag,
+	int			flags)
+{
+	struct xfs_mount	*mp = ip->i_mount;
+	struct xfs_trans	*tp;
+	int			error;
+
+	if (!ip->i_update_core)
+		return 0;
+
+	tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
+	error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
+	if (error) {
+		xfs_trans_cancel(tp, 0);
+		return error;
+	}
+
+	xfs_ilock(ip, XFS_ILOCK_EXCL);
+	xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
+	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+	return xfs_trans_commit(tp, 0);
+}
+
 /*
  * When remounting a filesystem read-only or freezing the filesystem, we have
  * two phases to execute. This first phase is syncing the data before we
@@ -365,6 +391,17 @@ xfs_quiesce_data(
 
 	/* push and block till complete */
 	xfs_sync_data(mp, SYNC_WAIT);
+
+	/*
+	 * Log all pending size and timestamp updates.  The vfs writeback
+	 * code is supposed to do this, but due to its overagressive
+	 * livelock detection it will skip inodes where appending writes
+	 * were written out in the first non-blocking sync phase if their
+	 * completion took long enough that it happened after taking the
+	 * timestamp for the cut-off in the blocking phase.
+	 */
+	xfs_inode_ag_iterator(mp, xfs_log_dirty_inode, 0);
+
 	xfs_qm_sync(mp, SYNC_WAIT);
 
 	/* write superblock and hoover up shutdown errors */
fs/xfs/linux-2.6/xfs_sync.h +2 -0
@@ -42,6 +42,8 @@ void xfs_quiesce_attr(struct xfs_mount *
 
 void xfs_flush_inodes(struct xfs_inode *ip);
 
+int xfs_log_dirty_inode(struct xfs_inode *ip, struct xfs_perag *pag, int flags);
+
 int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
 
 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
author
#77 lore raw

PATCH 69/73 drm/radeon/kms/atom: fix possible segfault in pm setup

In reply to Greg KH

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

------------------
Content-Length: 1216
Lines: 36

From: =?UTF-8?q?Alexander=20M=C3=BCller?= <[email protected]>

commit 4376eee92e5a8332b470040e672ea99cd44c826a upstream.

If we end up with no power states, don't look up
current vddc.

fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=44130

agd5f: fix patch formatting

---
 drivers/gpu/drm/radeon/radeon_atombios.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_atombios.c +5 -1
@@ -2568,7 +2568,11 @@ void radeon_atombios_get_power_modes(str
 
 	rdev->pm.current_power_state_index = rdev->pm.default_power_state_index;
 	rdev->pm.current_clock_mode_index = 0;
-	rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
+	if (rdev->pm.default_power_state_index >= 0)
+		rdev->pm.current_vddc =
+			rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
+	else
+		rdev->pm.current_vddc = 0;
 }
 
 void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable)
author
#78 lore raw

PATCH 70/73 hung_task: fix false positive during vfork

In reply to Greg KH

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

------------------
Content-Length: 1649
Lines: 48

From: Mandeep Singh Baines <[email protected]>

commit f9fab10bbd768b0e5254e53a4a8477a94bfc4b96 upstream.

vfork parent uninterruptibly and unkillably waits for its child to exec/exit. This wait is of unbounded length. Ignore such waits in the hung_task detector.

LKML-Reference: <1325344394.28904.43.camel@lappy>

Cc Linus Torvalds <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Andrew Morton <[email protected]>
Cc John Kacur <[email protected]>
---
 kernel/hung_task.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
kernel/hung_task.c +10 -4
@@ -74,11 +74,17 @@ static void check_hung_task(struct task_
 
 	/*
 	 * Ensure the task is not frozen.
-	 * Also, when a freshly created task is scheduled once, changes
-	 * its state to TASK_UNINTERRUPTIBLE without having ever been
-	 * switched out once, it musn't be checked.
+	 * Also, skip vfork and any other user process that freezer should skip.
 	 */
-	if (unlikely(t->flags & PF_FROZEN || !switch_count))
+	if (unlikely(t->flags & (PF_FROZEN | PF_FREEZER_SKIP)))
+	    return;
+
+	/*
+	 * When a freshly created task is scheduled once, changes its state to
+	 * TASK_UNINTERRUPTIBLE without having ever been switched out once, it
+	 * musn't be checked.
+	 */
+	if (unlikely(!switch_count))
 		return;
 
 	if (switch_count != t->last_switch_count) {
author
#79 lore raw

PATCH 71/73 Revert "rtc: Disable the alarm in the hardware"

In reply to Greg KH

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

------------------
Content-Length: 3184
Lines: 115

From: Linus Torvalds <[email protected]>

commit 157e8bf8b4823bfcdefa6c1548002374b61f61df upstream.

This reverts commit c0afabd3d553c521e003779c127143ffde55a16f.

It causes failures on Toshiba laptops - instead of disabling the alarm, it actually seems to enable it on the affected laptops, resulting in (for example) the laptop powering on automatically five minutes after shutdown.

There's a patch for it that appears to work for at least some people, but it's too late to play around with this, so revert for now and try again in the next merge window.

See for example

	http://bugs.debian.org/652869
---
 drivers/rtc/interface.c |   44 ++++++++++----------------------------------
 1 file changed, 10 insertions(+), 34 deletions(-)
drivers/rtc/interface.c +10 -34
@@ -318,20 +318,6 @@ int rtc_read_alarm(struct rtc_device *rt
 }
 EXPORT_SYMBOL_GPL(rtc_read_alarm);
 
-static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
-{
-	int err;
-
-	if (!rtc->ops)
-		err = -ENODEV;
-	else if (!rtc->ops->set_alarm)
-		err = -EINVAL;
-	else
-		err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
-
-	return err;
-}
-
 static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 {
 	struct rtc_time tm;
@@ -355,7 +341,14 @@ static int __rtc_set_alarm(struct rtc_de
 	 * over right here, before we set the alarm.
 	 */
 
-	return ___rtc_set_alarm(rtc, alarm);
+	if (!rtc->ops)
+		err = -ENODEV;
+	else if (!rtc->ops->set_alarm)
+		err = -EINVAL;
+	else
+		err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
+
+	return err;
 }
 
 int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
@@ -769,20 +762,6 @@ static int rtc_timer_enqueue(struct rtc_
 	return 0;
 }
 
-static void rtc_alarm_disable(struct rtc_device *rtc)
-{
-	struct rtc_wkalrm alarm;
-	struct rtc_time tm;
-
-	__rtc_read_time(rtc, &tm);
-
-	alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm),
-				     ktime_set(300, 0)));
-	alarm.enabled = 0;
-
-	___rtc_set_alarm(rtc, &alarm);
-}
-
 /**
  * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue
  * @rtc rtc device
@@ -804,10 +783,8 @@ static void rtc_timer_remove(struct rtc_
 		struct rtc_wkalrm alarm;
 		int err;
 		next = timerqueue_getnext(&rtc->timerqueue);
-		if (!next) {
-			rtc_alarm_disable(rtc);
+		if (!next)
 			return;
-		}
 		alarm.time = rtc_ktime_to_tm(next->expires);
 		alarm.enabled = 1;
 		err = __rtc_set_alarm(rtc, &alarm);
@@ -869,8 +846,7 @@ again:
 		err = __rtc_set_alarm(rtc, &alarm);
 		if (err == -ETIME)
 			goto again;
-	} else
-		rtc_alarm_disable(rtc);
+	}
 
 	mutex_unlock(&rtc->ops_lock);
 }
author
#80 lore raw

PATCH 72/73 ptrace: partially fix the do_wait(WEXITED) vs EXIT_DEAD->EXIT_ZOMBIE race

In reply to Greg KH

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

------------------
Content-Length: 2354
Lines: 86

From: Oleg Nesterov <[email protected]>

commit 50b8d257486a45cba7b65ca978986ed216bbcc10 upstream.

Test-case:

	int main(void)
	{
		int pid, status;

		pid = fork();
		if (!pid) {
			for (;;) {
				if (!fork())
					return 0;
				if (waitpid(-1, &status, 0) < 0) {
					printf("ERR!! wait: %m\n");
					return 0;
				}
			}
		}

		assert(ptrace(PTRACE_ATTACH, pid, 0,0) == 0);
		assert(waitpid(-1, NULL, 0) == pid);

		assert(ptrace(PTRACE_SETOPTIONS, pid, 0,
					PTRACE_O_TRACEFORK) == 0);

		do {
			ptrace(PTRACE_CONT, pid, 0, 0);
			pid = waitpid(-1, NULL, 0);
		} while (pid > 0);

		return 1;
	}

It fails because ->real_parent sees its child in EXIT_DEAD state while the tracer is going to change the state back to EXIT_ZOMBIE in wait_task_zombie().

The offending commit is 823b018e which moved the EXIT_DEAD check, but in fact we should not blame it. The original code was not correct as well because it didn't take ptrace_reparented() into account and because we can't really trust ->ptrace.

This patch adds the additional check to close this particular race but it doesn't solve the whole problem. We simply can't rely on ->ptrace in this case, it can be cleared if the tracer is multithreaded by the exiting ->parent.

I think we should kill EXIT_DEAD altogether, we should always remove the soon-to-be-reaped child from ->children or at least we should never do the DEAD->ZOMBIE transition. But this is too complex for 3.2.

---
 kernel/exit.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
kernel/exit.c +8 -1
@@ -1553,8 +1553,15 @@ static int wait_consider_task(struct wai
 	}
 
 	/* dead body doesn't have much to contribute */
-	if (p->exit_state == EXIT_DEAD)
+	if (unlikely(p->exit_state == EXIT_DEAD)) {
+		/*
+		 * But do not ignore this task until the tracer does
+		 * wait_task_zombie()->do_notify_parent().
+		 */
+		if (likely(!ptrace) && unlikely(ptrace_reparented(p)))
+			wo->notask_error = 0;
 		return 0;
+	}
 
 	/* slay zombie? */
 	if (p->exit_state == EXIT_ZOMBIE) {
author
#81 lore raw

PATCH 73/73 ath9k: Fix kernel panic in AR2427 in AP mode

In reply to Greg KH

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

------------------
Content-Length: 2620
Lines: 69

From: Mohammed Shafi Shajakhan <[email protected]>

commit b25bfda38236f349cde0d1b28952f4eea2148d3f upstream.

don't do aggregation related stuff for 'AP mode client power save handling' if aggregation is not enabled in the driver, otherwise it will lead to panic because those data structures won't be never intialized in 'ath_tx_node_init' if aggregation is disabled

	EIP is at ath_tx_aggr_wakeup+0x37/0x80 [ath9k]
	EAX: e8c09a20 EBX: f2a304e8 ECX: 00000001 EDX: 00000000
	ESI: e8c085e0 EDI: f2a304ac EBP: f40e1ca4 ESP: f40e1c8c
	DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
	Process swapper/1 (pid: 0, ti=f40e0000 task=f408e860
	task.ti=f40dc000)
	Stack:
	0001e966 e8c09a20 00000000 f2a304ac e8c085e0 f2a304ac
	f40e1cb0 f8186741
	f8186700 f40e1d2c f922988d f2a304ac 00000202 00000001
	c0b4ba43 00000000
	0000000f e8eb75c0 e8c085e0 205b0001 34383220 f2a304ac
	f2a30000 00010020
	Call Trace:
	[<f8186741>] ath9k_sta_notify+0x41/0x50 [ath9k]
	[<f8186700>] ? ath9k_get_survey+0x110/0x110 [ath9k]
	[<f922988d>] ieee80211_sta_ps_deliver_wakeup+0x9d/0x350
	[mac80211]
	[<c018dc75>] ? __module_address+0x95/0xb0
	[<f92465b3>] ap_sta_ps_end+0x63/0xa0 [mac80211]
	[<f9246746>] ieee80211_rx_h_sta_process+0x156/0x2b0
	[mac80211]
	[<f9247d1e>] ieee80211_rx_handlers+0xce/0x510 [mac80211]
	[<c018440b>] ? trace_hardirqs_on+0xb/0x10
	[<c056936e>] ? skb_queue_tail+0x3e/0x50
	[<f9248271>] ieee80211_prepare_and_rx_handle+0x111/0x750
	[mac80211]
	[<f9248bf9>] ieee80211_rx+0x349/0xb20 [mac80211]
	[<f9248949>] ? ieee80211_rx+0x99/0xb20 [mac80211]
	[<f818b0b8>] ath_rx_tasklet+0x818/0x1d00 [ath9k]
	[<f8187a75>] ? ath9k_tasklet+0x35/0x1c0 [ath9k]
	[<f8187a75>] ? ath9k_tasklet+0x35/0x1c0 [ath9k]
	[<f8187b33>] ath9k_tasklet+0xf3/0x1c0 [ath9k]
	[<c0151b7e>] tasklet_action+0xbe/0x180
---
 drivers/net/wireless/ath/ath9k/main.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/net/wireless/ath/ath9k/main.c +3 -0
@@ -1828,6 +1828,9 @@ static void ath9k_sta_notify(struct ieee
 	struct ath_softc *sc = hw->priv;
 	struct ath_node *an = (struct ath_node *) sta->drv_priv;
 
+	if (!(sc->sc_flags & SC_OP_TXAGGR))
+		return;
+
 	switch (cmd) {
 	case STA_NOTIFY_SLEEP:
 		an->sleeping = true;