From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:4.4 commit in: /
Date: Mon, 13 Apr 2020 11:14:06 +0000 (UTC) [thread overview]
Message-ID: <1586776428.29844256de5e753a88a18e250b81b1d20b16c783.mpagano@gentoo> (raw)
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)
next reply other threads:[~2020-04-13 11:14 UTC|newest]
Thread overview: 355+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-13 11:14 Mike Pagano [this message]
-- strict thread matches above, loose matches on Subject: below --
2022-02-03 11:46 [gentoo-commits] proj/linux-patches:4.4 commit in: / Mike Pagano
2022-01-29 17:47 Mike Pagano
2022-01-27 11:42 Mike Pagano
2022-01-11 12:57 Mike Pagano
2022-01-05 12:57 Mike Pagano
2021-12-29 13:13 Mike Pagano
2021-12-22 14:09 Mike Pagano
2021-12-14 10:38 Mike Pagano
2021-12-08 12:58 Mike Pagano
2021-11-26 12:02 Mike Pagano
2021-11-12 13:39 Mike Pagano
2021-11-02 17:07 Mike Pagano
2021-10-27 12:01 Mike Pagano
2021-10-17 13:15 Mike Pagano
2021-10-09 21:36 Mike Pagano
2021-10-07 10:37 Mike Pagano
2021-10-06 11:33 Mike Pagano
2021-09-26 14:16 Mike Pagano
2021-09-22 11:43 Mike Pagano
2021-09-20 22:07 Mike Pagano
2021-09-03 11:26 Mike Pagano
2021-08-26 14:02 Mike Pagano
2021-08-25 23:20 Mike Pagano
2021-08-15 20:12 Mike Pagano
2021-08-10 16:22 Mike Pagano
2021-08-08 13:47 Mike Pagano
2021-08-04 11:56 Mike Pagano
2021-08-03 12:51 Mike Pagano
2021-07-28 12:39 Mike Pagano
2021-07-20 15:17 Alice Ferrazzi
2021-07-11 14:48 Mike Pagano
2021-06-30 14:29 Mike Pagano
2021-06-17 11:05 Alice Ferrazzi
2021-06-10 11:09 Mike Pagano
2021-06-03 10:43 Alice Ferrazzi
2021-05-26 11:59 Mike Pagano
2021-05-22 10:00 Mike Pagano
2021-04-28 11:08 Alice Ferrazzi
2021-04-16 11:20 Alice Ferrazzi
2021-04-10 13:21 Mike Pagano
2021-04-07 12:10 Mike Pagano
2021-03-30 14:13 Mike Pagano
2021-03-24 12:06 Mike Pagano
2021-03-17 15:39 Mike Pagano
2021-03-11 13:34 Mike Pagano
2021-03-07 15:12 Mike Pagano
2021-03-03 16:34 Alice Ferrazzi
2021-02-23 13:46 Mike Pagano
2021-02-10 10:17 Alice Ferrazzi
2021-02-05 14:57 Alice Ferrazzi
2021-02-03 23:23 Mike Pagano
2021-01-30 13:11 Alice Ferrazzi
2021-01-23 16:33 Mike Pagano
2021-01-17 16:23 Mike Pagano
2021-01-12 20:08 Mike Pagano
2021-01-09 12:53 Mike Pagano
2020-12-29 14:16 Mike Pagano
2020-12-11 12:54 Mike Pagano
2020-12-02 12:17 Mike Pagano
2020-11-24 13:29 Mike Pagano
2020-11-22 19:08 Mike Pagano
2020-11-18 19:21 Mike Pagano
2020-11-11 15:27 Mike Pagano
2020-11-10 13:53 Mike Pagano
2020-10-29 11:14 Mike Pagano
2020-10-17 10:13 Mike Pagano
2020-10-14 20:30 Mike Pagano
2020-10-01 11:41 Mike Pagano
2020-10-01 11:24 Mike Pagano
2020-09-24 16:04 Mike Pagano
2020-09-23 11:51 Mike Pagano
2020-09-23 11:50 Mike Pagano
2020-09-12 17:08 Mike Pagano
2020-09-03 11:32 Mike Pagano
2020-08-26 11:12 Mike Pagano
2020-08-21 11:11 Alice Ferrazzi
2020-07-31 16:10 Mike Pagano
2020-07-22 12:24 Mike Pagano
2020-07-09 12:05 Mike Pagano
2020-07-01 12:09 Mike Pagano
2020-06-22 14:43 Mike Pagano
2020-06-11 11:25 Mike Pagano
2020-06-03 11:35 Mike Pagano
2020-05-27 15:26 Mike Pagano
2020-05-20 11:20 Mike Pagano
2020-05-13 13:01 Mike Pagano
2020-05-11 22:52 Mike Pagano
2020-05-05 17:37 Mike Pagano
2020-05-02 19:20 Mike Pagano
2020-04-24 11:59 Mike Pagano
2020-04-15 18:24 Mike Pagano
2020-04-02 18:55 Mike Pagano
2020-03-20 11:53 Mike Pagano
2020-03-20 11:51 Mike Pagano
2020-03-20 11:49 Mike Pagano
2020-03-11 10:14 Mike Pagano
2020-02-28 15:24 Mike Pagano
2020-02-14 23:34 Mike Pagano
2020-02-05 14:47 Mike Pagano
2020-01-29 12:36 Mike Pagano
2020-01-23 11:00 Mike Pagano
2020-01-14 22:24 Mike Pagano
2020-01-12 14:48 Mike Pagano
2020-01-04 16:46 Mike Pagano
2019-12-21 14:51 Mike Pagano
2019-12-05 14:47 Alice Ferrazzi
2019-11-29 21:41 Thomas Deutschmann
2019-11-28 23:49 Mike Pagano
2019-11-25 16:25 Mike Pagano
2019-11-16 10:54 Mike Pagano
2019-11-12 20:57 Mike Pagano
2019-11-10 16:13 Mike Pagano
2019-11-06 14:22 Mike Pagano
2019-10-29 10:08 Mike Pagano
2019-10-17 22:18 Mike Pagano
2019-10-07 21:03 Mike Pagano
2019-10-05 20:43 Mike Pagano
2019-09-21 15:56 Mike Pagano
2019-09-20 15:50 Mike Pagano
2019-09-16 12:21 Mike Pagano
2019-09-10 11:10 Mike Pagano
2019-09-06 17:17 Mike Pagano
2019-08-25 17:33 Mike Pagano
2019-08-11 10:58 Mike Pagano
2019-08-06 19:14 Mike Pagano
2019-08-04 16:03 Mike Pagano
2019-07-21 14:36 Mike Pagano
2019-07-10 11:01 Mike Pagano
2019-06-27 11:11 Mike Pagano
2019-06-22 19:01 Mike Pagano
2019-06-17 19:18 Mike Pagano
2019-06-11 17:30 Mike Pagano
2019-06-11 12:38 Mike Pagano
2019-05-16 23:01 Mike Pagano
2019-04-27 17:28 Mike Pagano
2019-04-03 10:49 Mike Pagano
2019-04-03 10:49 Mike Pagano
2019-03-23 14:17 Mike Pagano
2019-02-23 14:40 Mike Pagano
2019-02-20 11:14 Mike Pagano
2019-02-15 23:38 Mike Pagano
2019-02-15 23:35 Mike Pagano
2019-02-08 15:21 Mike Pagano
2019-02-06 20:51 Mike Pagano
2019-02-06 0:05 Mike Pagano
2019-01-26 14:59 Mike Pagano
2019-01-16 23:27 Mike Pagano
2019-01-13 19:46 Mike Pagano
2019-01-13 19:24 Mike Pagano
2018-12-29 22:56 Mike Pagano
2018-12-21 14:40 Mike Pagano
2018-12-17 21:56 Mike Pagano
2018-12-13 11:35 Mike Pagano
2018-12-01 18:35 Mike Pagano
2018-12-01 15:02 Mike Pagano
2018-11-27 16:59 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 15:02 Mike Pagano
2018-11-21 12:18 Mike Pagano
2018-11-10 21:27 Mike Pagano
2018-10-20 12:33 Mike Pagano
2018-10-13 16:35 Mike Pagano
2018-10-10 11:20 Mike Pagano
2018-09-29 13:32 Mike Pagano
2018-09-26 10:44 Mike Pagano
2018-09-19 22:37 Mike Pagano
2018-09-15 10:09 Mike Pagano
2018-09-09 23:26 Mike Pagano
2018-09-05 15:21 Mike Pagano
2018-08-28 22:32 Mike Pagano
2018-08-24 11:41 Mike Pagano
2018-08-22 10:08 Alice Ferrazzi
2018-08-18 18:06 Mike Pagano
2018-08-17 19:24 Mike Pagano
2018-08-15 16:44 Mike Pagano
2018-08-09 10:49 Mike Pagano
2018-08-07 18:14 Mike Pagano
2018-07-28 10:37 Mike Pagano
2018-07-22 15:15 Mike Pagano
2018-07-19 15:27 Mike Pagano
2018-07-17 10:24 Mike Pagano
2018-07-12 16:21 Alice Ferrazzi
2018-07-04 14:26 Mike Pagano
2018-06-16 15:41 Mike Pagano
2018-06-13 14:54 Mike Pagano
2018-06-06 18:00 Mike Pagano
2018-05-30 22:35 Mike Pagano
2018-05-30 11:38 Mike Pagano
2018-05-26 13:43 Mike Pagano
2018-05-16 10:22 Mike Pagano
2018-05-02 16:11 Mike Pagano
2018-04-29 11:48 Mike Pagano
2018-04-24 11:28 Mike Pagano
2018-04-13 22:20 Mike Pagano
2018-04-08 14:25 Mike Pagano
2018-03-31 23:00 Mike Pagano
2018-03-31 22:16 Mike Pagano
2018-03-25 13:42 Mike Pagano
2018-03-22 12:54 Mike Pagano
2018-03-11 18:25 Mike Pagano
2018-03-05 2:52 Alice Ferrazzi
2018-02-28 15:05 Alice Ferrazzi
2018-02-25 15:46 Mike Pagano
2018-02-22 23:20 Mike Pagano
2018-02-17 15:10 Alice Ferrazzi
2018-02-03 21:23 Mike Pagano
2018-01-31 13:36 Alice Ferrazzi
2018-01-23 21:15 Mike Pagano
2018-01-17 10:20 Alice Ferrazzi
2018-01-17 9:18 Alice Ferrazzi
2018-01-15 15:01 Alice Ferrazzi
2018-01-10 11:56 Mike Pagano
2018-01-10 11:48 Mike Pagano
2018-01-05 15:59 Alice Ferrazzi
2018-01-05 15:05 Alice Ferrazzi
2018-01-02 20:12 Mike Pagano
2017-12-25 14:41 Alice Ferrazzi
2017-12-20 12:45 Mike Pagano
2017-12-16 11:46 Alice Ferrazzi
2017-12-09 18:50 Alice Ferrazzi
2017-12-05 11:39 Mike Pagano
2017-11-30 12:25 Alice Ferrazzi
2017-11-24 10:49 Alice Ferrazzi
2017-11-24 9:46 Alice Ferrazzi
2017-11-21 8:40 Alice Ferrazzi
2017-11-18 18:12 Mike Pagano
2017-11-15 16:44 Alice Ferrazzi
2017-11-08 13:50 Mike Pagano
2017-11-02 10:02 Mike Pagano
2017-10-27 10:33 Mike Pagano
2017-10-21 20:13 Mike Pagano
2017-10-18 13:44 Mike Pagano
2017-10-12 12:22 Mike Pagano
2017-10-08 14:25 Mike Pagano
2017-10-05 11:39 Mike Pagano
2017-09-27 10:38 Mike Pagano
2017-09-14 13:37 Mike Pagano
2017-09-13 22:26 Mike Pagano
2017-09-13 14:33 Mike Pagano
2017-09-07 22:42 Mike Pagano
2017-09-02 17:14 Mike Pagano
2017-08-30 10:08 Mike Pagano
2017-08-25 10:53 Mike Pagano
2017-08-16 22:30 Mike Pagano
2017-08-13 16:52 Mike Pagano
2017-08-11 17:44 Mike Pagano
2017-08-07 10:25 Mike Pagano
2017-05-14 13:32 Mike Pagano
2017-05-08 10:40 Mike Pagano
2017-05-03 17:41 Mike Pagano
2017-04-30 18:08 Mike Pagano
2017-04-30 17:59 Mike Pagano
2017-04-27 8:18 Alice Ferrazzi
2017-04-22 17:00 Mike Pagano
2017-04-18 10:21 Mike Pagano
2017-04-12 17:59 Mike Pagano
2017-04-08 13:56 Mike Pagano
2017-03-31 10:43 Mike Pagano
2017-03-30 18:16 Mike Pagano
2017-03-26 11:53 Mike Pagano
2017-03-22 12:28 Mike Pagano
2017-03-18 14:32 Mike Pagano
2017-03-15 14:39 Mike Pagano
2017-03-12 12:17 Mike Pagano
2017-03-02 16:29 Mike Pagano
2017-03-02 16:29 Mike Pagano
2017-02-26 20:45 Mike Pagano
2017-02-24 0:38 Mike Pagano
2017-02-23 20:12 Mike Pagano
2017-02-18 16:27 Alice Ferrazzi
2017-02-15 16:22 Alice Ferrazzi
2017-02-09 8:05 Alice Ferrazzi
2017-02-04 13:47 Alice Ferrazzi
2017-02-01 12:59 Alice Ferrazzi
2017-01-26 8:24 Alice Ferrazzi
2017-01-20 12:45 Alice Ferrazzi
2017-01-15 22:57 Mike Pagano
2017-01-14 14:46 Mike Pagano
2017-01-12 12:11 Mike Pagano
2017-01-09 12:46 Mike Pagano
2017-01-06 23:13 Mike Pagano
2016-12-15 23:41 Mike Pagano
2016-12-11 15:02 Alice Ferrazzi
2016-12-09 13:57 Alice Ferrazzi
2016-12-08 0:03 Mike Pagano
2016-12-02 16:21 Mike Pagano
2016-11-26 18:51 Mike Pagano
2016-11-26 18:40 Mike Pagano
2016-11-22 0:14 Mike Pagano
2016-11-19 11:03 Mike Pagano
2016-11-15 10:05 Alice Ferrazzi
2016-11-10 18:13 Alice Ferrazzi
2016-11-01 3:14 Alice Ferrazzi
2016-10-31 14:09 Alice Ferrazzi
2016-10-28 18:27 Alice Ferrazzi
2016-10-22 13:05 Mike Pagano
2016-10-21 11:10 Mike Pagano
2016-10-16 19:25 Mike Pagano
2016-10-08 19:55 Mike Pagano
2016-09-30 19:07 Mike Pagano
2016-09-24 10:51 Mike Pagano
2016-09-16 19:10 Mike Pagano
2016-09-15 13:58 Mike Pagano
2016-09-09 19:20 Mike Pagano
2016-08-20 16:31 Mike Pagano
2016-08-17 11:48 Mike Pagano
2016-08-10 12:56 Mike Pagano
2016-07-27 19:19 Mike Pagano
2016-07-11 19:59 Mike Pagano
2016-07-02 15:30 Mike Pagano
2016-07-01 0:55 Mike Pagano
2016-06-24 20:40 Mike Pagano
2016-06-08 13:38 Mike Pagano
2016-06-02 18:24 Mike Pagano
2016-05-19 13:00 Mike Pagano
2016-05-12 0:14 Mike Pagano
2016-05-04 23:51 Mike Pagano
2016-04-20 11:27 Mike Pagano
2016-04-12 18:59 Mike Pagano
2016-03-22 22:47 Mike Pagano
2016-03-16 19:43 Mike Pagano
2016-03-10 0:51 Mike Pagano
2016-03-04 11:15 Mike Pagano
2016-02-26 0:02 Mike Pagano
2016-02-19 23:33 Mike Pagano
2016-02-18 0:20 Mike Pagano
2016-02-01 0:19 Mike Pagano
2016-02-01 0:13 Mike Pagano
2016-01-31 23:33 Mike Pagano
2016-01-20 12:38 Mike Pagano
2016-01-10 17:19 Mike Pagano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1586776428.29844256de5e753a88a18e250b81b1d20b16c783.mpagano@gentoo \
--to=mpagano@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox