--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 23:02:20 2007
+Date: Wed, 06 Jun 2007 23:02:16 -0700 (PDT)
+Message-Id: <20070606.230216.42775266.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: BLUETOOTH: Fix locking in hci_sock_dev_event().
+
+From: Satyam Sharma <ssatyam@cse.iitk.ac.in>
+
+We presently use lock_sock() to acquire a lock on a socket in
+hci_sock_dev_event(), but this goes BUG because lock_sock()
+can sleep and we're already holding a read-write spinlock at
+that point. So, we must use the non-sleeping BH version,
+bh_lock_sock().
+
+However, hci_sock_dev_event() is called from user context and
+hence using simply bh_lock_sock() will deadlock against a
+concurrent softirq that tries to acquire a lock on the same
+socket. Hence, disabling BH's before acquiring the socket lock
+and enable them afterwards, is the proper solution to fix
+socket locking in hci_sock_dev_event().
+
+Signed-off-by: Satyam Sharma <ssatyam@cse.iitk.ac.in>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/bluetooth/hci_sock.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- linux-2.6.21.3.orig/net/bluetooth/hci_sock.c
++++ linux-2.6.21.3/net/bluetooth/hci_sock.c
+@@ -656,7 +656,8 @@ static int hci_sock_dev_event(struct not
+ /* Detach sockets from device */
+ read_lock(&hci_sk_list.lock);
+ sk_for_each(sk, node, &hci_sk_list.head) {
+- lock_sock(sk);
++ local_bh_disable();
++ bh_lock_sock_nested(sk);
+ if (hci_pi(sk)->hdev == hdev) {
+ hci_pi(sk)->hdev = NULL;
+ sk->sk_err = EPIPE;
+@@ -665,7 +666,8 @@ static int hci_sock_dev_event(struct not
+
+ hci_dev_put(hdev);
+ }
+- release_sock(sk);
++ bh_unlock_sock(sk);
++ local_bh_enable();
+ }
+ read_unlock(&hci_sk_list.lock);
+ }
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:28:45 2007
+Date: Wed, 06 Jun 2007 22:28:53 -0700 (PDT)
+Message-Id: <20070606.222853.10297477.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: Fix AF_UNIX OOPS
+
+This combines two upstream commits to fix an OOPS with
+AF_UNIX and SELINUX.
+
+Basically, sk->sk_socket can become NULL because we access
+a peer socket without any locking, so it can be shut down and
+released in another thread.
+
+Commit: d410b81b4eef2e4409f9c38ef201253fbbcc7d94
+[AF_UNIX]: Make socket locking much less confusing.
+
+The unix_state_*() locking macros imply that there is some
+rwlock kind of thing going on, but the implementation is
+actually a spinlock which makes the code more confusing than
+it needs to be.
+
+So use plain unix_state_lock and unix_state_unlock.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+
+Commit: 19fec3e807a487415e77113cb9dbdaa2da739836
+[AF_UNIX]: Fix datagram connect race causing an OOPS.
+
+Based upon an excellent bug report and initial patch by
+Frederik Deweerdt.
+
+The UNIX datagram connect code blindly dereferences other->sk_socket
+via the call down to the security_unix_may_send() function.
+
+Without locking 'other' that pointer can go NULL via unix_release_sock()
+which does sock_orphan() which also marks the socket SOCK_DEAD.
+
+So we have to lock both 'sk' and 'other' yet avoid all kinds of
+potential deadlocks (connect to self is OK for datagram sockets and it
+is possible for two datagram sockets to perform a simultaneous connect
+to each other). So what we do is have a "double lock" function similar
+to how we handle this situation in other areas of the kernel. We take
+the lock of the socket pointer with the smallest address first in
+order to avoid ABBA style deadlocks.
+
+Once we have them both locked, we check to see if SOCK_DEAD is set
+for 'other' and if so, drop everything and retry the lookup.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ include/net/af_unix.h | 8 +--
+ net/unix/af_unix.c | 127 +++++++++++++++++++++++++++++++-------------------
+ 2 files changed, 83 insertions(+), 52 deletions(-)
+
+--- linux-2.6.21.3.orig/include/net/af_unix.h
++++ linux-2.6.21.3/include/net/af_unix.h
+@@ -62,13 +62,11 @@ struct unix_skb_parms {
+ #define UNIXCREDS(skb) (&UNIXCB((skb)).creds)
+ #define UNIXSID(skb) (&UNIXCB((skb)).secid)
+
+-#define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock)
+-#define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock)
+-#define unix_state_wlock(s) spin_lock(&unix_sk(s)->lock)
+-#define unix_state_wlock_nested(s) \
++#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock)
++#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock)
++#define unix_state_lock_nested(s) \
+ spin_lock_nested(&unix_sk(s)->lock, \
+ SINGLE_DEPTH_NESTING)
+-#define unix_state_wunlock(s) spin_unlock(&unix_sk(s)->lock)
+
+ #ifdef __KERNEL__
+ /* The AF_UNIX socket */
+--- linux-2.6.21.3.orig/net/unix/af_unix.c
++++ linux-2.6.21.3/net/unix/af_unix.c
+@@ -175,11 +175,11 @@ static struct sock *unix_peer_get(struct
+ {
+ struct sock *peer;
+
+- unix_state_rlock(s);
++ unix_state_lock(s);
+ peer = unix_peer(s);
+ if (peer)
+ sock_hold(peer);
+- unix_state_runlock(s);
++ unix_state_unlock(s);
+ return peer;
+ }
+
+@@ -370,7 +370,7 @@ static int unix_release_sock (struct soc
+ unix_remove_socket(sk);
+
+ /* Clear state */
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ sock_orphan(sk);
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ dentry = u->dentry;
+@@ -379,7 +379,7 @@ static int unix_release_sock (struct soc
+ u->mnt = NULL;
+ state = sk->sk_state;
+ sk->sk_state = TCP_CLOSE;
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+
+ wake_up_interruptible_all(&u->peer_wait);
+
+@@ -387,12 +387,12 @@ static int unix_release_sock (struct soc
+
+ if (skpair!=NULL) {
+ if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
+- unix_state_wlock(skpair);
++ unix_state_lock(skpair);
+ /* No more writes */
+ skpair->sk_shutdown = SHUTDOWN_MASK;
+ if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
+ skpair->sk_err = ECONNRESET;
+- unix_state_wunlock(skpair);
++ unix_state_unlock(skpair);
+ skpair->sk_state_change(skpair);
+ read_lock(&skpair->sk_callback_lock);
+ sk_wake_async(skpair,1,POLL_HUP);
+@@ -449,7 +449,7 @@ static int unix_listen(struct socket *so
+ err = -EINVAL;
+ if (!u->addr)
+ goto out; /* No listens on an unbound socket */
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
+ goto out_unlock;
+ if (backlog > sk->sk_max_ack_backlog)
+@@ -463,7 +463,7 @@ static int unix_listen(struct socket *so
+ err = 0;
+
+ out_unlock:
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ out:
+ return err;
+ }
+@@ -859,6 +859,31 @@ out_mknod_parent:
+ goto out_up;
+ }
+
++static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
++{
++ if (unlikely(sk1 == sk2) || !sk2) {
++ unix_state_lock(sk1);
++ return;
++ }
++ if (sk1 < sk2) {
++ unix_state_lock(sk1);
++ unix_state_lock_nested(sk2);
++ } else {
++ unix_state_lock(sk2);
++ unix_state_lock_nested(sk1);
++ }
++}
++
++static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
++{
++ if (unlikely(sk1 == sk2) || !sk2) {
++ unix_state_unlock(sk1);
++ return;
++ }
++ unix_state_unlock(sk1);
++ unix_state_unlock(sk2);
++}
++
+ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
+ int alen, int flags)
+ {
+@@ -878,11 +903,19 @@ static int unix_dgram_connect(struct soc
+ !unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
+ goto out;
+
++restart:
+ other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
+ if (!other)
+ goto out;
+
+- unix_state_wlock(sk);
++ unix_state_double_lock(sk, other);
++
++ /* Apparently VFS overslept socket death. Retry. */
++ if (sock_flag(other, SOCK_DEAD)) {
++ unix_state_double_unlock(sk, other);
++ sock_put(other);
++ goto restart;
++ }
+
+ err = -EPERM;
+ if (!unix_may_send(sk, other))
+@@ -897,7 +930,7 @@ static int unix_dgram_connect(struct soc
+ * 1003.1g breaking connected state with AF_UNSPEC
+ */
+ other = NULL;
+- unix_state_wlock(sk);
++ unix_state_double_lock(sk, other);
+ }
+
+ /*
+@@ -906,19 +939,19 @@ static int unix_dgram_connect(struct soc
+ if (unix_peer(sk)) {
+ struct sock *old_peer = unix_peer(sk);
+ unix_peer(sk)=other;
+- unix_state_wunlock(sk);
++ unix_state_double_unlock(sk, other);
+
+ if (other != old_peer)
+ unix_dgram_disconnected(sk, old_peer);
+ sock_put(old_peer);
+ } else {
+ unix_peer(sk)=other;
+- unix_state_wunlock(sk);
++ unix_state_double_unlock(sk, other);
+ }
+ return 0;
+
+ out_unlock:
+- unix_state_wunlock(sk);
++ unix_state_double_unlock(sk, other);
+ sock_put(other);
+ out:
+ return err;
+@@ -937,7 +970,7 @@ static long unix_wait_for_peer(struct so
+ (skb_queue_len(&other->sk_receive_queue) >
+ other->sk_max_ack_backlog);
+
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+
+ if (sched)
+ timeo = schedule_timeout(timeo);
+@@ -995,11 +1028,11 @@ restart:
+ goto out;
+
+ /* Latch state of peer */
+- unix_state_rlock(other);
++ unix_state_lock(other);
+
+ /* Apparently VFS overslept socket death. Retry. */
+ if (sock_flag(other, SOCK_DEAD)) {
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ sock_put(other);
+ goto restart;
+ }
+@@ -1049,18 +1082,18 @@ restart:
+ goto out_unlock;
+ }
+
+- unix_state_wlock_nested(sk);
++ unix_state_lock_nested(sk);
+
+ if (sk->sk_state != st) {
+- unix_state_wunlock(sk);
+- unix_state_runlock(other);
++ unix_state_unlock(sk);
++ unix_state_unlock(other);
+ sock_put(other);
+ goto restart;
+ }
+
+ err = security_unix_stream_connect(sock, other->sk_socket, newsk);
+ if (err) {
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ goto out_unlock;
+ }
+
+@@ -1097,7 +1130,7 @@ restart:
+ smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
+ unix_peer(sk) = newsk;
+
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+
+ /* take ten and and send info to listening sock */
+ spin_lock(&other->sk_receive_queue.lock);
+@@ -1106,14 +1139,14 @@ restart:
+ * is installed to listening socket. */
+ atomic_inc(&newu->inflight);
+ spin_unlock(&other->sk_receive_queue.lock);
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ other->sk_data_ready(other, 0);
+ sock_put(other);
+ return 0;
+
+ out_unlock:
+ if (other)
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+
+ out:
+ if (skb)
+@@ -1179,10 +1212,10 @@ static int unix_accept(struct socket *so
+ wake_up_interruptible(&unix_sk(sk)->peer_wait);
+
+ /* attach accepted sock to socket */
+- unix_state_wlock(tsk);
++ unix_state_lock(tsk);
+ newsock->state = SS_CONNECTED;
+ sock_graft(tsk, newsock);
+- unix_state_wunlock(tsk);
++ unix_state_unlock(tsk);
+ return 0;
+
+ out:
+@@ -1209,7 +1242,7 @@ static int unix_getname(struct socket *s
+ }
+
+ u = unix_sk(sk);
+- unix_state_rlock(sk);
++ unix_state_lock(sk);
+ if (!u->addr) {
+ sunaddr->sun_family = AF_UNIX;
+ sunaddr->sun_path[0] = 0;
+@@ -1220,7 +1253,7 @@ static int unix_getname(struct socket *s
+ *uaddr_len = addr->len;
+ memcpy(sunaddr, addr->name, *uaddr_len);
+ }
+- unix_state_runlock(sk);
++ unix_state_unlock(sk);
+ sock_put(sk);
+ out:
+ return err;
+@@ -1338,7 +1371,7 @@ restart:
+ goto out_free;
+ }
+
+- unix_state_rlock(other);
++ unix_state_lock(other);
+ err = -EPERM;
+ if (!unix_may_send(sk, other))
+ goto out_unlock;
+@@ -1348,20 +1381,20 @@ restart:
+ * Check with 1003.1g - what should
+ * datagram error
+ */
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ sock_put(other);
+
+ err = 0;
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ if (unix_peer(sk) == other) {
+ unix_peer(sk)=NULL;
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+
+ unix_dgram_disconnected(sk, other);
+ sock_put(other);
+ err = -ECONNREFUSED;
+ } else {
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ }
+
+ other = NULL;
+@@ -1398,14 +1431,14 @@ restart:
+ }
+
+ skb_queue_tail(&other->sk_receive_queue, skb);
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ other->sk_data_ready(other, len);
+ sock_put(other);
+ scm_destroy(siocb->scm);
+ return len;
+
+ out_unlock:
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ out_free:
+ kfree_skb(skb);
+ out:
+@@ -1495,14 +1528,14 @@ static int unix_stream_sendmsg(struct ki
+ goto out_err;
+ }
+
+- unix_state_rlock(other);
++ unix_state_lock(other);
+
+ if (sock_flag(other, SOCK_DEAD) ||
+ (other->sk_shutdown & RCV_SHUTDOWN))
+ goto pipe_err_free;
+
+ skb_queue_tail(&other->sk_receive_queue, skb);
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ other->sk_data_ready(other, size);
+ sent+=size;
+ }
+@@ -1513,7 +1546,7 @@ static int unix_stream_sendmsg(struct ki
+ return sent;
+
+ pipe_err_free:
+- unix_state_runlock(other);
++ unix_state_unlock(other);
+ kfree_skb(skb);
+ pipe_err:
+ if (sent==0 && !(msg->msg_flags&MSG_NOSIGNAL))
+@@ -1642,7 +1675,7 @@ static long unix_stream_data_wait(struct
+ {
+ DEFINE_WAIT(wait);
+
+- unix_state_rlock(sk);
++ unix_state_lock(sk);
+
+ for (;;) {
+ prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+@@ -1655,14 +1688,14 @@ static long unix_stream_data_wait(struct
+ break;
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+- unix_state_runlock(sk);
++ unix_state_unlock(sk);
+ timeo = schedule_timeout(timeo);
+- unix_state_rlock(sk);
++ unix_state_lock(sk);
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ }
+
+ finish_wait(sk->sk_sleep, &wait);
+- unix_state_runlock(sk);
++ unix_state_unlock(sk);
+ return timeo;
+ }
+
+@@ -1817,12 +1850,12 @@ static int unix_shutdown(struct socket *
+ mode = (mode+1)&(RCV_SHUTDOWN|SEND_SHUTDOWN);
+
+ if (mode) {
+- unix_state_wlock(sk);
++ unix_state_lock(sk);
+ sk->sk_shutdown |= mode;
+ other=unix_peer(sk);
+ if (other)
+ sock_hold(other);
+- unix_state_wunlock(sk);
++ unix_state_unlock(sk);
+ sk->sk_state_change(sk);
+
+ if (other &&
+@@ -1834,9 +1867,9 @@ static int unix_shutdown(struct socket *
+ peer_mode |= SEND_SHUTDOWN;
+ if (mode&SEND_SHUTDOWN)
+ peer_mode |= RCV_SHUTDOWN;
+- unix_state_wlock(other);
++ unix_state_lock(other);
+ other->sk_shutdown |= peer_mode;
+- unix_state_wunlock(other);
++ unix_state_unlock(other);
+ other->sk_state_change(other);
+ read_lock(&other->sk_callback_lock);
+ if (peer_mode == SHUTDOWN_MASK)
+@@ -1974,7 +2007,7 @@ static int unix_seq_show(struct seq_file
+ else {
+ struct sock *s = v;
+ struct unix_sock *u = unix_sk(s);
+- unix_state_rlock(s);
++ unix_state_lock(s);
+
+ seq_printf(seq, "%p: %08X %08X %08X %04X %02X %5lu",
+ s,
+@@ -2002,7 +2035,7 @@ static int unix_seq_show(struct seq_file
+ for ( ; i < len; i++)
+ seq_putc(seq, u->addr->name->sun_path[i]);
+ }
+- unix_state_runlock(s);
++ unix_state_unlock(s);
+ seq_putc(seq, '\n');
+ }
+
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:38:00 2007
+Date: Wed, 06 Jun 2007 22:38:11 -0700 (PDT)
+Message-Id: <20070606.223811.34759359.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: ICMP: Fix icmp_errors_use_inbound_ifaddr sysctl
+
+Currently when icmp_errors_use_inbound_ifaddr is set and an ICMP error is
+sent after the packet passed through ip_output(), an address from the
+outgoing interface is chosen as ICMP source address since skb->dev doesn't
+point to the incoming interface anymore.
+
+Fix this by doing an interface lookup on rt->dst.iif and using that device.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/ipv4/icmp.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- linux-2.6.21.3.orig/net/ipv4/icmp.c
++++ linux-2.6.21.3/net/ipv4/icmp.c
+@@ -513,9 +513,15 @@ void icmp_send(struct sk_buff *skb_in, i
+
+ saddr = iph->daddr;
+ if (!(rt->rt_flags & RTCF_LOCAL)) {
+- if (sysctl_icmp_errors_use_inbound_ifaddr)
+- saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
+- else
++ struct net_device *dev = NULL;
++
++ if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
++ dev = dev_get_by_index(rt->fl.iif);
++
++ if (dev) {
++ saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
++ dev_put(dev);
++ } else
+ saddr = 0;
+ }
+
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:41:41 2007
+Date: Wed, 06 Jun 2007 22:41:52 -0700 (PDT)
+Message-Id: <20070606.224152.68156938.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: IPSEC: Fix panic when using inter address familiy IPsec on loopback.
+
+From: Kazunori MIYAZAWA <kazunori@miyazawa.org>
+
+Signed-off-by: Kazunori MIYAZAWA <kazunori@miyazawa.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/ipv4/xfrm4_input.c | 6 ++----
+ net/ipv4/xfrm4_mode_tunnel.c | 2 ++
+ net/ipv6/xfrm6_input.c | 6 ++----
+ net/ipv6/xfrm6_mode_tunnel.c | 1 +
+ 4 files changed, 7 insertions(+), 8 deletions(-)
+
+--- linux-2.6.21.3.orig/net/ipv4/xfrm4_input.c
++++ linux-2.6.21.3/net/ipv4/xfrm4_input.c
+@@ -138,10 +138,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb,
+ nf_reset(skb);
+
+ if (decaps) {
+- if (!(skb->dev->flags&IFF_LOOPBACK)) {
+- dst_release(skb->dst);
+- skb->dst = NULL;
+- }
++ dst_release(skb->dst);
++ skb->dst = NULL;
+ netif_rx(skb);
+ return 0;
+ } else {
+--- linux-2.6.21.3.orig/net/ipv4/xfrm4_mode_tunnel.c
++++ linux-2.6.21.3/net/ipv4/xfrm4_mode_tunnel.c
+@@ -84,6 +84,8 @@ static int xfrm4_tunnel_output(struct xf
+ top_iph->saddr = x->props.saddr.a4;
+ top_iph->daddr = x->id.daddr.a4;
+
++ skb->protocol = htons(ETH_P_IP);
++
+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+ return 0;
+ }
+--- linux-2.6.21.3.orig/net/ipv6/xfrm6_input.c
++++ linux-2.6.21.3/net/ipv6/xfrm6_input.c
+@@ -104,10 +104,8 @@ int xfrm6_rcv_spi(struct sk_buff *skb, _
+ nf_reset(skb);
+
+ if (decaps) {
+- if (!(skb->dev->flags&IFF_LOOPBACK)) {
+- dst_release(skb->dst);
+- skb->dst = NULL;
+- }
++ dst_release(skb->dst);
++ skb->dst = NULL;
+ netif_rx(skb);
+ return -1;
+ } else {
+--- linux-2.6.21.3.orig/net/ipv6/xfrm6_mode_tunnel.c
++++ linux-2.6.21.3/net/ipv6/xfrm6_mode_tunnel.c
+@@ -80,6 +80,7 @@ static int xfrm6_tunnel_output(struct xf
+ top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
+ ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
+ ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
++ skb->protocol = htons(ETH_P_IPV6);
+ return 0;
+ }
+
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:47:58 2007
+Date: Wed, 06 Jun 2007 22:48:09 -0700 (PDT)
+Message-Id: <20070606.224809.35355405.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: IPV4: Correct rp_filter help text.
+
+From: Dave Jones <davej@redhat.com>
+
+As mentioned in http://bugzilla.kernel.org/show_bug.cgi?id=5015
+The helptext implies that this is on by default.
+This may be true on some distros (Fedora/RHEL have it enabled
+in /etc/sysctl.conf), but the kernel defaults to it off.
+
+Signed-off-by: Dave Jones <davej@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/ipv4/Kconfig | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- linux-2.6.21.3.orig/net/ipv4/Kconfig
++++ linux-2.6.21.3/net/ipv4/Kconfig
+@@ -43,11 +43,11 @@ config IP_ADVANCED_ROUTER
+ asymmetric routing (packets from you to a host take a different path
+ than packets from that host to you) or if you operate a non-routing
+ host which has several IP addresses on different interfaces. To turn
+- rp_filter off use:
++ rp_filter on use:
+
+- echo 0 > /proc/sys/net/ipv4/conf/<device>/rp_filter
++ echo 1 > /proc/sys/net/ipv4/conf/<device>/rp_filter
+ or
+- echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
++ echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
+
+ If unsure, say N here.
+
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:42:46 2007
+Date: Wed, 06 Jun 2007 22:42:58 -0700 (PDT)
+Message-Id: <20070606.224258.27782785.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: IPV6 ROUTE: No longer handle ::/0 specially.
+
+From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+
+We do not need to handle ::/0 routes specially any longer.
+This should fix BUG #8349.
+
+Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Acked-by: Yuji Sekiya <sekiya@wide.ad.jp>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/ipv6/ip6_fib.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- linux-2.6.21.3.orig/net/ipv6/ip6_fib.c
++++ linux-2.6.21.3/net/ipv6/ip6_fib.c
+@@ -619,14 +619,6 @@ static int fib6_add_rt2node(struct fib6_
+
+ ins = &fn->leaf;
+
+- if (fn->fn_flags&RTN_TL_ROOT &&
+- fn->leaf == &ip6_null_entry &&
+- !(rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) ){
+- fn->leaf = rt;
+- rt->u.dst.rt6_next = NULL;
+- goto out;
+- }
+-
+ for (iter = fn->leaf; iter; iter=iter->u.dst.rt6_next) {
+ /*
+ * Search for duplicates
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:44:02 2007
+Date: Wed, 06 Jun 2007 22:44:14 -0700 (PDT)
+Message-Id: <20070606.224414.77057904.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NET: Fix BMSR_100{HALF,FULL}2 defines in linux/mii.h
+
+Noticed by Matvejchikov Ilya.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ include/linux/mii.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.21.3.orig/include/linux/mii.h
++++ linux-2.6.21.3/include/linux/mii.h
+@@ -56,8 +56,8 @@
+ #define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+ #define BMSR_RESV 0x00c0 /* Unused... */
+ #define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
+-#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */
+-#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */
++#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */
++#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */
+ #define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+ #define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+ #define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:46:56 2007
+Date: Wed, 06 Jun 2007 22:47:07 -0700 (PDT)
+Message-Id: <20070606.224707.26532542.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NET: Fix race condition about network device name allocation.
+
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+
+Kenji Kaneshige found this race between device removal and
+registration. On unregister it is possible for the old device to
+exist, because sysfs file is still open. A new device with 'eth%d'
+will select the same name, but sysfs kobject register will fial.
+
+The following changes the shutdown order slightly. It hold a removes
+the sysfs entries earlier (on unregister_netdevice), but holds a
+kobject reference. Then when todo runs the actual last put free
+happens.
+
+Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/core/dev.c | 10 ++++++----
+ net/core/net-sysfs.c | 8 +++++++-
+ 2 files changed, 13 insertions(+), 5 deletions(-)
+
+--- linux-2.6.21.3.orig/net/core/dev.c
++++ linux-2.6.21.3/net/core/dev.c
+@@ -3135,7 +3135,6 @@ void netdev_run_todo(void)
+ continue;
+ }
+
+- netdev_unregister_sysfs(dev);
+ dev->reg_state = NETREG_UNREGISTERED;
+
+ netdev_wait_allrefs(dev);
+@@ -3146,11 +3145,11 @@ void netdev_run_todo(void)
+ BUG_TRAP(!dev->ip6_ptr);
+ BUG_TRAP(!dev->dn_ptr);
+
+- /* It must be the very last action,
+- * after this 'dev' may point to freed up memory.
+- */
+ if (dev->destructor)
+ dev->destructor(dev);
++
++ /* Free network device */
++ kobject_put(&dev->dev.kobj);
+ }
+
+ out:
+@@ -3305,6 +3304,9 @@ void unregister_netdevice(struct net_dev
+ /* Notifier chain MUST detach us from master device. */
+ BUG_TRAP(!dev->master);
+
++ /* Remove entries from sysfs */
++ netdev_unregister_sysfs(dev);
++
+ /* Finish processing unregister after unlock */
+ net_set_todo(dev);
+
+--- linux-2.6.21.3.orig/net/core/net-sysfs.c
++++ linux-2.6.21.3/net/core/net-sysfs.c
+@@ -451,9 +451,15 @@ static struct class net_class = {
+ #endif
+ };
+
++/* Delete sysfs entries but hold kobject reference until after all
++ * netdev references are gone.
++ */
+ void netdev_unregister_sysfs(struct net_device * net)
+ {
+- device_del(&(net->dev));
++ struct device *dev = &(net->dev);
++
++ kobject_get(&dev->kobj);
++ device_del(dev);
+ }
+
+ /* Create sysfs entries for network device. */
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:40:19 2007
+Date: Wed, 06 Jun 2007 22:40:27 -0700 (PDT)
+Message-Id: <20070606.224027.02298887.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NET: parse ip:port strings correctly in in4_pton
+
+From: Jerome Borsboom <j.borsboom@erasmusmc.nl>
+
+in4_pton converts a textual representation of an ip4 address
+into an integer representation. However, when the textual representation
+is of in the form ip:port, e.g. 192.168.1.1:5060, and 'delim' is set to
+-1, the function bails out with an error when reading the colon.
+
+It makes sense to allow the colon as a delimiting character without
+explicitly having to set it through the 'delim' variable as there can be
+no ambiguity in the point where the ip address is completely parsed. This
+function is indeed called from nf_conntrack_sip.c in this way to parse
+textual ip:port combinations which fails due to the reason stated above.
+
+Signed-off-by: Jerome Borsboom <j.borsboom@erasmusmc.nl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/core/utils.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- linux-2.6.21.3.orig/net/core/utils.c
++++ linux-2.6.21.3/net/core/utils.c
+@@ -137,16 +137,16 @@ int in4_pton(const char *src, int srclen
+ while(1) {
+ int c;
+ c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
+- if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM))) {
++ if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK))) {
+ goto out;
+ }
+- if (c & (IN6PTON_DOT | IN6PTON_DELIM)) {
++ if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+ if (w == 0)
+ goto out;
+ *d++ = w & 0xff;
+ w = 0;
+ i++;
+- if (c & IN6PTON_DELIM) {
++ if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+ if (i != 4)
+ goto out;
+ break;
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:50:52 2007
+Date: Wed, 06 Jun 2007 22:51:03 -0700 (PDT)
+Message-Id: <20070606.225103.52166535.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: NET: "wrong timeout value" in sk_wait_data() v2
+
+From: Vasily Averin <vvs@sw.ru>
+
+sys_setsockopt() do not check properly timeout values for
+SO_RCVTIMEO/SO_SNDTIMEO, for example it's possible to set negative timeout
+values. POSIX do not defines behaviour for sys_setsockopt in case negative
+timeouts, but requires that setsockopt() shall fail with -EDOM if the send and
+receive timeout values are too big to fit into the timeout fields in the socket
+structure.
+In current implementation negative timeout can lead to error messages like
+"schedule_timeout: wrong timeout value".
+
+Proposed patch:
+- checks tv_usec and returns -EDOM if it is wrong
+- do not allows to set negative timeout values (sets 0 instead) and outputs
+ratelimited information message about such attempts.
+
+Signed-off-By: Vasily Averin <vvs@sw.ru>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ net/core/sock.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- linux-2.6.21.3.orig/net/core/sock.c
++++ linux-2.6.21.3/net/core/sock.c
+@@ -204,7 +204,19 @@ static int sock_set_timeout(long *timeo_
+ return -EINVAL;
+ if (copy_from_user(&tv, optval, sizeof(tv)))
+ return -EFAULT;
++ if (tv.tv_usec < 0 || tv.tv_usec >= USEC_PER_SEC)
++ return -EDOM;
+
++ if (tv.tv_sec < 0) {
++ static int warned = 0;
++ *timeo_p = 0;
++ if (warned < 10 && net_ratelimit())
++ warned++;
++ printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
++ "tries to set negative timeout\n",
++ current->comm, current->pid);
++ return 0;
++ }
+ *timeo_p = MAX_SCHEDULE_TIMEOUT;
+ if (tv.tv_sec == 0 && tv.tv_usec == 0)
+ return 0;
sysfs-store-sysfs-inode-nrs-in-s_ino-to-avoid-readdir-oopses.patch
work-around-dell-e520-bios-reboot-bug.patch
netfilter-ip-nf-_conntrack_sctp-fix-remotely-triggerable-null-ptr-dereference.patch
+fix-af_unix-oops.patch
+icmp-fix-icmp_errors_use_inbound_ifaddr-sysctl.patch
+net-parse-ip-port-strings-correctly-in-in4_pton.patch
+ipsec-fix-panic-when-using-inter-address-familiy-ipsec-on-loopback.patch
+ipv6-route-no-longer-handle-0-specially.patch
+net-fix-bmsr_100-half-full-2-defines-in-linux-mii.h.patch
+net-fix-race-condition-about-network-device-name-allocation.patch
+ipv4-correct-rp_filter-help-text.patch
+sparc-linux-always-started-with-9600-8n1.patch
+net-wrong-timeout-value-in-sk_wait_data-v2.patch
+sparc64-fix-two-bugs-wrt.-kernel-4mb-tsb.patch
+sparc64-fix-_page_exec_4u-check-in-sun4u-i-tlb-miss-handler.patch
+sparc64-don-t-be-picky-about-virtual-dma-values-on-sun4v.patch
+tcp-use-default-32768-61000-outgoing-port-range-in-all-cases.patch
+bluetooth-fix-locking-in-hci_sock_dev_event.patch
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:49:03 2007
+Date: Wed, 06 Jun 2007 22:49:14 -0700 (PDT)
+Message-Id: <20070606.224914.26966192.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: SPARC: Linux always started with 9600 8N1
+
+From: Jan Engelhardt <jengelh@gmx.de>
+
+The Linux kernel ignored the PROM's serial settings (115200,n,8,1 in
+my case). This was because mode_prop remained "ttyX-mode" (expected:
+"ttya-mode") due to the constness of string literals when used with
+"char *". Since there is no "ttyX-mode" property in the PROM, Linux
+always used the default 9600.
+
+[ Investigation of the suncore.s assembler reveals that gcc optimizied
+ away the stores, yet did not emit a warning, which is a pretty
+ anti-social thing to do and is the only reason this bug lived for
+ so long -DaveM ]
+
+Signed-off-by: Jan Engelhardt <jengelh@gmx.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ drivers/serial/suncore.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- linux-2.6.21.3.orig/drivers/serial/suncore.c
++++ linux-2.6.21.3/drivers/serial/suncore.c
+@@ -30,9 +30,9 @@ void
+ sunserial_console_termios(struct console *con)
+ {
+ char mode[16], buf[16], *s;
+- char *mode_prop = "ttyX-mode";
+- char *cd_prop = "ttyX-ignore-cd";
+- char *dtr_prop = "ttyX-rts-dtr-off";
++ char mode_prop[] = "ttyX-mode";
++ char cd_prop[] = "ttyX-ignore-cd";
++ char dtr_prop[] = "ttyX-rts-dtr-off";
+ char *ssp_console_modes_prop = "ssp-console-modes";
+ int baud, bits, stop, cflag;
+ char parity;
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:59:13 2007
+Date: Wed, 06 Jun 2007 22:59:24 -0700 (PDT)
+Message-Id: <20070606.225924.88342677.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: SPARC64: Don't be picky about virtual-dma values on sun4v.
+
+Handle arbitrary base and length values as long as they
+are multiples of IO_PAGE_SIZE.
+
+Bug found by Arun Kumar Rao.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ arch/sparc64/kernel/pci_sun4v.c | 36 ++++++++++--------------------------
+ 1 file changed, 10 insertions(+), 26 deletions(-)
+
+--- linux-2.6.21.3.orig/arch/sparc64/kernel/pci_sun4v.c
++++ linux-2.6.21.3/arch/sparc64/kernel/pci_sun4v.c
+@@ -12,6 +12,7 @@
+ #include <linux/percpu.h>
+ #include <linux/irq.h>
+ #include <linux/msi.h>
++#include <linux/log2.h>
+
+ #include <asm/pbm.h>
+ #include <asm/iommu.h>
+@@ -996,9 +997,8 @@ static void pci_sun4v_iommu_init(struct
+ {
+ struct pci_iommu *iommu = pbm->iommu;
+ struct property *prop;
+- unsigned long num_tsb_entries, sz;
++ unsigned long num_tsb_entries, sz, tsbsize;
+ u32 vdma[2], dma_mask, dma_offset;
+- int tsbsize;
+
+ prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
+ if (prop) {
+@@ -1012,31 +1012,15 @@ static void pci_sun4v_iommu_init(struct
+ vdma[1] = 0x80000000;
+ }
+
+- dma_mask = vdma[0];
+- switch (vdma[1]) {
+- case 0x20000000:
+- dma_mask |= 0x1fffffff;
+- tsbsize = 64;
+- break;
+-
+- case 0x40000000:
+- dma_mask |= 0x3fffffff;
+- tsbsize = 128;
+- break;
+-
+- case 0x80000000:
+- dma_mask |= 0x7fffffff;
+- tsbsize = 256;
+- break;
+-
+- default:
+- prom_printf("PCI-SUN4V: strange virtual-dma size.\n");
+- prom_halt();
++ if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) {
++ prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n",
++ vdma[0], vdma[1]);
++ prom_halt();
+ };
+
+- tsbsize *= (8 * 1024);
+-
+- num_tsb_entries = tsbsize / sizeof(iopte_t);
++ dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL);
++ num_tsb_entries = vdma[1] / IO_PAGE_SIZE;
++ tsbsize = num_tsb_entries * sizeof(iopte_t);
+
+ dma_offset = vdma[0];
+
+@@ -1047,7 +1031,7 @@ static void pci_sun4v_iommu_init(struct
+ iommu->dma_addr_mask = dma_mask;
+
+ /* Allocate and initialize the free area map. */
+- sz = num_tsb_entries / 8;
++ sz = (num_tsb_entries + 7) / 8;
+ sz = (sz + 7UL) & ~7UL;
+ iommu->arena.map = kzalloc(sz, GFP_KERNEL);
+ if (!iommu->arena.map) {
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:56:08 2007
+Date: Wed, 06 Jun 2007 22:56:19 -0700 (PDT)
+Message-Id: <20070606.225619.91314293.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: SPARC64: Fix _PAGE_EXEC_4U check in sun4u I-TLB miss handler.
+
+It was using an immediate _PAGE_EXEC_4U value in an 'and'
+instruction to perform the test. This doesn't work because
+the immediate field is signed 13-bit, this the mask being
+tested against the PTE was 0x1000 sign-extended to 32-bits
+instead of just plain 0x1000.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ arch/sparc64/kernel/itlb_miss.S | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.21.3.orig/arch/sparc64/kernel/itlb_miss.S
++++ linux-2.6.21.3/arch/sparc64/kernel/itlb_miss.S
+@@ -11,12 +11,12 @@
+ /* ITLB ** ICACHE line 2: TSB compare and TLB load */
+ bne,pn %xcc, tsb_miss_itlb ! Miss
+ mov FAULT_CODE_ITLB, %g3
+- andcc %g5, _PAGE_EXEC_4U, %g0 ! Executable?
++ sethi %hi(_PAGE_EXEC_4U), %g4
++ andcc %g5, %g4, %g0 ! Executable?
+ be,pn %xcc, tsb_do_fault
+ nop ! Delay slot, fill me
+ stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load TLB
+ retry ! Trap done
+- nop
+
+ /* ITLB ** ICACHE line 3: */
+ nop
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 22:52:23 2007
+Date: Wed, 06 Jun 2007 22:52:35 -0700 (PDT)
+Message-Id: <20070606.225235.53338976.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: SPARC64: Fix two bugs wrt. kernel 4MB TSB.
+
+From: David S. Miller <davem@sunset.davemloft.net>
+
+1) The TSB lookup was not using the correct hash mask.
+
+2) It was not aligned on a boundary equal to it's size,
+ which is required by the sun4v Hypervisor.
+
+wasn't having it's return value checked, and that bug will be fixed up
+as well in a subsequent changeset.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+
+---
+ arch/sparc64/kernel/head.S | 31 ++++++++++++++++++++++++++-----
+ arch/sparc64/mm/init.c | 7 +++++--
+ include/asm-sparc64/tsb.h | 2 +-
+ 3 files changed, 32 insertions(+), 8 deletions(-)
+
+--- linux-2.6.21.3.orig/arch/sparc64/kernel/head.S
++++ linux-2.6.21.3/arch/sparc64/kernel/head.S
+@@ -653,33 +653,54 @@ setup_tba:
+ restore
+ sparc64_boot_end:
+
+-#include "ktlb.S"
+-#include "tsb.S"
+ #include "etrap.S"
+ #include "rtrap.S"
+ #include "winfixup.S"
+ #include "entry.S"
+ #include "sun4v_tlb_miss.S"
+ #include "sun4v_ivec.S"
++#include "ktlb.S"
++#include "tsb.S"
+
+ /*
+ * The following skip makes sure the trap table in ttable.S is aligned
+ * on a 32K boundary as required by the v9 specs for TBA register.
+ *
+ * We align to a 32K boundary, then we have the 32K kernel TSB,
+- * then the 32K aligned trap table.
++ * the 64K kernel 4MB TSB, and then the 32K aligned trap table.
+ */
+ 1:
+ .skip 0x4000 + _start - 1b
+
++! 0x0000000000408000
++
+ .globl swapper_tsb
+ swapper_tsb:
+ .skip (32 * 1024)
+
+-! 0x0000000000408000
+-
++ .globl swapper_4m_tsb
++swapper_4m_tsb:
++ .skip (64 * 1024)
++
++! 0x0000000000420000
++
++ /* Some care needs to be exercised if you try to move the
++ * location of the trap table relative to other things. For
++ * one thing there are br* instructions in some of the
++ * trap table entires which branch back to code in ktlb.S
++ * Those instructions can only handle a signed 16-bit
++ * displacement.
++ *
++ * There is a binutils bug (bugzilla #4558) which causes
++ * the relocation overflow checks for such instructions to
++ * not be done correctly. So bintuils will not notice the
++ * error and will instead write junk into the relocation and
++ * you'll have an unbootable kernel.
++ */
+ #include "ttable.S"
+
++! 0x0000000000428000
++
+ #include "systbls.S"
+
+ .data
+--- linux-2.6.21.3.orig/arch/sparc64/mm/init.c
++++ linux-2.6.21.3/arch/sparc64/mm/init.c
+@@ -60,8 +60,11 @@ unsigned long kern_linear_pte_xor[2] __r
+ unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
+
+ #ifndef CONFIG_DEBUG_PAGEALLOC
+-/* A special kernel TSB for 4MB and 256MB linear mappings. */
+-struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
++/* A special kernel TSB for 4MB and 256MB linear mappings.
++ * Space is allocated for this right after the trap table
++ * in arch/sparc64/kernel/head.S
++ */
++extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES];
+ #endif
+
+ #define MAX_BANKS 32
+--- linux-2.6.21.3.orig/include/asm-sparc64/tsb.h
++++ linux-2.6.21.3/include/asm-sparc64/tsb.h
+@@ -271,7 +271,7 @@ extern struct tsb_phys_patch_entry __tsb
+ #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \
+ sethi %hi(swapper_4m_tsb), REG1; \
+ or REG1, %lo(swapper_4m_tsb), REG1; \
+- and TAG, (KERNEL_TSB_NENTRIES - 1), REG2; \
++ and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \
+ sllx REG2, 4, REG2; \
+ add REG1, REG2, REG2; \
+ KTSB_LOAD_QUAD(REG2, REG3); \
--- /dev/null
+From stable-bounces@linux.kernel.org Wed Jun 6 23:01:11 2007
+Date: Wed, 06 Jun 2007 23:01:05 -0700 (PDT)
+Message-Id: <20070606.230105.57444963.davem@davemloft.net>
+To: stable@kernel.org
+From: David Miller <davem@davemloft.net>
+Cc: bunk@stusta.de
+Subject: TCP: Use default 32768-61000 outgoing port range in all cases.
+
+From: Mark Glines <mark@glines.org>
+
+This diff changes the default port range used for outgoing connections,
+from "use 32768-61000 in most cases, but use N-4999 on small boxes
+(where N is a multiple of 1024, depending on just *how* small the box
+is)" to just "use 32768-61000 in all cases".
+
+I don't believe there are any drawbacks to this change, and it keeps
+outgoing connection ports farther away from the mess of
+IANA-registered ports.
+
+Signed-off-by: Mark Glines <mark@glines.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/ipv4/inet_connection_sock.c | 4 +---
+ net/ipv4/tcp.c | 3 ---
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+--- linux-2.6.21.3.orig/net/ipv4/inet_connection_sock.c
++++ linux-2.6.21.3/net/ipv4/inet_connection_sock.c
+@@ -31,10 +31,8 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
+
+ /*
+ * This array holds the first and last local port number.
+- * For high-usage systems, use sysctl to change this to
+- * 32768-61000
+ */
+-int sysctl_local_port_range[2] = { 1024, 4999 };
++int sysctl_local_port_range[2] = { 32768, 61000 };
+
+ int inet_csk_bind_conflict(const struct sock *sk,
+ const struct inet_bind_bucket *tb)
+--- linux-2.6.21.3.orig/net/ipv4/tcp.c
++++ linux-2.6.21.3/net/ipv4/tcp.c
+@@ -2445,13 +2445,10 @@ void __init tcp_init(void)
+ order++)
+ ;
+ if (order >= 4) {
+- sysctl_local_port_range[0] = 32768;
+- sysctl_local_port_range[1] = 61000;
+ tcp_death_row.sysctl_max_tw_buckets = 180000;
+ sysctl_tcp_max_orphans = 4096 << (order - 4);
+ sysctl_max_syn_backlog = 1024;
+ } else if (order < 3) {
+- sysctl_local_port_range[0] = 1024 * (3 - order);
+ tcp_death_row.sysctl_max_tw_buckets >>= (3 - order);
+ sysctl_tcp_max_orphans >>= (3 - order);
+ sysctl_max_syn_backlog = 128;