Skip to contentSkip to conversation

2.6.25-stable review

PATCH In review Greg KH 6 participants 43 messages Apr 29, 2008 – May 1, 2008

Subsystems (28)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

cover 2.6.25-stable review

This is the start of the stable review cycle for the 2.6.25.1 release. There are 37 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.

These patches are sent out with a number of different people on the Cc:
line. If you wish to be a reviewer, please email [email protected] to add your name to the list. If you want to be off the reviewer list, also email us.

Responses should be made by Thursday, May 1 16: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/v2.6/stable-review/patch-2.6.25.1-rc1.gz

and the diffstat can be found below.

thanks,

the -stable release team

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

 Makefile                              |    2 
 arch/alpha/kernel/osf_sys.c           |    1 
 arch/x86/kernel/io_apic_32.c          |    1 
 arch/x86/pci/irq.c                    |   12 ++---
 drivers/infiniband/hw/nes/nes.c       |    4 -
 drivers/infiniband/hw/nes/nes_cm.c    |    6 +-
 drivers/infiniband/hw/nes/nes_hw.c    |   20 ++++-----
 drivers/md/dm-exception-store.c       |    2 
 drivers/media/video/cx88/cx88-cards.c |    4 +
 drivers/media/video/ivtv/ivtv-ioctl.c |    3 -
 drivers/media/video/tea5761.c         |   15 ++++--
 drivers/media/video/tuner-core.c      |    6 +-
 drivers/net/s2io.c                    |    4 -
 drivers/net/tehuti.c                  |   15 ++++++
 drivers/net/tg3.c                     |   52 ++++++++++++++++++++++--
 drivers/net/tg3.h                     |    1 
 drivers/net/wireless/b43/dma.c        |   73 ++++++++++++++++++++++++----------
 drivers/net/wireless/b43/main.c       |   28 ++++++++++++-
 drivers/rtc/rtc-pcf8583.c             |    2 
 drivers/scsi/qla2xxx/qla_os.c         |    2 
 drivers/serial/dz.c                   |    2 
 drivers/ssb/pci.c                     |    5 ++
 drivers/usb/core/hub.c                |    1 
 drivers/usb/host/ohci-pci.c           |    4 +
 drivers/usb/serial/sierra.c           |    1 
 fs/aio.c                              |   12 +++++
 fs/jffs2/erase.c                      |   18 +++-----
 include/linux/rtnetlink.h             |    4 -
 include/net/tcp.h                     |    7 ++-
 include/net/xfrm.h                    |    3 +
 kernel/cgroup.c                       |    7 ++-
 kernel/hrtimer.c                      |   34 +++++++++++++--
 mm/pagewalk.c                         |    8 ++-
 net/can/raw.c                         |    3 -
 net/core/rtnetlink.c                  |    6 ++
 net/dccp/probe.c                      |    2 
 net/ipv4/tcp_probe.c                  |    9 +---
 net/key/af_key.c                      |    2 
 net/rose/af_rose.c                    |    6 +-
 net/tipc/socket.c                     |    4 -
 net/xfrm/xfrm_policy.c                |    2 
 net/xfrm/xfrm_user.c                  |    2 
 security/selinux/hooks.c              |   15 +++++-
 43 files changed, 307 insertions(+), 103 deletions(-)
author
#1 lore raw

PATCH 1/37 USB: log an error message when USB enumeration fails

2.6.25-stable review patch. If anyone has any objections, please let us know.

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

From: Alan Stern <[email protected]>

commit: 6427f7995338387ddded92f98adec19ddbf0ae5e

This patch (as1077) logs an error message whenever the kernel is unable to enumerate a new USB device.

---
 drivers/usb/core/hub.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/core/hub.c +1 -0
@@ -2664,6 +2664,7 @@ loop:
 		if ((status == -ENOTCONN) || (status == -ENOTSUPP))
 			break;
 	}
+	dev_err(hub_dev, "unable to enumerate USB device on port %d\n", port1);
  
 done:
 	hub_port_disable(hub, port1, 1);
author
#2 lore raw

PATCH 2/37 USB: Add HP hs2300 Broadband Wireless Module to sierra.c

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

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

From: Stefan Seyfried <[email protected]>

commit 8f7f85e9f9561507b009d26395c53e70758695ec upstream

Add the HP hs2300 Broadband Wireless Module (relabeled MC8775) USB IDs

---
 drivers/usb/serial/sierra.c |    1 +
 1 file changed, 1 insertion(+)
drivers/usb/serial/sierra.c +1 -0
@@ -164,6 +164,7 @@ static struct usb_device_id id_table [] 
 	{ USB_DEVICE(0x1199, 0x6812) },	/* Sierra Wireless MC8775 & AC 875U */
 	{ USB_DEVICE(0x1199, 0x6813) },	/* Sierra Wireless MC8775 (Thinkpad internal) */
 	{ USB_DEVICE(0x1199, 0x6815) },	/* Sierra Wireless MC8775 */
+	{ USB_DEVICE(0x03f0, 0x1e1d) },	/* HP hs2300 a.k.a MC8775 */
 	{ USB_DEVICE(0x1199, 0x6820) },	/* Sierra Wireless AirCard 875 */
 	{ USB_DEVICE(0x1199, 0x6832) },	/* Sierra Wireless MC8780*/
 	{ USB_DEVICE(0x1199, 0x6833) },	/* Sierra Wireless MC8781*/
author
#3 lore raw

PATCH 3/37 JFFS2: Fix free space leak with in-band cleanmarkers

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: David Woodhouse <[email protected]>

We were accounting for the cleanmarker by calling jffs2_link_node_ref() (without locking!), which adjusted both superblock and per-eraseblock accounting, subtracting the size of the cleanmarker from {jeb,c}->free_size and adding it to {jeb,c}->used_size.

But only _then_ were we adding the size of the newly-erased block back to the superblock counts, and we were adding each of jeb->{free,used}_size to the corresponding superblock counts. Thus, the size of the cleanmarker was effectively subtracted from the superblock's free_size _twice_.

Fix this, by always adding a full eraseblock size to c->free_size when we've erased a block. And call jffs2_link_node_ref() under the proper lock, while we're at it.

Thanks to Alexander Yurchenko and/or Damir Shayhutdinov for (almost) pinpointing the problem.

[Backport of commit 014b164e1392a166fe96e003d2f0e7ad2e2a0bb7]

---
 fs/jffs2/erase.c |   18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)
fs/jffs2/erase.c +8 -10
@@ -419,9 +419,6 @@ static void jffs2_mark_erased_block(stru
 			if (jffs2_write_nand_cleanmarker(c, jeb))
 				goto filebad;
 		}
-
-		/* Everything else got zeroed before the erase */
-		jeb->free_size = c->sector_size;
 	} else {
 
 		struct kvec vecs[1];
@@ -449,18 +446,19 @@ static void jffs2_mark_erased_block(stru
 
 			goto filebad;
 		}
-
-		/* Everything else got zeroed before the erase */
-		jeb->free_size = c->sector_size;
-		/* FIXME Special case for cleanmarker in empty block */
-		jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
 	}
+	/* Everything else got zeroed before the erase */
+	jeb->free_size = c->sector_size;
 
 	down(&c->erase_free_sem);
 	spin_lock(&c->erase_completion_lock);
+
 	c->erasing_size -= c->sector_size;
-	c->free_size += jeb->free_size;
-	c->used_size += jeb->used_size;
+	c->free_size += c->sector_size;
+
+	/* Account for cleanmarker now, if it's in-band */
+	if (c->cleanmarker_size && !jffs2_cleanmarker_oob(c))
+		jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
 
 	jffs2_dbg_acct_sanity_check_nolock(c,jeb);
 	jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
author
#4 lore raw

PATCH 4/37 tg3: 5701 DMA corruption fix

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Matt Carlson <[email protected]>

[ Upstream commit: 41588ba1ae166eaba0a70abf2d7ff064ad9331d3 ]

Herbert Xu's commit fb93134dfc2a6e6fbedc7c270a31da03fce88db9, entitled "[TCP]: Fix size calculation in sk_stream_alloc_pskb", has triggered a bug in the 5701 where the 5701 DMA engine will corrupt outgoing packets. This problem only happens when the starting address of the packet matches a certain range of offsets and only when the 5701 is placed downstream of a particular Intel bridge.

This patch detects the problematic bridge and if present, readjusts the starting address of the packet data to a dword aligned boundary.

---
 drivers/net/tg3.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++----
 drivers/net/tg3.h |    1 +
 2 files changed, 49 insertions(+), 4 deletions(-)
drivers/net/tg3.c +48 -4
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.90"
-#define DRV_MODULE_RELDATE	"April 12, 2008"
+#define DRV_MODULE_VERSION	"3.91"
+#define DRV_MODULE_RELDATE	"April 18, 2008"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -4135,11 +4135,21 @@ static int tigon3_dma_hwbug_workaround(s
 				       u32 last_plus_one, u32 *start,
 				       u32 base_flags, u32 mss)
 {
-	struct sk_buff *new_skb = skb_copy(skb, GFP_ATOMIC);
+	struct sk_buff *new_skb;
 	dma_addr_t new_addr = 0;
 	u32 entry = *start;
 	int i, ret = 0;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
+		new_skb = skb_copy(skb, GFP_ATOMIC);
+	else {
+		int more_headroom = 4 - ((unsigned long)skb->data & 3);
+
+		new_skb = skb_copy_expand(skb,
+					  skb_headroom(skb) + more_headroom,
+					  skb_tailroom(skb), GFP_ATOMIC);
+	}
+
 	if (!new_skb) {
 		ret = -1;
 	} else {
@@ -4462,7 +4472,9 @@ static int tg3_start_xmit_dma_bug(struct
 
 	would_hit_hwbug = 0;
 
-	if (tg3_4g_overflow_test(mapping, len))
+	if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+		would_hit_hwbug = 1;
+	else if (tg3_4g_overflow_test(mapping, len))
 		would_hit_hwbug = 1;
 
 	tg3_set_txd(tp, entry, mapping, len, base_flags,
@@ -11339,6 +11351,38 @@ static int __devinit tg3_get_invariants(
 		}
 	}
 
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
+		static struct tg3_dev_id {
+			u32	vendor;
+			u32	device;
+		} bridge_chipsets[] = {
+			{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0 },
+			{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1 },
+			{ },
+		};
+		struct tg3_dev_id *pci_id = &bridge_chipsets[0];
+		struct pci_dev *bridge = NULL;
+
+		while (pci_id->vendor != 0) {
+			bridge = pci_get_device(pci_id->vendor,
+						pci_id->device,
+						bridge);
+			if (!bridge) {
+				pci_id++;
+				continue;
+			}
+			if (bridge->subordinate &&
+			    (bridge->subordinate->number <=
+			     tp->pdev->bus->number) &&
+			    (bridge->subordinate->subordinate >=
+			     tp->pdev->bus->number)) {
+				tp->tg3_flags3 |= TG3_FLG3_5701_DMA_BUG;
+				pci_dev_put(bridge);
+				break;
+			}
+		}
+	}
+
 	/* The EPB bridge inside 5714, 5715, and 5780 cannot support
 	 * DMA addresses > 40-bit. This bridge may have other additional
 	 * 57xx devices behind it in some 4-port NIC designs for example.
drivers/net/tg3.h +1 -0
@@ -2476,6 +2476,7 @@ struct tg3 {
 #define TG3_FLG3_NO_NVRAM_ADDR_TRANS	0x00000001
 #define TG3_FLG3_ENABLE_APE		0x00000002
 #define TG3_FLG3_5761_5784_AX_FIXES	0x00000004
+#define TG3_FLG3_5701_DMA_BUG		0x00000008
 
 	struct timer_list		timer;
 	u16				timer_counter;
author
#5 lore raw

PATCH 5/37 tcp: tcp_probe buffer overflow and incorrect return value

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Tom Quetchenbach <[email protected]>

[ Upstream commit: 8d390efd903485923419584275fd0c2aa4c94183 ]

tcp_probe has a bounds-checking bug that causes many programs (less, python) to crash reading /proc/net/tcp_probe. When it outputs a log line to the reader, it only checks if that line alone will fit in the reader's buffer, rather than that line and all the previous lines it has already written.

tcpprobe_read also returns the wrong value if copy_to_user fails--it just passes on the return value of copy_to_user (number of bytes not copied), which makes a failure look like a success.

This patch fixes the buffer overflow and sets the return value to -EFAULT if copy_to_user fails.

Patch is against latest net-2.6; tested briefly and seems to fix the crashes in less and python.

---
 net/ipv4/tcp_probe.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
net/ipv4/tcp_probe.c +4 -5
@@ -190,19 +190,18 @@ static ssize_t tcpprobe_read(struct file
 
 		width = tcpprobe_sprint(tbuf, sizeof(tbuf));
 
-		if (width < len)
+		if (cnt + width < len)
 			tcp_probe.tail = (tcp_probe.tail + 1) % bufsize;
 
 		spin_unlock_bh(&tcp_probe.lock);
 
 		/* if record greater than space available
 		   return partial buffer (so far) */
-		if (width >= len)
+		if (cnt + width >= len)
 			break;
 
-		error = copy_to_user(buf + cnt, tbuf, width);
-		if (error)
-			break;
+		if (copy_to_user(buf + cnt, tbuf, width))
+			return -EFAULT;
 		cnt += width;
 	}
 
author
#6 lore raw

PATCH 7/37 RTNETLINK: Fix bogus ASSERT_RTNL warning

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Patrick McHardy <[email protected]>

[ Upstream commit: c9c1014b2bd014c7ec037bbb6f58818162fdb265 ]

ASSERT_RTNL uses mutex_trylock to test whether the rtnl_mutex is held. This bogus warnings when running in atomic context, which f.e. happens when adding secondary unicast addresses through macvlan or vlan or when synchronizing multicast addresses from wireless devices.

Mid-term we might want to consider moving all address updates to process context since the locking seems overly complicated, for now just fix the bogus warning by changing ASSERT_RTNL to use mutex_is_locked().

---
 include/linux/rtnetlink.h |    4 ++--
 net/core/rtnetlink.c      |    6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)
include/linux/rtnetlink.h +2 -2
@@ -740,13 +740,13 @@ extern void rtmsg_ifinfo(int type, struc
 extern void rtnl_lock(void);
 extern void rtnl_unlock(void);
 extern int rtnl_trylock(void);
+extern int rtnl_is_locked(void);
 
 extern void rtnetlink_init(void);
 extern void __rtnl_unlock(void);
 
 #define ASSERT_RTNL() do { \
-	if (unlikely(rtnl_trylock())) { \
-		rtnl_unlock(); \
+	if (unlikely(!rtnl_is_locked())) { \
 		printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
 		       __FILE__,  __LINE__); \
 		dump_stack(); \
net/core/rtnetlink.c +6 -0
@@ -82,6 +82,11 @@ int rtnl_trylock(void)
 	return mutex_trylock(&rtnl_mutex);
 }
 
+int rtnl_is_locked(void)
+{
+	return mutex_is_locked(&rtnl_mutex);
+}
+
 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
 
 static inline int rtm_msgindex(int msgtype)
@@ -1389,6 +1394,7 @@ EXPORT_SYMBOL(rtnetlink_put_metrics);
 EXPORT_SYMBOL(rtnl_lock);
 EXPORT_SYMBOL(rtnl_trylock);
 EXPORT_SYMBOL(rtnl_unlock);
+EXPORT_SYMBOL(rtnl_is_locked);
 EXPORT_SYMBOL(rtnl_unicast);
 EXPORT_SYMBOL(rtnl_notify);
 EXPORT_SYMBOL(rtnl_set_sk_err);
author
#7 lore raw

PATCH 8/37 rose: Socket lock was not released before returning to user space

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Bernard Pidoux <[email protected]>

[ Upstream commit: 43837b1e6c5aef803d57009a68db18df13e64892 ]

================================================
[ BUG: lock held when returning to user space! ]
------------------------------------------------
xfbbd/3683 is leaving the kernel with locks still held!
1 lock held by xfbbd/3683:
#0: (sk_lock-AF_ROSE){--..}, at: [<c8cd1eb3>] rose_connect+0x73/0x420 [rose]

INFO: task xfbbd:3683 blocked for more than 120 seconds.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
xfbbd         D 00000246     0  3683   3669
        c6965ee0 00000092 c02c5c40 00000246 c0f6b5f0 c0f6b5c0 c0f6b5f0 c0f6b5c0
        c0f6b614 c6965f18 c024b74b ffffffff c06ba070 00000000 00000000 00000001
        c6ab07c0 c012d450 c0f6b634 c0f6b634 c7b5bf10 c0d6004c c7b5bf10 c6965f40
Call Trace:
  [<c024b74b>] lock_sock_nested+0x6b/0xd0
  [<c012d450>] ? autoremove_wake_function+0x0/0x40
  [<c02488f1>] sock_fasync+0x41/0x150
  [<c0249e69>] sock_close+0x19/0x40
  [<c0175d54>] __fput+0xb4/0x170
  [<c0176018>] fput+0x18/0x20
  [<c017300e>] filp_close+0x3e/0x70
  [<c01744e9>] sys_close+0x69/0xb0
  [<c0103bda>] sysenter_past_esp+0x5f/0xa5
  =======================

INFO: lockdep is turned off.

---
 net/rose/af_rose.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/rose/af_rose.c +4 -2
@@ -760,8 +760,10 @@ static int rose_connect(struct socket *s
 
 	rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
 					 &diagnostic);
-	if (!rose->neighbour)
-		return -ENETUNREACH;
+	if (!rose->neighbour) {
+		err = -ENETUNREACH;
+		goto out_release;
+	}
 
 	rose->lci = rose_new_lci(rose->neighbour);
 	if (!rose->lci) {
author
#8 lore raw

PATCH 9/37 net: Fix wrong interpretation of some copy_to_user() results.

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Pavel Emelyanov <[email protected]>

[ Upstream commit: 653252c2302cdf2dfbca66a7e177f7db783f9efa ]

I found some places, that erroneously return the value obtained from the copy_to_user() call: if some amount of bytes were not able to get to the user (this is what this one returns) the proper behavior is to return the -EFAULT error, not that number itself.

---
 net/can/raw.c     |    3 ++-
 net/dccp/probe.c  |    2 +-
 net/tipc/socket.c |    4 ++--
 3 files changed, 5 insertions(+), 4 deletions(-)
net/can/raw.c +2 -1
@@ -573,7 +573,8 @@ static int raw_getsockopt(struct socket 
 			int fsize = ro->count * sizeof(struct can_filter);
 			if (len > fsize)
 				len = fsize;
-			err = copy_to_user(optval, ro->filter, len);
+			if (copy_to_user(optval, ro->filter, len))
+				err = -EFAULT;
 		} else
 			len = 0;
 		release_sock(sk);
net/dccp/probe.c +1 -1
@@ -145,7 +145,7 @@ static ssize_t dccpprobe_read(struct fil
 		goto out_free;
 
 	cnt = kfifo_get(dccpw.fifo, tbuf, len);
-	error = copy_to_user(buf, tbuf, cnt);
+	error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
 	vfree(tbuf);
net/tipc/socket.c +2 -2
@@ -1600,8 +1600,8 @@ static int getsockopt(struct socket *soc
 	else if (len < sizeof(value)) {
 		res = -EINVAL;
 	}
-	else if ((res = copy_to_user(ov, &value, sizeof(value)))) {
-		/* couldn't return value */
+	else if (copy_to_user(ov, &value, sizeof(value))) {
+		res = -EFAULT;
 	}
 	else {
 		res = put_user(sizeof(value), ol);
author
#9 lore raw

PATCH 10/37 IPSEC: Fix catch-22 with algorithm IDs above 31

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Herbert Xu <[email protected]>

[ Upstream commit: c5d18e984a313adf5a1a4ae69e0b1d93cf410229 ]

As it stands it's impossible to use any authentication algorithms with an ID above 31 portably. It just happens to work on x86 but fails miserably on ppc64.

The reason is that we're using a bit mask to check the algorithm ID but the mask is only 32 bits wide.

After looking at how this is used in the field, I have concluded that in the long term we should phase out state matching by IDs because this is made superfluous by the reqid feature. For current applications, the best solution IMHO is to allow all algorithms when the bit masks are all ~0.

The following patch does exactly that.

This bug was identified by IBM when testing on the ppc64 platform using the NULL authentication algorithm which has an ID of 251.

---
 include/net/xfrm.h     |    3 +++
 net/key/af_key.c       |    2 +-
 net/xfrm/xfrm_policy.c |    2 +-
 net/xfrm/xfrm_user.c   |    2 ++
 4 files changed, 7 insertions(+), 2 deletions(-)
include/net/xfrm.h +3 -0
@@ -435,6 +435,9 @@ struct xfrm_tmpl
 /* May skip this transfomration if no SA is found */
 	__u8			optional;
 
+/* Skip aalgos/ealgos/calgos checks. */
+	__u8			allalgs;
+
 /* Bit mask of algos allowed for acquisition */
 	__u32			aalgos;
 	__u32			ealgos;
net/key/af_key.c +1 -1
@@ -1856,7 +1856,7 @@ parse_ipsecrequest(struct xfrm_policy *x
 		t->encap_family = xp->family;
 
 	/* No way to set this via kame pfkey */
-	t->aalgos = t->ealgos = t->calgos = ~0;
+	t->allalgs = 1;
 	xp->xfrm_nr++;
 	return 0;
 }
net/xfrm/xfrm_policy.c +1 -1
@@ -1772,7 +1772,7 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, st
 		(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
 		(x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
 		x->props.mode == tmpl->mode &&
-		((tmpl->aalgos & (1<<x->props.aalgo)) ||
+		(tmpl->allalgs || (tmpl->aalgos & (1<<x->props.aalgo)) ||
 		 !(xfrm_id_proto_match(tmpl->id.proto, IPSEC_PROTO_ANY))) &&
 		!(x->props.mode != XFRM_MODE_TRANSPORT &&
 		  xfrm_state_addr_cmp(tmpl, x, family));
net/xfrm/xfrm_user.c +2 -0
@@ -975,6 +975,8 @@ static void copy_templates(struct xfrm_p
 		t->aalgos = ut->aalgos;
 		t->ealgos = ut->ealgos;
 		t->calgos = ut->calgos;
+		/* If all masks are ~0, then we allow all algorithms. */
+		t->allalgs = !~(t->aalgos & t->ealgos & t->calgos);
 		t->encap_family = ut->family;
 	}
 }
author
#10 lore raw

PATCH 11/37 USB: OHCI: fix bug in controller resume

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Alan Stern <[email protected]>

commit: 0d22f65515307c878ddd20b1305cce925ca9516c

This patch (as1063) fixes a bug in the way ohci-hcd resumes its controllers. It leaves the Master Interrupt Enable bit turned off.

If the root hub is resumed immediately this won't matter. But if the root hub is suspended (say because no devices are plugged in), it won't ever wake up by itself.

---
 drivers/usb/host/ohci-pci.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/usb/host/ohci-pci.c +3 -1
@@ -312,11 +312,13 @@ static int ohci_pci_suspend (struct usb_
 
 static int ohci_pci_resume (struct usb_hcd *hcd)
 {
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+
 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
 	/* FIXME: we should try to detect loss of VBUS power here */
 	prepare_for_handover(hcd);
-
+	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
 	return 0;
 }
 
author
#11 lore raw

PATCH 12/37 dm snapshot: fix chunksize sector conversion

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Mikulas Patocka <[email protected]>

commit: 924362629bf5645aee5f49f8a0d0d5b193e65997

If a snapshot has a smaller chunksize than the page size the conversion to pages currently returns 0 instead of 1, causing:
kernel BUG in mempool_resize.

---
 drivers/md/dm-exception-store.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/dm-exception-store.c +1 -1
@@ -131,7 +131,7 @@ struct pstore {
 
 static unsigned sectors_to_pages(unsigned sectors)
 {
-	return sectors / (PAGE_SIZE >> 9);
+	return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9);
 }
 
 static int alloc_area(struct pstore *ps)
author
#12 lore raw

PATCH 13/37 cgroup: fix a race condition in manipulating tsk->cg_list

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Li Zefan <[email protected]>

commit: 0e04388f0189fa1f6812a8e1cb6172136eada87e

When I ran a test program to fork mass processes and at the same time 'cat /cgroup/tasks', I got the following oops:

  ------------[ cut here ]------------
  kernel BUG at lib/list_debug.c:72!
  invalid opcode: 0000 [#1] SMP
  Pid: 4178, comm: a.out Not tainted (2.6.25-rc9 #72)
  ...
  Call Trace:
   [<c044a5f9>] ? cgroup_exit+0x55/0x94
   [<c0427acf>] ? do_exit+0x217/0x5ba
   [<c0427ed7>] ? do_group_exit+0.65/0x7c
   [<c0427efd>] ? sys_exit_group+0xf/0x11
   [<c0404842>] ? syscall_call+0x7/0xb
   [<c05e0000>] ? init_cyrix+0x2fa/0x479
  ...
  EIP: [<c04df671>] list_del+0x35/0x53 SS:ESP 0068:ebc7df4
  ---[ end trace caffb7332252612b ]---
  Fixing recursive fault but reboot is needed!

After digging into the code and debugging, I finlly found out a race situation:

				do_exit()
				  ->cgroup_exit()
				    ->if (!list_empty(&tsk->cg_list))
				        list_del(&tsk->cg_list);
  cgroup_iter_start()
    ->cgroup_enable_task_cg_list()
      ->list_add(&tsk->cg_list, ..);

In this case the list won't be deleted though the process has exited.

We got two bug reports in the past, which seem to be the same bug as this one:

	http://lkml.org/lkml/2008/3/5/332
	http://lkml.org/lkml/2007/10/17/224

Actually sometimes I got oops on list_del, sometimes oops on list_add. And I can change my test program a bit to trigger other oops.

The patch has been tested both on x86_32 and x86_64.

---
 kernel/cgroup.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/cgroup.c +6 -1
@@ -1722,7 +1722,12 @@ void cgroup_enable_task_cg_lists(void)
 	use_task_css_set_links = 1;
 	do_each_thread(g, p) {
 		task_lock(p);
-		if (list_empty(&p->cg_list))
+		/*
+		 * We should check if the process is exiting, otherwise
+		 * it will race with cgroup_exit() in that the list
+		 * entry won't be deleted though the process has exited.
+		 */
+		if (!(p->flags & PF_EXITING) && list_empty(&p->cg_list))
 			list_add(&p->cg_list, &p->cgroups->tasks);
 		task_unlock(p);
 	} while_each_thread(g, p);
author
#13 lore raw

PATCH 14/37 RDMA/nes: Free IRQ before killing tasklet

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Roland Dreier <[email protected]>

commit: 4cd1e5eb3cbe6e0cc934959770b4c60eac6ecf66

Move the free_irq() call in nes_remove() to before the tasklet_kill(); otherwise there is a window after tasklet_kill() where a new interrupt can be handled and reschedule the tasklet, leading to a use-after-free crash.

---
 drivers/infiniband/hw/nes/nes.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/hw/nes/nes.c +2 -2
@@ -751,13 +751,13 @@ static void __devexit nes_remove(struct 
 
 	list_del(&nesdev->list);
 	nes_destroy_cqp(nesdev);
+
+	free_irq(pcidev->irq, nesdev);
 	tasklet_kill(&nesdev->dpc_tasklet);
 
 	/* Deallocate the Adapter Structure */
 	nes_destroy_adapter(nesdev->nesadapter);
 
-	free_irq(pcidev->irq, nesdev);
-
 	if (nesdev->msi_enabled) {
 		pci_disable_msi(pcidev);
 	}
author
#14 lore raw

PATCH 15/37 V4L: Fix VIDIOCGAP corruption in ivtv

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Alan Cox <[email protected]>

(cherry picked from commit d2b213f7b76f187c4391079c7581d3a08b940133)

Frank Bennett reported that ivtv was causing skype to crash. With help from one of their developers he showed it was a kernel problem. VIDIOCGCAP copies a name into a fixed length buffer - ivtv uses names that are too long and does not truncate them so corrupts a few bytes of the app data area.

Possibly the names also want trimming but for now this should fix the corruption case.

---
 drivers/media/video/ivtv/ivtv-ioctl.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/media/video/ivtv/ivtv-ioctl.c +2 -1
@@ -741,7 +741,8 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, s
 
 		memset(vcap, 0, sizeof(*vcap));
 		strcpy(vcap->driver, IVTV_DRIVER_NAME);     /* driver name */
-		strcpy(vcap->card, itv->card_name); 	    /* card type */
+		strncpy(vcap->card, itv->card_name,
+				sizeof(vcap->card)-1); 	    /* card type */
 		strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
 		vcap->version = IVTV_DRIVER_VERSION; 	    /* version */
 		vcap->capabilities = itv->v4l2_cap; 	    /* capabilities */
author
#15 lore raw

PATCH 16/37 V4L: tea5761: bugzilla #10462: tea5761 autodetection code were broken

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Mauro Carvalho Chehab <[email protected]>

(cherry picked from commit 867e835f4db4eba6d49072382cc05fc210c4ed1c)

Fix bugzilla #10462: "tea5761 autodetection code were broken"

---
 drivers/media/video/tea5761.c    |   15 ++++++++++-----
 drivers/media/video/tuner-core.c |    6 +++---
 2 files changed, 13 insertions(+), 8 deletions(-)
drivers/media/video/tea5761.c +10 -5
@@ -249,14 +249,19 @@ int tea5761_autodetection(struct i2c_ada
 
 	if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
 		printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc);
-		return EINVAL;
+		return -EINVAL;
 	}
 
-	if (!((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061))) {
-		printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x. It is not a TEA5761\n",buffer[13],buffer[14],buffer[15]);
-		return EINVAL;
+	if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) {
+		printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x."
+				    " It is not a TEA5761\n",
+				    buffer[13], buffer[14], buffer[15]);
+		return -EINVAL;
 	}
-	printk(KERN_WARNING "TEA5761 detected.\n");
+	printk(KERN_WARNING "tea5761: TEA%02x%02x detected. "
+			    "Manufacturer ID= 0x%02x\n",
+			    buffer[14], buffer[15], buffer[13]);
+
 	return 0;
 }
 
drivers/media/video/tuner-core.c +3 -3
@@ -1112,8 +1112,8 @@ static int tuner_probe(struct i2c_client
 	if (!no_autodetect) {
 		switch (client->addr) {
 		case 0x10:
-			if (tea5761_autodetection(t->i2c->adapter, t->i2c->addr)
-					!= EINVAL) {
+			if (tea5761_autodetection(t->i2c->adapter,
+						  t->i2c->addr) >= 0) {
 				t->type = TUNER_TEA5761;
 				t->mode_mask = T_RADIO;
 				t->mode = T_STANDBY;
@@ -1125,7 +1125,7 @@ static int tuner_probe(struct i2c_client
 
 				goto register_client;
 			}
-			break;
+			return -ENODEV;
 		case 0x42:
 		case 0x43:
 		case 0x4a:
author
#16 lore raw

PATCH 17/37 V4L: cx88: enable radio GPIO correctly

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Steven Toth <[email protected]>

(cherry picked from commit 6b92b3bd7ac91b7e255541f4be9bfd55b12dae41)

This patch fixes an issue on the HVR1300, where GPIO is blown away due to the radio input being undefined, breaking the functionality of the DVB demodulator and MPEG2 encoder used on the cx8802 mpeg TS port.

This is a minimal patch for 2.6.26 and the -stable series. This must be fixed a better way for 2.6.27.

---
 drivers/media/video/cx88/cx88-cards.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/media/video/cx88/cx88-cards.c +4 -0
@@ -1354,6 +1354,10 @@ static const struct cx88_board cx88_boar
 		}},
 		/* fixme: Add radio support */
 		.mpeg           = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
+		.radio = {
+			.type   = CX88_RADIO,
+			.gpio0	= 0xe780,
+		},
 	},
 	[CX88_BOARD_ADSTECH_PTV_390] = {
 		.name           = "ADS Tech Instant Video PCI",
author
#17 lore raw

PATCH 18/37 S2io: Fix memory leak during free_tx_buffers

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Sreenivasa Honnur <[email protected]>

commit b35b3b49fc6750806964048b31799c8782980ef9 upstream

- Fix the memory leak during free_tx_buffers.

---
 drivers/net/s2io.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/s2io.c +1 -1
@@ -2339,7 +2339,7 @@ static void free_tx_buffers(struct s2io_
 	for (i = 0; i < config->tx_fifo_num; i++) {
 		unsigned long flags;
 		spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags);
-		for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
+		for (j = 0; j < config->tx_cfg[i].fifo_len; j++) {
 			txdp = (struct TxD *) \
 			mac_control->fifos[i].list_info[j].list_virt_addr;
 			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
author
#18 lore raw

PATCH 19/37 S2io: Version update for memory leak fix during free_tx_buffers

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Sreenivasa Honnur <[email protected]>

commit 10371b5e6ba22173425877ea6a7040619b005fa1 upstream

- Updated version number.

---
 drivers/net/s2io.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/s2io.c +1 -1
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.20"
+#define DRV_VERSION "2.0.26.22"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
author
#19 lore raw

PATCH 20/37 SELinux: no BUG_ON(!ss_initialized) in selinux_clone_mnt_opts

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Eric Paris <[email protected]>

commit 0f5e64200f20fc8f5b759c4010082f577ab0af3f upstream

The Fedora installer actually makes multiple NFS mounts before it loads selinux policy. The code in selinux_clone_mnt_opts() assumed that the init process would always be loading policy before NFS was up and running. It might be possible to hit this in a diskless environment as well, I'm not sure. There is no need to BUG_ON() in this situation since we can safely continue given the circumstances.

---
 security/selinux/hooks.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)
security/selinux/hooks.c +12 -3
@@ -756,9 +756,18 @@ static void selinux_sb_clone_mnt_opts(co
 	int set_context =	(oldsbsec->flags & CONTEXT_MNT);
 	int set_rootcontext =	(oldsbsec->flags & ROOTCONTEXT_MNT);
 
-	/* we can't error, we can't save the info, this shouldn't get called
-	 * this early in the boot process. */
-	BUG_ON(!ss_initialized);
+	/*
+	 * if the parent was able to be mounted it clearly had no special lsm
+	 * mount options.  thus we can safely put this sb on the list and deal
+	 * with it later
+	 */
+	if (!ss_initialized) {
+		spin_lock(&sb_security_lock);
+		if (list_empty(&newsbsec->list))
+			list_add(&newsbsec->list, &superblock_security_head);
+		spin_unlock(&sb_security_lock);
+		return;
+	}
 
 	/* how can we clone if the old one wasn't set up?? */
 	BUG_ON(!oldsbsec->initialized);
author
#20 lore raw

PATCH 21/37 x86, pci: fix off-by-one errors in some pirq warnings

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Björn Steinbrink <[email protected]>

commit 223ac2f42d49dd0324ca02ea15897ead1a2f5133 upstream.

fix bogus pirq warnings reported in:

http://bugzilla.kernel.org/show_bug.cgi?id=10366

safe to be backported to v2.6.25 and earlier.

---
 arch/x86/pci/irq.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
arch/x86/pci/irq.c +6 -6
@@ -200,7 +200,7 @@ static int pirq_ali_get(struct pci_dev *
 {
 	static const unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 };
 
-	WARN_ON_ONCE(pirq >= 16);
+	WARN_ON_ONCE(pirq > 16);
 	return irqmap[read_config_nybble(router, 0x48, pirq-1)];
 }
 
@@ -209,7 +209,7 @@ static int pirq_ali_set(struct pci_dev *
 	static const unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 };
 	unsigned int val = irqmap[irq];
 
-	WARN_ON_ONCE(pirq >= 16);
+	WARN_ON_ONCE(pirq > 16);
 	if (val) {
 		write_config_nybble(router, 0x48, pirq-1, val);
 		return 1;
@@ -260,7 +260,7 @@ static int pirq_via586_get(struct pci_de
 {
 	static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
 
-	WARN_ON_ONCE(pirq >= 5);
+	WARN_ON_ONCE(pirq > 5);
 	return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
 }
 
@@ -268,7 +268,7 @@ static int pirq_via586_set(struct pci_de
 {
 	static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
 
-	WARN_ON_ONCE(pirq >= 5);
+	WARN_ON_ONCE(pirq > 5);
 	write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
 	return 1;
 }
@@ -282,7 +282,7 @@ static int pirq_ite_get(struct pci_dev *
 {
 	static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
 
-	WARN_ON_ONCE(pirq >= 4);
+	WARN_ON_ONCE(pirq > 4);
 	return read_config_nybble(router,0x43, pirqmap[pirq-1]);
 }
 
@@ -290,7 +290,7 @@ static int pirq_ite_set(struct pci_dev *
 {
 	static const unsigned char pirqmap[4] = { 1, 0, 2, 3 };
 
-	WARN_ON_ONCE(pirq >= 4);
+	WARN_ON_ONCE(pirq > 4);
 	write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
 	return 1;
 }
author
#21 lore raw

PATCH 22/37 ssb: Fix all-ones boardflags

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Larry Finger <[email protected]>

commit 4503183aa32e6886400d82282292934fa64a81b0 upstream

In the SSB SPROM a field set to all ones means the value is not defined in the SPROM.
In case of the boardflags, we need to set them to zero to avoid confusing drivers. Drivers will only check the flags by ANDing.

---
 drivers/ssb/pci.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/ssb/pci.c +5 -0
@@ -482,6 +482,11 @@ static int sprom_extract(struct ssb_bus 
 			goto unsupported;
 	}
 
+	if (out->boardflags_lo == 0xFFFF)
+		out->boardflags_lo = 0;  /* per specs */
+	if (out->boardflags_hi == 0xFFFF)
+		out->boardflags_hi = 0;  /* per specs */
+
 	return 0;
 unsupported:
 	ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d "
author
#22 lore raw

PATCH 23/37 b43: Workaround invalid bluetooth settings

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Michael Buesch <[email protected]>

commit 1855ba7812dbd294fcfc083dc7d3b14d3b1f38db upstream.

This adds a workaround for invalid bluetooth SPROM settings on ASUS PCI cards.
This will stop the microcode from poking with the BT GPIO line. This fixes data transmission on this device, as the BT GPIO line is used for something TX related on this device
(probably the power amplifier or the radio).
This also adds a modparam knob to help debugging this in the future, as more devices with this bug may show up.

---
 drivers/net/wireless/b43/main.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/net/wireless/b43/main.c +21 -2
@@ -78,6 +78,11 @@ static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
+static int modparam_btcoex = 1;
+module_param_named(btcoex, modparam_btcoex, int, 0444);
+MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)");
+
+
 static const struct ssb_device_id b43_ssb_tbl[] = {
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
 	SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
@@ -3339,6 +3344,8 @@ static void b43_bluetooth_coext_enable(s
 	struct ssb_sprom *sprom = &dev->dev->bus->sprom;
 	u32 hf;
 
+	if (!modparam_btcoex)
+		return;
 	if (!(sprom->boardflags_lo & B43_BFL_BTCOEXIST))
 		return;
 	if (dev->phy.type != B43_PHYTYPE_B && !dev->phy.gmode)
@@ -3350,11 +3357,13 @@ static void b43_bluetooth_coext_enable(s
 	else
 		hf |= B43_HF_BTCOEX;
 	b43_hf_write(dev, hf);
-	//TODO
 }
 
 static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
-{				//TODO
+{
+	if (!modparam_btcoex)
+		return;
+	//TODO
 }
 
 static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
@@ -4002,6 +4011,8 @@ static int b43_one_core_attach(struct ss
 
 static void b43_sprom_fixup(struct ssb_bus *bus)
 {
+	struct pci_dev *pdev;
+
 	/* boardflags workarounds */
 	if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL &&
 	    bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74)
@@ -4009,6 +4020,14 @@ static void b43_sprom_fixup(struct ssb_b
 	if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
 	    bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40)
 		bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
+	if (bus->bustype == SSB_BUSTYPE_PCI) {
+		pdev = bus->host_pci;
+		if (pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
+		    pdev->device == 0x4318 &&
+		    pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK &&
+		    pdev->subsystem_device == 0x100F)
+			bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
+	}
 }
 
 static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl)
author
#23 lore raw

PATCH 24/37 b43: Add more btcoexist workarounds

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Michael Buesch <[email protected]>

commit 9fc38458355525f801cd2ab403ac89850489a05e upstream

This adds more workarounds for devices with broken BT bits.

---
 drivers/net/wireless/b43/main.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/b43/main.c +9 -4
@@ -4009,6 +4009,12 @@ static int b43_one_core_attach(struct ss
 	return err;
 }
 
+#define IS_PDEV(pdev, _vendor, _device, _subvendor, _subdevice)		( \
+	(pdev->vendor == PCI_VENDOR_ID_##_vendor) &&			\
+	(pdev->device == _device) &&					\
+	(pdev->subsystem_vendor == PCI_VENDOR_ID_##_subvendor) &&	\
+	(pdev->subsystem_device == _subdevice)				)
+
 static void b43_sprom_fixup(struct ssb_bus *bus)
 {
 	struct pci_dev *pdev;
@@ -4022,10 +4028,9 @@ static void b43_sprom_fixup(struct ssb_b
 		bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
 	if (bus->bustype == SSB_BUSTYPE_PCI) {
 		pdev = bus->host_pci;
-		if (pdev->vendor == PCI_VENDOR_ID_BROADCOM &&
-		    pdev->device == 0x4318 &&
-		    pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK &&
-		    pdev->subsystem_device == 0x100F)
+		if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
+		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
+		    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
 			bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
 	}
 }
author
#24 lore raw

PATCH 25/37 b43: Workaround DMA quirks

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Michael Buesch <[email protected]>

commit 1033b3ea11820ea1fb1b877207bd6724e9aaedc3 upstream

Some mainboards/CPUs don't allow DMA masks bigger than a certain limit. Some VIA crap^h^h^h^hdevices have an upper limit of 0xFFFFFFFF. So in this case a 64-bit b43 device would always fail to acquire the mask. Implement a workaround to fallback to lower DMA mask, as we can always also support a lower mask.

---
 drivers/net/wireless/b43/dma.c |   73 +++++++++++++++++++++++++++++------------
 1 file changed, 52 insertions(+), 21 deletions(-)
drivers/net/wireless/b43/dma.c +52 -21
@@ -822,6 +822,18 @@ static u64 supported_dma_mask(struct b43
 	return DMA_30BIT_MASK;
 }
 
+static enum b43_dmatype dma_mask_to_engine_type(u64 dmamask)
+{
+	if (dmamask == DMA_30BIT_MASK)
+		return B43_DMA_30BIT;
+	if (dmamask == DMA_32BIT_MASK)
+		return B43_DMA_32BIT;
+	if (dmamask == DMA_64BIT_MASK)
+		return B43_DMA_64BIT;
+	B43_WARN_ON(1);
+	return B43_DMA_30BIT;
+}
+
 /* Main initialization function. */
 static
 struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
@@ -982,6 +994,42 @@ void b43_dma_free(struct b43_wldev *dev)
 	dma->tx_ring0 = NULL;
 }
 
+static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
+{
+	u64 orig_mask = mask;
+	bool fallback = 0;
+	int err;
+
+	/* Try to set the DMA mask. If it fails, try falling back to a
+	 * lower mask, as we can always also support a lower one. */
+	while (1) {
+		err = ssb_dma_set_mask(dev->dev, mask);
+		if (!err)
+			break;
+		if (mask == DMA_64BIT_MASK) {
+			mask = DMA_32BIT_MASK;
+			fallback = 1;
+			continue;
+		}
+		if (mask == DMA_32BIT_MASK) {
+			mask = DMA_30BIT_MASK;
+			fallback = 1;
+			continue;
+		}
+		b43err(dev->wl, "The machine/kernel does not support "
+		       "the required %u-bit DMA mask\n",
+		       (unsigned int)dma_mask_to_engine_type(orig_mask));
+		return -EOPNOTSUPP;
+	}
+	if (fallback) {
+		b43info(dev->wl, "DMA mask fallback from %u-bit to %u-bit\n",
+			(unsigned int)dma_mask_to_engine_type(orig_mask),
+			(unsigned int)dma_mask_to_engine_type(mask));
+	}
+
+	return 0;
+}
+
 int b43_dma_init(struct b43_wldev *dev)
 {
 	struct b43_dma *dma = &dev->dma;
@@ -991,27 +1039,10 @@ int b43_dma_init(struct b43_wldev *dev)
 	enum b43_dmatype type;
 
 	dmamask = supported_dma_mask(dev);
-	switch (dmamask) {
-	default:
-		B43_WARN_ON(1);
-	case DMA_30BIT_MASK:
-		type = B43_DMA_30BIT;
-		break;
-	case DMA_32BIT_MASK:
-		type = B43_DMA_32BIT;
-		break;
-	case DMA_64BIT_MASK:
-		type = B43_DMA_64BIT;
-		break;
-	}
-	err = ssb_dma_set_mask(dev->dev, dmamask);
-	if (err) {
-		b43err(dev->wl, "The machine/kernel does not support "
-		       "the required DMA mask (0x%08X%08X)\n",
-		       (unsigned int)((dmamask & 0xFFFFFFFF00000000ULL) >> 32),
-		       (unsigned int)(dmamask & 0x00000000FFFFFFFFULL));
-		return -EOPNOTSUPP;
-	}
+	type = dma_mask_to_engine_type(dmamask);
+	err = b43_dma_set_mask(dev, dmamask);
+	if (err)
+		return err;
 
 	err = -ENOMEM;
 	/* setup TX DMA channels. */
author
#25 lore raw

PATCH 26/37 tehuti: check register size (CVE-2008-1675)

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Francois Romieu <[email protected]>

commit 6131a2601f42cd7fdbac0e960713396fe68af59f upstream

---
 drivers/net/tehuti.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/net/tehuti.c +14 -0
@@ -625,6 +625,12 @@ static void __init bdx_firmware_endianes
 		s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
 }
 
+static int bdx_range_check(struct bdx_priv *priv, u32 offset)
+{
+	return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ?
+		-EINVAL : 0;
+}
+
 static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
 {
 	struct bdx_priv *priv = ndev->priv;
@@ -646,6 +652,9 @@ static int bdx_ioctl_priv(struct net_dev
 	switch (data[0]) {
 
 	case BDX_OP_READ:
+		error = bdx_range_check(priv, data[1]);
+		if (error < 0)
+			return error;
 		data[2] = READ_REG(priv, data[1]);
 		DBG("read_reg(0x%x)=0x%x (dec %d)\n", data[1], data[2],
 		    data[2]);
@@ -655,6 +664,11 @@ static int bdx_ioctl_priv(struct net_dev
 		break;
 
 	case BDX_OP_WRITE:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		error = bdx_range_check(priv, data[1]);
+		if (error < 0)
+			return error;
 		WRITE_REG(priv, data[1], data[2]);
 		DBG("write_reg(0x%x, 0x%x)\n", data[1], data[2]);
 		break;
author
#26 lore raw

PATCH 27/37 tehuti: move ioctl perm check closer to function start (CVE-2008-1675)

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Jeff Garzik <[email protected]>

Commit f946dffed6334f08da065a89ed65026ebf8b33b4 upstream

Noticed by davem.

---
 drivers/net/tehuti.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/tehuti.c +3 -2
@@ -649,6 +649,9 @@ static int bdx_ioctl_priv(struct net_dev
 		DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
 	}
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	switch (data[0]) {
 
 	case BDX_OP_READ:
@@ -664,8 +667,6 @@ static int bdx_ioctl_priv(struct net_dev
 		break;
 
 	case BDX_OP_WRITE:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		error = bdx_range_check(priv, data[1]);
 		if (error < 0)
 			return error;
#27 lore raw

Re: [27/37] tehuti: move ioctl perm check closer to function start (CVE-2008-1675)

Quoted 20 lines · On Tue, 29 Apr 2008 10:19:01 -0700 Greg KH <[email protected]> wrote:

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Jeff Garzik <[email protected]>

Commit f946dffed6334f08da065a89ed65026ebf8b33b4 upstream

Noticed by davem.

---
 drivers/net/tehuti.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

drivers/net/tehuti.c static int bdx_ioctl_priv(struct net_dev · line 654

Quoted 6 lines
drivers/net/tehuti.c +3 -0
@@ -649,6 +649,9 @@ static int bdx_ioctl_priv(struct net_dev
 		DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
 	}
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+

Should be CAP_SYS_RAWIO

Alan

author
#28 lore raw

Re: [27/37] tehuti: move ioctl perm check closer to function start (CVE-2008-1675)

Quoted 26 lines · Alan Cox
Quoted 23 lines · On Tue, 29 Apr 2008 10:19:01 -0700 Greg KH <[email protected]> wrote:

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Jeff Garzik <[email protected]>

Commit f946dffed6334f08da065a89ed65026ebf8b33b4 upstream

Noticed by davem.

---
 drivers/net/tehuti.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/tehuti.c +0 -0
@@ -649,6 +649,9 @@ static int bdx_ioctl_priv(struct net_dev
 		DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
 	}
 
Quoted 5 lines

drivers/net/tehuti.c static int bdx_ioctl_priv(struct net_dev · line 654

Quoted 3 lines
drivers/net/tehuti.c +3 -0
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+

Should be CAP_SYS_RAWIO

Hm, that's the way it is in Linus's tree, we should change it there first.

thanks,

greg k-h

#29 lore raw

Re: [27/37] tehuti: move ioctl perm check closer to function start (CVE-2008-1675)

Quoted 3 lines · Greg KH

Hm, that's the way it is in Linus's tree, we should change it there first.

Done. It will be commit 6203554207728f43cfb9fd48585cd6500da73d42 when I push out (but please point to the original commit that actually adds the
check: 6203554 just changes from CAP_NET_ADMIN to CAP_SYS_RAWIO and is not as important as adding the check in the first place.

(I don't know of anybody who actually really uses capabilities with individual bits, so I seriously doubt it matters)

Linus

#30 lore raw

Re: [stable] [27/37] tehuti: move ioctl perm check closer to function start (CVE-2008-1675)

Quoted 11 lines · Linus Torvalds
Quoted 3 lines · Greg KH

Hm, that's the way it is in Linus's tree, we should change it there first.

Done. It will be commit 6203554207728f43cfb9fd48585cd6500da73d42 when I push out (but please point to the original commit that actually adds the
check: 6203554 just changes from CAP_NET_ADMIN to CAP_SYS_RAWIO and is not as important as adding the check in the first place.

Thanks, I'll add this to the queue for 2.6.25-stable as well.

greg k-h

author
#31 lore raw

PATCH 28/37 aio: io_getevents() should return if io_destroy() is invoked

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Jeff Moyer <[email protected]>

commit e92adcba261fd391591bb63c1703185a04a41554 upstream

This patch wakes up a thread waiting in io_getevents if another thread destroys the context. This was tested using a small program that spawns a thread to wait in io_getevents while the parent thread destroys the io context and then waits for the getevents thread to exit. Without this patch, the program hangs indefinitely. With the patch, the program exits as expected.

---
 fs/aio.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
fs/aio.c +11 -1
@@ -1166,7 +1166,10 @@ retry:
 				break;
 			if (min_nr <= i)
 				break;
-			ret = 0;
+			if (unlikely(ctx->dead)) {
+				ret = -EINVAL;
+				break;
+			}
 			if (to.timed_out)	/* Only check after read evt */
 				break;
 			/* Try to only show up in io wait if there are ops
@@ -1231,6 +1234,13 @@ static void io_destroy(struct kioctx *io
 
 	aio_cancel_all(ioctx);
 	wait_for_all_aios(ioctx);
+
+	/*
+	 * Wake up any waiters.  The setting of ctx->dead must be seen
+	 * by other CPUs at this point.  Right now, we rely on the
+	 * locking done by the above calls to ensure this consistency.
+	 */
+	wake_up(&ioctx->wait);
 	put_ioctx(ioctx);	/* once for the lookup */
 }
 
author
#32 lore raw

PATCH 29/37 rtc-pcf8583 build fix

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: David Brownell <[email protected]>

commit 77459b059b02c16b2c8cbc39b524941a576ad36e upstream

Fix bogus #include in rtc-pcf8583, so it compiles on platforms that don't support PC clone RTCs. (Original issue noted by Adrian Bunk.)

---
 drivers/rtc/rtc-pcf8583.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-pcf8583.c +1 -1
@@ -15,7 +15,7 @@
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/mc146818rtc.h>
+#include <linux/rtc.h>
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/bcd.h>
author
#33 lore raw

PATCH 30/37 dz: test after postfix decrement fails in dz_console_putchar()

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Roel Kluin <[email protected]>

commit 1ecf0d0cd28a4bfed3009f752061998e52d14db2 upstream

When loops reaches 0 the postfix decrement still subtracts, so the subsequent test fails.

---
 drivers/serial/dz.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/serial/dz.c +1 -1
@@ -819,7 +819,7 @@ static void dz_console_putchar(struct ua
 		dz_out(dport, DZ_TCR, mask);
 		iob();
 		udelay(2);
-	} while (loops--);
+	} while (--loops);
 
 	if (loops)				/* Cannot send otherwise. */
 		dz_out(dport, DZ_TDR, ch);
author
#34 lore raw

PATCH 31/37 mm: fix possible off-by-one in walk_pte_range()

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Johannes Weiner <[email protected]>

commit 556637cdabcd5918c7d4a1a2679b8f86fc81e891 upstream

After the loop in walk_pte_range() pte might point to the first address after the pmd it walks. The pte_unmap() is then applied to something bad.

Spotted by Roel Kluin and Andreas Schwab.

---
 mm/pagewalk.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
mm/pagewalk.c +6 -2
@@ -9,11 +9,15 @@ static int walk_pte_range(pmd_t *pmd, un
 	int err = 0;
 
 	pte = pte_offset_map(pmd, addr);
-	do {
+	for (;;) {
 		err = walk->pte_entry(pte, addr, addr + PAGE_SIZE, private);
 		if (err)
 		       break;
-	} while (pte++, addr += PAGE_SIZE, addr != end);
+		addr += PAGE_SIZE;
+		if (addr == end)
+			break;
+		pte++;
+	}
 
 	pte_unmap(pte);
 	return err;
author
#35 lore raw

PATCH 32/37 hrtimer: timeout too long when using HRTIMER_CB_SOFTIRQ

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Bodo Stroesser <[email protected]>

commit d7b41a24bfb5d7fa02f7b49be1293d468814e424 upstream

When using hrtimer with timer->cb_mode == HRTIMER_CB_SOFTIRQ in some cases the clockevent is not programmed.
This happens, if:
- a timer is rearmed while it's state is HRTIMER_STATE_CALLBACK
- hrtimer_reprogram() returns -ETIME, when it is called after CALLBACK is finished. This occurs if the new timer->expires is in the past when CALLBACK is done.
In this case, the timer needs to be removed from the tree and put onto the pending list again.

The patch is against 2.6.22.5, but AFAICS, it is relevant for 2.6.25 also (in run_hrtimer_pending()).

---
 kernel/hrtimer.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)
kernel/hrtimer.c +13 -2
@@ -1080,8 +1080,19 @@ static void run_hrtimer_pending(struct h
 			 * If the timer was rearmed on another CPU, reprogram
 			 * the event device.
 			 */
-			if (timer->base->first == &timer->node)
-				hrtimer_reprogram(timer, timer->base);
+			struct hrtimer_clock_base *base = timer->base;
+
+			if (base->first == &timer->node &&
+			    hrtimer_reprogram(timer, base)) {
+				/*
+				 * Timer is expired. Thus move it from tree to
+				 * pending list again.
+				 */
+				__remove_hrtimer(timer, base,
+						 HRTIMER_STATE_PENDING, 0);
+				list_add_tail(&timer->cb_entry,
+					      &base->cpu_base->cb_pending);
+			}
 		}
 	}
 	spin_unlock_irq(&cpu_base->lock);
author
#36 lore raw

PATCH 33/37 RDMA/nes: Fix adapter reset after PXE boot

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Chien Tung <[email protected]>

commit: bc5698f3ecc9587e1edb343a2878f8d228c49e0e upstream

After PXE boot, the iw_nes driver does a full reset to ensure the card is in a clean state. However, it doesn't wait for firmware to complete its work before issuing a port reset to enable the ports, which leads to problems bringing up the ports.

The solution is to wait for firmware to complete its work before proceeding with port reset.

This bug was flagged by Roland Dreier <[email protected]>.

---
 drivers/infiniband/hw/nes/nes_cm.c |    6 ++++--
 drivers/infiniband/hw/nes/nes_hw.c |   20 +++++++++-----------
 2 files changed, 13 insertions(+), 13 deletions(-)
drivers/infiniband/hw/nes/nes_cm.c +4 -2
@@ -1834,8 +1834,10 @@ int mini_cm_recv_pkt(struct nes_cm_core 
 	nfo.rem_addr = ntohl(iph->saddr);
 	nfo.rem_port = ntohs(tcph->source);
 
-	nes_debug(NES_DBG_CM, "Received packet: dest=0x%08X:0x%04X src=0x%08X:0x%04X\n",
-			iph->daddr, tcph->dest, iph->saddr, tcph->source);
+	nes_debug(NES_DBG_CM, "Received packet: dest=" NIPQUAD_FMT
+		  ":0x%04X src=" NIPQUAD_FMT ":0x%04X\n",
+		  NIPQUAD(iph->daddr), tcph->dest,
+		  NIPQUAD(iph->saddr), tcph->source);
 
 	/* note: this call is going to increment cm_node ref count */
 	cm_node = find_node(cm_core,
drivers/infiniband/hw/nes/nes_hw.c +9 -11
@@ -625,6 +625,15 @@ unsigned int nes_reset_adapter_ne020(str
 			nes_debug(NES_DBG_INIT, "Did not see full soft reset done.\n");
 			return 0;
 		}
+
+		i = 0;
+		while ((nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS) != 0x80) && i++ < 10000)
+			mdelay(1);
+		if (i >= 10000) {
+			printk(KERN_ERR PFX "Internal CPU not ready, status = %02X\n",
+			       nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS));
+			return 0;
+		}
 	}
 
 	/* port reset */
@@ -673,17 +682,6 @@ unsigned int nes_reset_adapter_ne020(str
 		}
 	}
 
-
-
-	i = 0;
-	while ((nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS) != 0x80) && i++ < 10000)
-		mdelay(1);
-	if (i >= 10000) {
-		printk(KERN_ERR PFX "Internal CPU not ready, status = %02X\n",
-				nes_read_indexed(nesdev, NES_IDX_INT_CPU_STATUS));
-		return 0;
-	}
-
 	return port_count;
 }
 
author
#37 lore raw

PATCH 34/37 SCSI: qla2xxx: Correct regression in relogin code.

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Andrew Vasquez <[email protected]>

commit: 666301e673e192c87a40e07a8357d6996b57b70f upstream

Commit 63a8651f2548c6bb5132c0b4e7dad4f57a9274db ([SCSI] qla2xxx:
Correct infinite-login-retry issue.) introduced a small regression where a successful relogin would result in an fcport's loop_id to be incorrectly reset to FC_NO_LOOP_ID. Only clear-out loopid, if retries have been 'truly' exhausted.

---
 drivers/scsi/qla2xxx/qla_os.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/qla2xxx/qla_os.c +1 -1
@@ -2357,7 +2357,7 @@ qla2x00_do_dpc(void *data)
 					} else {
 						fcport->login_retry = 0;
 					}
-					if (fcport->login_retry == 0)
+					if (fcport->login_retry == 0 && status != QLA_SUCCESS)
 						fcport->loop_id = FC_NO_LOOP_ID;
 				}
 				if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
author
#38 lore raw

PATCH 35/37 alpha: unbreak OSF/1 (a.out) binaries

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Ivan Kokshaysky <[email protected]>

commit 2444e56b0c08e6f3e3877583841a1213e3263d98 upstream

OSF/1 brk(2) was broken by following one-liner in sys_brk() (commit 4cc6028d4040f95cdb590a87db478b42b8be0508):

- if (brk < mm->end_code)
+ if (brk < mm->start_brk)

		goto out;

The problem is that osf_set_program_attributes() does update mm->end_code, but not mm->start_brk, which still contains inappropriate value left from binary loader, so brk() always fails.

---
 arch/alpha/kernel/osf_sys.c |    1 +
 1 file changed, 1 insertion(+)
arch/alpha/kernel/osf_sys.c +1 -0
@@ -75,6 +75,7 @@ osf_set_program_attributes(unsigned long
 	lock_kernel();
 	mm = current->mm;
 	mm->end_code = bss_start + bss_len;
+	mm->start_brk = bss_start + bss_len;
 	mm->brk = bss_start + bss_len;
 #if 0
 	printk("set_program_attributes(%lx %lx %lx %lx)\n",
author
#39 lore raw

PATCH 36/37 x86: Fix 32-bit x86 MSI-X allocation leakage

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: PJ Waskiewicz <[email protected]>

commit 9d9ad4b51d2b29b5bbeb4011f5e76f7538119cf9 upstream

This bug was introduced in the 2.6.24 i386/x86_64 tree merge, where MSI-X vector allocation will eventually fail. The cause is the new bit array tracking used vectors is not getting cleared properly on IRQ destruction on the 32-bit APIC code.

This can be seen easily using the ixgbe 10 GbE driver on multi-core systems by simply loading and unloading the driver a few times. Depending on the number of available vectors on the host system, the MSI-X allocation will eventually fail, and the driver will only be able to use legacy interrupts.

---
 arch/x86/kernel/io_apic_32.c |    1 +
 1 file changed, 1 insertion(+)
arch/x86/kernel/io_apic_32.c +1 -0
@@ -2477,6 +2477,7 @@ void destroy_irq(unsigned int irq)
 	dynamic_irq_cleanup(irq);
 
 	spin_lock_irqsave(&vector_lock, flags);
+	clear_bit(irq_vector[irq], used_vectors);
 	irq_vector[irq] = 0;
 	spin_unlock_irqrestore(&vector_lock, flags);
 }
author
#40 lore raw

PATCH 37/37 hrtimer: raise softirq unlocked to avoid circular lock dependency

In reply to Greg KH

2.6.25-stable review patch. If anyone has any objections, please let us know.

------------------
From: Thomas Gleixner <[email protected]>

commit 0c96c5979a522c3323c30a078a70120e29b5bdbc upstream

The scheduler hrtimer bits in 2.6.25 introduced a circular lock dependency in a rare code path:

=======================================================
[ INFO: possible circular locking dependency detected ] 2.6.25-sched-devel.git-x86-latest.git #19
-------------------------------------------------------
X/2980 is trying to acquire lock:
(&rq->rq_lock_key#2){++..}, at: [<ffffffff80230146>] task_rq_lock+0x56/0xa0

but task is already holding lock:
(&cpu_base->lock){++..}, at: [<ffffffff80257ae1>] lock_hrtimer_base+0x31/0x60

which lock already depends on the new lock.

The scenario which leads to this is:

posix-timer signal is delivered
-> posix-timer is rearmed
timer is already expired in hrtimer_enqueue()
-> softirq is raised

To prevent this we need to move the raise of the softirq out of the base->lock protected code path.

---
 kernel/hrtimer.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
kernel/hrtimer.c +17 -2
@@ -590,7 +590,6 @@ static inline int hrtimer_enqueue_reprog
 			list_add_tail(&timer->cb_entry,
 				      &base->cpu_base->cb_pending);
 			timer->state = HRTIMER_STATE_PENDING;
-			raise_softirq(HRTIMER_SOFTIRQ);
 			return 1;
 		default:
 			BUG();
@@ -633,6 +632,11 @@ static int hrtimer_switch_to_hres(void)
 	return 1;
 }
 
+static inline void hrtimer_raise_softirq(void)
+{
+	raise_softirq(HRTIMER_SOFTIRQ);
+}
+
 #else
 
 static inline int hrtimer_hres_active(void) { return 0; }
@@ -651,6 +655,7 @@ static inline int hrtimer_reprogram(stru
 {
 	return 0;
 }
+static inline void hrtimer_raise_softirq(void) { }
 
 #endif /* CONFIG_HIGH_RES_TIMERS */
 
@@ -850,7 +855,7 @@ hrtimer_start(struct hrtimer *timer, kti
 {
 	struct hrtimer_clock_base *base, *new_base;
 	unsigned long flags;
-	int ret;
+	int ret, raise;
 
 	base = lock_hrtimer_base(timer, &flags);
 
@@ -884,8 +889,18 @@ hrtimer_start(struct hrtimer *timer, kti
 	enqueue_hrtimer(timer, new_base,
 			new_base->cpu_base == &__get_cpu_var(hrtimer_bases));
 
+	/*
+	 * The timer may be expired and moved to the cb_pending
+	 * list. We can not raise the softirq with base lock held due
+	 * to a possible deadlock with runqueue lock.
+	 */
+	raise = timer->state == HRTIMER_STATE_PENDING;
+
 	unlock_hrtimer_base(timer, &flags);
 
+	if (raise)
+		hrtimer_raise_softirq();
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hrtimer_start);
#41 lore raw
In reply to Greg KH
Quoted 1 line · Greg KH

This is the start of the stable review cycle for the 2.6.25.1 release.

Neil sent out the following patch for md which is not contained in the list.

Please consider adding it to the list.

Thanks
Andre

From: Dan Williams <[email protected]>

rdev->mddev is no longer valid upon return from entry->store() when the 'remove' command is given.

This should go in 2.6.25.stable.

### Diffstat output

 ./drivers/md/md.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/md.c +1 -1
diff .prev/drivers/md/md.c ./drivers/md/md.c
@@ -2096,7 +2096,7 @@ rdev_attr_store(struct kobject *kobj, st
 			rv = -EBUSY;
 		else
 			rv = entry->store(rdev, page, length);
-		mddev_unlock(rdev->mddev);
+		mddev_unlock(mddev);
 	}
 	return rv;
 }
Signature · 1 line
The only person who always got his work done by Friday was Robinson Crusoe
#42 lore raw
Quoted 8 lines · * Andre Noll ([email protected]) wrote:
Quoted 1 line · Greg KH

This is the start of the stable review cycle for the 2.6.25.1 release.

Neil sent out the following patch for md which is not contained in the list.

Please consider adding it to the list.

It is on its way upstream. Once it gets to Linus' tree we'll queue it up.