From fbc8ccb3fbe661f5219e34fd08a502d1c6d09696 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 May 2010 10:43:46 -0700 Subject: [PATCH] .33 network and sparc patches --- ...ther-fix-autosuspend-for-mbm-devices.patch | 34 +++ ...ix-oops-during-ieee802154_sock_ioctl.patch | 39 ++++ ...nd_response-transport-header-setting.patch | 40 ++++ ...-from-tcp_collapse-when-using-splice.patch | 34 +++ ...nversion-while-call-sk-sk_data_ready.patch | 79 +++++++ ...ps-when-sending-queued-asconf-chunks.patch | 154 +++++++++++++ ...tential-reference-of-a-freed-pointer.patch | 36 +++ ...it-ack-chunk-length-correctly-is-set.patch | 156 +++++++++++++ ...les-should-be-in-bh_disabled-section.patch | 46 ++++ queue-2.6.33/series | 19 ++ ..._local_irq_save-to-cooperate-in-nmis.patch | 61 +++++ ...-hardirq-tracing-in-trap-return-path.patch | 43 ++++ ...ry-leak-in-pci_register_iommu_region.patch | 50 +++++ .../sparc64-fix-preempt_active-value.patch | 29 +++ ...gs-in-decode_access_size-error-paths.patch | 45 ++++ ...64-use-kstack_valid-in-die_if_kernel.patch | 69 ++++++ ...-prior-to-entering-networked-mode-v3.patch | 208 ++++++++++++++++++ queue-2.6.33/tun-orphan-an-skb-on-tx.patch | 58 +++++ ...fix-for-unicast-rx-path-optimization.patch | 57 +++++ ...-to-prevent-panic-on-rmmod-hw_driver.patch | 42 ++++ 20 files changed, 1299 insertions(+) create mode 100644 queue-2.6.33/cdc_ether-fix-autosuspend-for-mbm-devices.patch create mode 100644 queue-2.6.33/ieee802154-fix-oops-during-ieee802154_sock_ioctl.patch create mode 100644 queue-2.6.33/ipv6-fix-tcp_v6_send_response-transport-header-setting.patch create mode 100644 queue-2.6.33/net-fix-oops-from-tcp_collapse-when-using-splice.patch create mode 100644 queue-2.6.33/sctp-avoid-irq-lock-inversion-while-call-sk-sk_data_ready.patch create mode 100644 queue-2.6.33/sctp-fix-oops-when-sending-queued-asconf-chunks.patch create mode 100644 queue-2.6.33/sctp-fix-potential-reference-of-a-freed-pointer.patch create mode 100644 queue-2.6.33/sctp-fix-to-calc-the-init-init-ack-chunk-length-correctly-is-set.patch create mode 100644 queue-2.6.33/sctp-per_cpu-variables-should-be-in-bh_disabled-section.patch create mode 100644 queue-2.6.33/sparc64-adjust-__raw_local_irq_save-to-cooperate-in-nmis.patch create mode 100644 queue-2.6.33/sparc64-fix-hardirq-tracing-in-trap-return-path.patch create mode 100644 queue-2.6.33/sparc64-fix-memory-leak-in-pci_register_iommu_region.patch create mode 100644 queue-2.6.33/sparc64-fix-preempt_active-value.patch create mode 100644 queue-2.6.33/sparc64-use-correct-pt_regs-in-decode_access_size-error-paths.patch create mode 100644 queue-2.6.33/sparc64-use-kstack_valid-in-die_if_kernel.patch create mode 100644 queue-2.6.33/tipc-fix-oops-on-send-prior-to-entering-networked-mode-v3.patch create mode 100644 queue-2.6.33/tun-orphan-an-skb-on-tx.patch create mode 100644 queue-2.6.33/udp-fix-for-unicast-rx-path-optimization.patch create mode 100644 queue-2.6.33/wan-flush-tx_queue-in-hdlc_ppp-to-prevent-panic-on-rmmod-hw_driver.patch diff --git a/queue-2.6.33/cdc_ether-fix-autosuspend-for-mbm-devices.patch b/queue-2.6.33/cdc_ether-fix-autosuspend-for-mbm-devices.patch new file mode 100644 index 00000000000..0b432e2c534 --- /dev/null +++ b/queue-2.6.33/cdc_ether-fix-autosuspend-for-mbm-devices.patch @@ -0,0 +1,34 @@ +From 5b2882f368eb7f33ab814b709b2db52fc5ed1b14 Mon Sep 17 00:00:00 2001 +From: Torgny Johansson +Date: Tue, 27 Apr 2010 17:07:40 -0700 +Subject: cdc_ether: fix autosuspend for mbm devices + + +From: Torgny Johansson + +[ Upstream commit 55964d72d63b15df49a5df11ef91dc8601270815 ] + +Autosuspend works until you bring the wwan interface up, then the +device does not enter autosuspend anymore. + +The following patch fixes the problem by setting the .manage_power +field in the mbm_info struct to the same as in the cdc_info struct +(cdc_manager_power). + +Signed-off-by: Torgny Johansson +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_ether.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -433,6 +433,7 @@ static const struct driver_info mbm_info + .bind = cdc_bind, + .unbind = usbnet_cdc_unbind, + .status = cdc_status, ++ .manage_power = cdc_manage_power, + }; + + /*-------------------------------------------------------------------------*/ diff --git a/queue-2.6.33/ieee802154-fix-oops-during-ieee802154_sock_ioctl.patch b/queue-2.6.33/ieee802154-fix-oops-during-ieee802154_sock_ioctl.patch new file mode 100644 index 00000000000..56fe61bb423 --- /dev/null +++ b/queue-2.6.33/ieee802154-fix-oops-during-ieee802154_sock_ioctl.patch @@ -0,0 +1,39 @@ +From 69764660ad1f2e3a1d644879688bdbc369a4140e Mon Sep 17 00:00:00 2001 +From: Stefan Schmidt +Date: Mon, 26 Apr 2010 11:20:32 -0700 +Subject: ieee802154: Fix oops during ieee802154_sock_ioctl + + +From: Stefan Schmidt + +[ Upstream commit 93c0c8b4a5a174645550d444bd5c3ff0cccf74cb ] + +Trying to run izlisten (from lowpan-tools tests) on a device that does not +exists I got the oops below. The problem is that we are using get_dev_by_name +without checking if we really get a device back. We don't in this case and +writing to dev->type generates this oops. + +[Oops code removed by Dmitry Eremin-Solenikov] + +If possible this patch should be applied to the current -rc fixes branch. + +Signed-off-by: Stefan Schmidt +Signed-off-by: Dmitry Eremin-Solenikov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ieee802154/af_ieee802154.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/ieee802154/af_ieee802154.c ++++ b/net/ieee802154/af_ieee802154.c +@@ -147,6 +147,9 @@ static int ieee802154_dev_ioctl(struct s + dev_load(sock_net(sk), ifr.ifr_name); + dev = dev_get_by_name(sock_net(sk), ifr.ifr_name); + ++ if (!dev) ++ return -ENODEV; ++ + if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl) + ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd); + diff --git a/queue-2.6.33/ipv6-fix-tcp_v6_send_response-transport-header-setting.patch b/queue-2.6.33/ipv6-fix-tcp_v6_send_response-transport-header-setting.patch new file mode 100644 index 00000000000..84803b54108 --- /dev/null +++ b/queue-2.6.33/ipv6-fix-tcp_v6_send_response-transport-header-setting.patch @@ -0,0 +1,40 @@ +From e3f67eeca10790018054e4ddb7b42997a9c7237d Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 21 Apr 2010 00:47:15 -0700 +Subject: ipv6: Fix tcp_v6_send_response transport header setting. + + +From: Herbert Xu + +[ Upstream commit 6651ffc8e8bdd5fb4b7d1867c6cfebb4f309512c ] + +My recent patch to remove the open-coded checksum sequence in +tcp_v6_send_response broke it as we did not set the transport +header pointer on the new packet. + +Actually, there is code there trying to set the transport +header properly, but it sets it for the wrong skb ('skb' +instead of 'buff'). + +This bug was introduced by commit +a8fdf2b331b38d61fb5f11f3aec4a4f9fb2dedcb ("ipv6: Fix +tcp_v6_send_response(): it didn't set skb transport header") + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/tcp_ipv6.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1006,7 +1006,7 @@ static void tcp_v6_send_response(struct + skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); + + t1 = (struct tcphdr *) skb_push(buff, tot_len); +- skb_reset_transport_header(skb); ++ skb_reset_transport_header(buff); + + /* Swap the send and the receive. */ + memset(t1, 0, sizeof(*t1)); diff --git a/queue-2.6.33/net-fix-oops-from-tcp_collapse-when-using-splice.patch b/queue-2.6.33/net-fix-oops-from-tcp_collapse-when-using-splice.patch new file mode 100644 index 00000000000..8ac597ca2f5 --- /dev/null +++ b/queue-2.6.33/net-fix-oops-from-tcp_collapse-when-using-splice.patch @@ -0,0 +1,34 @@ +From 93ef635335d69068b8de53bf07cb82c28f52a6bd Mon Sep 17 00:00:00 2001 +From: Steven J. Magnani +Date: Tue, 30 Mar 2010 13:56:01 -0700 +Subject: net: Fix oops from tcp_collapse() when using splice() + + +From: Steven J. Magnani + +[ Upstream commit baff42ab1494528907bf4d5870359e31711746ae ] + +tcp_read_sock() can have a eat skbs without immediately advancing copied_seq. +This can cause a panic in tcp_collapse() if it is called as a result +of the recv_actor dropping the socket lock. + +A userspace program that splices data from a socket to either another +socket or to a file can trigger this bug. + +Signed-off-by: Steven J. Magnani +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -1368,6 +1368,7 @@ int tcp_read_sock(struct sock *sk, read_ + sk_eat_skb(sk, skb, 0); + if (!desc->count) + break; ++ tp->copied_seq = seq; + } + tp->copied_seq = seq; + diff --git a/queue-2.6.33/sctp-avoid-irq-lock-inversion-while-call-sk-sk_data_ready.patch b/queue-2.6.33/sctp-avoid-irq-lock-inversion-while-call-sk-sk_data_ready.patch new file mode 100644 index 00000000000..cf2f7003bdf --- /dev/null +++ b/queue-2.6.33/sctp-avoid-irq-lock-inversion-while-call-sk-sk_data_ready.patch @@ -0,0 +1,79 @@ +From 8ee41032d070157c8457b443c08d31e2630fc977 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Wed, 28 Apr 2010 08:47:18 +0000 +Subject: sctp: avoid irq lock inversion while call sk->sk_data_ready() + + +From: Wei Yongjun + +[ Upstream commit 561b1733a465cf9677356b40c27653dd45f1ac56 ] + +sk->sk_data_ready() of sctp socket can be called from both BH and non-BH +contexts, but the default sk->sk_data_ready(), sock_def_readable(), can +not be used in this case. Therefore, we have to make a new function +sctp_data_ready() to grab sk->sk_data_ready() with BH disabling. + +========================================================= +[ INFO: possible irq lock inversion dependency detected ] +2.6.33-rc6 #129 +--------------------------------------------------------- +sctp_darn/1517 just changed the state of lock: + (clock-AF_INET){++.?..}, at: [] sock_def_readable+0x20/0x80 +but this lock took another, SOFTIRQ-unsafe lock in the past: + (slock-AF_INET){+.-...} + +and interrupts could create inverse lock ordering between them. + +other info that might help us debug this: +1 lock held by sctp_darn/1517: + #0: (sk_lock-AF_INET){+.+.+.}, at: [] sctp_sendmsg+0x23d/0xc00 [sctp] + +Signed-off-by: Wei Yongjun +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sctp/sctp.h | 1 + + net/sctp/endpointola.c | 1 + + net/sctp/socket.c | 10 ++++++++++ + 3 files changed, 12 insertions(+) + +--- a/include/net/sctp/sctp.h ++++ b/include/net/sctp/sctp.h +@@ -128,6 +128,7 @@ extern int sctp_register_pf(struct sctp_ + int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb); + int sctp_inet_listen(struct socket *sock, int backlog); + void sctp_write_space(struct sock *sk); ++void sctp_data_ready(struct sock *sk, int len); + unsigned int sctp_poll(struct file *file, struct socket *sock, + poll_table *wait); + void sctp_sock_rfree(struct sk_buff *skb); +--- a/net/sctp/endpointola.c ++++ b/net/sctp/endpointola.c +@@ -144,6 +144,7 @@ static struct sctp_endpoint *sctp_endpoi + /* Use SCTP specific send buffer space queues. */ + ep->sndbuf_policy = sctp_sndbuf_policy; + ++ sk->sk_data_ready = sctp_data_ready; + sk->sk_write_space = sctp_write_space; + sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -6188,6 +6188,16 @@ do_nonblock: + goto out; + } + ++void sctp_data_ready(struct sock *sk, int len) ++{ ++ read_lock_bh(&sk->sk_callback_lock); ++ if (sk_has_sleeper(sk)) ++ wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN | ++ POLLRDNORM | POLLRDBAND); ++ sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); ++ read_unlock_bh(&sk->sk_callback_lock); ++} ++ + /* If socket sndbuf has changed, wake up all per association waiters. */ + void sctp_write_space(struct sock *sk) + { diff --git a/queue-2.6.33/sctp-fix-oops-when-sending-queued-asconf-chunks.patch b/queue-2.6.33/sctp-fix-oops-when-sending-queued-asconf-chunks.patch new file mode 100644 index 00000000000..5d0991f5500 --- /dev/null +++ b/queue-2.6.33/sctp-fix-oops-when-sending-queued-asconf-chunks.patch @@ -0,0 +1,154 @@ +From 644ff90a27bef443c97e1bf2b322f1de44f02e64 Mon Sep 17 00:00:00 2001 +From: Vlad Yasevich +Date: Wed, 28 Apr 2010 08:47:22 +0000 +Subject: sctp: Fix oops when sending queued ASCONF chunks + + +From: Vlad Yasevich + +[ Upstream commit c0786693404cffd80ca3cb6e75ee7b35186b2825 ] + +When we finish processing ASCONF_ACK chunk, we try to send +the next queued ASCONF. This action runs the sctp state +machine recursively and it's not prepared to do so. + +kernel BUG at kernel/timer.c:790! +invalid opcode: 0000 [#1] SMP +last sysfs file: /sys/module/ipv6/initstate +Modules linked in: sha256_generic sctp libcrc32c ipv6 dm_multipath +uinput 8139too i2c_piix4 8139cp mii i2c_core pcspkr virtio_net joydev +floppy virtio_blk virtio_pci [last unloaded: scsi_wait_scan] + +Pid: 0, comm: swapper Not tainted 2.6.34-rc4 #15 /Bochs +EIP: 0060:[] EFLAGS: 00010286 CPU: 0 +EIP is at add_timer+0xd/0x1b +EAX: cecbab14 EBX: 000000f0 ECX: c0957b1c EDX: 03595cf4 +ESI: cecba800 EDI: cf276f00 EBP: c0957aa0 ESP: c0957aa0 + DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 +Process swapper (pid: 0, ti=c0956000 task=c0988ba0 task.ti=c0956000) +Stack: + c0957ae0 d1851214 c0ab62e4 c0ab5f26 0500ffff 00000004 00000005 00000004 +<0> 00000000 d18694fd 00000004 1666b892 cecba800 cecba800 c0957b14 +00000004 +<0> c0957b94 d1851b11 ceda8b00 cecba800 cf276f00 00000001 c0957b14 +000000d0 +Call Trace: + [] ? sctp_side_effects+0x607/0xdfc [sctp] + [] ? sctp_do_sm+0x108/0x159 [sctp] + [] ? sctp_pname+0x0/0x1d [sctp] + [] ? sctp_primitive_ASCONF+0x36/0x3b [sctp] + [] ? sctp_process_asconf_ack+0x2a4/0x2d3 [sctp] + [] ? sctp_sf_do_asconf_ack+0x1dd/0x2b4 [sctp] + [] ? sctp_do_sm+0xb8/0x159 [sctp] + [] ? sctp_cname+0x0/0x52 [sctp] + [] ? sctp_assoc_bh_rcv+0xac/0xe1 [sctp] + [] ? sctp_inq_push+0x2d/0x30 [sctp] + [] ? sctp_rcv+0x797/0x82e [sctp] + +Tested-by: Wei Yongjun +Signed-off-by: Yuansong Qiao +Signed-off-by: Shuaijun Zhang +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sctp/command.h | 1 + + net/sctp/sm_make_chunk.c | 15 --------------- + net/sctp/sm_sideeffect.c | 26 ++++++++++++++++++++++++++ + net/sctp/sm_statefuns.c | 8 +++++++- + 4 files changed, 34 insertions(+), 16 deletions(-) + +--- a/include/net/sctp/command.h ++++ b/include/net/sctp/command.h +@@ -107,6 +107,7 @@ typedef enum { + SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ + SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ + SCTP_CMD_SEND_MSG, /* Send the whole use message */ ++ SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ + SCTP_CMD_LAST + } sctp_verb_t; + +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -3317,21 +3317,6 @@ int sctp_process_asconf_ack(struct sctp_ + sctp_chunk_free(asconf); + asoc->addip_last_asconf = NULL; + +- /* Send the next asconf chunk from the addip chunk queue. */ +- if (!list_empty(&asoc->addip_chunk_list)) { +- struct list_head *entry = asoc->addip_chunk_list.next; +- asconf = list_entry(entry, struct sctp_chunk, list); +- +- list_del_init(entry); +- +- /* Hold the chunk until an ASCONF_ACK is received. */ +- sctp_chunk_hold(asconf); +- if (sctp_primitive_ASCONF(asoc, asconf)) +- sctp_chunk_free(asconf); +- else +- asoc->addip_last_asconf = asconf; +- } +- + return retval; + } + +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -961,6 +961,29 @@ static int sctp_cmd_send_msg(struct sctp + } + + ++/* Sent the next ASCONF packet currently stored in the association. ++ * This happens after the ASCONF_ACK was succeffully processed. ++ */ ++static void sctp_cmd_send_asconf(struct sctp_association *asoc) ++{ ++ /* Send the next asconf chunk from the addip chunk ++ * queue. ++ */ ++ if (!list_empty(&asoc->addip_chunk_list)) { ++ struct list_head *entry = asoc->addip_chunk_list.next; ++ struct sctp_chunk *asconf = list_entry(entry, ++ struct sctp_chunk, list); ++ list_del_init(entry); ++ ++ /* Hold the chunk until an ASCONF_ACK is received. */ ++ sctp_chunk_hold(asconf); ++ if (sctp_primitive_ASCONF(asoc, asconf)) ++ sctp_chunk_free(asconf); ++ else ++ asoc->addip_last_asconf = asconf; ++ } ++} ++ + + /* These three macros allow us to pull the debugging code out of the + * main flow of sctp_do_sm() to keep attention focused on the real +@@ -1616,6 +1639,9 @@ static int sctp_cmd_interpreter(sctp_eve + } + error = sctp_cmd_send_msg(asoc, cmd->obj.msg); + break; ++ case SCTP_CMD_SEND_NEXT_ASCONF: ++ sctp_cmd_send_asconf(asoc); ++ break; + default: + printk(KERN_WARNING "Impossible command: %u, %p\n", + cmd->verb, cmd->obj.ptr); +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -3675,8 +3675,14 @@ sctp_disposition_t sctp_sf_do_asconf_ack + SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); + + if (!sctp_process_asconf_ack((struct sctp_association *)asoc, +- asconf_ack)) ++ asconf_ack)) { ++ /* Successfully processed ASCONF_ACK. We can ++ * release the next asconf if we have one. ++ */ ++ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, ++ SCTP_NULL()); + return SCTP_DISPOSITION_CONSUME; ++ } + + abort = sctp_make_abort(asoc, asconf_ack, + sizeof(sctp_errhdr_t)); diff --git a/queue-2.6.33/sctp-fix-potential-reference-of-a-freed-pointer.patch b/queue-2.6.33/sctp-fix-potential-reference-of-a-freed-pointer.patch new file mode 100644 index 00000000000..0c3b6648622 --- /dev/null +++ b/queue-2.6.33/sctp-fix-potential-reference-of-a-freed-pointer.patch @@ -0,0 +1,36 @@ +From 8cc68b8205d9e0c543d29cf662dfc012c2b4637f Mon Sep 17 00:00:00 2001 +From: Vlad Yasevich +Date: Wed, 28 Apr 2010 08:47:19 +0000 +Subject: sctp: fix potential reference of a freed pointer + + +From: Vlad Yasevich + +[ Upstream commit 0c42749cffbb4a06be86c5e5db6c7ebad548781f ] + +When sctp attempts to update an assocition, it removes any +addresses that were not in the updated INITs. However, the loop +may attempt to refrence a transport with address after removing it. + +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/associola.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/sctp/associola.c ++++ b/net/sctp/associola.c +@@ -1194,8 +1194,10 @@ void sctp_assoc_update(struct sctp_assoc + /* Remove any peer addresses not present in the new association. */ + list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { + trans = list_entry(pos, struct sctp_transport, transports); +- if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) +- sctp_assoc_del_peer(asoc, &trans->ipaddr); ++ if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) { ++ sctp_assoc_rm_peer(asoc, trans); ++ continue; ++ } + + if (asoc->state >= SCTP_STATE_ESTABLISHED) + sctp_transport_reset(trans); diff --git a/queue-2.6.33/sctp-fix-to-calc-the-init-init-ack-chunk-length-correctly-is-set.patch b/queue-2.6.33/sctp-fix-to-calc-the-init-init-ack-chunk-length-correctly-is-set.patch new file mode 100644 index 00000000000..6fb5de6b4f5 --- /dev/null +++ b/queue-2.6.33/sctp-fix-to-calc-the-init-init-ack-chunk-length-correctly-is-set.patch @@ -0,0 +1,156 @@ +From 63cb26d154d5fe28b3fda793c407c14544756705 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Wed, 28 Apr 2010 08:47:21 +0000 +Subject: sctp: fix to calc the INIT/INIT-ACK chunk length correctly is set + + +From: Wei Yongjun + +[ Upstream commita8170c35e738d62e9919ce5b109cf4ed66e95bde ] + +When calculating the INIT/INIT-ACK chunk length, we should not +only account the length of parameters, but also the parameters +zero padding length, such as AUTH HMACS parameter and CHUNKS +parameter. Without the parameters zero padding length we may get +following oops. + +skb_over_panic: text:ce2068d2 len:130 put:6 head:cac3fe00 data:cac3fe00 tail:0xcac3fe82 end:0xcac3fe80 dev: +------------[ cut here ]------------ +kernel BUG at net/core/skbuff.c:127! +invalid opcode: 0000 [#2] SMP +last sysfs file: /sys/module/aes_generic/initstate +Modules linked in: authenc ...... + +Pid: 4102, comm: sctp_darn Tainted: G D 2.6.34-rc2 #6 +EIP: 0060:[] EFLAGS: 00010282 CPU: 0 +EIP is at skb_over_panic+0x37/0x3e +EAX: 00000078 EBX: c07c024b ECX: c07c02b9 EDX: cb607b78 +ESI: 00000000 EDI: cac3fe7a EBP: 00000002 ESP: cb607b74 + DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 +Process sctp_darn (pid: 4102, ti=cb607000 task=cabdc990 task.ti=cb607000) +Stack: + c07c02b9 ce2068d2 00000082 00000006 cac3fe00 cac3fe00 cac3fe82 cac3fe80 +<0> c07c024b cac3fe7c cac3fe7a c0608dec ca986e80 ce2068d2 00000006 0000007a +<0> cb8120ca ca986e80 cb812000 00000003 cb8120c4 ce208a25 cb8120ca cadd9400 +Call Trace: + [] ? sctp_addto_chunk+0x45/0x85 [sctp] + [] ? skb_put+0x2e/0x32 + [] ? sctp_addto_chunk+0x45/0x85 [sctp] + [] ? sctp_make_init+0x279/0x28c [sctp] + [] ? apic_timer_interrupt+0x2a/0x30 + [] ? sctp_sf_do_prm_asoc+0x2b/0x7b [sctp] + [] ? sctp_do_sm+0xa0/0x14a [sctp] + [] ? sctp_pname+0x0/0x14 [sctp] + [] ? sctp_primitive_ASSOCIATE+0x2b/0x31 [sctp] + [] ? sctp_sendmsg+0x7a0/0x9eb [sctp] + [] ? inet_sendmsg+0x3b/0x43 + [] ? task_tick_fair+0x2d/0xd9 + [] ? sock_sendmsg+0xa7/0xc1 + [] ? smp_apic_timer_interrupt+0x6b/0x75 + [] ? dequeue_task_fair+0x34/0x19b + [] ? sched_clock_local+0x17/0x11e + [] ? _copy_from_user+0x2b/0x10c + [] ? verify_iovec+0x3c/0x6a + [] ? sys_sendmsg+0x186/0x1e2 + [] ? __wake_up_common+0x34/0x5b + [] ? __wake_up+0x2c/0x3b + [] ? tty_wakeup+0x43/0x47 + [] ? remove_wait_queue+0x16/0x24 + [] ? n_tty_read+0x5b8/0x65e + [] ? default_wake_function+0x0/0x8 + [] ? sys_socketcall+0x17f/0x1cd + [] ? sysenter_do_call+0x12/0x22 +Code: 0f 45 de 53 ff b0 98 00 00 00 ff b0 94 ...... +EIP: [] skb_over_panic+0x37/0x3e SS:ESP 0068:cb607b74 + +To reproduce: + +# modprobe sctp +# echo 1 > /proc/sys/net/sctp/addip_enable +# echo 1 > /proc/sys/net/sctp/auth_enable +# sctp_test -H 3ffe:501:ffff:100:20c:29ff:fe4d:f37e -P 800 -l +# sctp_darn -H 3ffe:501:ffff:100:20c:29ff:fe4d:f37e -P 900 -h 192.168.0.21 -p 800 -I -s -t +sctp_darn ready to send... +3ffe:501:ffff:100:20c:29ff:fe4d:f37e:900-192.168.0.21:800 Interactive mode> bindx-add=192.168.0.21 +3ffe:501:ffff:100:20c:29ff:fe4d:f37e:900-192.168.0.21:800 Interactive mode> bindx-add=192.168.1.21 +3ffe:501:ffff:100:20c:29ff:fe4d:f37e:900-192.168.0.21:800 Interactive mode> snd=10 + +------------------------------------------------------------------ +eth0 has addresses: 3ffe:501:ffff:100:20c:29ff:fe4d:f37e and 192.168.0.21 +eth1 has addresses: 192.168.1.21 +------------------------------------------------------------------ + +Reported-by: George Cheimonidis +Signed-off-by: Wei Yongjun +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/sm_make_chunk.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -207,7 +207,8 @@ struct sctp_chunk *sctp_make_init(const + sp = sctp_sk(asoc->base.sk); + num_types = sp->pf->supported_addrs(sp, types); + +- chunksize = sizeof(init) + addrs_len + SCTP_SAT_LEN(num_types); ++ chunksize = sizeof(init) + addrs_len; ++ chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types)); + chunksize += sizeof(ecap_param); + + if (sctp_prsctp_enable) +@@ -237,14 +238,14 @@ struct sctp_chunk *sctp_make_init(const + /* Add HMACS parameter length if any were defined */ + auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; + if (auth_hmacs->length) +- chunksize += ntohs(auth_hmacs->length); ++ chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); + else + auth_hmacs = NULL; + + /* Add CHUNKS parameter length */ + auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; + if (auth_chunks->length) +- chunksize += ntohs(auth_chunks->length); ++ chunksize += WORD_ROUND(ntohs(auth_chunks->length)); + else + auth_chunks = NULL; + +@@ -254,7 +255,8 @@ struct sctp_chunk *sctp_make_init(const + + /* If we have any extensions to report, account for that */ + if (num_ext) +- chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; ++ chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + ++ num_ext); + + /* RFC 2960 3.3.2 Initiation (INIT) (1) + * +@@ -396,13 +398,13 @@ struct sctp_chunk *sctp_make_init_ack(co + + auth_hmacs = (sctp_paramhdr_t *)asoc->c.auth_hmacs; + if (auth_hmacs->length) +- chunksize += ntohs(auth_hmacs->length); ++ chunksize += WORD_ROUND(ntohs(auth_hmacs->length)); + else + auth_hmacs = NULL; + + auth_chunks = (sctp_paramhdr_t *)asoc->c.auth_chunks; + if (auth_chunks->length) +- chunksize += ntohs(auth_chunks->length); ++ chunksize += WORD_ROUND(ntohs(auth_chunks->length)); + else + auth_chunks = NULL; + +@@ -411,7 +413,8 @@ struct sctp_chunk *sctp_make_init_ack(co + } + + if (num_ext) +- chunksize += sizeof(sctp_supported_ext_param_t) + num_ext; ++ chunksize += WORD_ROUND(sizeof(sctp_supported_ext_param_t) + ++ num_ext); + + /* Now allocate and fill out the chunk. */ + retval = sctp_make_chunk(asoc, SCTP_CID_INIT_ACK, 0, chunksize); diff --git a/queue-2.6.33/sctp-per_cpu-variables-should-be-in-bh_disabled-section.patch b/queue-2.6.33/sctp-per_cpu-variables-should-be-in-bh_disabled-section.patch new file mode 100644 index 00000000000..4d55b9f2776 --- /dev/null +++ b/queue-2.6.33/sctp-per_cpu-variables-should-be-in-bh_disabled-section.patch @@ -0,0 +1,46 @@ +From 4caa6bb7183951198b6dc1683fdd09f6fa545f54 Mon Sep 17 00:00:00 2001 +From: Vlad Yasevich +Date: Wed, 28 Apr 2010 08:47:20 +0000 +Subject: sctp: per_cpu variables should be in bh_disabled section + + +From: Vlad Yasevich + +[ Upstream commit 81419d862db743fe4450a021893f24bab4698c1d ] + +Since the change of the atomics to percpu variables, we now +have to disable BH in process context when touching percpu variables. + +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -3718,12 +3718,12 @@ SCTP_STATIC int sctp_init_sock(struct so + sp->hmac = NULL; + + SCTP_DBG_OBJCNT_INC(sock); +- percpu_counter_inc(&sctp_sockets_allocated); + + /* Set socket backlog limit. */ + sk->sk_backlog.limit = sysctl_sctp_rmem[1]; + + local_bh_disable(); ++ percpu_counter_inc(&sctp_sockets_allocated); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); + local_bh_enable(); + +@@ -3740,8 +3740,8 @@ SCTP_STATIC void sctp_destroy_sock(struc + /* Release our hold on the endpoint. */ + ep = sctp_sk(sk)->ep; + sctp_endpoint_free(ep); +- percpu_counter_dec(&sctp_sockets_allocated); + local_bh_disable(); ++ percpu_counter_dec(&sctp_sockets_allocated); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); + local_bh_enable(); + } diff --git a/queue-2.6.33/series b/queue-2.6.33/series index d6b88c6a73d..2fa96b78322 100644 --- a/queue-2.6.33/series +++ b/queue-2.6.33/series @@ -80,3 +80,22 @@ powerpc-reset-kernel-stack-on-cpu-online-from-cede-state.patch powerpc-move-checks-in-pseries_mach_cpu_die.patch powerpc-reduce-printk-from-pseries_mach_cpu_die.patch bnx2-fix-lost-msi-x-problem-on-5709-nics.patch +cdc_ether-fix-autosuspend-for-mbm-devices.patch +ieee802154-fix-oops-during-ieee802154_sock_ioctl.patch +ipv6-fix-tcp_v6_send_response-transport-header-setting.patch +sctp-avoid-irq-lock-inversion-while-call-sk-sk_data_ready.patch +sctp-fix-potential-reference-of-a-freed-pointer.patch +sctp-per_cpu-variables-should-be-in-bh_disabled-section.patch +sctp-fix-to-calc-the-init-init-ack-chunk-length-correctly-is-set.patch +sctp-fix-oops-when-sending-queued-asconf-chunks.patch +net-fix-oops-from-tcp_collapse-when-using-splice.patch +tipc-fix-oops-on-send-prior-to-entering-networked-mode-v3.patch +tun-orphan-an-skb-on-tx.patch +udp-fix-for-unicast-rx-path-optimization.patch +wan-flush-tx_queue-in-hdlc_ppp-to-prevent-panic-on-rmmod-hw_driver.patch +sparc64-use-correct-pt_regs-in-decode_access_size-error-paths.patch +sparc64-fix-preempt_active-value.patch +sparc64-fix-hardirq-tracing-in-trap-return-path.patch +sparc64-use-kstack_valid-in-die_if_kernel.patch +sparc64-adjust-__raw_local_irq_save-to-cooperate-in-nmis.patch +sparc64-fix-memory-leak-in-pci_register_iommu_region.patch diff --git a/queue-2.6.33/sparc64-adjust-__raw_local_irq_save-to-cooperate-in-nmis.patch b/queue-2.6.33/sparc64-adjust-__raw_local_irq_save-to-cooperate-in-nmis.patch new file mode 100644 index 00000000000..986eab70ef5 --- /dev/null +++ b/queue-2.6.33/sparc64-adjust-__raw_local_irq_save-to-cooperate-in-nmis.patch @@ -0,0 +1,61 @@ +From 238e8427818fe23150a52141641fecfa0591761d Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 10 May 2010 05:19:10 -0700 +Subject: sparc64: Adjust __raw_local_irq_save() to cooperate in NMIs. + + +From: David S. Miller + +[ Upstream commits 0c25e9e6cbe7b233bb91d14d0e2c258bf8e6ec83 and + c011f80ba0912486fe51dd2b3f71d9b33a151188 ] + +If we are in an NMI then doing a plain raw_local_irq_disable() will +write PIL_NORMAL_MAX into %pil, which is lower than PIL_NMI, and thus +we'll re-enable NMIs and recurse. + +Doing a simple: + + %pil = %pil | PIL_NORMAL_MAX + +does what we want, if we're already at PIL_NMI (15) we leave it at +that setting, else we set it to PIL_NORMAL_MAX (14). + +This should get the function tracer working on sparc64. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/include/asm/irqflags_64.h | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +--- a/arch/sparc/include/asm/irqflags_64.h ++++ b/arch/sparc/include/asm/irqflags_64.h +@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void + */ + static inline unsigned long __raw_local_irq_save(void) + { +- unsigned long flags = __raw_local_save_flags(); ++ unsigned long flags, tmp; + +- raw_local_irq_disable(); ++ /* Disable interrupts to PIL_NORMAL_MAX unless we already ++ * are using PIL_NMI, in which case PIL_NMI is retained. ++ * ++ * The only values we ever program into the %pil are 0, ++ * PIL_NORMAL_MAX and PIL_NMI. ++ * ++ * Since PIL_NMI is the largest %pil value and all bits are ++ * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX ++ * actually is. ++ */ ++ __asm__ __volatile__( ++ "rdpr %%pil, %0\n\t" ++ "or %0, %2, %1\n\t" ++ "wrpr %1, 0x0, %%pil" ++ : "=r" (flags), "=r" (tmp) ++ : "i" (PIL_NORMAL_MAX) ++ : "memory" ++ ); + + return flags; + } diff --git a/queue-2.6.33/sparc64-fix-hardirq-tracing-in-trap-return-path.patch b/queue-2.6.33/sparc64-fix-hardirq-tracing-in-trap-return-path.patch new file mode 100644 index 00000000000..faed8bad78a --- /dev/null +++ b/queue-2.6.33/sparc64-fix-hardirq-tracing-in-trap-return-path.patch @@ -0,0 +1,43 @@ +From 46321840e3451c9538d7144d740010e4e5dc73ba Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Tue, 20 Apr 2010 00:48:37 -0700 +Subject: sparc64: Fix hardirq tracing in trap return path. + + +From: David S. Miller + +[ Upstream commit 28a1f533ae8606020238b840b82ae70a3f87609e ] + +We can overflow the hardirq stack if we set the %pil here +so early, just let the normal control flow do it. + +This is fine as we are allowed to do the actual IRQ enable +at any point after we call trace_hardirqs_on. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/rtrap_64.S | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/arch/sparc/kernel/rtrap_64.S ++++ b/arch/sparc/kernel/rtrap_64.S +@@ -172,7 +172,17 @@ rtrap_xcall: + nop + call trace_hardirqs_on + nop +- wrpr %l4, %pil ++ /* Do not actually set the %pil here. We will do that ++ * below after we clear PSTATE_IE in the %pstate register. ++ * If we re-enable interrupts here, we can recurse down ++ * the hardirq stack potentially endlessly, causing a ++ * stack overflow. ++ * ++ * It is tempting to put this test and trace_hardirqs_on ++ * call at the 'rt_continue' label, but that will not work ++ * as that path hits unconditionally and we do not want to ++ * execute this in NMI return paths, for example. ++ */ + #endif + rtrap_no_irq_enable: + andcc %l1, TSTATE_PRIV, %l3 diff --git a/queue-2.6.33/sparc64-fix-memory-leak-in-pci_register_iommu_region.patch b/queue-2.6.33/sparc64-fix-memory-leak-in-pci_register_iommu_region.patch new file mode 100644 index 00000000000..36ae90bccb8 --- /dev/null +++ b/queue-2.6.33/sparc64-fix-memory-leak-in-pci_register_iommu_region.patch @@ -0,0 +1,50 @@ +From 2509d4f02c769d306fb4450beb5f62603320c518 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Sat, 10 Apr 2010 20:26:55 -0700 +Subject: sparc64: Fix memory leak in pci_register_iommu_region(). + + +From: David S. Miller + +[ Upstream commit e182c77cc291456eed127b1472952ddb59a81a9d ] + +Found by kmemleak. + +If request_resource() fails, we leak the struct resource we +allocated to represent the IOMMU mapping area. + +This actually happens on sun4v machines because the IOMEM area is only +reported sans the IOMMU region, unlike all previous systems. I'll +need to fix that at some point, but for now fix the leak. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/pci_common.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/arch/sparc/kernel/pci_common.c ++++ b/arch/sparc/kernel/pci_common.c +@@ -371,14 +371,19 @@ static void pci_register_iommu_region(st + struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); + + if (!rp) { +- prom_printf("Cannot allocate IOMMU resource.\n"); +- prom_halt(); ++ pr_info("%s: Cannot allocate IOMMU resource.\n", ++ pbm->name); ++ return; + } + rp->name = "IOMMU"; + rp->start = pbm->mem_space.start + (unsigned long) vdma[0]; + rp->end = rp->start + (unsigned long) vdma[1] - 1UL; + rp->flags = IORESOURCE_BUSY; +- request_resource(&pbm->mem_space, rp); ++ if (request_resource(&pbm->mem_space, rp)) { ++ pr_info("%s: Unable to request IOMMU resource.\n", ++ pbm->name); ++ kfree(rp); ++ } + } + } + diff --git a/queue-2.6.33/sparc64-fix-preempt_active-value.patch b/queue-2.6.33/sparc64-fix-preempt_active-value.patch new file mode 100644 index 00000000000..07fd5a11670 --- /dev/null +++ b/queue-2.6.33/sparc64-fix-preempt_active-value.patch @@ -0,0 +1,29 @@ +From 3a34c0f4f901d6f4972e1b9158affaff7b813a9a Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 19 Apr 2010 01:30:51 -0700 +Subject: sparc64: Fix PREEMPT_ACTIVE value. + + +From: David S. Miller + +[ Upstream commit 6c94b1ee0ca2bfb526d779c088ec20da6a3761db ] + +It currently overlaps the NMI bit. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/include/asm/thread_info_64.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc/include/asm/thread_info_64.h ++++ b/arch/sparc/include/asm/thread_info_64.h +@@ -121,7 +121,7 @@ struct thread_info { + #define THREAD_SHIFT PAGE_SHIFT + #endif /* PAGE_SHIFT == 13 */ + +-#define PREEMPT_ACTIVE 0x4000000 ++#define PREEMPT_ACTIVE 0x10000000 + + /* + * macros/functions for gaining access to the thread information structure diff --git a/queue-2.6.33/sparc64-use-correct-pt_regs-in-decode_access_size-error-paths.patch b/queue-2.6.33/sparc64-use-correct-pt_regs-in-decode_access_size-error-paths.patch new file mode 100644 index 00000000000..4184d91be3c --- /dev/null +++ b/queue-2.6.33/sparc64-use-correct-pt_regs-in-decode_access_size-error-paths.patch @@ -0,0 +1,45 @@ +From 6bbe91c3a36d67e83199ba0d120df6a1a6c0ee17 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 19 Apr 2010 13:46:48 -0700 +Subject: sparc64: Use correct pt_regs in decode_access_size() error paths. + + +From: David S. Miller + +[ Upstream commit baa06775e224e9f74e5c2de894c95cd49678beff ] + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/unaligned_64.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/sparc/kernel/unaligned_64.c ++++ b/arch/sparc/kernel/unaligned_64.c +@@ -49,7 +49,7 @@ static inline enum direction decode_dire + } + + /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */ +-static inline int decode_access_size(unsigned int insn) ++static inline int decode_access_size(struct pt_regs *regs, unsigned int insn) + { + unsigned int tmp; + +@@ -65,7 +65,7 @@ static inline int decode_access_size(uns + return 2; + else { + printk("Impossible unaligned trap. insn=%08x\n", insn); +- die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs); ++ die_if_kernel("Byte sized unaligned access?!?!", regs); + + /* GCC should never warn that control reaches the end + * of this function without returning a value because +@@ -289,7 +289,7 @@ static void log_unaligned(struct pt_regs + asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) + { + enum direction dir = decode_direction(insn); +- int size = decode_access_size(insn); ++ int size = decode_access_size(regs, insn); + int orig_asi, asi; + + current_thread_info()->kern_una_regs = regs; diff --git a/queue-2.6.33/sparc64-use-kstack_valid-in-die_if_kernel.patch b/queue-2.6.33/sparc64-use-kstack_valid-in-die_if_kernel.patch new file mode 100644 index 00000000000..d2d18950867 --- /dev/null +++ b/queue-2.6.33/sparc64-use-kstack_valid-in-die_if_kernel.patch @@ -0,0 +1,69 @@ +From 1b36a0035de387d2593b92c1ddf3af515e5834c7 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 12 Apr 2010 22:16:22 -0700 +Subject: sparc64: Use kstack_valid() in die_if_kernel(). + + +From: David S. Miller + +[ Upstream commit cb256aa60409efd803806cfb0528a4b3f8397dba ] + +This gets rid of a local function (is_kernel_stack()) which tries to +do the same thing, yet poorly in that it doesn't handle IRQ stacks +properly. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + arch/sparc/kernel/traps_64.c | 26 +++----------------------- + 1 file changed, 3 insertions(+), 23 deletions(-) + +--- a/arch/sparc/kernel/traps_64.c ++++ b/arch/sparc/kernel/traps_64.c +@@ -2202,27 +2202,6 @@ void dump_stack(void) + + EXPORT_SYMBOL(dump_stack); + +-static inline int is_kernel_stack(struct task_struct *task, +- struct reg_window *rw) +-{ +- unsigned long rw_addr = (unsigned long) rw; +- unsigned long thread_base, thread_end; +- +- if (rw_addr < PAGE_OFFSET) { +- if (task != &init_task) +- return 0; +- } +- +- thread_base = (unsigned long) task_stack_page(task); +- thread_end = thread_base + sizeof(union thread_union); +- if (rw_addr >= thread_base && +- rw_addr < thread_end && +- !(rw_addr & 0x7UL)) +- return 1; +- +- return 0; +-} +- + static inline struct reg_window *kernel_stack_up(struct reg_window *rw) + { + unsigned long fp = rw->ins[6]; +@@ -2251,6 +2230,7 @@ void die_if_kernel(char *str, struct pt_ + show_regs(regs); + add_taint(TAINT_DIE); + if (regs->tstate & TSTATE_PRIV) { ++ struct thread_info *tp = current_thread_info(); + struct reg_window *rw = (struct reg_window *) + (regs->u_regs[UREG_FP] + STACK_BIAS); + +@@ -2258,8 +2238,8 @@ void die_if_kernel(char *str, struct pt_ + * find some badly aligned kernel stack. + */ + while (rw && +- count++ < 30&& +- is_kernel_stack(current, rw)) { ++ count++ < 30 && ++ kstack_valid(tp, (unsigned long) rw)) { + printk("Caller[%016lx]: %pS\n", rw->ins[7], + (void *) rw->ins[7]); + diff --git a/queue-2.6.33/tipc-fix-oops-on-send-prior-to-entering-networked-mode-v3.patch b/queue-2.6.33/tipc-fix-oops-on-send-prior-to-entering-networked-mode-v3.patch new file mode 100644 index 00000000000..14847a9027c --- /dev/null +++ b/queue-2.6.33/tipc-fix-oops-on-send-prior-to-entering-networked-mode-v3.patch @@ -0,0 +1,208 @@ +From d695a045630b0d3533abc2bc49bf16dddba9d8a6 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Wed, 3 Mar 2010 08:31:23 +0000 +Subject: tipc: Fix oops on send prior to entering networked mode (v3) + + +From: Neil Horman + +[ Upstream commit d0021b252eaf65ca07ed14f0d66425dd9ccab9a6 ] + +Fix TIPC to disallow sending to remote addresses prior to entering NET_MODE + +user programs can oops the kernel by sending datagrams via AF_TIPC prior to +entering networked mode. The following backtrace has been observed: + +ID: 13459 TASK: ffff810014640040 CPU: 0 COMMAND: "tipc-client" +[exception RIP: tipc_node_select_next_hop+90] +RIP: ffffffff8869d3c3 RSP: ffff81002d9a5ab8 RFLAGS: 00010202 +RAX: 0000000000000001 RBX: 0000000000000001 RCX: 0000000000000001 +RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000001001001 +RBP: 0000000001001001 R8: 0074736575716552 R9: 0000000000000000 +R10: ffff81003fbd0680 R11: 00000000000000c8 R12: 0000000000000008 +R13: 0000000000000001 R14: 0000000000000001 R15: ffff810015c6ca00 +ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 +RIP: 0000003cbd8d49a3 RSP: 00007fffc84e0be8 RFLAGS: 00010206 +RAX: 000000000000002c RBX: ffffffff8005d116 RCX: 0000000000000000 +RDX: 0000000000000008 RSI: 00007fffc84e0c00 RDI: 0000000000000003 +RBP: 0000000000000000 R8: 00007fffc84e0c10 R9: 0000000000000010 +R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007fffc84e0d10 R14: 0000000000000000 R15: 00007fffc84e0c30 +ORIG_RAX: 000000000000002c CS: 0033 SS: 002b + +What happens is that, when the tipc module in inserted it enters a standalone +node mode in which communication to its own address is allowed <0.0.0> but not +to other addresses, since the appropriate data structures have not been +allocated yet (specifically the tipc_net pointer). There is nothing stopping a +client from trying to send such a message however, and if that happens, we +attempt to dereference tipc_net.zones while the pointer is still NULL, and +explode. The fix is pretty straightforward. Since these oopses all arise from +the dereference of global pointers prior to their assignment to allocated +values, and since these allocations are small (about 2k total), lets convert +these pointers to static arrays of the appropriate size. All the accesses to +these bits consider 0/NULL to be a non match when searching, so all the lookups +still work properly, and there is no longer a chance of a bad dererence +anywhere. As a bonus, this lets us eliminate the setup/teardown routines for +those pointers, and elimnates the need to preform any locking around them to +prevent access while their being allocated/freed. + +I've updated the tipc_net structure to behave this way to fix the exact reported +problem, and also fixed up the tipc_bearers and media_list arrays to fix an +obvious simmilar problem that arises from issuing tipc-config commands to +manipulate bearers/links prior to entering networked mode + +I've tested this for a few hours by running the sanity tests and stress test +with the tipcutils suite, and nothing has fallen over. There have been a few +lockdep warnings, but those were there before, and can be addressed later, as +they didn't actually result in any deadlock. + +Signed-off-by: Neil Horman +CC: Allan Stephens +CC: David S. Miller +CC: tipc-discussion@lists.sourceforge.net +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/bearer.c | 37 ++++++------------------------------- + net/tipc/bearer.h | 2 +- + net/tipc/net.c | 25 ++++--------------------- + 3 files changed, 11 insertions(+), 53 deletions(-) + +--- a/net/tipc/bearer.c ++++ b/net/tipc/bearer.c +@@ -45,10 +45,10 @@ + + #define MAX_ADDR_STR 32 + +-static struct media *media_list = NULL; ++static struct media media_list[MAX_MEDIA]; + static u32 media_count = 0; + +-struct bearer *tipc_bearers = NULL; ++struct bearer tipc_bearers[MAX_BEARERS]; + + /** + * media_name_valid - validate media name +@@ -108,9 +108,11 @@ int tipc_register_media(u32 media_type, + int res = -EINVAL; + + write_lock_bh(&tipc_net_lock); +- if (!media_list) +- goto exit; + ++ if (tipc_mode != TIPC_NET_MODE) { ++ warn("Media <%s> rejected, not in networked mode yet\n", name); ++ goto exit; ++ } + if (!media_name_valid(name)) { + warn("Media <%s> rejected, illegal name\n", name); + goto exit; +@@ -660,33 +662,10 @@ int tipc_disable_bearer(const char *name + + + +-int tipc_bearer_init(void) +-{ +- int res; +- +- write_lock_bh(&tipc_net_lock); +- tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); +- media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); +- if (tipc_bearers && media_list) { +- res = 0; +- } else { +- kfree(tipc_bearers); +- kfree(media_list); +- tipc_bearers = NULL; +- media_list = NULL; +- res = -ENOMEM; +- } +- write_unlock_bh(&tipc_net_lock); +- return res; +-} +- + void tipc_bearer_stop(void) + { + u32 i; + +- if (!tipc_bearers) +- return; +- + for (i = 0; i < MAX_BEARERS; i++) { + if (tipc_bearers[i].active) + tipc_bearers[i].publ.blocked = 1; +@@ -695,10 +674,6 @@ void tipc_bearer_stop(void) + if (tipc_bearers[i].active) + bearer_disable(tipc_bearers[i].publ.name); + } +- kfree(tipc_bearers); +- kfree(media_list); +- tipc_bearers = NULL; +- media_list = NULL; + media_count = 0; + } + +--- a/net/tipc/bearer.h ++++ b/net/tipc/bearer.h +@@ -114,7 +114,7 @@ struct bearer_name { + + struct link; + +-extern struct bearer *tipc_bearers; ++extern struct bearer tipc_bearers[]; + + void tipc_media_addr_printf(struct print_buf *pb, struct tipc_media_addr *a); + struct sk_buff *tipc_media_get_names(void); +--- a/net/tipc/net.c ++++ b/net/tipc/net.c +@@ -116,7 +116,8 @@ + */ + + DEFINE_RWLOCK(tipc_net_lock); +-struct network tipc_net = { NULL }; ++struct _zone *tipc_zones[256] = { NULL, }; ++struct network tipc_net = { tipc_zones }; + + struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref) + { +@@ -158,28 +159,12 @@ void tipc_net_send_external_routes(u32 d + } + } + +-static int net_init(void) +-{ +- memset(&tipc_net, 0, sizeof(tipc_net)); +- tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC); +- if (!tipc_net.zones) { +- return -ENOMEM; +- } +- return 0; +-} +- + static void net_stop(void) + { + u32 z_num; + +- if (!tipc_net.zones) +- return; +- +- for (z_num = 1; z_num <= tipc_max_zones; z_num++) { ++ for (z_num = 1; z_num <= tipc_max_zones; z_num++) + tipc_zone_delete(tipc_net.zones[z_num]); +- } +- kfree(tipc_net.zones); +- tipc_net.zones = NULL; + } + + static void net_route_named_msg(struct sk_buff *buf) +@@ -282,9 +267,7 @@ int tipc_net_start(u32 addr) + tipc_named_reinit(); + tipc_port_reinit(); + +- if ((res = tipc_bearer_init()) || +- (res = net_init()) || +- (res = tipc_cltr_init()) || ++ if ((res = tipc_cltr_init()) || + (res = tipc_bclink_init())) { + return res; + } diff --git a/queue-2.6.33/tun-orphan-an-skb-on-tx.patch b/queue-2.6.33/tun-orphan-an-skb-on-tx.patch new file mode 100644 index 00000000000..13ae156a754 --- /dev/null +++ b/queue-2.6.33/tun-orphan-an-skb-on-tx.patch @@ -0,0 +1,58 @@ +From e17f49e28a1686f3d21ee3e0f62a802f97bac386 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Tue, 13 Apr 2010 04:59:44 +0000 +Subject: tun: orphan an skb on tx + + +From: Michael S. Tsirkin + +[ Upstream commit 0110d6f22f392f976e84ab49da1b42f85b64a3c5 ] + +The following situation was observed in the field: +tap1 sends packets, tap2 does not consume them, as a result +tap1 can not be closed. This happens because +tun/tap devices can hang on to skbs undefinitely. + +As noted by Herbert, possible solutions include a timeout followed by a +copy/change of ownership of the skb, or always copying/changing +ownership if we're going into a hostile device. + +This patch implements the second approach. + +Note: one issue still remaining is that since skbs +keep reference to tun socket and tun socket has a +reference to tun device, we won't flush backlog, +instead simply waiting for all skbs to get transmitted. +At least this is not user-triggerable, and +this was not reported in practice, my assumption is +other devices besides tap complete an skb +within finite time after it has been queued. + +A possible solution for the second issue +would not to have socket reference the device, +instead, implement dev->destructor for tun, and +wait for all skbs to complete there, but this +needs some thought, probably too risky for 2.6.34. + +Signed-off-by: Michael S. Tsirkin +Tested-by: Yan Vugenfirer +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -380,6 +380,10 @@ static netdev_tx_t tun_net_xmit(struct s + } + } + ++ /* Orphan the skb - required as we might hang on to it ++ * for indefinite time. */ ++ skb_orphan(skb); ++ + /* Enqueue packet */ + skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); + dev->trans_start = jiffies; diff --git a/queue-2.6.33/udp-fix-for-unicast-rx-path-optimization.patch b/queue-2.6.33/udp-fix-for-unicast-rx-path-optimization.patch new file mode 100644 index 00000000000..879515aca19 --- /dev/null +++ b/queue-2.6.33/udp-fix-for-unicast-rx-path-optimization.patch @@ -0,0 +1,57 @@ +From fc8416e5e57ab7d9eb2d512e758f489c72852ed4 Mon Sep 17 00:00:00 2001 +From: Jorge Boncompte [DTI2] +Date: Thu, 8 Apr 2010 04:56:48 +0000 +Subject: udp: fix for unicast RX path optimization + + +From: Jorge Boncompte [DTI2] + +[ Upstream commit 1223c67c0938d2df309fde618bd82c87c8c1af04 ] + +Commits 5051ebd275de672b807c28d93002c2fb0514a3c9 and +5051ebd275de672b807c28d93002c2fb0514a3c9 ("ipv[46]: udp: optimize unicast RX +path") broke some programs. + + After upgrading a L2TP server to 2.6.33 it started to fail, tunnels going up an +down, after the 10th tunnel came up. My modified rp-l2tp uses a global +unconnected socket bound to (INADDR_ANY, 1701) and one connected socket per +tunnel after parameter negotiation. + + After ten sockets were open and due to mixed parameters to +udp[46]_lib_lookup2() kernel started to drop packets. + +Signed-off-by: Jorge Boncompte [DTI2] +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 4 ++-- + net/ipv6/udp.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -471,8 +471,8 @@ static struct sock *__udp4_lib_lookup(st + if (hslot->count < hslot2->count) + goto begin; + +- result = udp4_lib_lookup2(net, INADDR_ANY, sport, +- daddr, hnum, dif, ++ result = udp4_lib_lookup2(net, saddr, sport, ++ INADDR_ANY, hnum, dif, + hslot2, slot2); + } + rcu_read_unlock(); +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -258,8 +258,8 @@ static struct sock *__udp6_lib_lookup(st + if (hslot->count < hslot2->count) + goto begin; + +- result = udp6_lib_lookup2(net, &in6addr_any, sport, +- daddr, hnum, dif, ++ result = udp6_lib_lookup2(net, saddr, sport, ++ &in6addr_any, hnum, dif, + hslot2, slot2); + } + rcu_read_unlock(); diff --git a/queue-2.6.33/wan-flush-tx_queue-in-hdlc_ppp-to-prevent-panic-on-rmmod-hw_driver.patch b/queue-2.6.33/wan-flush-tx_queue-in-hdlc_ppp-to-prevent-panic-on-rmmod-hw_driver.patch new file mode 100644 index 00000000000..ec5a28f4e1e --- /dev/null +++ b/queue-2.6.33/wan-flush-tx_queue-in-hdlc_ppp-to-prevent-panic-on-rmmod-hw_driver.patch @@ -0,0 +1,42 @@ +From 8c773e04509732500d6ae245a6f4a163425a7403 Mon Sep 17 00:00:00 2001 +From: Krzysztof Halasa +Date: Wed, 14 Apr 2010 14:09:52 +0000 +Subject: WAN: flush tx_queue in hdlc_ppp to prevent panic on rmmod hw_driver. + + +From: Krzysztof Halasa + +[ Upstream commit 31f634a63de7068c6a5dcb0d7b09b24b61a5cf88 ] + +tx_queue is used as a temporary queue when not allowed to queue skb +directly to the hw device driver (which may sleep). Most paths flush +it before returning, but ppp_start() currently cannot. Make sure we +don't leave skbs pointing to a non-existent device. + +Thanks to Michael Barkowski for reporting this problem. + +Signed-off-by: Krzysztof Hałasa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wan/hdlc_ppp.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wan/hdlc_ppp.c ++++ b/drivers/net/wan/hdlc_ppp.c +@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device * + ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL); + } + ++static void ppp_close(struct net_device *dev) ++{ ++ ppp_tx_flush(); ++} ++ + static struct hdlc_proto proto = { + .start = ppp_start, + .stop = ppp_stop, ++ .close = ppp_close, + .type_trans = ppp_type_trans, + .ioctl = ppp_ioctl, + .netif_rx = ppp_rx, -- 2.47.3