]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Update 2.6.21 queue with DaveM's batch of patches
authorChris Wright <chrisw@sous-sol.org>
Thu, 7 Jun 2007 15:52:14 +0000 (08:52 -0700)
committerChris Wright <chrisw@sous-sol.org>
Thu, 7 Jun 2007 15:52:14 +0000 (08:52 -0700)
16 files changed:
queue-2.6.21/bluetooth-fix-locking-in-hci_sock_dev_event.patch [new file with mode: 0644]
queue-2.6.21/fix-af_unix-oops.patch [new file with mode: 0644]
queue-2.6.21/icmp-fix-icmp_errors_use_inbound_ifaddr-sysctl.patch [new file with mode: 0644]
queue-2.6.21/ipsec-fix-panic-when-using-inter-address-familiy-ipsec-on-loopback.patch [new file with mode: 0644]
queue-2.6.21/ipv4-correct-rp_filter-help-text.patch [new file with mode: 0644]
queue-2.6.21/ipv6-route-no-longer-handle-0-specially.patch [new file with mode: 0644]
queue-2.6.21/net-fix-bmsr_100-half-full-2-defines-in-linux-mii.h.patch [new file with mode: 0644]
queue-2.6.21/net-fix-race-condition-about-network-device-name-allocation.patch [new file with mode: 0644]
queue-2.6.21/net-parse-ip-port-strings-correctly-in-in4_pton.patch [new file with mode: 0644]
queue-2.6.21/net-wrong-timeout-value-in-sk_wait_data-v2.patch [new file with mode: 0644]
queue-2.6.21/series
queue-2.6.21/sparc-linux-always-started-with-9600-8n1.patch [new file with mode: 0644]
queue-2.6.21/sparc64-don-t-be-picky-about-virtual-dma-values-on-sun4v.patch [new file with mode: 0644]
queue-2.6.21/sparc64-fix-_page_exec_4u-check-in-sun4u-i-tlb-miss-handler.patch [new file with mode: 0644]
queue-2.6.21/sparc64-fix-two-bugs-wrt.-kernel-4mb-tsb.patch [new file with mode: 0644]
queue-2.6.21/tcp-use-default-32768-61000-outgoing-port-range-in-all-cases.patch [new file with mode: 0644]

diff --git a/queue-2.6.21/bluetooth-fix-locking-in-hci_sock_dev_event.patch b/queue-2.6.21/bluetooth-fix-locking-in-hci_sock_dev_event.patch
new file mode 100644 (file)
index 0000000..64b49b5
--- /dev/null
@@ -0,0 +1,54 @@
+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);
+       }
diff --git a/queue-2.6.21/fix-af_unix-oops.patch b/queue-2.6.21/fix-af_unix-oops.patch
new file mode 100644 (file)
index 0000000..527e253
--- /dev/null
@@ -0,0 +1,481 @@
+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');
+       }
diff --git a/queue-2.6.21/icmp-fix-icmp_errors_use_inbound_ifaddr-sysctl.patch b/queue-2.6.21/icmp-fix-icmp_errors_use_inbound_ifaddr-sysctl.patch
new file mode 100644 (file)
index 0000000..1439325
--- /dev/null
@@ -0,0 +1,44 @@
+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;
+       }
diff --git a/queue-2.6.21/ipsec-fix-panic-when-using-inter-address-familiy-ipsec-on-loopback.patch b/queue-2.6.21/ipsec-fix-panic-when-using-inter-address-familiy-ipsec-on-loopback.patch
new file mode 100644 (file)
index 0000000..3543494
--- /dev/null
@@ -0,0 +1,72 @@
+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;
+ }
diff --git a/queue-2.6.21/ipv4-correct-rp_filter-help-text.patch b/queue-2.6.21/ipv4-correct-rp_filter-help-text.patch
new file mode 100644 (file)
index 0000000..f802b54
--- /dev/null
@@ -0,0 +1,40 @@
+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.
diff --git a/queue-2.6.21/ipv6-route-no-longer-handle-0-specially.patch b/queue-2.6.21/ipv6-route-no-longer-handle-0-specially.patch
new file mode 100644 (file)
index 0000000..0144959
--- /dev/null
@@ -0,0 +1,39 @@
+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
diff --git a/queue-2.6.21/net-fix-bmsr_100-half-full-2-defines-in-linux-mii.h.patch b/queue-2.6.21/net-fix-bmsr_100-half-full-2-defines-in-linux-mii.h.patch
new file mode 100644 (file)
index 0000000..25c4a50
--- /dev/null
@@ -0,0 +1,30 @@
+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 */
diff --git a/queue-2.6.21/net-fix-race-condition-about-network-device-name-allocation.patch b/queue-2.6.21/net-fix-race-condition-about-network-device-name-allocation.patch
new file mode 100644 (file)
index 0000000..fee5168
--- /dev/null
@@ -0,0 +1,83 @@
+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. */
diff --git a/queue-2.6.21/net-parse-ip-port-strings-correctly-in-in4_pton.patch b/queue-2.6.21/net-parse-ip-port-strings-correctly-in-in4_pton.patch
new file mode 100644 (file)
index 0000000..165a7b0
--- /dev/null
@@ -0,0 +1,51 @@
+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;
diff --git a/queue-2.6.21/net-wrong-timeout-value-in-sk_wait_data-v2.patch b/queue-2.6.21/net-wrong-timeout-value-in-sk_wait_data-v2.patch
new file mode 100644 (file)
index 0000000..c50d555
--- /dev/null
@@ -0,0 +1,54 @@
+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;
index a14dce61db6000108cee8f4082f0b423178b9fa1..d2c95aad98e3d6530893f8f68757854bafb774c2 100644 (file)
@@ -39,3 +39,18 @@ cciss-fix-pci_driver.shutdown-while-device-is-still-active.patch
 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
diff --git a/queue-2.6.21/sparc-linux-always-started-with-9600-8n1.patch b/queue-2.6.21/sparc-linux-always-started-with-9600-8n1.patch
new file mode 100644 (file)
index 0000000..2f7e800
--- /dev/null
@@ -0,0 +1,44 @@
+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;
diff --git a/queue-2.6.21/sparc64-don-t-be-picky-about-virtual-dma-values-on-sun4v.patch b/queue-2.6.21/sparc64-don-t-be-picky-about-virtual-dma-values-on-sun4v.patch
new file mode 100644 (file)
index 0000000..6c84f00
--- /dev/null
@@ -0,0 +1,89 @@
+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) {
diff --git a/queue-2.6.21/sparc64-fix-_page_exec_4u-check-in-sun4u-i-tlb-miss-handler.patch b/queue-2.6.21/sparc64-fix-_page_exec_4u-check-in-sun4u-i-tlb-miss-handler.patch
new file mode 100644 (file)
index 0000000..1370f7d
--- /dev/null
@@ -0,0 +1,38 @@
+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
diff --git a/queue-2.6.21/sparc64-fix-two-bugs-wrt.-kernel-4mb-tsb.patch b/queue-2.6.21/sparc64-fix-two-bugs-wrt.-kernel-4mb-tsb.patch
new file mode 100644 (file)
index 0000000..32451fa
--- /dev/null
@@ -0,0 +1,116 @@
+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); \
diff --git a/queue-2.6.21/tcp-use-default-32768-61000-outgoing-port-range-in-all-cases.patch b/queue-2.6.21/tcp-use-default-32768-61000-outgoing-port-range-in-all-cases.patch
new file mode 100644 (file)
index 0000000..5dd92ed
--- /dev/null
@@ -0,0 +1,57 @@
+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;