From 6d3a4c404648e415e7d96e285d723936d4df7ed0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 6 Oct 2016 15:41:49 +0200 Subject: strparser: Propagate correct error code in strp_recv() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With m68k-linux-gnu-gcc-4.1: net/strparser/strparser.c: In function ‘strp_recv’: net/strparser/strparser.c:98: warning: ‘err’ may be used uninitialized in this function Pass "len" (which is an error code when negative) instead of the uninitialized "err" variable to fix this. Fixes: 43a0c6751a322847 ("strparser: Stream parser for messages") Signed-off-by: Geert Uytterhoeven Signed-off-by: David S. Miller --- net/strparser/strparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index 5c7549b5b92c..41adf362936d 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c @@ -246,7 +246,7 @@ static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, } else { strp->rx_interrupted = 1; } - strp_parser_err(strp, err, desc); + strp_parser_err(strp, len, desc); break; } else if (len > strp->sk->sk_rcvbuf) { /* Message length exceeds maximum allowed */ -- cgit From fa59b27c9d6f84e91e333175a242afa4aee79283 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 9 Oct 2016 20:25:55 -0700 Subject: net_sched: do not broadcast RTM_GETTFILTER result There are two ways to get tc filters from kernel to user space. 1) Full dump (tc_dump_tfilter()) 2) RTM_GETTFILTER to get one precise filter, reducing overhead. The second operation is unfortunately broadcasting its result, polluting "tc monitor" users. This patch makes sure only the requester gets the result, using netlink_unicast() instead of rtnetlink_send() Jamal cooked an iproute2 patch to implement "tc filter get" operation, but other user space libraries already use RTM_GETTFILTER when a single filter is queried, instead of dumping all filters. Signed-off-by: Eric Dumazet Cc: Jamal Hadi Salim Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- net/sched/cls_api.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 11da7da0b7c4..2ee29a3375f6 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -101,7 +101,7 @@ EXPORT_SYMBOL(unregister_tcf_proto_ops); static int tfilter_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct tcf_proto *tp, - unsigned long fh, int event); + unsigned long fh, int event, bool unicast); static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, @@ -112,7 +112,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, for (it_chain = chain; (tp = rtnl_dereference(*it_chain)) != NULL; it_chain = &tp->next) - tfilter_notify(net, oskb, n, tp, 0, event); + tfilter_notify(net, oskb, n, tp, 0, event, false); } /* Select new prio value from the range, managed by kernel. */ @@ -319,7 +319,8 @@ replay: RCU_INIT_POINTER(*back, next); - tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER); + tfilter_notify(net, skb, n, tp, fh, + RTM_DELTFILTER, false); tcf_destroy(tp, true); err = 0; goto errout; @@ -345,14 +346,14 @@ replay: struct tcf_proto *next = rtnl_dereference(tp->next); tfilter_notify(net, skb, n, tp, fh, - RTM_DELTFILTER); + RTM_DELTFILTER, false); if (tcf_destroy(tp, false)) RCU_INIT_POINTER(*back, next); } goto errout; case RTM_GETTFILTER: err = tfilter_notify(net, skb, n, tp, fh, - RTM_NEWTFILTER); + RTM_NEWTFILTER, true); goto errout; default: err = -EINVAL; @@ -367,7 +368,7 @@ replay: RCU_INIT_POINTER(tp->next, rtnl_dereference(*back)); rcu_assign_pointer(*back, tp); } - tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER); + tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER, false); } else { if (tp_created) tcf_destroy(tp, true); @@ -419,7 +420,7 @@ nla_put_failure: static int tfilter_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct tcf_proto *tp, - unsigned long fh, int event) + unsigned long fh, int event, bool unicast) { struct sk_buff *skb; u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; @@ -433,6 +434,9 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, return -EINVAL; } + if (unicast) + return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, n->nlmsg_flags & NLM_F_ECHO); } -- cgit From a9339b8e138d81b6ee928d0de3372c551cbd3d34 Mon Sep 17 00:00:00 2001 From: Paul Durrant Date: Mon, 10 Oct 2016 09:30:53 +0100 Subject: xen-netback: (re-)create a debugfs node for hash information It is useful to be able to see the hash configuration when running tests. This patch adds a debugfs node for that purpose. The original version of this patch (commit c0c64c152389) was reverted due to build failures caused by a conflict with commit 0364a8824c02 ("xen-netback: switch to threaded irq for control ring"). This new version of the patch is nearly identical to the original, the only difference being that creation of the debugfs node is predicated on 'ctrl_irq' being non-zero rather then the now non-existent 'ctrl_task'. Signed-off-by: Paul Durrant Cc: Wei Liu Cc: David S. Miller Acked-by: Wei Liu Signed-off-by: David S. Miller --- drivers/net/xen-netback/common.h | 4 +++ drivers/net/xen-netback/hash.c | 68 ++++++++++++++++++++++++++++++++++++++++ drivers/net/xen-netback/xenbus.c | 37 ++++++++++++++++++++-- 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index cf68149cbb55..3ce1f7da8647 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -407,4 +407,8 @@ u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len, void xenvif_set_skb_hash(struct xenvif *vif, struct sk_buff *skb); +#ifdef CONFIG_DEBUG_FS +void xenvif_dump_hash_info(struct xenvif *vif, struct seq_file *m); +#endif + #endif /* __XEN_NETBACK__COMMON_H__ */ diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c index 613bac057650..e8c5dddc54ba 100644 --- a/drivers/net/xen-netback/hash.c +++ b/drivers/net/xen-netback/hash.c @@ -360,6 +360,74 @@ u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len, return XEN_NETIF_CTRL_STATUS_SUCCESS; } +#ifdef CONFIG_DEBUG_FS +void xenvif_dump_hash_info(struct xenvif *vif, struct seq_file *m) +{ + unsigned int i; + + switch (vif->hash.alg) { + case XEN_NETIF_CTRL_HASH_ALGORITHM_TOEPLITZ: + seq_puts(m, "Hash Algorithm: TOEPLITZ\n"); + break; + + case XEN_NETIF_CTRL_HASH_ALGORITHM_NONE: + seq_puts(m, "Hash Algorithm: NONE\n"); + /* FALLTHRU */ + default: + return; + } + + if (vif->hash.flags) { + seq_puts(m, "\nHash Flags:\n"); + + if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4) + seq_puts(m, "- IPv4\n"); + if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV4_TCP) + seq_puts(m, "- IPv4 + TCP\n"); + if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6) + seq_puts(m, "- IPv6\n"); + if (vif->hash.flags & XEN_NETIF_CTRL_HASH_TYPE_IPV6_TCP) + seq_puts(m, "- IPv6 + TCP\n"); + } + + seq_puts(m, "\nHash Key:\n"); + + for (i = 0; i < XEN_NETBK_MAX_HASH_KEY_SIZE; ) { + unsigned int j, n; + + n = 8; + if (i + n >= XEN_NETBK_MAX_HASH_KEY_SIZE) + n = XEN_NETBK_MAX_HASH_KEY_SIZE - i; + + seq_printf(m, "[%2u - %2u]: ", i, i + n - 1); + + for (j = 0; j < n; j++, i++) + seq_printf(m, "%02x ", vif->hash.key[i]); + + seq_puts(m, "\n"); + } + + if (vif->hash.size != 0) { + seq_puts(m, "\nHash Mapping:\n"); + + for (i = 0; i < vif->hash.size; ) { + unsigned int j, n; + + n = 8; + if (i + n >= vif->hash.size) + n = vif->hash.size - i; + + seq_printf(m, "[%4u - %4u]: ", i, i + n - 1); + + for (j = 0; j < n; j++, i++) + seq_printf(m, "%4u ", vif->hash.mapping[i]); + + seq_puts(m, "\n"); + } + } +} +#endif /* CONFIG_DEBUG_FS */ + void xenvif_init_hash(struct xenvif *vif) { if (xenvif_hash_cache_size == 0) diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index 7056404e3cb8..8674e188b697 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -165,7 +165,7 @@ xenvif_write_io_ring(struct file *filp, const char __user *buf, size_t count, return count; } -static int xenvif_dump_open(struct inode *inode, struct file *filp) +static int xenvif_io_ring_open(struct inode *inode, struct file *filp) { int ret; void *queue = NULL; @@ -179,13 +179,35 @@ static int xenvif_dump_open(struct inode *inode, struct file *filp) static const struct file_operations xenvif_dbg_io_ring_ops_fops = { .owner = THIS_MODULE, - .open = xenvif_dump_open, + .open = xenvif_io_ring_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = xenvif_write_io_ring, }; +static int xenvif_read_ctrl(struct seq_file *m, void *v) +{ + struct xenvif *vif = m->private; + + xenvif_dump_hash_info(vif, m); + + return 0; +} + +static int xenvif_ctrl_open(struct inode *inode, struct file *filp) +{ + return single_open(filp, xenvif_read_ctrl, inode->i_private); +} + +static const struct file_operations xenvif_dbg_ctrl_ops_fops = { + .owner = THIS_MODULE, + .open = xenvif_ctrl_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static void xenvif_debugfs_addif(struct xenvif *vif) { struct dentry *pfile; @@ -210,6 +232,17 @@ static void xenvif_debugfs_addif(struct xenvif *vif) pr_warn("Creation of io_ring file returned %ld!\n", PTR_ERR(pfile)); } + + if (vif->ctrl_irq) { + pfile = debugfs_create_file("ctrl", + S_IRUSR, + vif->xenvif_dbg_root, + vif, + &xenvif_dbg_ctrl_ops_fops); + if (IS_ERR_OR_NULL(pfile)) + pr_warn("Creation of ctrl file returned %ld!\n", + PTR_ERR(pfile)); + } } else netdev_warn(vif->dev, "Creation of vif debugfs dir returned %ld!\n", -- cgit From 1e09c106a44c2b2685a77a1ef27951381c9fcd23 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 10 Oct 2016 14:41:10 +0200 Subject: tlan: avoid unused label with PCI=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While build testing with randconfig on x86, I ran into this warning that appears to have been around forever drivers/net/ethernet/ti/tlan.c: In function ‘tlan_probe1’: drivers/net/ethernet/ti/tlan.c:614:1: error: label ‘err_out’ defined but not used [-Werror=unused-label] This can be trivially avoided by just moving the label into the existing #ifdef. Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/tlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index ece0ea0f6b38..6c7ec1ddd475 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -610,8 +610,8 @@ err_out_regions: #ifdef CONFIG_PCI if (pdev) pci_release_regions(pdev); -#endif err_out: +#endif if (pdev) pci_disable_device(pdev); return rc; -- cgit From 88a2428b83db4328e69d1c0e2f7364041b8045bf Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 10 Oct 2016 14:08:28 +0000 Subject: qed: Fix to use list_for_each_entry_safe() when delete items Since we will remove items off the list using list_del() we need to use a safe version of the list_for_each_entry() macro aptly named list_for_each_entry_safe(). Signed-off-by: Wei Yongjun Acked-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_ll2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index a6db10717d5c..02a8be2faed7 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -1517,7 +1517,7 @@ static void qed_ll2_register_cb_ops(struct qed_dev *cdev, static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) { struct qed_ll2_info ll2_info; - struct qed_ll2_buffer *buffer; + struct qed_ll2_buffer *buffer, *tmp_buffer; enum qed_ll2_conn_type conn_type; struct qed_ptt *p_ptt; int rc, i; @@ -1587,7 +1587,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) /* Post all Rx buffers to FW */ spin_lock_bh(&cdev->ll2->lock); - list_for_each_entry(buffer, &cdev->ll2->list, list) { + list_for_each_entry_safe(buffer, tmp_buffer, &cdev->ll2->list, list) { rc = qed_ll2_post_rx_buffer(QED_LEADING_HWFN(cdev), cdev->ll2->handle, buffer->phys_addr, 0, buffer, 1); -- cgit From 20ecf1e4e30005ad50f561a92c888b6477f99341 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Mon, 10 Oct 2016 17:02:42 +0200 Subject: openvswitch: vlan: remove wrong likely statement This code is called whenever flow key is being extracted from the packet. The packet may be as likely vlan tagged as not. Fixes: 018c1dda5ff1 ("openvswitch: 802.1AD Flow handling, actions, vlan parsing, netlink attributes") Signed-off-by: Jiri Benc Acked-by: Pravin B Shelar Acked-by: Eric Garver Signed-off-by: David S. Miller --- net/openvswitch/flow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index c8c82e109c68..22087062bd10 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -343,7 +343,7 @@ static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) key->eth.cvlan.tci = 0; key->eth.cvlan.tpid = 0; - if (likely(skb_vlan_tag_present(skb))) { + if (skb_vlan_tag_present(skb)) { key->eth.vlan.tci = htons(skb->vlan_tci); key->eth.vlan.tpid = skb->vlan_proto; } else { -- cgit From 72ec108d701506fa6cd2f66ec5b15ea71df3c464 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Mon, 10 Oct 2016 17:02:43 +0200 Subject: openvswitch: fix vlan subtraction from packet length When the packet has its vlan tag in skb->vlan_tci, the length of the VLAN header is not counted in skb->len. It doesn't make sense to subtract it. Fixes: 018c1dda5ff1 ("openvswitch: 802.1AD Flow handling, actions, vlan parsing, netlink attributes") Signed-off-by: Jiri Benc Acked-by: Pravin B Shelar Acked-by: Eric Garver Signed-off-by: David S. Miller --- net/openvswitch/vport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 8f198437c724..7387418ac514 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -485,7 +485,8 @@ static unsigned int packet_length(const struct sk_buff *skb) { unsigned int length = skb->len - ETH_HLEN; - if (skb_vlan_tagged(skb)) + if (!skb_vlan_tag_present(skb) && + eth_type_vlan(skb->protocol)) length -= VLAN_HLEN; /* Don't subtract for multiple VLAN tags. Most (all?) drivers allow -- cgit From 3145c037e74926dea9241a3f68ada6f294b0119a Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Mon, 10 Oct 2016 17:02:44 +0200 Subject: openvswitch: add NETIF_F_HW_VLAN_STAG_TX to internal dev The internal device does support 802.1AD offloading since 018c1dda5ff1 ("openvswitch: 802.1AD Flow handling, actions, vlan parsing, netlink attributes"). Signed-off-by: Jiri Benc Acked-by: Pravin B Shelar Acked-by: Eric Garver Signed-off-by: David S. Miller --- net/openvswitch/vport-internal_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c index 95c36147a6e1..e7da29021b38 100644 --- a/net/openvswitch/vport-internal_dev.c +++ b/net/openvswitch/vport-internal_dev.c @@ -176,7 +176,7 @@ static void do_setup(struct net_device *netdev) netdev->vlan_features = netdev->features; netdev->hw_enc_features = netdev->features; - netdev->features |= NETIF_F_HW_VLAN_CTAG_TX; + netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX; netdev->hw_features = netdev->features & ~NETIF_F_LLTX; eth_hw_addr_random(netdev); -- cgit From 9a765881bf3dcd32847d7108cf48cb04a4ed993f Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 10 Oct 2016 21:12:49 +0200 Subject: qmi_wwan: add support for Quectel EC21 and EC25 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Quectel EC21 and EC25 need the same "set DTR" request as devices based on the MDM9230 chipset, but has no USB3 support. Our best guess is that the "set DTR" functionality depends on chipset and/or baseband firmware generation. But USB3 is still an optional feature. Since we cannot enable this unconditionally for all older devices, and there doesn't appear to be anything we can use in the USB descriptors to identify these chips, we are forced to use a device specific quirk flag. Reported-and-tested-by: Sebastian Sjoholm Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 9d1fce8a6e84..3ff76c6db4f6 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -59,6 +59,10 @@ enum qmi_wwan_flags { QMI_WWAN_FLAG_RAWIP = 1 << 0, }; +enum qmi_wwan_quirks { + QMI_WWAN_QUIRK_DTR = 1 << 0, /* needs "set DTR" request */ +}; + static void qmi_wwan_netdev_setup(struct net_device *net) { struct usbnet *dev = netdev_priv(net); @@ -411,9 +415,14 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) * clearing out state the clients might need. * * MDM9x30 is the first QMI chipset with USB3 support. Abuse - * this fact to enable the quirk. + * this fact to enable the quirk for all USB3 devices. + * + * There are also chipsets with the same "set DTR" requirement + * but without USB3 support. Devices based on these chips + * need a quirk flag in the device ID table. */ - if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) { + if (dev->driver_info->data & QMI_WWAN_QUIRK_DTR || + le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) { qmi_wwan_manage_power(dev, 1); qmi_wwan_change_dtr(dev, true); } @@ -526,6 +535,16 @@ static const struct driver_info qmi_wwan_info = { .rx_fixup = qmi_wwan_rx_fixup, }; +static const struct driver_info qmi_wwan_info_quirk_dtr = { + .description = "WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind, + .unbind = qmi_wwan_unbind, + .manage_power = qmi_wwan_manage_power, + .rx_fixup = qmi_wwan_rx_fixup, + .data = QMI_WWAN_QUIRK_DTR, +}; + #define HUAWEI_VENDOR_ID 0x12D1 /* map QMI/wwan function by a fixed interface number */ @@ -533,6 +552,11 @@ static const struct driver_info qmi_wwan_info = { USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ .driver_info = (unsigned long)&qmi_wwan_info +/* devices requiring "set DTR" quirk */ +#define QMI_QUIRK_SET_DTR(vend, prod, num) \ + USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ + .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr + /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ #define QMI_GOBI1K_DEVICE(vend, prod) \ QMI_FIXED_INTF(vend, prod, 3) @@ -895,6 +919,8 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ {QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */ {QMI_FIXED_INTF(0x1e0e, 0x9001, 5)}, /* SIMCom 7230E */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0125, 4)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */ /* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ -- cgit From b8a4ddb2e8f44f872fb93bbda2d541b27079fd2b Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Wed, 12 Oct 2016 04:57:10 +0300 Subject: net/mlx5: Add MLX5_ARRAY_SET64 to fix BUILD_BUG_ON I am hitting this in mlx5: drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c: In function reclaim_pages_cmd.clone.0: drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c:346: error: call to __compiletime_assert_346 declared with attribute error: BUILD_BUG_ON failed: __mlx5_bit_off(manage_pages_out, pas[i]) % 64 drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c: In function give_pages: drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c:291: error: call to __compiletime_assert_291 declared with attribute error: BUILD_BUG_ON failed: __mlx5_bit_off(manage_pages_in, pas[i]) % 64 Problem is that this is doing a BUILD_BUG_ON on a non-constant expression because of trying to take offset of pas[i] in the structure. Fix is to create MLX5_ARRAY_SET64 that takes an additional argument that is the field index to separate between BUILD_BUG_ON on the array constant field and the indexed field to assign the value to. There are two callers of MLX5_SET64 that are trying to get a variable offset, change those to call MLX5_ARRAY_SET64 passing 'pas' and 'i' as the arguments to use in the offset check and the indexed value assignment. Fixes: a533ed5e179cd ("net/mlx5: Pages management commands via mlx5 ifc") Signed-off-by: Tom Herbert Signed-off-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 4 ++-- include/linux/mlx5/device.h | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index d4585154151d..cc4fd61914d3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -287,7 +287,7 @@ retry: goto retry; } - MLX5_SET64(manage_pages_in, in, pas[i], addr); + MLX5_ARRAY_SET64(manage_pages_in, in, pas, i, addr); } MLX5_SET(manage_pages_in, in, opcode, MLX5_CMD_OP_MANAGE_PAGES); @@ -344,7 +344,7 @@ static int reclaim_pages_cmd(struct mlx5_core_dev *dev, if (fwp->func_id != func_id) continue; - MLX5_SET64(manage_pages_out, out, pas[i], fwp->addr); + MLX5_ARRAY_SET64(manage_pages_out, out, pas, i, fwp->addr); i++; } diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index 77c141797152..58276144ba81 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -92,12 +92,21 @@ __mlx5_mask(typ, fld)) ___t; \ }) -#define MLX5_SET64(typ, p, fld, v) do { \ +#define __MLX5_SET64(typ, p, fld, v) do { \ BUILD_BUG_ON(__mlx5_bit_sz(typ, fld) != 64); \ - BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \ *((__be64 *)(p) + __mlx5_64_off(typ, fld)) = cpu_to_be64(v); \ } while (0) +#define MLX5_SET64(typ, p, fld, v) do { \ + BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \ + __MLX5_SET64(typ, p, fld, v); \ +} while (0) + +#define MLX5_ARRAY_SET64(typ, p, fld, idx, v) do { \ + BUILD_BUG_ON(__mlx5_bit_off(typ, fld) % 64); \ + __MLX5_SET64(typ, p, fld[idx], v); \ +} while (0) + #define MLX5_GET64(typ, p, fld) be64_to_cpu(*((__be64 *)(p) + __mlx5_64_off(typ, fld))) #define MLX5_GET64_PR(typ, p, fld) ({ \ -- cgit From 02a9079c66341836c4914c33c06a73245060df2e Mon Sep 17 00:00:00 2001 From: Vlad Tsyrklevich Date: Tue, 11 Oct 2016 15:02:47 +0200 Subject: drivers/ptp: Fix kernel memory disclosure The reserved field precise_offset->rsv is not cleared before being copied to user space, leaking kernel stack memory. Clear the struct before it's copied. Signed-off-by: Vlad Tsyrklevich Acked-by: Richard Cochran Signed-off-by: David S. Miller --- drivers/ptp/ptp_chardev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index d637c933c8a9..58a97d420572 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -193,6 +193,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) if (err) break; + memset(&precise_offset, 0, sizeof(precise_offset)); ts = ktime_to_timespec64(xtstamp.device); precise_offset.device.sec = ts.tv_sec; precise_offset.device.nsec = ts.tv_nsec; -- cgit From d1ef006dc116bf6487426b0b50c1bf2bf51e6423 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Tue, 11 Oct 2016 16:48:27 +0100 Subject: xen-netback: fix guest Rx stall detection (after guest Rx refactor) If a VIF has been ready for rx_stall_timeout (60s by default) and an Rx ring is drained of all requests an Rx stall will be incorrectly detected. When this occurs and the guest Rx queue is empty, the Rx ring's event index will not be set and the frontend will not raise an event when new requests are placed on the ring, permanently stalling the VIF. This is a regression introduced by eb1723a29b9a7 (xen-netback: refactor guest rx). Fix this by reinstating the setting of queue->last_rx_time when placing a packet onto the guest Rx ring. Signed-off-by: David Vrabel Reviewed-by: Paul Durrant Signed-off-by: David S. Miller --- drivers/net/xen-netback/rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c index 8e9ade6ccf18..d69f2a92063c 100644 --- a/drivers/net/xen-netback/rx.c +++ b/drivers/net/xen-netback/rx.c @@ -425,6 +425,8 @@ void xenvif_rx_skb(struct xenvif_queue *queue) xenvif_rx_next_skb(queue, &pkt); + queue->last_rx_time = jiffies; + do { struct xen_netif_rx_request *req; struct xen_netif_rx_response *rsp; -- cgit From ab102b80cef28c20b3ef7794806c3a982c6444fc Mon Sep 17 00:00:00 2001 From: WANG Cong Date: Tue, 11 Oct 2016 10:56:45 -0700 Subject: net_sched: reorder pernet ops and act ops registrations Krister reported a kernel NULL pointer dereference after tcf_action_init_1() invokes a_o->init(), it is a race condition where one thread calling tcf_register_action() to initialize the netns data after putting act ops in the global list and the other thread searching the list and then calling a_o->init(net, ...). Fix this by moving the pernet ops registration before making the action ops visible. This is fine because: a) we don't rely on act_base in pernet ops->init(), b) in the worst case we have a fully initialized netns but ops is still not ready so new actions still can't be created. Reported-by: Krister Johansen Tested-by: Krister Johansen Cc: Jamal Hadi Salim Signed-off-by: Cong Wang Acked-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- net/sched/act_api.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index c9102172ce3b..a512b18c0088 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -341,22 +341,25 @@ int tcf_register_action(struct tc_action_ops *act, if (!act->act || !act->dump || !act->init || !act->walk || !act->lookup) return -EINVAL; + /* We have to register pernet ops before making the action ops visible, + * otherwise tcf_action_init_1() could get a partially initialized + * netns. + */ + ret = register_pernet_subsys(ops); + if (ret) + return ret; + write_lock(&act_mod_lock); list_for_each_entry(a, &act_base, head) { if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) { write_unlock(&act_mod_lock); + unregister_pernet_subsys(ops); return -EEXIST; } } list_add_tail(&act->head, &act_base); write_unlock(&act_mod_lock); - ret = register_pernet_subsys(ops); - if (ret) { - tcf_unregister_action(act, ops); - return ret; - } - return 0; } EXPORT_SYMBOL(tcf_register_action); @@ -367,8 +370,6 @@ int tcf_unregister_action(struct tc_action_ops *act, struct tc_action_ops *a; int err = -ENOENT; - unregister_pernet_subsys(ops); - write_lock(&act_mod_lock); list_for_each_entry(a, &act_base, head) { if (a == act) { @@ -378,6 +379,8 @@ int tcf_unregister_action(struct tc_action_ops *act, } } write_unlock(&act_mod_lock); + if (!err) + unregister_pernet_subsys(ops); return err; } EXPORT_SYMBOL(tcf_unregister_action); -- cgit From ad19bc8a95baee4588e9ec4481297d97c0bec765 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Tue, 11 Oct 2016 14:03:07 -0700 Subject: netvsc: fix checksum on UDP IPV6 The software calculation of UDP checksum in Netvsc driver was only handling IPv4 case. By using skb_checksum_help() instead all protocols can be handled. Rearrange code to eliminate goto and look like other drivers. This is a temporary solution; recent versions of Window Server etc do support UDP checksum offload, just need to do the appropriate negotiation with host to validate before using. This will be done in later patch. Please queue this for -stable as well. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 72 +++++++++++++---------------------------- 1 file changed, 22 insertions(+), 50 deletions(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 52eeb2f67276..9570d2142db1 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "hyperv_net.h" @@ -442,8 +443,6 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) } net_trans_info = get_net_transport_info(skb, &hdr_offset); - if (net_trans_info == TRANSPORT_INFO_NOT_IP) - goto do_send; /* * Setup the sendside checksum offload only if this is not a @@ -478,56 +477,29 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) } lso_info->lso_v2_transmit.tcp_header_offset = hdr_offset; lso_info->lso_v2_transmit.mss = skb_shinfo(skb)->gso_size; - goto do_send; - } - - if ((skb->ip_summed == CHECKSUM_NONE) || - (skb->ip_summed == CHECKSUM_UNNECESSARY)) - goto do_send; - - rndis_msg_size += NDIS_CSUM_PPI_SIZE; - ppi = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE, - TCPIP_CHKSUM_PKTINFO); - - csum_info = (struct ndis_tcp_ip_checksum_info *)((void *)ppi + - ppi->ppi_offset); - - if (net_trans_info & (INFO_IPV4 << 16)) - csum_info->transmit.is_ipv4 = 1; - else - csum_info->transmit.is_ipv6 = 1; - - if (net_trans_info & INFO_TCP) { - csum_info->transmit.tcp_checksum = 1; - csum_info->transmit.tcp_header_offset = hdr_offset; - } else if (net_trans_info & INFO_UDP) { - /* UDP checksum offload is not supported on ws2008r2. - * Furthermore, on ws2012 and ws2012r2, there are some - * issues with udp checksum offload from Linux guests. - * (these are host issues). - * For now compute the checksum here. - */ - struct udphdr *uh; - u16 udp_len; - - ret = skb_cow_head(skb, 0); - if (ret) - goto no_memory; - - uh = udp_hdr(skb); - udp_len = ntohs(uh->len); - uh->check = 0; - uh->check = csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, - udp_len, IPPROTO_UDP, - csum_partial(uh, udp_len, 0)); - if (uh->check == 0) - uh->check = CSUM_MANGLED_0; - - csum_info->transmit.udp_checksum = 0; + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (net_trans_info & INFO_TCP) { + rndis_msg_size += NDIS_CSUM_PPI_SIZE; + ppi = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE, + TCPIP_CHKSUM_PKTINFO); + + csum_info = (struct ndis_tcp_ip_checksum_info *)((void *)ppi + + ppi->ppi_offset); + + if (net_trans_info & (INFO_IPV4 << 16)) + csum_info->transmit.is_ipv4 = 1; + else + csum_info->transmit.is_ipv6 = 1; + + csum_info->transmit.tcp_checksum = 1; + csum_info->transmit.tcp_header_offset = hdr_offset; + } else { + /* UDP checksum (and other) offload is not supported. */ + if (skb_checksum_help(skb)) + goto drop; + } } -do_send: /* Start filling in the page buffers with the rndis hdr */ rndis_msg->msg_len += rndis_msg_size; packet->total_data_buflen = rndis_msg->msg_len; -- cgit From d4e991313bd5e10bfa66cd280b8fce6dc3f2d897 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 10 Oct 2016 13:59:16 +0200 Subject: qed: fix old-style function definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The definition of qed_get_rdma_ops() is not a prototype unless we add 'void' here, as indicated by this W=1 warning: drivers/net/ethernet/qlogic/qed/qed_roce.c: In function ‘qed_get_rdma_ops’: drivers/net/ethernet/qlogic/qed/qed_roce.c:2950:28: error: old-style function definition [-Werror=old-style-definition] Fixes: abd49676c707 ("qed: Add RoCE ll2 & GSI support") Signed-off-by: Arnd Bergmann Acked-by: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_roce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/qlogic/qed/qed_roce.c b/drivers/net/ethernet/qlogic/qed/qed_roce.c index 23430059471c..76831a398bed 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_roce.c +++ b/drivers/net/ethernet/qlogic/qed/qed_roce.c @@ -2947,7 +2947,7 @@ static const struct qed_rdma_ops qed_rdma_ops_pass = { .roce_ll2_stats = &qed_roce_ll2_stats, }; -const struct qed_rdma_ops *qed_get_rdma_ops() +const struct qed_rdma_ops *qed_get_rdma_ops(void) { return &qed_rdma_ops_pass; } -- cgit From be9b3174c49109457c490a0ad8976aaeb3df5585 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 12 Oct 2016 15:42:03 +0200 Subject: stmmac: fix ptp init for gmac4 The gmac 4.x version has not extended descriptors (that are available on 3.x instead of). While initializing the PTP module, the advanced PTP was enabled in case of extended descriptors. This cannot be applied for 4.x version where only the hardware capability register has to show if the feature is present. Patch also adds some extra netdev_(debug/inof) to better dump the configuration. Signed-off-by: Giuseppe Cavallaro Cc: Alexandre TORGUE Cc: Rayagond Kokatanur Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 4c8c60af7985..e838850cc7c3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -650,20 +650,27 @@ static int stmmac_init_ptp(struct stmmac_priv *priv) if (IS_ERR(priv->clk_ptp_ref)) { priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk); priv->clk_ptp_ref = NULL; + netdev_dbg(priv->dev, "PTP uses main clock\n"); } else { clk_prepare_enable(priv->clk_ptp_ref); priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref); + netdev_dbg(priv->dev, "PTP rate %d\n", priv->clk_ptp_rate); } priv->adv_ts = 0; - if (priv->dma_cap.atime_stamp && priv->extend_desc) + /* Check if adv_ts can be enabled for dwmac 4.x core */ + if (priv->plat->has_gmac4 && priv->dma_cap.atime_stamp) + priv->adv_ts = 1; + /* Dwmac 3.x core with extend_desc can support adv_ts */ + else if (priv->extend_desc && priv->dma_cap.atime_stamp) priv->adv_ts = 1; - if (netif_msg_hw(priv) && priv->dma_cap.time_stamp) - pr_debug("IEEE 1588-2002 Time Stamp supported\n"); + if (priv->dma_cap.time_stamp) + netdev_info(priv->dev, "IEEE 1588-2002 Timestamp supported\n"); - if (netif_msg_hw(priv) && priv->adv_ts) - pr_debug("IEEE 1588-2008 Advanced Time Stamp supported\n"); + if (priv->adv_ts) + netdev_info(priv->dev, + "IEEE 1588-2008 Advanced Timestamp supported\n"); priv->hw->ptp = &stmmac_ptp; priv->hwts_tx_en = 0; -- cgit From 7086605a6ab57a5a37eb613cfe214fc62d2bb87b Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 12 Oct 2016 15:42:04 +0200 Subject: stmmac: fix error check when init ptp This patch fixes a problem when propagated the failure of ptp_clock_register to open function. Signed-off-by: Giuseppe Cavallaro Cc: Alexandre TORGUE Cc: Rayagond Kokatanur Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 ++-- drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index e838850cc7c3..6c85b61aaa0b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1709,8 +1709,8 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) if (init_ptp) { ret = stmmac_init_ptp(priv); - if (ret && ret != -EOPNOTSUPP) - pr_warn("%s: failed PTP initialisation\n", __func__); + if (ret) + netdev_warn(priv->dev, "PTP support cannot init.\n"); } #ifdef CONFIG_DEBUG_FS diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c index 6e3b82972ce8..289d52725a6c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c @@ -186,10 +186,12 @@ int stmmac_ptp_register(struct stmmac_priv *priv) priv->device); if (IS_ERR(priv->ptp_clock)) { priv->ptp_clock = NULL; - pr_err("ptp_clock_register() failed on %s\n", priv->dev->name); - } else if (priv->ptp_clock) - pr_debug("Added PTP HW clock successfully on %s\n", - priv->dev->name); + return PTR_ERR(priv->ptp_clock); + } + + spin_lock_init(&priv->ptp_lock); + + netdev_dbg(priv->dev, "Added PTP HW clock successfully\n"); return 0; } -- cgit From f112be65fd3964ec2d56ddd0d5e6061b0fd502da Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 12 Oct 2016 16:54:01 +0200 Subject: xen-netback: fix type mismatch warning Wiht the latest rework of the xen-netback driver, we get a warning on ARM about the types passed into min(): drivers/net/xen-netback/rx.c: In function 'xenvif_rx_next_chunk': include/linux/kernel.h:739:16: error: comparison of distinct pointer types lacks a cast [-Werror] The reason is that XEN_PAGE_SIZE is not size_t here. There is no actual bug, and we can easily avoid the warning using the min_t() macro instead of min(). Fixes: eb1723a29b9a ("xen-netback: refactor guest rx") Signed-off-by: Arnd Bergmann Acked-by: Paul Durrant Signed-off-by: David S. Miller --- drivers/net/xen-netback/rx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c index d69f2a92063c..b1cf7c6f407a 100644 --- a/drivers/net/xen-netback/rx.c +++ b/drivers/net/xen-netback/rx.c @@ -337,9 +337,9 @@ static void xenvif_rx_next_chunk(struct xenvif_queue *queue, frag_data += pkt->frag_offset; frag_len -= pkt->frag_offset; - chunk_len = min(frag_len, XEN_PAGE_SIZE - offset); - chunk_len = min(chunk_len, - XEN_PAGE_SIZE - xen_offset_in_page(frag_data)); + chunk_len = min_t(size_t, frag_len, XEN_PAGE_SIZE - offset); + chunk_len = min_t(size_t, chunk_len, XEN_PAGE_SIZE - + xen_offset_in_page(frag_data)); pkt->frag_offset += chunk_len; -- cgit From 3f2b0a5a3583a2c6c3aeb2d59e7f775d43faa89c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 13 Oct 2016 11:04:07 -0400 Subject: netvsc: Remove mistaken udp.h inclusion. Based upon v2 of Stephen's patch. Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 9570d2142db1..f0919bd3a563 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include "hyperv_net.h" -- cgit From 8ce48623f0cf3d632e32448411feddccb693d351 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 12 Oct 2016 19:01:45 +0200 Subject: ipv6: tcp: restore IP6CB for pktoptions skbs Baozeng Ding reported following KASAN splat : BUG: KASAN: use-after-free in ip6_datagram_recv_specific_ctl+0x13f1/0x15c0 at addr ffff880029c84ec8 Read of size 1 by task poc/25548 Call Trace: [] dump_stack+0x12e/0x185 /lib/dump_stack.c:15 [< inline >] print_address_description /mm/kasan/report.c:204 [] kasan_report_error+0x48b/0x4b0 /mm/kasan/report.c:283 [< inline >] kasan_report /mm/kasan/report.c:303 [] __asan_report_load1_noabort+0x3e/0x40 /mm/kasan/report.c:321 [] ip6_datagram_recv_specific_ctl+0x13f1/0x15c0 /net/ipv6/datagram.c:687 [] ip6_datagram_recv_ctl+0x33/0x40 [] do_ipv6_getsockopt.isra.4+0xaec/0x2150 [] ipv6_getsockopt+0x116/0x230 [] tcp_getsockopt+0x82/0xd0 /net/ipv4/tcp.c:3035 [] sock_common_getsockopt+0x95/0xd0 /net/core/sock.c:2647 [< inline >] SYSC_getsockopt /net/socket.c:1776 [] SyS_getsockopt+0x142/0x230 /net/socket.c:1758 [] entry_SYSCALL_64_fastpath+0x23/0xc6 Memory state around the buggy address: ffff880029c84d80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff880029c84e00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > ffff880029c84e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ^ ffff880029c84f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffff880029c84f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff He also provided a syzkaller reproducer. Issue is that ip6_datagram_recv_specific_ctl() expects to find IP6CB data that was moved at a different place in tcp_v6_rcv() This patch moves tcp_v6_restore_cb() up and calls it from tcp_v6_do_rcv() when np->pktoptions is set. Fixes: 971f10eca186 ("tcp: better TCP_SKB_CB layout to reduce cache line misses") Signed-off-by: Eric Dumazet Reported-by: Baozeng Ding Signed-off-by: David S. Miller --- net/ipv6/tcp_ipv6.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 54cf7197c7ab..5a27ab4eab39 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1190,6 +1190,16 @@ out: return NULL; } +static void tcp_v6_restore_cb(struct sk_buff *skb) +{ + /* We need to move header back to the beginning if xfrm6_policy_check() + * and tcp_v6_fill_cb() are going to be called again. + * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there. + */ + memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, + sizeof(struct inet6_skb_parm)); +} + /* The socket must have it's spinlock held when we get * here, unless it is a TCP_LISTEN socket. * @@ -1319,6 +1329,7 @@ ipv6_pktoptions: np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb)); if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) { skb_set_owner_r(opt_skb, sk); + tcp_v6_restore_cb(opt_skb); opt_skb = xchg(&np->pktoptions, opt_skb); } else { __kfree_skb(opt_skb); @@ -1352,15 +1363,6 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, TCP_SKB_CB(skb)->sacked = 0; } -static void tcp_v6_restore_cb(struct sk_buff *skb) -{ - /* We need to move header back to the beginning if xfrm6_policy_check() - * and tcp_v6_fill_cb() are going to be called again. - */ - memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, - sizeof(struct inet6_skb_parm)); -} - static int tcp_v6_rcv(struct sk_buff *skb) { const struct tcphdr *th; -- cgit From 3c293f4e08b58ad5b78f78d89ca1fd41f87f8729 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 12 Oct 2016 22:14:53 +0200 Subject: net: phy: Trigger state machine on state change and not polling. The phy_start() is used to indicate the PHY is now ready to do its work. The state is changed, normally to PHY_UP which means that both the MAC and the PHY are ready. If the phy driver is using polling, when the next poll happens, the state machine notices the PHY is now in PHY_UP, and kicks off auto-negotiation, if needed. If however, the PHY is using interrupts, there is no polling. The phy is stuck in PHY_UP until the next interrupt comes along. And there is no reason for the PHY to interrupt. Have phy_start() schedule the state machine to run, which both speeds up the polling use case, and makes the interrupt use case actually work. This problems exists whenever there is a state change which will not cause an interrupt. Trigger the state machine in these cases, e.g. phy_error(). Signed-off-by: Andrew Lunn Cc: Kyle Roeschley Tested-by: Kyle Roeschley Signed-off-by: David S. Miller --- drivers/net/phy/phy.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index c6f66832a1a6..f424b867f73e 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -607,6 +607,21 @@ void phy_start_machine(struct phy_device *phydev) queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, HZ); } +/** + * phy_trigger_machine - trigger the state machine to run + * + * @phydev: the phy_device struct + * + * Description: There has been a change in state which requires that the + * state machine runs. + */ + +static void phy_trigger_machine(struct phy_device *phydev) +{ + cancel_delayed_work_sync(&phydev->state_queue); + queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0); +} + /** * phy_stop_machine - stop the PHY state machine tracking * @phydev: target phy_device struct @@ -639,6 +654,8 @@ static void phy_error(struct phy_device *phydev) mutex_lock(&phydev->lock); phydev->state = PHY_HALTED; mutex_unlock(&phydev->lock); + + phy_trigger_machine(phydev); } /** @@ -800,8 +817,7 @@ void phy_change(struct work_struct *work) } /* reschedule state queue work to run as soon as possible */ - cancel_delayed_work_sync(&phydev->state_queue); - queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0); + phy_trigger_machine(phydev); return; ignore: @@ -890,6 +906,8 @@ void phy_start(struct phy_device *phydev) /* if phy was suspended, bring the physical link up again */ if (do_resume) phy_resume(phydev); + + phy_trigger_machine(phydev); } EXPORT_SYMBOL(phy_start); -- cgit From 6104e112f4a613506ba1ea9d4b974279f888006b Mon Sep 17 00:00:00 2001 From: David Ahern Date: Wed, 12 Oct 2016 13:20:11 -0700 Subject: net: ipv4: Do not drop to make_route if oif is l3mdev Commit e0d56fdd7342 was a bit aggressive removing l3mdev calls in the IPv4 stack. If the fib_lookup fails we do not want to drop to make_route if the oif is an l3mdev device. Also reverts 19664c6a0009 ("net: l3mdev: Remove netif_index_is_l3_master") which removed netif_index_is_l3_master. Fixes: e0d56fdd7342 ("net: l3mdev: remove redundant calls") Signed-off-by: David Ahern Signed-off-by: David S. Miller --- include/net/l3mdev.h | 24 ++++++++++++++++++++++++ net/ipv4/route.c | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h index b220dabeab45..3832099289c5 100644 --- a/include/net/l3mdev.h +++ b/include/net/l3mdev.h @@ -114,6 +114,25 @@ static inline u32 l3mdev_fib_table(const struct net_device *dev) return tb_id; } +static inline bool netif_index_is_l3_master(struct net *net, int ifindex) +{ + struct net_device *dev; + bool rc = false; + + if (ifindex == 0) + return false; + + rcu_read_lock(); + + dev = dev_get_by_index_rcu(net, ifindex); + if (dev) + rc = netif_is_l3_master(dev); + + rcu_read_unlock(); + + return rc; +} + struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6); static inline @@ -207,6 +226,11 @@ static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex) return 0; } +static inline bool netif_index_is_l3_master(struct net *net, int ifindex) +{ + return false; +} + static inline struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6) { diff --git a/net/ipv4/route.c b/net/ipv4/route.c index f2be689a6c85..62d4d90c1389 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2265,7 +2265,8 @@ struct rtable *__ip_route_output_key_hash(struct net *net, struct flowi4 *fl4, if (err) { res.fi = NULL; res.table = NULL; - if (fl4->flowi4_oif) { + if (fl4->flowi4_oif && + !netif_index_is_l3_master(net, fl4->flowi4_oif)) { /* Apparently, routing tables are wrong. Assume, that the destination is on link. -- cgit From 7307616245babb12c923151d8ef69af02e46c255 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Oct 2016 11:06:06 +0300 Subject: tipc: info leak in __tipc_nl_add_udp_addr() We should clear out the padding and unused struct members so that we don't expose stack information to userspace. Fixes: fdb3accc2c15 ('tipc: add the ability to get UDP options via netlink') Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/tipc/udp_media.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index d80cd3f7503f..78cab9c5a445 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -407,6 +407,7 @@ static int __tipc_nl_add_udp_addr(struct sk_buff *skb, if (ntohs(addr->proto) == ETH_P_IP) { struct sockaddr_in ip4; + memset(&ip4, 0, sizeof(ip4)); ip4.sin_family = AF_INET; ip4.sin_port = addr->port; ip4.sin_addr.s_addr = addr->ipv4.s_addr; @@ -417,6 +418,7 @@ static int __tipc_nl_add_udp_addr(struct sk_buff *skb, } else if (ntohs(addr->proto) == ETH_P_IPV6) { struct sockaddr_in6 ip6; + memset(&ip6, 0, sizeof(ip6)); ip6.sin6_family = AF_INET6; ip6.sin6_port = addr->port; memcpy(&ip6.sin6_addr, &addr->ipv6, sizeof(struct in6_addr)); -- cgit From 775f4f05501b3e36550ab63a592de3abd02e7591 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Oct 2016 11:45:28 +0300 Subject: net: rtnl: info leak in rtnl_fill_vfinfo() The "vf_vlan_info" struct ends with a 2 byte struct hole so we have to memset it to ensure that no stack information is revealed to user space. Fixes: 79aab093a0b5 ('net: Update API for VF vlan protocol 802.1ad support') Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b06d2f46b83e..fb7348f13501 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1144,6 +1144,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi)) return 0; + memset(&vf_vlan_info, 0, sizeof(vf_vlan_info)); + vf_mac.vf = vf_vlan.vf = vf_vlan_info.vf = -- cgit From 10f6c4d6ab2cdde768e29f41fbfbdde6c91fd1ff Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 13 Oct 2016 11:56:57 +0300 Subject: liquidio: CN23XX: fix a loop timeout This is supposed to loop 1000 times and then give up. The problem is it's a post-op and after the loop we test if "loop" is zero when really it would be -1. Fix this by making it a pre-op. Fixes: 1b7c55c4538b ("liquidio: CN23XX queue manipulation") Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c index bddb198c0b74..380a64115a98 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c @@ -693,7 +693,7 @@ static int cn23xx_enable_io_queues(struct octeon_device *oct) while ((reg_val & CN23XX_PKT_INPUT_CTL_RST) && !(reg_val & CN23XX_PKT_INPUT_CTL_QUIET) && - loop--) { + --loop) { reg_val = octeon_read_csr64( oct, CN23XX_SLI_IQ_PKT_CONTROL64(q_no)); -- cgit From 5852e93d4b67b9996a18541a657f87f1ae8c6a4a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 13 Oct 2016 13:28:33 +0200 Subject: net: axienet: Remove unused parameter from __axienet_device_reset The dev parameter passed to __axienet_device_reset() is not used inside the function, so remove it. Signed-off-by: Tobias Klauser Reviewed-by: Michal Simek Signed-off-by: David S. Miller --- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 35f9f9742a48..c688d68c39aa 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -431,8 +431,7 @@ static void axienet_setoptions(struct net_device *ndev, u32 options) lp->options |= options; } -static void __axienet_device_reset(struct axienet_local *lp, - struct device *dev, off_t offset) +static void __axienet_device_reset(struct axienet_local *lp, off_t offset) { u32 timeout; /* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset @@ -468,8 +467,8 @@ static void axienet_device_reset(struct net_device *ndev) u32 axienet_status; struct axienet_local *lp = netdev_priv(ndev); - __axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET); - __axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET); + __axienet_device_reset(lp, XAXIDMA_TX_CR_OFFSET); + __axienet_device_reset(lp, XAXIDMA_RX_CR_OFFSET); lp->max_frm_size = XAE_MAX_VLAN_FRAME_SIZE; lp->options |= XAE_OPTION_VLAN; @@ -1338,8 +1337,8 @@ static void axienet_dma_err_handler(unsigned long data) axienet_iow(lp, XAE_MDIO_MC_OFFSET, (mdio_mcreg & ~XAE_MDIO_MC_MDIOEN_MASK)); - __axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET); - __axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET); + __axienet_device_reset(lp, XAXIDMA_TX_CR_OFFSET); + __axienet_device_reset(lp, XAXIDMA_RX_CR_OFFSET); axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg); axienet_mdio_wait_until_ready(lp); -- cgit From 4eb6753c3324873752f56543e149956e39dd32b6 Mon Sep 17 00:00:00 2001 From: Nikolay Aleksandrov Date: Thu, 13 Oct 2016 15:20:52 +0200 Subject: net: bridge: add the multicast_flood flag attribute to brport_attrs When I added the multicast flood control flag, I also added an attribute for it for sysfs similar to other flags, but I forgot to add it to brport_attrs. Fixes: b6cb5ac8331b ("net: bridge: add per-port multicast flood flag") Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- net/bridge/br_sysfs_if.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index e657258e1f2c..8bd569695e76 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -217,6 +217,7 @@ static const struct brport_attribute *brport_attrs[] = { #endif &brport_attr_proxyarp, &brport_attr_proxyarp_wifi, + &brport_attr_multicast_flood, NULL }; -- cgit