commit: 29844256de5e753a88a18e250b81b1d20b16c783 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Mon Apr 13 11:13:48 2020 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Mon Apr 13 11:13:48 2020 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=29844256
Linux patch 4.4.219 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1218_linux-4.4.219.patch | 1261 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1265 insertions(+) diff --git a/0000_README b/0000_README index 48c827e..3d36ad7 100644 --- a/0000_README +++ b/0000_README @@ -915,6 +915,10 @@ Patch: 1217_linux-4.4.218.patch From: http://www.kernel.org Desc: Linux 4.4.218 +Patch: 1218_linux-4.4.219.patch +From: http://www.kernel.org +Desc: Linux 4.4.219 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1218_linux-4.4.219.patch b/1218_linux-4.4.219.patch new file mode 100644 index 0000000..426540a --- /dev/null +++ b/1218_linux-4.4.219.patch @@ -0,0 +1,1261 @@ +diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c +index f40578026a04..8b14a6b08862 100644 +--- a/Documentation/accounting/getdelays.c ++++ b/Documentation/accounting/getdelays.c +@@ -135,7 +135,7 @@ static int send_cmd(int sd, __u16 nlmsg_type, __u32 nlmsg_pid, + msg.g.version = 0x1; + na = (struct nlattr *) GENLMSG_DATA(&msg); + na->nla_type = nla_type; +- na->nla_len = nla_len + 1 + NLA_HDRLEN; ++ na->nla_len = nla_len + NLA_HDRLEN; + memcpy(NLA_DATA(na), nla_data, nla_len); + msg.n.nlmsg_len += NLMSG_ALIGN(na->nla_len); + +diff --git a/Makefile b/Makefile +index 2a06e5e4cc8d..738ef5d8ec0f 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 218 ++SUBLEVEL = 219 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index 2916d08ee30e..661ed5ec546e 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1824,9 +1824,6 @@ unsigned int get_random_int(void) + __u32 *hash; + unsigned int ret; + +- if (arch_get_random_int(&ret)) +- return ret; +- + hash = get_cpu_var(get_random_int_hash); + + hash[0] += current->pid + jiffies + random_get_entropy(); +@@ -1846,9 +1843,6 @@ unsigned long get_random_long(void) + __u32 *hash; + unsigned long ret; + +- if (arch_get_random_long(&ret)) +- return ret; +- + hash = get_cpu_var(get_random_int_hash); + + hash[0] += current->pid + jiffies + random_get_entropy(); +diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c +index 8b549ece9f13..d5f3fcc30002 100644 +--- a/drivers/clk/qcom/clk-rcg2.c ++++ b/drivers/clk/qcom/clk-rcg2.c +@@ -107,7 +107,7 @@ static int update_config(struct clk_rcg2 *rcg) + } + + WARN(1, "%s: rcg didn't update its configuration.", name); +- return 0; ++ return -EBUSY; + } + + static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index) +diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c +index a39b0343c197..401c218567af 100644 +--- a/drivers/gpu/drm/bochs/bochs_hw.c ++++ b/drivers/gpu/drm/bochs/bochs_hw.c +@@ -97,10 +97,8 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) + size = min(size, mem); + } + +- if (pci_request_region(pdev, 0, "bochs-drm") != 0) { +- DRM_ERROR("Cannot request framebuffer\n"); +- return -EBUSY; +- } ++ if (pci_request_region(pdev, 0, "bochs-drm") != 0) ++ DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); + + bochs->fb_map = ioremap(addr, size); + if (bochs->fb_map == NULL) { +diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c +index 2cb924ffd5a3..f5229b083f8e 100644 +--- a/drivers/gpu/drm/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/drm_dp_mst_topology.c +@@ -431,6 +431,7 @@ static bool drm_dp_sideband_parse_remote_dpcd_read(struct drm_dp_sideband_msg_rx + if (idx > raw->curlen) + goto fail_len; + repmsg->u.remote_dpcd_read_ack.num_bytes = raw->msg[idx]; ++ idx++; + if (idx > raw->curlen) + goto fail_len; + +diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c +index 5ed9b5f8a037..b59a4a819aaa 100644 +--- a/drivers/infiniband/core/cma.c ++++ b/drivers/infiniband/core/cma.c +@@ -2378,6 +2378,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) + err2: + kfree(route->path_rec); + route->path_rec = NULL; ++ route->num_paths = 0; + err1: + kfree(work); + return ret; +diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c +index 27f42763eaf5..5bacb019ec1f 100644 +--- a/drivers/net/can/slcan.c ++++ b/drivers/net/can/slcan.c +@@ -147,7 +147,7 @@ static void slc_bump(struct slcan *sl) + u32 tmpid; + char *cmd = sl->rbuff; + +- cf.can_id = 0; ++ memset(&cf, 0, sizeof(cf)); + + switch (*cmd) { + case 'r': +@@ -186,8 +186,6 @@ static void slc_bump(struct slcan *sl) + else + return; + +- *(u64 *) (&cf.data) = 0; /* clear payload */ +- + /* RTR frames may have a dlc > 0 but they never have any data bytes */ + if (!(cf.can_id & CAN_RTR_FLAG)) { + for (i = 0; i < cf.can_dlc; i++) { +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +index 1df84c8de9d7..b535f6c37838 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +@@ -188,7 +188,7 @@ static void dwmac1000_set_filter(struct mac_device_info *hw, + reg++; + } + +- while (reg <= perfect_addr_number) { ++ while (reg < perfect_addr_number) { + writel(0, ioaddr + GMAC_ADDR_HIGH(reg)); + writel(0, ioaddr + GMAC_ADDR_LOW(reg)); + reg++; +diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c +index 89eec6fead75..e99a07d5fda7 100644 +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1835,7 +1835,7 @@ static int talk_to_netback(struct xenbus_device *dev, + err = xen_net_read_mac(dev, info->netdev->dev_addr); + if (err) { + xenbus_dev_fatal(dev, err, "parsing %s/mac", dev->nodename); +- goto out; ++ goto out_unlocked; + } + + rtnl_lock(); +@@ -1950,6 +1950,7 @@ abort_transaction_no_dev_fatal: + xennet_destroy_queues(info); + out: + rtnl_unlock(); ++out_unlocked: + device_unregister(&dev->dev); + return err; + } +@@ -1981,10 +1982,6 @@ static int xennet_connect(struct net_device *dev) + /* talk_to_netback() sets the correct number of queues */ + num_queues = dev->real_num_tx_queues; + +- rtnl_lock(); +- netdev_update_features(dev); +- rtnl_unlock(); +- + if (dev->reg_state == NETREG_UNINITIALIZED) { + err = register_netdev(dev); + if (err) { +@@ -1994,6 +1991,10 @@ static int xennet_connect(struct net_device *dev) + } + } + ++ rtnl_lock(); ++ netdev_update_features(dev); ++ rtnl_unlock(); ++ + /* + * All public and private state should now be sane. Get + * ready to start sending and receiving packets and give the driver +diff --git a/drivers/power/axp288_charger.c b/drivers/power/axp288_charger.c +index e4d569f57acc..0c6fed79c363 100644 +--- a/drivers/power/axp288_charger.c ++++ b/drivers/power/axp288_charger.c +@@ -883,6 +883,10 @@ static int axp288_charger_probe(struct platform_device *pdev) + /* Register charger interrupts */ + for (i = 0; i < CHRG_INTR_END; i++) { + pirq = platform_get_irq(info->pdev, i); ++ if (pirq < 0) { ++ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pirq); ++ return pirq; ++ } + info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); + if (info->irq[i] < 0) { + dev_warn(&info->pdev->dev, +diff --git a/drivers/staging/rdma/hfi1/sysfs.c b/drivers/staging/rdma/hfi1/sysfs.c +index 1dd6727dd5ef..a86828f44c4d 100644 +--- a/drivers/staging/rdma/hfi1/sysfs.c ++++ b/drivers/staging/rdma/hfi1/sysfs.c +@@ -620,7 +620,11 @@ int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, + dd_dev_err(dd, + "Skipping sc2vl sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail; ++ /* ++ * Based on the documentation for kobject_init_and_add(), the ++ * caller should call kobject_put even if this call fails. ++ */ ++ goto bail_sc2vl; + } + kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); + +@@ -630,7 +634,7 @@ int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, + dd_dev_err(dd, + "Skipping sl2sc sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail_sc2vl; ++ goto bail_sl2sc; + } + kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); + +@@ -640,7 +644,7 @@ int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, + dd_dev_err(dd, + "Skipping vl2mtu sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail_sl2sc; ++ goto bail_vl2mtu; + } + kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); + +@@ -651,7 +655,7 @@ int hfi1_create_port_files(struct ib_device *ibdev, u8 port_num, + dd_dev_err(dd, + "Skipping Congestion Control sysfs info, (err %d) port %u\n", + ret, port_num); +- goto bail_vl2mtu; ++ goto bail_cc; + } + + kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); +@@ -691,7 +695,6 @@ bail_sl2sc: + kobject_put(&ppd->sl2sc_kobj); + bail_sc2vl: + kobject_put(&ppd->sc2vl_kobj); +-bail: + return ret; + } + +diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c +index 0fbfb2b2aa08..69afc17fca38 100644 +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -161,14 +161,6 @@ static struct usb_endpoint_descriptor hs_ep_out_desc = { + .wMaxPacketSize = cpu_to_le16(512) + }; + +-static struct usb_qualifier_descriptor dev_qualifier = { +- .bLength = sizeof(dev_qualifier), +- .bDescriptorType = USB_DT_DEVICE_QUALIFIER, +- .bcdUSB = cpu_to_le16(0x0200), +- .bDeviceClass = USB_CLASS_PRINTER, +- .bNumConfigurations = 1 +-}; +- + static struct usb_descriptor_header *hs_printer_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &hs_ep_in_desc, +diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c +index e931c3cb0840..ac190650314a 100644 +--- a/drivers/usb/gadget/function/f_uac2.c ++++ b/drivers/usb/gadget/function/f_uac2.c +@@ -598,18 +598,6 @@ static struct usb_gadget_strings *fn_strings[] = { + NULL, + }; + +-static struct usb_qualifier_descriptor devqual_desc = { +- .bLength = sizeof devqual_desc, +- .bDescriptorType = USB_DT_DEVICE_QUALIFIER, +- +- .bcdUSB = cpu_to_le16(0x200), +- .bDeviceClass = USB_CLASS_MISC, +- .bDeviceSubClass = 0x02, +- .bDeviceProtocol = 0x01, +- .bNumConfigurations = 1, +- .bRESERVED = 0, +-}; +- + static struct usb_interface_assoc_descriptor iad_desc = { + .bLength = sizeof iad_desc, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, +diff --git a/kernel/padata.c b/kernel/padata.c +index 0d7ec5fd520b..ae036af3f012 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -640,8 +640,8 @@ int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, + struct cpumask *serial_mask, *parallel_mask; + int err = -EINVAL; + +- mutex_lock(&pinst->lock); + get_online_cpus(); ++ mutex_lock(&pinst->lock); + + switch (cpumask_type) { + case PADATA_CPU_PARALLEL: +@@ -659,8 +659,8 @@ int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type, + err = __padata_set_cpumasks(pinst, parallel_mask, serial_mask); + + out: +- put_online_cpus(); + mutex_unlock(&pinst->lock); ++ put_online_cpus(); + + return err; + } +diff --git a/mm/mempolicy.c b/mm/mempolicy.c +index 41c678199b80..e101cac3d4a6 100644 +--- a/mm/mempolicy.c ++++ b/mm/mempolicy.c +@@ -2725,7 +2725,9 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) + switch (mode) { + case MPOL_PREFERRED: + /* +- * Insist on a nodelist of one node only ++ * Insist on a nodelist of one node only, although later ++ * we use first_node(nodes) to grab a single node, so here ++ * nodelist (or nodes) cannot be empty. + */ + if (nodelist) { + char *rest = nodelist; +@@ -2733,6 +2735,8 @@ int mpol_parse_str(char *str, struct mempolicy **mpol) + rest++; + if (*rest) + goto out; ++ if (nodes_empty(nodes)) ++ goto out; + } + break; + case MPOL_INTERLEAVE: +diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c +index 8e385a0ae60e..939fbf7b352d 100644 +--- a/net/bluetooth/rfcomm/tty.c ++++ b/net/bluetooth/rfcomm/tty.c +@@ -413,10 +413,8 @@ static int __rfcomm_create_dev(struct sock *sk, void __user *arg) + dlc = rfcomm_dlc_exists(&req.src, &req.dst, req.channel); + if (IS_ERR(dlc)) + return PTR_ERR(dlc); +- else if (dlc) { +- rfcomm_dlc_put(dlc); ++ if (dlc) + return -EBUSY; +- } + dlc = rfcomm_dlc_alloc(GFP_KERNEL); + if (!dlc) + return -ENOMEM; +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index fdaa905dccdd..0d87639deb27 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -2230,6 +2230,7 @@ static int fib_triestat_seq_show(struct seq_file *seq, void *v) + " %Zd bytes, size of tnode: %Zd bytes.\n", + LEAF_SIZE, TNODE_SIZE(0)); + ++ rcu_read_lock(); + for (h = 0; h < FIB_TABLE_HASHSZ; h++) { + struct hlist_head *head = &net->ipv4.fib_table_hash[h]; + struct fib_table *tb; +@@ -2249,7 +2250,9 @@ static int fib_triestat_seq_show(struct seq_file *seq, void *v) + trie_show_usage(seq, t->stats); + #endif + } ++ cond_resched_rcu(); + } ++ rcu_read_unlock(); + + return 0; + } +diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c +index e598aa14f167..20b21f8578e1 100644 +--- a/net/ipv4/ip_tunnel.c ++++ b/net/ipv4/ip_tunnel.c +@@ -155,11 +155,8 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + cand = t; + } + +- if (flags & TUNNEL_NO_KEY) +- goto skip_key_lookup; +- + hlist_for_each_entry_rcu(t, head, hash_node) { +- if (t->parms.i_key != key || ++ if ((!(flags & TUNNEL_NO_KEY) && t->parms.i_key != key) || + t->parms.iph.saddr != 0 || + t->parms.iph.daddr != 0 || + !(t->dev->flags & IFF_UP)) +@@ -171,7 +168,6 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, + cand = t; + } + +-skip_key_lookup: + if (cand) + return cand; + +diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c +index 429dbb064240..2b8b5c57c7f0 100644 +--- a/net/l2tp/l2tp_core.c ++++ b/net/l2tp/l2tp_core.c +@@ -277,6 +277,55 @@ struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunn + } + EXPORT_SYMBOL_GPL(l2tp_session_find); + ++/* Like l2tp_session_find() but takes a reference on the returned session. ++ * Optionally calls session->ref() too if do_ref is true. ++ */ ++struct l2tp_session *l2tp_session_get(struct net *net, ++ struct l2tp_tunnel *tunnel, ++ u32 session_id, bool do_ref) ++{ ++ struct hlist_head *session_list; ++ struct l2tp_session *session; ++ ++ if (!tunnel) { ++ struct l2tp_net *pn = l2tp_pernet(net); ++ ++ session_list = l2tp_session_id_hash_2(pn, session_id); ++ ++ rcu_read_lock_bh(); ++ hlist_for_each_entry_rcu(session, session_list, global_hlist) { ++ if (session->session_id == session_id) { ++ l2tp_session_inc_refcount(session); ++ if (do_ref && session->ref) ++ session->ref(session); ++ rcu_read_unlock_bh(); ++ ++ return session; ++ } ++ } ++ rcu_read_unlock_bh(); ++ ++ return NULL; ++ } ++ ++ session_list = l2tp_session_id_hash(tunnel, session_id); ++ read_lock_bh(&tunnel->hlist_lock); ++ hlist_for_each_entry(session, session_list, hlist) { ++ if (session->session_id == session_id) { ++ l2tp_session_inc_refcount(session); ++ if (do_ref && session->ref) ++ session->ref(session); ++ read_unlock_bh(&tunnel->hlist_lock); ++ ++ return session; ++ } ++ } ++ read_unlock_bh(&tunnel->hlist_lock); ++ ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(l2tp_session_get); ++ + struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth, + bool do_ref) + { +@@ -328,6 +377,48 @@ struct l2tp_session *l2tp_session_find_by_ifname(struct net *net, char *ifname) + } + EXPORT_SYMBOL_GPL(l2tp_session_find_by_ifname); + ++static int l2tp_session_add_to_tunnel(struct l2tp_tunnel *tunnel, ++ struct l2tp_session *session) ++{ ++ struct l2tp_session *session_walk; ++ struct hlist_head *g_head; ++ struct hlist_head *head; ++ struct l2tp_net *pn; ++ ++ head = l2tp_session_id_hash(tunnel, session->session_id); ++ ++ write_lock_bh(&tunnel->hlist_lock); ++ hlist_for_each_entry(session_walk, head, hlist) ++ if (session_walk->session_id == session->session_id) ++ goto exist; ++ ++ if (tunnel->version == L2TP_HDR_VER_3) { ++ pn = l2tp_pernet(tunnel->l2tp_net); ++ g_head = l2tp_session_id_hash_2(l2tp_pernet(tunnel->l2tp_net), ++ session->session_id); ++ ++ spin_lock_bh(&pn->l2tp_session_hlist_lock); ++ hlist_for_each_entry(session_walk, g_head, global_hlist) ++ if (session_walk->session_id == session->session_id) ++ goto exist_glob; ++ ++ hlist_add_head_rcu(&session->global_hlist, g_head); ++ spin_unlock_bh(&pn->l2tp_session_hlist_lock); ++ } ++ ++ hlist_add_head(&session->hlist, head); ++ write_unlock_bh(&tunnel->hlist_lock); ++ ++ return 0; ++ ++exist_glob: ++ spin_unlock_bh(&pn->l2tp_session_hlist_lock); ++exist: ++ write_unlock_bh(&tunnel->hlist_lock); ++ ++ return -EEXIST; ++} ++ + /* Lookup a tunnel by id + */ + struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id) +@@ -636,6 +727,9 @@ discard: + * a data (not control) frame before coming here. Fields up to the + * session-id have already been parsed and ptr points to the data + * after the session-id. ++ * ++ * session->ref() must have been called prior to l2tp_recv_common(). ++ * session->deref() will be called automatically after skb is processed. + */ + void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, + unsigned char *ptr, unsigned char *optr, u16 hdrflags, +@@ -645,14 +739,6 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, + int offset; + u32 ns, nr; + +- /* The ref count is increased since we now hold a pointer to +- * the session. Take care to decrement the refcnt when exiting +- * this function from now on... +- */ +- l2tp_session_inc_refcount(session); +- if (session->ref) +- (*session->ref)(session); +- + /* Parse and check optional cookie */ + if (session->peer_cookie_len > 0) { + if (memcmp(ptr, &session->peer_cookie[0], session->peer_cookie_len)) { +@@ -803,8 +889,6 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, + /* Try to dequeue as many skbs from reorder_q as we can. */ + l2tp_recv_dequeue(session); + +- l2tp_session_dec_refcount(session); +- + return; + + discard: +@@ -813,8 +897,6 @@ discard: + + if (session->deref) + (*session->deref)(session); +- +- l2tp_session_dec_refcount(session); + } + EXPORT_SYMBOL(l2tp_recv_common); + +@@ -921,8 +1003,14 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, + } + + /* Find the session context */ +- session = l2tp_session_find(tunnel->l2tp_net, tunnel, session_id); ++ session = l2tp_session_get(tunnel->l2tp_net, tunnel, session_id, true); + if (!session || !session->recv_skb) { ++ if (session) { ++ if (session->deref) ++ session->deref(session); ++ l2tp_session_dec_refcount(session); ++ } ++ + /* Not found? Pass to userspace to deal with */ + l2tp_info(tunnel, L2TP_MSG_DATA, + "%s: no session found (%u/%u). Passing up.\n", +@@ -935,6 +1023,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, + goto error; + + l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook); ++ l2tp_session_dec_refcount(session); + + return 0; + +@@ -1262,6 +1351,9 @@ again: + + hlist_del_init(&session->hlist); + ++ if (test_and_set_bit(0, &session->dead)) ++ goto again; ++ + if (session->ref != NULL) + (*session->ref)(session); + +@@ -1710,6 +1802,9 @@ EXPORT_SYMBOL_GPL(__l2tp_session_unhash); + */ + int l2tp_session_delete(struct l2tp_session *session) + { ++ if (test_and_set_bit(0, &session->dead)) ++ return 0; ++ + if (session->ref) + (*session->ref)(session); + __l2tp_session_unhash(session); +@@ -1745,6 +1840,7 @@ EXPORT_SYMBOL_GPL(l2tp_session_set_header_len); + struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) + { + struct l2tp_session *session; ++ int err; + + session = kzalloc(sizeof(struct l2tp_session) + priv_size, GFP_KERNEL); + if (session != NULL) { +@@ -1800,6 +1896,13 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn + + l2tp_session_set_header_len(session, tunnel->version); + ++ err = l2tp_session_add_to_tunnel(tunnel, session); ++ if (err) { ++ kfree(session); ++ ++ return ERR_PTR(err); ++ } ++ + /* Bump the reference count. The session context is deleted + * only when this drops to zero. + */ +@@ -1809,28 +1912,14 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn + /* Ensure tunnel socket isn't deleted */ + sock_hold(tunnel->sock); + +- /* Add session to the tunnel's hash list */ +- write_lock_bh(&tunnel->hlist_lock); +- hlist_add_head(&session->hlist, +- l2tp_session_id_hash(tunnel, session_id)); +- write_unlock_bh(&tunnel->hlist_lock); +- +- /* And to the global session list if L2TPv3 */ +- if (tunnel->version != L2TP_HDR_VER_2) { +- struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net); +- +- spin_lock_bh(&pn->l2tp_session_hlist_lock); +- hlist_add_head_rcu(&session->global_hlist, +- l2tp_session_id_hash_2(pn, session_id)); +- spin_unlock_bh(&pn->l2tp_session_hlist_lock); +- } +- + /* Ignore management session in session count value */ + if (session->session_id != 0) + atomic_inc(&l2tp_session_count); ++ ++ return session; + } + +- return session; ++ return ERR_PTR(-ENOMEM); + } + EXPORT_SYMBOL_GPL(l2tp_session_create); + +diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h +index fad47e9d74bc..06323a12d62c 100644 +--- a/net/l2tp/l2tp_core.h ++++ b/net/l2tp/l2tp_core.h +@@ -85,6 +85,7 @@ struct l2tp_session_cfg { + struct l2tp_session { + int magic; /* should be + * L2TP_SESSION_MAGIC */ ++ long dead; + + struct l2tp_tunnel *tunnel; /* back pointer to tunnel + * context */ +@@ -243,6 +244,9 @@ out: + return tunnel; + } + ++struct l2tp_session *l2tp_session_get(struct net *net, ++ struct l2tp_tunnel *tunnel, ++ u32 session_id, bool do_ref); + struct l2tp_session *l2tp_session_find(struct net *net, + struct l2tp_tunnel *tunnel, + u32 session_id); +diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c +index e253c26f31ac..c94160df71af 100644 +--- a/net/l2tp/l2tp_eth.c ++++ b/net/l2tp/l2tp_eth.c +@@ -223,12 +223,6 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p + goto out; + } + +- session = l2tp_session_find(net, tunnel, session_id); +- if (session) { +- rc = -EEXIST; +- goto out; +- } +- + if (cfg->ifname) { + dev = dev_get_by_name(net, cfg->ifname); + if (dev) { +@@ -242,8 +236,8 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p + + session = l2tp_session_create(sizeof(*spriv), tunnel, session_id, + peer_session_id, cfg); +- if (!session) { +- rc = -ENOMEM; ++ if (IS_ERR(session)) { ++ rc = PTR_ERR(session); + goto out; + } + +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index 7efb3cadc152..58f87bdd12c7 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -142,19 +142,19 @@ static int l2tp_ip_recv(struct sk_buff *skb) + } + + /* Ok, this is a data packet. Lookup the session. */ +- session = l2tp_session_find(net, NULL, session_id); +- if (session == NULL) ++ session = l2tp_session_get(net, NULL, session_id, true); ++ if (!session) + goto discard; + + tunnel = session->tunnel; +- if (tunnel == NULL) +- goto discard; ++ if (!tunnel) ++ goto discard_sess; + + /* Trace packet contents, if enabled */ + if (tunnel->debug & L2TP_MSG_DATA) { + length = min(32u, skb->len); + if (!pskb_may_pull(skb, length)) +- goto discard; ++ goto discard_sess; + + /* Point to L2TP header */ + optr = ptr = skb->data; +@@ -167,6 +167,7 @@ static int l2tp_ip_recv(struct sk_buff *skb) + goto discard; + + l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); ++ l2tp_session_dec_refcount(session); + + return 0; + +@@ -204,6 +205,12 @@ pass_up: + + return sk_receive_skb(sk, skb, 1); + ++discard_sess: ++ if (session->deref) ++ session->deref(session); ++ l2tp_session_dec_refcount(session); ++ goto discard; ++ + discard_put: + sock_put(sk); + +diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c +index a88649c5d26c..af04a8a68269 100644 +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -127,6 +127,7 @@ static inline struct sock *l2tp_ip6_bind_lookup(struct net *net, + */ + static int l2tp_ip6_recv(struct sk_buff *skb) + { ++ struct net *net = dev_net(skb->dev); + struct sock *sk; + u32 session_id; + u32 tunnel_id; +@@ -153,19 +154,19 @@ static int l2tp_ip6_recv(struct sk_buff *skb) + } + + /* Ok, this is a data packet. Lookup the session. */ +- session = l2tp_session_find(&init_net, NULL, session_id); +- if (session == NULL) ++ session = l2tp_session_get(net, NULL, session_id, true); ++ if (!session) + goto discard; + + tunnel = session->tunnel; +- if (tunnel == NULL) +- goto discard; ++ if (!tunnel) ++ goto discard_sess; + + /* Trace packet contents, if enabled */ + if (tunnel->debug & L2TP_MSG_DATA) { + length = min(32u, skb->len); + if (!pskb_may_pull(skb, length)) +- goto discard; ++ goto discard_sess; + + /* Point to L2TP header */ + optr = ptr = skb->data; +@@ -179,6 +180,8 @@ static int l2tp_ip6_recv(struct sk_buff *skb) + + l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, + tunnel->recv_payload_hook); ++ l2tp_session_dec_refcount(session); ++ + return 0; + + pass_up: +@@ -190,7 +193,7 @@ pass_up: + goto discard; + + tunnel_id = ntohl(*(__be32 *) &skb->data[4]); +- tunnel = l2tp_tunnel_find(&init_net, tunnel_id); ++ tunnel = l2tp_tunnel_find(net, tunnel_id); + if (tunnel) { + sk = tunnel->sock; + sock_hold(sk); +@@ -198,7 +201,7 @@ pass_up: + struct ipv6hdr *iph = ipv6_hdr(skb); + + read_lock_bh(&l2tp_ip6_lock); +- sk = __l2tp_ip6_bind_lookup(&init_net, &iph->daddr, ++ sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, + 0, tunnel_id); + if (!sk) { + read_unlock_bh(&l2tp_ip6_lock); +@@ -216,6 +219,12 @@ pass_up: + + return sk_receive_skb(sk, skb, 1); + ++discard_sess: ++ if (session->deref) ++ session->deref(session); ++ l2tp_session_dec_refcount(session); ++ goto discard; ++ + discard_put: + sock_put(sk); + +@@ -267,6 +276,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) + struct inet_sock *inet = inet_sk(sk); + struct ipv6_pinfo *np = inet6_sk(sk); + struct sockaddr_l2tpip6 *addr = (struct sockaddr_l2tpip6 *) uaddr; ++ struct net *net = sock_net(sk); + __be32 v4addr = 0; + int addr_type; + int err; +@@ -288,7 +298,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) + + err = -EADDRINUSE; + read_lock_bh(&l2tp_ip6_lock); +- if (__l2tp_ip6_bind_lookup(&init_net, &addr->l2tp_addr, ++ if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, + sk->sk_bound_dev_if, addr->l2tp_conn_id)) + goto out_in_use; + read_unlock_bh(&l2tp_ip6_lock); +@@ -461,7 +471,7 @@ static int l2tp_ip6_backlog_recv(struct sock *sk, struct sk_buff *skb) + return 0; + + drop: +- IP_INC_STATS(&init_net, IPSTATS_MIB_INDISCARDS); ++ IP_INC_STATS(sock_net(sk), IPSTATS_MIB_INDISCARDS); + kfree_skb(skb); + return -1; + } +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index d3f1222c1a8c..bc5d6b8f8ede 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -177,7 +177,7 @@ static int pppol2tp_recv_payload_hook(struct sk_buff *skb) + if (!pskb_may_pull(skb, 2)) + return 1; + +- if ((skb->data[0] == 0xff) && (skb->data[1] == 0x03)) ++ if ((skb->data[0] == PPP_ALLSTATIONS) && (skb->data[1] == PPP_UI)) + skb_pull(skb, 2); + + return 0; +@@ -297,7 +297,6 @@ static void pppol2tp_session_sock_put(struct l2tp_session *session) + static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, + size_t total_len) + { +- static const unsigned char ppph[2] = { 0xff, 0x03 }; + struct sock *sk = sock->sk; + struct sk_buff *skb; + int error; +@@ -327,7 +326,7 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, + error = -ENOMEM; + skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) + + uhlen + session->hdr_len + +- sizeof(ppph) + total_len, ++ 2 + total_len, /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */ + 0, GFP_KERNEL); + if (!skb) + goto error_put_sess_tun; +@@ -340,8 +339,8 @@ static int pppol2tp_sendmsg(struct socket *sock, struct msghdr *m, + skb_reserve(skb, uhlen); + + /* Add PPP header */ +- skb->data[0] = ppph[0]; +- skb->data[1] = ppph[1]; ++ skb->data[0] = PPP_ALLSTATIONS; ++ skb->data[1] = PPP_UI; + skb_put(skb, 2); + + /* Copy user data into skb */ +@@ -384,7 +383,6 @@ error: + */ + static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) + { +- static const u8 ppph[2] = { 0xff, 0x03 }; + struct sock *sk = (struct sock *) chan->private; + struct sock *sk_tun; + struct l2tp_session *session; +@@ -413,14 +411,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) + sizeof(struct iphdr) + /* IP header */ + uhlen + /* UDP header (if L2TP_ENCAPTYPE_UDP) */ + session->hdr_len + /* L2TP header */ +- sizeof(ppph); /* PPP header */ ++ 2; /* 2 bytes for PPP_ALLSTATIONS & PPP_UI */ + if (skb_cow_head(skb, headroom)) + goto abort_put_sess_tun; + + /* Setup PPP header */ +- __skb_push(skb, sizeof(ppph)); +- skb->data[0] = ppph[0]; +- skb->data[1] = ppph[1]; ++ __skb_push(skb, 2); ++ skb->data[0] = PPP_ALLSTATIONS; ++ skb->data[1] = PPP_UI; + + local_bh_disable(); + l2tp_xmit_skb(session, skb, session->hdr_len); +@@ -454,11 +452,11 @@ static void pppol2tp_session_close(struct l2tp_session *session) + + BUG_ON(session->magic != L2TP_SESSION_MAGIC); + +- if (sock) { +- inet_shutdown(sock, 2); +- /* Don't let the session go away before our socket does */ +- l2tp_session_inc_refcount(session); +- } ++ if (sock) ++ inet_shutdown(sock, SEND_SHUTDOWN); ++ ++ /* Don't let the session go away before our socket does */ ++ l2tp_session_inc_refcount(session); + } + + /* Really kill the session socket. (Called from sock_put() if +@@ -600,6 +598,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, + int error = 0; + u32 tunnel_id, peer_tunnel_id; + u32 session_id, peer_session_id; ++ bool drop_refcnt = false; + int ver = 2; + int fd; + +@@ -708,36 +707,36 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, + if (tunnel->peer_tunnel_id == 0) + tunnel->peer_tunnel_id = peer_tunnel_id; + +- /* Create session if it doesn't already exist. We handle the +- * case where a session was previously created by the netlink +- * interface by checking that the session doesn't already have +- * a socket and its tunnel socket are what we expect. If any +- * of those checks fail, return EEXIST to the caller. +- */ +- session = l2tp_session_find(sock_net(sk), tunnel, session_id); +- if (session == NULL) { +- /* Default MTU must allow space for UDP/L2TP/PPP +- * headers. ++ session = l2tp_session_get(sock_net(sk), tunnel, session_id, false); ++ if (session) { ++ drop_refcnt = true; ++ ps = l2tp_session_priv(session); ++ ++ /* Using a pre-existing session is fine as long as it hasn't ++ * been connected yet. + */ +- cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD; ++ if (ps->sock) { ++ error = -EEXIST; ++ goto end; ++ } + +- /* Allocate and initialize a new session context. */ +- session = l2tp_session_create(sizeof(struct pppol2tp_session), +- tunnel, session_id, +- peer_session_id, &cfg); +- if (session == NULL) { +- error = -ENOMEM; ++ /* consistency checks */ ++ if (ps->tunnel_sock != tunnel->sock) { ++ error = -EEXIST; + goto end; + } + } else { +- ps = l2tp_session_priv(session); +- error = -EEXIST; +- if (ps->sock != NULL) +- goto end; ++ /* Default MTU must allow space for UDP/L2TP/PPP headers */ ++ cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD; ++ cfg.mru = cfg.mtu; + +- /* consistency checks */ +- if (ps->tunnel_sock != tunnel->sock) ++ session = l2tp_session_create(sizeof(struct pppol2tp_session), ++ tunnel, session_id, ++ peer_session_id, &cfg); ++ if (IS_ERR(session)) { ++ error = PTR_ERR(session); + goto end; ++ } + } + + /* Associate session with its PPPoL2TP socket */ +@@ -802,6 +801,8 @@ out_no_ppp: + session->name); + + end: ++ if (drop_refcnt) ++ l2tp_session_dec_refcount(session); + release_sock(sk); + + return error; +@@ -829,12 +830,6 @@ static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_i + if (tunnel->sock == NULL) + goto out; + +- /* Check that this session doesn't already exist */ +- error = -EEXIST; +- session = l2tp_session_find(net, tunnel, session_id); +- if (session != NULL) +- goto out; +- + /* Default MTU values. */ + if (cfg->mtu == 0) + cfg->mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD; +@@ -842,12 +837,13 @@ static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_i + cfg->mru = cfg->mtu; + + /* Allocate and initialize a new session context. */ +- error = -ENOMEM; + session = l2tp_session_create(sizeof(struct pppol2tp_session), + tunnel, session_id, + peer_session_id, cfg); +- if (session == NULL) ++ if (IS_ERR(session)) { ++ error = PTR_ERR(session); + goto out; ++ } + + ps = l2tp_session_priv(session); + ps->tunnel_sock = tunnel->sock; +@@ -889,10 +885,8 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, + + pls = l2tp_session_priv(session); + tunnel = l2tp_sock_to_tunnel(pls->tunnel_sock); +- if (tunnel == NULL) { +- error = -EBADF; ++ if (tunnel == NULL) + goto end_put_sess; +- } + + inet = inet_sk(tunnel->sock); + if ((tunnel->version == 2) && (tunnel->sock->sk_family == AF_INET)) { +@@ -970,12 +964,11 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, + } + + *usockaddr_len = len; ++ error = 0; + + sock_put(pls->tunnel_sock); + end_put_sess: + sock_put(sk); +- error = 0; +- + end: + return error; + } +@@ -1171,11 +1164,18 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel, + if (stats.session_id != 0) { + /* resend to session ioctl handler */ + struct l2tp_session *session = +- l2tp_session_find(sock_net(sk), tunnel, stats.session_id); +- if (session != NULL) +- err = pppol2tp_session_ioctl(session, cmd, arg); +- else ++ l2tp_session_get(sock_net(sk), tunnel, ++ stats.session_id, true); ++ ++ if (session) { ++ err = pppol2tp_session_ioctl(session, cmd, ++ arg); ++ if (session->deref) ++ session->deref(session); ++ l2tp_session_dec_refcount(session); ++ } else { + err = -EBADR; ++ } + break; + } + #ifdef CONFIG_XFRM +diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c +index ae619cffc3a9..dd097e065f39 100644 +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -234,7 +234,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + { + struct sctp_association *asoc = t->asoc; + struct dst_entry *dst = NULL; +- struct flowi6 *fl6 = &fl->u.ip6; ++ struct flowi _fl; ++ struct flowi6 *fl6 = &_fl.u.ip6; + struct sctp_bind_addr *bp; + struct ipv6_pinfo *np = inet6_sk(sk); + struct sctp_sockaddr_entry *laddr; +@@ -244,7 +245,7 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + __u8 matchlen = 0; + sctp_scope_t scope; + +- memset(fl6, 0, sizeof(struct flowi6)); ++ memset(&_fl, 0, sizeof(_fl)); + fl6->daddr = daddr->v6.sin6_addr; + fl6->fl6_dport = daddr->v6.sin6_port; + fl6->flowi6_proto = IPPROTO_SCTP; +@@ -268,8 +269,11 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + rcu_read_unlock(); + + dst = ip6_dst_lookup_flow(sk, fl6, final_p); +- if (!asoc || saddr) ++ if (!asoc || saddr) { ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); + goto out; ++ } + + bp = &asoc->base.bind_addr; + scope = sctp_scope(daddr); +@@ -292,6 +296,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + if ((laddr->a.sa.sa_family == AF_INET6) && + (sctp_v6_cmp_addr(&dst_saddr, &laddr->a))) { + rcu_read_unlock(); ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); + goto out; + } + } +@@ -330,6 +336,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + if (!IS_ERR_OR_NULL(dst)) + dst_release(dst); + dst = bdst; ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); + break; + } + +@@ -343,6 +351,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + dst_release(dst); + dst = bdst; + matchlen = bmatchlen; ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); + } + rcu_read_unlock(); + +@@ -351,14 +361,12 @@ out: + struct rt6_info *rt; + + rt = (struct rt6_info *)dst; +- t->dst = dst; + t->dst_cookie = rt6_get_cookie(rt); + pr_debug("rt6_dst:%pI6/%d rt6_src:%pI6\n", + &rt->rt6i_dst.addr, rt->rt6i_dst.plen, +- &fl6->saddr); ++ &fl->u.ip6.saddr); + } else { + t->dst = NULL; +- + pr_debug("no route\n"); + } + } +diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c +index 7e550265df87..9c6c42fd9f8a 100644 +--- a/net/sctp/protocol.c ++++ b/net/sctp/protocol.c +@@ -428,14 +428,15 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + { + struct sctp_association *asoc = t->asoc; + struct rtable *rt; +- struct flowi4 *fl4 = &fl->u.ip4; ++ struct flowi _fl; ++ struct flowi4 *fl4 = &_fl.u.ip4; + struct sctp_bind_addr *bp; + struct sctp_sockaddr_entry *laddr; + struct dst_entry *dst = NULL; + union sctp_addr *daddr = &t->ipaddr; + union sctp_addr dst_saddr; + +- memset(fl4, 0x0, sizeof(struct flowi4)); ++ memset(&_fl, 0x0, sizeof(_fl)); + fl4->daddr = daddr->v4.sin_addr.s_addr; + fl4->fl4_dport = daddr->v4.sin_port; + fl4->flowi4_proto = IPPROTO_SCTP; +@@ -453,8 +454,11 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + &fl4->saddr); + + rt = ip_route_output_key(sock_net(sk), fl4); +- if (!IS_ERR(rt)) ++ if (!IS_ERR(rt)) { + dst = &rt->dst; ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); ++ } + + /* If there is no association or if a source address is passed, no + * more validation is required. +@@ -517,27 +521,33 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, + odev = __ip_dev_find(sock_net(sk), laddr->a.v4.sin_addr.s_addr, + false); + if (!odev || odev->ifindex != fl4->flowi4_oif) { +- if (!dst) ++ if (!dst) { + dst = &rt->dst; +- else ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); ++ } else { + dst_release(&rt->dst); ++ } + continue; + } + + dst_release(dst); + dst = &rt->dst; ++ t->dst = dst; ++ memcpy(fl, &_fl, sizeof(_fl)); + break; + } + + out_unlock: + rcu_read_unlock(); + out: +- t->dst = dst; +- if (dst) ++ if (dst) { + pr_debug("rt_dst:%pI4, rt_src:%pI4\n", +- &fl4->daddr, &fl4->saddr); +- else ++ &fl->u.ip4.daddr, &fl->u.ip4.saddr); ++ } else { ++ t->dst = NULL; + pr_debug("no route\n"); ++ } + } + + /* For v4, the source address is cached in the route entry(dst). So no need +diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c +index 794a3499e567..0dc1ab48fceb 100644 +--- a/sound/soc/jz4740/jz4740-i2s.c ++++ b/sound/soc/jz4740/jz4740-i2s.c +@@ -92,7 +92,7 @@ + #define JZ_AIC_I2S_STATUS_BUSY BIT(2) + + #define JZ_AIC_CLK_DIV_MASK 0xf +-#define I2SDIV_DV_SHIFT 8 ++#define I2SDIV_DV_SHIFT 0 + #define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT) + #define I2SDIV_IDV_SHIFT 8 + #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
