]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.24 networking patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Fri, 7 Mar 2008 00:13:21 +0000 (16:13 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 7 Mar 2008 00:13:21 +0000 (16:13 -0800)
14 files changed:
queue-2.6.24/ipcomp-disable-bh-on-output-when-using-shared-tfm.patch [new file with mode: 0644]
queue-2.6.24/ipconfig-the-kernel-gets-no-ip-from-some-dhcp-servers.patch [new file with mode: 0644]
queue-2.6.24/ipv4-remove-ip_tos-setting-privilege-checks.patch [new file with mode: 0644]
queue-2.6.24/ipv6-dst_entry-leak-in-ip4ip6_err.patch [new file with mode: 0644]
queue-2.6.24/ipv6-fix-ipsec-datagram-fragmentation.patch [new file with mode: 0644]
queue-2.6.24/net-fix-race-in-dev_close.patch [new file with mode: 0644]
queue-2.6.24/net-messed-multicast-lists-after-dev_mc_sync-unsync.patch [new file with mode: 0644]
queue-2.6.24/niu-bump-driver-version-and-release-date.patch [new file with mode: 0644]
queue-2.6.24/niu-fix-bmac-alternate-mac-address-indexing.patch [new file with mode: 0644]
queue-2.6.24/niu-more-bmac-alt-mac-address-fixes.patch [new file with mode: 0644]
queue-2.6.24/series
queue-2.6.24/sparc-fix-link-errors-with-gcc-4.3.patch [new file with mode: 0644]
queue-2.6.24/sparc64-loosen-checks-in-exception-table-handling.patch [new file with mode: 0644]
queue-2.6.24/tcp-improve-ipv4-established-hash-function.patch [new file with mode: 0644]

diff --git a/queue-2.6.24/ipcomp-disable-bh-on-output-when-using-shared-tfm.patch b/queue-2.6.24/ipcomp-disable-bh-on-output-when-using-shared-tfm.patch
new file mode 100644 (file)
index 0000000..d818afa
--- /dev/null
@@ -0,0 +1,53 @@
+From 946e8e7fb6e81dfd313da2c6b02d0c11c7c6902b Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 5 Mar 2008 20:07:37 -0800
+Subject: IPCOMP: Disable BH on output when using shared tfm
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+Upstream commit: 21e43188f272c7fd9efc84b8244c0b1dfccaa105
+
+Because we use shared tfm objects in order to conserve memory,
+(each tfm requires 128K of vmalloc memory), BH needs to be turned
+off on output as that can occur in process context.
+
+Previously this was done implicitly by the xfrm output code.
+That was lost when it became lockless.  So we need to add the
+BH disabling to IPComp directly.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/ipcomp.c  |    5 ++++-
+ net/ipv6/ipcomp6.c |    2 ++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/ipcomp.c
++++ b/net/ipv4/ipcomp.c
+@@ -108,8 +108,11 @@ static int ipcomp_compress(struct xfrm_s
+       const int cpu = get_cpu();
+       u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu);
+       struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu);
+-      int err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
++      int err;
++      local_bh_disable();
++      err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
++      local_bh_enable();
+       if (err)
+               goto out;
+--- a/net/ipv6/ipcomp6.c
++++ b/net/ipv6/ipcomp6.c
+@@ -146,7 +146,9 @@ static int ipcomp6_output(struct xfrm_st
+       scratch = *per_cpu_ptr(ipcomp6_scratches, cpu);
+       tfm = *per_cpu_ptr(ipcd->tfms, cpu);
++      local_bh_disable();
+       err = crypto_comp_compress(tfm, start, plen, scratch, &dlen);
++      local_bh_enable();
+       if (err || (dlen + sizeof(*ipch)) >= plen) {
+               put_cpu();
+               goto out_ok;
diff --git a/queue-2.6.24/ipconfig-the-kernel-gets-no-ip-from-some-dhcp-servers.patch b/queue-2.6.24/ipconfig-the-kernel-gets-no-ip-from-some-dhcp-servers.patch
new file mode 100644 (file)
index 0000000..09018d2
--- /dev/null
@@ -0,0 +1,44 @@
+From 2cd00bc51627bac6fba4acb44a1965b625480aea Mon Sep 17 00:00:00 2001
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+Date: Wed, 5 Mar 2008 14:44:01 -0800
+Subject: IPCONFIG: The kernel gets no IP from some DHCP servers
+
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+
+Upstream commit: dea75bdfa57f75a7a7ec2961ec28db506c18e5db
+
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+
+Based upon a patch by Marcel Wappler:
+
+   This patch fixes a DHCP issue of the kernel: some DHCP servers
+   (i.e.  in the Linksys WRT54Gv5) are very strict about the contents
+   of the DHCPDISCOVER packet they receive from clients.
+
+   Table 5 in RFC2131 page 36 requests the fields 'ciaddr' and
+   'siaddr' MUST be set to '0'.  These DHCP servers ignore Linux
+   kernel's DHCP discovery packets with these two fields set to
+   '255.255.255.255' (in contrast to popular DHCP clients, such as
+   'dhclient' or 'udhcpc').  This leads to a not booting system.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/ipconfig.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/ipconfig.c
++++ b/net/ipv4/ipconfig.c
+@@ -739,9 +739,9 @@ static void __init ic_bootp_send_if(stru
+               printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
+               b->htype = dev->type; /* can cause undefined behavior */
+       }
++
++      /* server_ip and your_ip address are both already zero per RFC2131 */
+       b->hlen = dev->addr_len;
+-      b->your_ip = NONE;
+-      b->server_ip = NONE;
+       memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
+       b->secs = htons(jiffies_diff / HZ);
+       b->xid = d->xid;
diff --git a/queue-2.6.24/ipv4-remove-ip_tos-setting-privilege-checks.patch b/queue-2.6.24/ipv4-remove-ip_tos-setting-privilege-checks.patch
new file mode 100644 (file)
index 0000000..d55f2eb
--- /dev/null
@@ -0,0 +1,66 @@
+From df4e45bc4436402f56a2cb74fcb241a630cace35 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 5 Mar 2008 14:44:30 -0800
+Subject: IPV4: Remove IP_TOS setting privilege checks.
+
+From: David S. Miller <davem@davemloft.net>
+
+Upstream commit: e4f8b5d4edc1edb0709531bd1a342655d5e8b98e
+
+Various RFCs have all sorts of things to say about the CS field of the
+DSCP value.  In particular they try to make the distinction between
+values that should be used by "user applications" and things like
+routing daemons.
+
+This seems to have influenced the CAP_NET_ADMIN check which exists for
+IP_TOS socket option settings, but in fact it has an off-by-one error
+so it wasn't allowing CS5 which is meant for "user applications" as
+well.
+
+Further adding to the inconsistency and brokenness here, IPV6 does not
+validate the DSCP values specified for the IPV6_TCLASS socket option.
+
+The real actual uses of these TOS values are system specific in the
+final analysis, and these RFC recommendations are just that, "a
+recommendation".  In fact the standards very purposefully use
+"SHOULD" and "SHOULD NOT" when describing how these values can be
+used.
+
+In the final analysis the only clean way to provide consistency here
+is to remove the CAP_NET_ADMIN check.  The alternatives just don't
+work out:
+
+1) If we add the CAP_NET_ADMIN check to ipv6, this can break existing
+   setups.
+
+2) If we just fix the off-by-one error in the class comparison in
+   IPV4, certain DSCP values can be used in IPV6 but not IPV4 by
+   default.  So people will just ask for a sysctl asking to
+   override that.
+
+I checked several other freely available kernel trees and they
+do not make any privilege checks in this area like we do.  For
+the BSD stacks, this goes back all the way to Stevens Volume 2
+and beyond.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/ip_sockglue.c |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -514,11 +514,6 @@ static int do_ip_setsockopt(struct sock 
+                       val &= ~3;
+                       val |= inet->tos & 3;
+               }
+-              if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP &&
+-                  !capable(CAP_NET_ADMIN)) {
+-                      err = -EPERM;
+-                      break;
+-              }
+               if (inet->tos != val) {
+                       inet->tos = val;
+                       sk->sk_priority = rt_tos2priority(val);
diff --git a/queue-2.6.24/ipv6-dst_entry-leak-in-ip4ip6_err.patch b/queue-2.6.24/ipv6-dst_entry-leak-in-ip4ip6_err.patch
new file mode 100644 (file)
index 0000000..170043a
--- /dev/null
@@ -0,0 +1,32 @@
+From 81d94c3b06d77a06ce1b1d933a033e9f81250196 Mon Sep 17 00:00:00 2001
+From: Denis V. Lunev <den@openvz.org>
+Date: Wed, 5 Mar 2008 14:43:05 -0800
+Subject: IPV6: dst_entry leak in ip4ip6_err.
+
+From: Denis V. Lunev <den@openvz.org>
+
+Upstream commit: 9937ded8e44de8865cba1509d24eea9d350cebf0
+
+The result of the ip_route_output is not assigned to skb. This means that
+- it is leaked
+- possible OOPS below dereferrencing skb->dst
+- no ICMP message for this case
+
+Signed-off-by: Denis V. Lunev <den@openvz.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/ip6_tunnel.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -550,6 +550,7 @@ ip4ip6_err(struct sk_buff *skb, struct i
+                       ip_rt_put(rt);
+                       goto out;
+               }
++              skb2->dst = (struct dst_entry *)rt;
+       } else {
+               ip_rt_put(rt);
+               if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
diff --git a/queue-2.6.24/ipv6-fix-ipsec-datagram-fragmentation.patch b/queue-2.6.24/ipv6-fix-ipsec-datagram-fragmentation.patch
new file mode 100644 (file)
index 0000000..686f654
--- /dev/null
@@ -0,0 +1,65 @@
+From a107d70a9562f1bedeb405d9da27971c91a8db4f Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 5 Mar 2008 14:46:35 -0800
+Subject: IPV6: Fix IPsec datagram fragmentation
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+Upstream commits: 28a89453b1e8de8d777ad96fa1eef27b5d1ce074
+                  b5c15fc004ac83b7ad280acbe0fd4bbed7e2c8d4
+
+This is a long-standing bug in the IPsec IPv6 code that breaks
+when we emit a IPsec tunnel-mode datagram packet.  The problem
+is that the code the emits the packet assumes the IPv6 stack
+will fragment it later, but the IPv6 stack assumes that whoever
+is emitting the packet is going to pre-fragment the packet.
+
+In the long term we need to fix both sides, e.g., to get the
+datagram code to pre-fragment as well as to get the IPv6 stack
+to fragment locally generated tunnel-mode packet.
+
+For now this patch does the second part which should make it
+work for the IPsec host case.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/ip6_output.c   |    6 +++++-
+ net/ipv6/xfrm6_output.c |    2 +-
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -593,7 +593,7 @@ static int ip6_fragment(struct sk_buff *
+        * or if the skb it not generated by a local socket.  (This last
+        * check should be redundant, but it's free.)
+        */
+-      if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) {
++      if (!skb->local_df) {
+               skb->dev = skb->dst->dev;
+               icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
+               IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
+@@ -1389,6 +1389,10 @@ int ip6_push_pending_frames(struct sock 
+               tmp_skb->sk = NULL;
+       }
++      /* Allow local fragmentation. */
++      if (np->pmtudisc < IPV6_PMTUDISC_DO)
++              skb->local_df = 1;
++
+       ipv6_addr_copy(final_dst, &fl->fl6_dst);
+       __skb_pull(skb, skb_network_header_len(skb));
+       if (opt && opt->opt_flen)
+--- a/net/ipv6/xfrm6_output.c
++++ b/net/ipv6/xfrm6_output.c
+@@ -34,7 +34,7 @@ static int xfrm6_tunnel_check_size(struc
+       if (mtu < IPV6_MIN_MTU)
+               mtu = IPV6_MIN_MTU;
+-      if (skb->len > mtu) {
++      if (!skb->local_df && skb->len > mtu) {
+               skb->dev = dst->dev;
+               icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
+               ret = -EMSGSIZE;
diff --git a/queue-2.6.24/net-fix-race-in-dev_close.patch b/queue-2.6.24/net-fix-race-in-dev_close.patch
new file mode 100644 (file)
index 0000000..7c8f972
--- /dev/null
@@ -0,0 +1,47 @@
+From 6a3fa0fb2ef9530b7975ba1e6b2fed1d56bac4b0 Mon Sep 17 00:00:00 2001
+From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
+Date: Wed, 5 Mar 2008 14:42:41 -0800
+Subject: NET: Fix race in dev_close(). (Bug 9750)
+
+From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
+
+Upstream commit: d8b2a4d21e0b37b9669b202867bfef19f68f786a
+
+There is a race in Linux kernel file net/core/dev.c, function dev_close.
+The function calls function dev_deactivate, which calls function
+dev_watchdog_down that deletes the watchdog timer. However, after that, a
+driver can call netif_carrier_ok, which calls function
+__netdev_watchdog_up that can add the watchdog timer again. Function
+unregister_netdevice calls function dev_shutdown that traps the bug
+!timer_pending(&dev->watchdog_timer). Moving dev_deactivate after
+netif_running() has been cleared prevents function netif_carrier_on
+from calling __netdev_watchdog_up and adding the watchdog timer again.
+
+Signed-off-by: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/core/dev.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1068,8 +1068,6 @@ int dev_close(struct net_device *dev)
+        */
+       call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
+-      dev_deactivate(dev);
+-
+       clear_bit(__LINK_STATE_START, &dev->state);
+       /* Synchronize to scheduled poll. We cannot touch poll list,
+@@ -1080,6 +1078,8 @@ int dev_close(struct net_device *dev)
+        */
+       smp_mb__after_clear_bit(); /* Commit netif_running(). */
++      dev_deactivate(dev);
++
+       /*
+        *      Call the device specific close. This cannot fail.
+        *      Only if device is UP
diff --git a/queue-2.6.24/net-messed-multicast-lists-after-dev_mc_sync-unsync.patch b/queue-2.6.24/net-messed-multicast-lists-after-dev_mc_sync-unsync.patch
new file mode 100644 (file)
index 0000000..f56749d
--- /dev/null
@@ -0,0 +1,38 @@
+From ec568efa8caeb82724e623b6e3e1d33b9f94d28a Mon Sep 17 00:00:00 2001
+From: Jorge Boncompte [DTI2] <jorge@dti2.net>
+Date: Wed, 5 Mar 2008 14:47:01 -0800
+Subject: NET: Messed multicast lists after dev_mc_sync/unsync
+
+From: Jorge Boncompte [DTI2] <jorge@dti2.net>
+
+Upstream commit: 12aa343add3eced38a44bdb612b35fdf634d918c
+
+Commit a0a400d79e3dd7843e7e81baa3ef2957bdc292d0 ("[NET]: dev_mcast:
+add multicast list synchronization helpers") from you introduced a new
+field "da_synced" to struct dev_addr_list that is not properly
+initialized to 0. So when any of the current users (8021q, macvlan,
+mac80211) calls dev_mc_sync/unsync they mess the address list for both
+devices.
+
+The attached patch fixed it for me and avoid future problems.
+
+Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2906,7 +2906,7 @@ int __dev_addr_add(struct dev_addr_list 
+               }
+       }
+-      da = kmalloc(sizeof(*da), GFP_ATOMIC);
++      da = kzalloc(sizeof(*da), GFP_ATOMIC);
+       if (da == NULL)
+               return -ENOMEM;
+       memcpy(da->da_addr, addr, alen);
diff --git a/queue-2.6.24/niu-bump-driver-version-and-release-date.patch b/queue-2.6.24/niu-bump-driver-version-and-release-date.patch
new file mode 100644 (file)
index 0000000..77d12de
--- /dev/null
@@ -0,0 +1,29 @@
+From d7ffb010f44bbda0f6bc050a6584813adb380ecd Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 5 Mar 2008 14:49:01 -0800
+Subject: NIU: Bump driver version and release date.
+
+From: David S. Miller <davem@davemloft.net>
+
+Upstream commit: a442585952f137bd4cdb1f2f3166e4157d383b82
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/niu.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -33,8 +33,8 @@
+ #define DRV_MODULE_NAME               "niu"
+ #define PFX DRV_MODULE_NAME   ": "
+-#define DRV_MODULE_VERSION    "0.6"
+-#define DRV_MODULE_RELDATE    "January 5, 2008"
++#define DRV_MODULE_VERSION    "0.7"
++#define DRV_MODULE_RELDATE    "February 18, 2008"
+ static char version[] __devinitdata =
+       DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
diff --git a/queue-2.6.24/niu-fix-bmac-alternate-mac-address-indexing.patch b/queue-2.6.24/niu-fix-bmac-alternate-mac-address-indexing.patch
new file mode 100644 (file)
index 0000000..117bf10
--- /dev/null
@@ -0,0 +1,36 @@
+From 9cdaf6ea8d30b92017680e7a260fd127efdfb8c5 Mon Sep 17 00:00:00 2001
+From: Matheos Worku <matheos.worku@sun.com>
+Date: Wed, 5 Mar 2008 14:47:36 -0800
+Subject: NIU: Fix BMAC alternate MAC address indexing.
+
+From: Matheos Worku <matheos.worku@sun.com>
+
+Upstream commit: 3b5bcedeeb755b6e813537fcf4c32f010b490aef
+
+BMAC port alternate MAC address index needs to start at 1. Index 0 is
+used for the main MAC address.
+
+Signed-off-by: Matheos Worku <matheos.worku@sun.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/niu.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -5148,7 +5148,12 @@ static void niu_set_rx_mode(struct net_d
+                       index++;
+               }
+       } else {
+-              for (i = 0; i < niu_num_alt_addr(np); i++) {
++              int alt_start;
++              if (np->flags & NIU_FLAGS_XMAC)
++                      alt_start = 0;
++              else
++                      alt_start = 1;
++              for (i = alt_start; i < niu_num_alt_addr(np); i++) {
+                       err = niu_enable_alt_mac(np, i, 0);
+                       if (err)
+                               printk(KERN_WARNING PFX "%s: Error %d "
diff --git a/queue-2.6.24/niu-more-bmac-alt-mac-address-fixes.patch b/queue-2.6.24/niu-more-bmac-alt-mac-address-fixes.patch
new file mode 100644 (file)
index 0000000..ba403c8
--- /dev/null
@@ -0,0 +1,55 @@
+From 02a607fbf9210056bb65a8caaf5d867aa28bb0bb Mon Sep 17 00:00:00 2001
+From: Matheos Worku <Matheos.Worku@Sun.COM>
+Date: Wed, 5 Mar 2008 14:48:37 -0800
+Subject: NIU: More BMAC alt MAC address fixes.
+
+From: Matheos Worku <Matheos.Worku@Sun.COM>
+
+Upstream commit: fa907895b7b776208a1406efe5ba7ffe0f49f507
+
+From: Matheos Worku <Matheos.Worku@Sun.COM>
+
+1) niu_enable_alt_mac() needs to be adjusted so that the mask
+   is computed properly for the BMAC case.
+
+2) BMAC has 6 alt MAC addresses available, not 7.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/niu.c |    9 +++++----
+ drivers/net/niu.h |    2 +-
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/niu.c
++++ b/drivers/net/niu.c
+@@ -1616,12 +1616,13 @@ static int niu_enable_alt_mac(struct niu
+       if (index >= niu_num_alt_addr(np))
+               return -EINVAL;
+-      if (np->flags & NIU_FLAGS_XMAC)
++      if (np->flags & NIU_FLAGS_XMAC) {
+               reg = XMAC_ADDR_CMPEN;
+-      else
++              mask = 1 << index;
++      } else {
+               reg = BMAC_ADDR_CMPEN;
+-
+-      mask = 1 << index;
++              mask = 1 << (index + 1);
++      }
+       val = nr64_mac(reg);
+       if (on)
+--- a/drivers/net/niu.h
++++ b/drivers/net/niu.h
+@@ -499,7 +499,7 @@
+ #define BMAC_ADDR2                    0x00110UL
+ #define  BMAC_ADDR2_ADDR2             0x000000000000ffffULL
+-#define BMAC_NUM_ALT_ADDR             7
++#define BMAC_NUM_ALT_ADDR             6
+ #define BMAC_ALT_ADDR0(NUM)           (0x00118UL + (NUM)*0x18UL)
+ #define  BMAC_ALT_ADDR0_ADDR0         0x000000000000ffffULL
index e48c2765f63f269151ab2648dc2dac073216fdf3..123c19f09ac11eabbac10764a6d48cb891021824 100644 (file)
@@ -1 +1,14 @@
 revert-net-add-if_addrlabel.h-to-sanitized-headers.patch
+sparc64-loosen-checks-in-exception-table-handling.patch
+sparc-fix-link-errors-with-gcc-4.3.patch
+tcp-improve-ipv4-established-hash-function.patch
+niu-more-bmac-alt-mac-address-fixes.patch
+niu-fix-bmac-alternate-mac-address-indexing.patch
+niu-bump-driver-version-and-release-date.patch
+net-messed-multicast-lists-after-dev_mc_sync-unsync.patch
+net-fix-race-in-dev_close.patch
+ipv6-fix-ipsec-datagram-fragmentation.patch
+ipv6-dst_entry-leak-in-ip4ip6_err.patch
+ipv4-remove-ip_tos-setting-privilege-checks.patch
+ipconfig-the-kernel-gets-no-ip-from-some-dhcp-servers.patch
+ipcomp-disable-bh-on-output-when-using-shared-tfm.patch
diff --git a/queue-2.6.24/sparc-fix-link-errors-with-gcc-4.3.patch b/queue-2.6.24/sparc-fix-link-errors-with-gcc-4.3.patch
new file mode 100644 (file)
index 0000000..c571263
--- /dev/null
@@ -0,0 +1,533 @@
+From fb34bf951edd97633baa418da85feab42cd61d72 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Thu, 6 Mar 2008 14:47:51 -0800
+Subject: SPARC: Fix link errors with gcc-4.3
+
+From: David S. Miller <davem@davemloft.net>
+
+Upstream commit: f0e98c387e61de00646be31fab4c2fa0224e1efb
+
+Reported by Adrian Bunk.
+
+Just like in changeset a3f9985843b674cbcb58f39fab8416675e7ab842
+("[SPARC64]: Move kernel unaligned trap handlers into assembler
+file.") we have to move the assembler bits into a seperate
+asm file because as far as the compiler is concerned
+these inline bits we're doing in unaligned.c are unreachable.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc/kernel/Makefile    |    5 
+ arch/sparc/kernel/una_asm.S   |  153 +++++++++++++++++++++++++
+ arch/sparc/kernel/unaligned.c |  252 +++++++-----------------------------------
+ 3 files changed, 203 insertions(+), 207 deletions(-)
+
+--- a/arch/sparc/kernel/Makefile
++++ b/arch/sparc/kernel/Makefile
+@@ -1,4 +1,4 @@
+-# $Id: Makefile,v 1.62 2000/12/15 00:41:17 davem Exp $
++#
+ # Makefile for the linux kernel.
+ #
+@@ -12,7 +12,8 @@ obj-y    := entry.o wof.o wuf.o etrap.o 
+           sys_sparc.o sunos_asm.o systbls.o \
+           time.o windows.o cpu.o devices.o sclow.o \
+           tadpole.o tick14.o ptrace.o sys_solaris.o \
+-          unaligned.o muldiv.o semaphore.o prom.o of_device.o devres.o
++          unaligned.o una_asm.o muldiv.o semaphore.o \
++          prom.o of_device.o devres.o
+ devres-y = ../../../kernel/irq/devres.o
+--- /dev/null
++++ b/arch/sparc/kernel/una_asm.S
+@@ -0,0 +1,153 @@
++/* una_asm.S: Kernel unaligned trap assembler helpers.
++ *
++ * Copyright (C) 1996,2005,2008 David S. Miller (davem@davemloft.net)
++ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
++ */
++
++#include <linux/errno.h>
++
++      .text
++
++retl_efault:
++      retl
++       mov    -EFAULT, %o0
++
++      /* int __do_int_store(unsigned long *dst_addr, int size,
++       *                    unsigned long *src_val)
++       *
++       * %o0 = dest_addr
++       * %o1 = size
++       * %o2 = src_val
++       *
++       * Return '0' on success, -EFAULT on failure.
++       */
++      .globl  __do_int_store
++__do_int_store:
++      ld      [%o2], %g1
++      cmp     %1, 2
++      be      2f
++       cmp    %1, 4
++      be      1f
++       srl    %g1, 24, %g2
++      srl     %g1, 16, %g7
++4:    stb     %g2, [%o0]
++      srl     %g1, 8, %g2
++5:    stb     %g7, [%o0 + 1]
++      ld      [%o2 + 4], %g7
++6:    stb     %g2, [%o0 + 2]
++      srl     %g7, 24, %g2
++7:    stb     %g1, [%o0 + 3]
++      srl     %g7, 16, %g1
++8:    stb     %g2, [%o0 + 4]
++      srl     %g7, 8, %g2
++9:    stb     %g1, [%o0 + 5]
++10:   stb     %g2, [%o0 + 6]
++      b       0f
++11:    stb    %g7, [%o0 + 7]
++1:    srl     %g1, 16, %g7
++12:   stb     %g2, [%o0]
++      srl     %g1, 8, %g2
++13:   stb     %g7, [%o0 + 1]
++14:   stb     %g2, [%o0 + 2]
++      b       0f
++15:    stb    %g1, [%o0 + 3]
++2:    srl     %g1, 8, %g2
++16:   stb     %g2, [%o0]
++17:   stb     %g1, [%o0 + 1]
++0:    retl
++       mov    0, %o0
++
++      .section __ex_table,#alloc
++      .word   4b, retl_efault
++      .word   5b, retl_efault
++      .word   6b, retl_efault
++      .word   7b, retl_efault
++      .word   8b, retl_efault
++      .word   9b, retl_efault
++      .word   10b, retl_efault
++      .word   11b, retl_efault
++      .word   12b, retl_efault
++      .word   13b, retl_efault
++      .word   14b, retl_efault
++      .word   15b, retl_efault
++      .word   16b, retl_efault
++      .word   17b, retl_efault
++      .previous
++
++      /* int do_int_load(unsigned long *dest_reg, int size,
++       *                 unsigned long *saddr, int is_signed)
++       *
++       * %o0 = dest_reg
++       * %o1 = size
++       * %o2 = saddr
++       * %o3 = is_signed
++       *
++       * Return '0' on success, -EFAULT on failure.
++       */
++      .globl  do_int_load
++do_int_load:
++      cmp     %o1, 8
++      be      9f
++       cmp    %o1, 4
++      be      6f
++4:     ldub   [%o2], %g1
++5:    ldub    [%o2 + 1], %g2
++      sll     %g1, 8, %g1
++      tst     %o3
++      be      3f
++       or     %g1, %g2, %g1
++      sll     %g1, 16, %g1
++      sra     %g1, 16, %g1
++3:    b       0f
++       st     %g1, [%o0]
++6:    ldub    [%o2 + 1], %g2
++      sll     %g1, 24, %g1
++7:    ldub    [%o2 + 2], %g7
++      sll     %g2, 16, %g2
++8:    ldub    [%o2 + 3], %g3
++      sll     %g7, 8, %g7
++      or      %g3, %g2, %g3
++      or      %g7, %g3, %g7
++      or      %g1, %g7, %g1
++      b       0f
++       st     %g1, [%o0]
++9:    ldub    [%o2], %g1
++10:   ldub    [%o2 + 1], %g2
++      sll     %g1, 24, %g1
++11:   ldub    [%o2 + 2], %g7
++      sll     %g2, 16, %g2
++12:   ldub    [%o2 + 3], %g3
++      sll     %g7, 8, %g7
++      or      %g1, %g2, %g1
++      or      %g7, %g3, %g7
++      or      %g1, %g7, %g7
++13:   ldub    [%o2 + 4], %g1
++      st      %g7, [%o0]
++14:   ldub    [%o2 + 5], %g2
++      sll     %g1, 24, %g1
++15:   ldub    [%o2 + 6], %g7
++      sll     %g2, 16, %g2
++16:   ldub    [%o2 + 7], %g3
++      sll     %g7, 8, %g7
++      or      %g1, %g2, %g1
++      or      %g7, %g3, %g7
++      or      %g1, %g7, %g7
++      st      %g7, [%o0 + 4]
++0:    retl
++       mov    0, %o0
++
++      .section __ex_table,#alloc
++      .word   4b, retl_efault
++      .word   5b, retl_efault
++      .word   6b, retl_efault
++      .word   7b, retl_efault
++      .word   8b, retl_efault
++      .word   9b, retl_efault
++      .word   10b, retl_efault
++      .word   11b, retl_efault
++      .word   12b, retl_efault
++      .word   13b, retl_efault
++      .word   14b, retl_efault
++      .word   15b, retl_efault
++      .word   16b, retl_efault
++      .previous
+--- a/arch/sparc/kernel/unaligned.c
++++ b/arch/sparc/kernel/unaligned.c
+@@ -175,157 +175,31 @@ static void unaligned_panic(char *str)
+       panic(str);
+ }
+-#define do_integer_load(dest_reg, size, saddr, is_signed, errh) ({            \
+-__asm__ __volatile__ (                                                                \
+-      "cmp    %1, 8\n\t"                                                      \
+-      "be     9f\n\t"                                                         \
+-      " cmp   %1, 4\n\t"                                                      \
+-      "be     6f\n"                                                           \
+-"4:\t"        " ldub  [%2], %%l1\n"                                                   \
+-"5:\t"        "ldub   [%2 + 1], %%l2\n\t"                                             \
+-      "sll    %%l1, 8, %%l1\n\t"                                              \
+-      "tst    %3\n\t"                                                         \
+-      "be     3f\n\t"                                                         \
+-      " add   %%l1, %%l2, %%l1\n\t"                                           \
+-      "sll    %%l1, 16, %%l1\n\t"                                             \
+-      "sra    %%l1, 16, %%l1\n"                                               \
+-"3:\t"        "b      0f\n\t"                                                         \
+-      " st    %%l1, [%0]\n"                                                   \
+-"6:\t"        "ldub   [%2 + 1], %%l2\n\t"                                             \
+-      "sll    %%l1, 24, %%l1\n"                                               \
+-"7:\t"        "ldub   [%2 + 2], %%g7\n\t"                                             \
+-      "sll    %%l2, 16, %%l2\n"                                               \
+-"8:\t"        "ldub   [%2 + 3], %%g1\n\t"                                             \
+-      "sll    %%g7, 8, %%g7\n\t"                                              \
+-      "or     %%l1, %%l2, %%l1\n\t"                                           \
+-      "or     %%g7, %%g1, %%g7\n\t"                                           \
+-      "or     %%l1, %%g7, %%l1\n\t"                                           \
+-      "b      0f\n\t"                                                         \
+-      " st    %%l1, [%0]\n"                                                   \
+-"9:\t"        "ldub   [%2], %%l1\n"                                                   \
+-"10:\t"       "ldub   [%2 + 1], %%l2\n\t"                                             \
+-      "sll    %%l1, 24, %%l1\n"                                               \
+-"11:\t"       "ldub   [%2 + 2], %%g7\n\t"                                             \
+-      "sll    %%l2, 16, %%l2\n"                                               \
+-"12:\t"       "ldub   [%2 + 3], %%g1\n\t"                                             \
+-      "sll    %%g7, 8, %%g7\n\t"                                              \
+-      "or     %%l1, %%l2, %%l1\n\t"                                           \
+-      "or     %%g7, %%g1, %%g7\n\t"                                           \
+-      "or     %%l1, %%g7, %%g7\n"                                             \
+-"13:\t"       "ldub   [%2 + 4], %%l1\n\t"                                             \
+-      "st     %%g7, [%0]\n"                                                   \
+-"14:\t"       "ldub   [%2 + 5], %%l2\n\t"                                             \
+-      "sll    %%l1, 24, %%l1\n"                                               \
+-"15:\t"       "ldub   [%2 + 6], %%g7\n\t"                                             \
+-      "sll    %%l2, 16, %%l2\n"                                               \
+-"16:\t"       "ldub   [%2 + 7], %%g1\n\t"                                             \
+-      "sll    %%g7, 8, %%g7\n\t"                                              \
+-      "or     %%l1, %%l2, %%l1\n\t"                                           \
+-      "or     %%g7, %%g1, %%g7\n\t"                                           \
+-      "or     %%l1, %%g7, %%g7\n\t"                                           \
+-      "st     %%g7, [%0 + 4]\n"                                               \
+-"0:\n\n\t"                                                                    \
+-      ".section __ex_table,#alloc\n\t"                                        \
+-      ".word  4b, " #errh "\n\t"                                              \
+-      ".word  5b, " #errh "\n\t"                                              \
+-      ".word  6b, " #errh "\n\t"                                              \
+-      ".word  7b, " #errh "\n\t"                                              \
+-      ".word  8b, " #errh "\n\t"                                              \
+-      ".word  9b, " #errh "\n\t"                                              \
+-      ".word  10b, " #errh "\n\t"                                             \
+-      ".word  11b, " #errh "\n\t"                                             \
+-      ".word  12b, " #errh "\n\t"                                             \
+-      ".word  13b, " #errh "\n\t"                                             \
+-      ".word  14b, " #errh "\n\t"                                             \
+-      ".word  15b, " #errh "\n\t"                                             \
+-      ".word  16b, " #errh "\n\n\t"                                           \
+-      ".previous\n\t"                                                         \
+-      : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed)            \
+-      : "l1", "l2", "g7", "g1", "cc");                                        \
+-})
+-      
+-#define store_common(dst_addr, size, src_val, errh) ({                                \
+-__asm__ __volatile__ (                                                                \
+-      "ld     [%2], %%l1\n"                                                   \
+-      "cmp    %1, 2\n\t"                                                      \
+-      "be     2f\n\t"                                                         \
+-      " cmp   %1, 4\n\t"                                                      \
+-      "be     1f\n\t"                                                         \
+-      " srl   %%l1, 24, %%l2\n\t"                                             \
+-      "srl    %%l1, 16, %%g7\n"                                               \
+-"4:\t"        "stb    %%l2, [%0]\n\t"                                                 \
+-      "srl    %%l1, 8, %%l2\n"                                                \
+-"5:\t"        "stb    %%g7, [%0 + 1]\n\t"                                             \
+-      "ld     [%2 + 4], %%g7\n"                                               \
+-"6:\t"        "stb    %%l2, [%0 + 2]\n\t"                                             \
+-      "srl    %%g7, 24, %%l2\n"                                               \
+-"7:\t"        "stb    %%l1, [%0 + 3]\n\t"                                             \
+-      "srl    %%g7, 16, %%l1\n"                                               \
+-"8:\t"        "stb    %%l2, [%0 + 4]\n\t"                                             \
+-      "srl    %%g7, 8, %%l2\n"                                                \
+-"9:\t"        "stb    %%l1, [%0 + 5]\n"                                               \
+-"10:\t"       "stb    %%l2, [%0 + 6]\n\t"                                             \
+-      "b      0f\n"                                                           \
+-"11:\t"       " stb   %%g7, [%0 + 7]\n"                                               \
+-"1:\t"        "srl    %%l1, 16, %%g7\n"                                               \
+-"12:\t"       "stb    %%l2, [%0]\n\t"                                                 \
+-      "srl    %%l1, 8, %%l2\n"                                                \
+-"13:\t"       "stb    %%g7, [%0 + 1]\n"                                               \
+-"14:\t"       "stb    %%l2, [%0 + 2]\n\t"                                             \
+-      "b      0f\n"                                                           \
+-"15:\t"       " stb   %%l1, [%0 + 3]\n"                                               \
+-"2:\t"        "srl    %%l1, 8, %%l2\n"                                                \
+-"16:\t"       "stb    %%l2, [%0]\n"                                                   \
+-"17:\t"       "stb    %%l1, [%0 + 1]\n"                                               \
+-"0:\n\n\t"                                                                    \
+-      ".section __ex_table,#alloc\n\t"                                        \
+-      ".word  4b, " #errh "\n\t"                                              \
+-      ".word  5b, " #errh "\n\t"                                              \
+-      ".word  6b, " #errh "\n\t"                                              \
+-      ".word  7b, " #errh "\n\t"                                              \
+-      ".word  8b, " #errh "\n\t"                                              \
+-      ".word  9b, " #errh "\n\t"                                              \
+-      ".word  10b, " #errh "\n\t"                                             \
+-      ".word  11b, " #errh "\n\t"                                             \
+-      ".word  12b, " #errh "\n\t"                                             \
+-      ".word  13b, " #errh "\n\t"                                             \
+-      ".word  14b, " #errh "\n\t"                                             \
+-      ".word  15b, " #errh "\n\t"                                             \
+-      ".word  16b, " #errh "\n\t"                                             \
+-      ".word  17b, " #errh "\n\n\t"                                           \
+-      ".previous\n\t"                                                         \
+-      : : "r" (dst_addr), "r" (size), "r" (src_val)                           \
+-      : "l1", "l2", "g7", "g1", "cc");                                        \
+-})
+-
+-#define do_integer_store(reg_num, size, dst_addr, regs, errh) ({              \
+-      unsigned long *src_val;                                                 \
+-      static unsigned long zero[2] = { 0, };                                  \
+-                                                                              \
+-      if (reg_num) src_val = fetch_reg_addr(reg_num, regs);                   \
+-      else {                                                                  \
+-              src_val = &zero[0];                                             \
+-              if (size == 8)                                                  \
+-                      zero[1] = fetch_reg(1, regs);                           \
+-      }                                                                       \
+-      store_common(dst_addr, size, src_val, errh);                            \
+-})
++/* una_asm.S */
++extern int do_int_load(unsigned long *dest_reg, int size,
++                     unsigned long *saddr, int is_signed);
++extern int __do_int_store(unsigned long *dst_addr, int size,
++                        unsigned long *src_val);
++
++static int do_int_store(int reg_num, int size, unsigned long *dst_addr,
++                      struct pt_regs *regs)
++{
++      unsigned long zero[2] = { 0, 0 };
++      unsigned long *src_val;
++
++      if (reg_num)
++              src_val = fetch_reg_addr(reg_num, regs);
++      else {
++              src_val = &zero[0];
++              if (size == 8)
++                      zero[1] = fetch_reg(1, regs);
++      }
++      return __do_int_store(dst_addr, size, src_val);
++}
+ extern void smp_capture(void);
+ extern void smp_release(void);
+-#define do_atomic(srcdest_reg, mem, errh) ({                                  \
+-      unsigned long flags, tmp;                                               \
+-                                                                              \
+-      smp_capture();                                                          \
+-      local_irq_save(flags);                                                  \
+-      tmp = *srcdest_reg;                                                     \
+-      do_integer_load(srcdest_reg, 4, mem, 0, errh);                          \
+-      store_common(mem, 4, &tmp, errh);                                       \
+-      local_irq_restore(flags);                                               \
+-      smp_release();                                                          \
+-})
+-
+ static inline void advance(struct pt_regs *regs)
+ {
+       regs->pc   = regs->npc;
+@@ -342,9 +216,7 @@ static inline int ok_for_kernel(unsigned
+       return !floating_point_load_or_store_p(insn);
+ }
+-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
+-
+-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
++static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+ {
+       unsigned long g2 = regs->u_regs [UREG_G2];
+       unsigned long fixup = search_extables_range(regs->pc, &g2);
+@@ -379,48 +251,34 @@ asmlinkage void kernel_unaligned_trap(st
+               printk("Unsupported unaligned load/store trap for kernel at <%08lx>.\n",
+                      regs->pc);
+               unaligned_panic("Wheee. Kernel does fpu/atomic unaligned load/store.");
+-
+-              __asm__ __volatile__ ("\n"
+-"kernel_unaligned_trap_fault:\n\t"
+-              "mov    %0, %%o0\n\t"
+-              "call   kernel_mna_trap_fault\n\t"
+-              " mov   %1, %%o1\n\t"
+-              :
+-              : "r" (regs), "r" (insn)
+-              : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+-                "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+       } else {
+               unsigned long addr = compute_effective_address(regs, insn);
++              int err;
+ #ifdef DEBUG_MNA
+               printk("KMNA: pc=%08lx [dir=%s addr=%08lx size=%d] retpc[%08lx]\n",
+                      regs->pc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
+ #endif
+-              switch(dir) {
++              switch (dir) {
+               case load:
+-                      do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+-                                      size, (unsigned long *) addr,
+-                                      decode_signedness(insn),
+-                                      kernel_unaligned_trap_fault);
++                      err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
++                                                       regs),
++                                        size, (unsigned long *) addr,
++                                        decode_signedness(insn));
+                       break;
+               case store:
+-                      do_integer_store(((insn>>25)&0x1f), size,
+-                                       (unsigned long *) addr, regs,
+-                                       kernel_unaligned_trap_fault);
+-                      break;
+-#if 0 /* unsupported */
+-              case both:
+-                      do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
+-                                (unsigned long *) addr,
+-                                kernel_unaligned_trap_fault);
++                      err = do_int_store(((insn>>25)&0x1f), size,
++                                         (unsigned long *) addr, regs);
+                       break;
+-#endif
+               default:
+                       panic("Impossible kernel unaligned trap.");
+                       /* Not reached... */
+               }
+-              advance(regs);
++              if (err)
++                      kernel_mna_trap_fault(regs, insn);
++              else
++                      advance(regs);
+       }
+ }
+@@ -459,9 +317,7 @@ static inline int ok_for_user(struct pt_
+       return 0;
+ }
+-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("user_mna_trap_fault");
+-
+-void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
++static void user_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+ {
+       siginfo_t info;
+@@ -485,7 +341,7 @@ asmlinkage void user_unaligned_trap(stru
+       if(!ok_for_user(regs, insn, dir)) {
+               goto kill_user;
+       } else {
+-              int size = decode_access_size(insn);
++              int err, size = decode_access_size(insn);
+               unsigned long addr;
+               if(floating_point_load_or_store_p(insn)) {
+@@ -496,48 +352,34 @@ asmlinkage void user_unaligned_trap(stru
+               addr = compute_effective_address(regs, insn);
+               switch(dir) {
+               case load:
+-                      do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+-                                      size, (unsigned long *) addr,
+-                                      decode_signedness(insn),
+-                                      user_unaligned_trap_fault);
++                      err = do_int_load(fetch_reg_addr(((insn>>25)&0x1f),
++                                                       regs),
++                                        size, (unsigned long *) addr,
++                                        decode_signedness(insn));
+                       break;
+               case store:
+-                      do_integer_store(((insn>>25)&0x1f), size,
+-                                       (unsigned long *) addr, regs,
+-                                       user_unaligned_trap_fault);
++                      err = do_int_store(((insn>>25)&0x1f), size,
++                                         (unsigned long *) addr, regs);
+                       break;
+               case both:
+-#if 0 /* unsupported */
+-                      do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
+-                                (unsigned long *) addr,
+-                                user_unaligned_trap_fault);
+-#else
+                       /*
+                        * This was supported in 2.4. However, we question
+                        * the value of SWAP instruction across word boundaries.
+                        */
+                       printk("Unaligned SWAP unsupported.\n");
+-                      goto kill_user;
+-#endif
++                      err = -EFAULT;
+                       break;
+               default:
+                       unaligned_panic("Impossible user unaligned trap.");
+-
+-                      __asm__ __volatile__ ("\n"
+-"user_unaligned_trap_fault:\n\t"
+-                      "mov    %0, %%o0\n\t"
+-                      "call   user_mna_trap_fault\n\t"
+-                      " mov   %1, %%o1\n\t"
+-                      :
+-                      : "r" (regs), "r" (insn)
+-                      : "o0", "o1", "o2", "o3", "o4", "o5", "o7",
+-                        "g1", "g2", "g3", "g4", "g5", "g7", "cc");
+                       goto out;
+               }
+-              advance(regs);
++              if (err)
++                      goto kill_user;
++              else
++                      advance(regs);
+               goto out;
+       }
diff --git a/queue-2.6.24/sparc64-loosen-checks-in-exception-table-handling.patch b/queue-2.6.24/sparc64-loosen-checks-in-exception-table-handling.patch
new file mode 100644 (file)
index 0000000..bc7a24d
--- /dev/null
@@ -0,0 +1,65 @@
+From a015b781cfa15853ff6423d4c07baf6e41f664dd Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Thu, 6 Mar 2008 14:47:20 -0800
+Subject: SPARC64: Loosen checks in exception table handling.
+
+From: David S. Miller <davem@davemloft.net>
+
+Upstream commits: 622eaec613130e6ea78f2a5d5070e3278b21cd8f
+                  be71716e464f4ea38f08034dc666f2feb55535d9
+
+Some parts of the kernel now do things like do *_user() accesses while
+set_fs(KERNEL_DS) that fault on purpose.
+
+See, for example, the code added by changeset
+a0c1e9073ef7428a14309cba010633a6cd6719ea ("futex: runtime enable pi
+and robust functionality").
+
+That trips up the ASI sanity checking we make in do_kernel_fault().
+
+Just remove it for now.  Maybe we can add it back later with an added
+conditional which looks at the current get_fs() value.
+
+Also, because of the new futex validation init handler, we have
+to accept faults in init section text as well as the normal
+kernel text.
+
+Thanks to Tom Callaway for the bug report.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc64/mm/fault.c |   14 +++-----------
+ 1 file changed, 3 insertions(+), 11 deletions(-)
+
+--- a/arch/sparc64/mm/fault.c
++++ b/arch/sparc64/mm/fault.c
+@@ -244,16 +244,8 @@ static void do_kernel_fault(struct pt_re
+       if (regs->tstate & TSTATE_PRIV) {
+               const struct exception_table_entry *entry;
+-              if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
+-                      if (insn & 0x2000)
+-                              asi = (regs->tstate >> 24);
+-                      else
+-                              asi = (insn >> 5);
+-              }
+-      
+-              /* Look in asi.h: All _S asis have LS bit set */
+-              if ((asi & 0x1) &&
+-                  (entry = search_exception_tables(regs->tpc))) {
++              entry = search_exception_tables(regs->tpc);
++              if (entry) {
+                       regs->tpc = entry->fixup;
+                       regs->tnpc = regs->tpc + 4;
+                       return;
+@@ -294,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fau
+               unsigned long tpc = regs->tpc;
+               /* Sanity check the PC. */
+-              if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
++              if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
+                   (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
+                       /* Valid, no problems... */
+               } else {
diff --git a/queue-2.6.24/tcp-improve-ipv4-established-hash-function.patch b/queue-2.6.24/tcp-improve-ipv4-established-hash-function.patch
new file mode 100644 (file)
index 0000000..19c3752
--- /dev/null
@@ -0,0 +1,50 @@
+From bd8d97c0139013b2976eb5e0905263ab2e8d93e8 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 5 Mar 2008 14:49:24 -0800
+Subject: TCP: Improve ipv4 established hash function.
+
+From: David S. Miller <davem@davemloft.net>
+
+Upstream commit: 7adc3830f90df04a13366914d80a3ed407db5381
+
+If all of the entropy is in the local and foreign addresses,
+but xor'ing together would cancel out that entropy, the
+current hash performs poorly.
+
+Suggested by Cosmin Ratiu:
+
+       Basically, the situation is as follows: There is a client
+       machine and a server machine. Both create 15000 virtual
+       interfaces, open up a socket for each pair of interfaces and
+       do SIP traffic. By profiling I noticed that there is a lot of
+       time spent walking the established hash chains with this
+       particular setup.
+
+       The addresses were distributed like this: client interfaces
+       were 198.18.0.1/16 with increments of 1 and server interfaces
+       were 198.18.128.1/16 with increments of 1. As I said, there
+       were 15000 interfaces. Source and destination ports were 5060
+       for each connection.  So in this case, ports don't matter for
+       hashing purposes, and the bits from the address pairs used
+       cancel each other, meaning there are no differences in the
+       whole lot of pairs, so they all end up in the same hash chain.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/inet_sock.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/include/net/inet_sock.h
++++ b/include/net/inet_sock.h
+@@ -175,7 +175,8 @@ extern void build_ehash_secret(void);
+ static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport,
+                                       const __be32 faddr, const __be16 fport)
+ {
+-      return jhash_2words((__force __u32) laddr ^ (__force __u32) faddr,
++      return jhash_3words((__force __u32) laddr,
++                          (__force __u32) faddr,
+                           ((__u32) lport) << 16 | (__force __u32)fport,
+                           inet_ehash_secret);
+ }