Netdev List
 help / color / mirror / Atom feed
* Re: KASAN: use-after-free Read in __dev_queue_xmit
From: Willem de Bruijn @ 2018-05-09 16:38 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Eric Dumazet, Eric Dumazet, syzbot, alexander.deucher,
	Andrey Konovalov, Anoob Soman, chris, David Miller,
	Reshetova, Elena, Greg Kroah-Hartman, Kees Cook, LKML,
	Mike Maloney, mchehab, netdev, Rosen, Rami, Sowmini Varadhan,
	syzkaller-bugs, Willem de Bruijn
In-Reply-To: <CAF=yD-Je0ej2XDcfyEKano4R-og5oGjPvP36X4dSmpYshzBuKA@mail.gmail.com>

>> But a crash with the same signature is still occurring, so it should eventually
>> get reported again.  C reproducer is here, it works on Linus' tree (commit
>> 036db8bd963): https://syzkaller.appspot.com/text?tag=ReproC&x=105b1ae7800000
>
> This appears to be a separate issue.
>
> This reproducer requires a setsockopt SOL_SOCKET/SO_TIMESTAMPING
> to trigger the use-after-free. And the freed path also points at a timestamping
> skb:
>
> [   31.963619] Freed by task 2672:
> [   31.964006]  __kasan_slab_free+0x125/0x170
> [   31.964509]  kfree+0x8b/0x1a0
> [   31.964875]  skb_free_head+0x6f/0xa0
> [   31.965314]  skb_release_data+0x420/0x5a0
> [   31.965802]  skb_release_all+0x46/0x60
> [   31.966260]  kfree_skb+0x91/0x1c0
> [   31.966669]  __skb_complete_tx_timestamp+0x2e9/0x3d0
> [   31.967273]  __skb_tstamp_tx+0x3b3/0x620
> [   31.967774]  __dev_queue_xmit+0xed5/0x1a20
> [   31.968300]  packet_sendmsg+0x36fd/0x5400
> [   31.968821]  sock_sendmsg+0xc0/0x100
> [   31.969284]  ___sys_sendmsg+0x367/0x880
> [   31.969777]  __sys_sendmmsg+0x178/0x410
> [   31.970267]  __x64_sys_sendmmsg+0x99/0x100
> [   31.970789]  do_syscall_64+0x9a/0x2c0
> [   31.971260]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

This is a rare path taken when the timestamp skb cannot be queued
onto the socket (likely because of insufficient rcvbuf).

Somehow, freeing the timestamp skb triggers this use-after-free in
the original skb from which the timestamp was cloned. As if there
is a bug in the shared info dataref.

The report does occur on reading a shinfo field (gso_size).

^ permalink raw reply

* [PATCH net-next 4/4] net: hns3: refactor the loopback related function
From: Salil Mehta @ 2018-05-09 16:24 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
	linux-kernel, linuxarm, Yunsheng Lin
In-Reply-To: <20180509162441.18068-1-salil.mehta@huawei.com>

From: Yunsheng Lin <linyunsheng@huawei.com>

This patch refactors the loopback related function in order
to support the serdes loopback.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 21 +++----
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    | 68 +++++++++++-----------
 2 files changed, 42 insertions(+), 47 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
index eb3c34f..c16bb6c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -74,7 +74,7 @@ struct hns3_link_mode_mapping {
 	u32 ethtool_link_mode;
 };
 
-static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop)
+static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
 {
 	struct hnae3_handle *h = hns3_get_handle(ndev);
 	int ret;
@@ -85,11 +85,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop)
 
 	switch (loop) {
 	case HNAE3_MAC_INTER_LOOP_MAC:
-		ret = h->ae_algo->ops->set_loopback(h, loop, true);
-		break;
-	case HNAE3_MAC_LOOP_NONE:
-		ret = h->ae_algo->ops->set_loopback(h,
-			HNAE3_MAC_INTER_LOOP_MAC, false);
+		ret = h->ae_algo->ops->set_loopback(h, loop, en);
 		break;
 	default:
 		ret = -ENOTSUPP;
@@ -99,10 +95,7 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop)
 	if (ret)
 		return ret;
 
-	if (loop == HNAE3_MAC_LOOP_NONE)
-		h->ae_algo->ops->set_promisc_mode(h, ndev->flags & IFF_PROMISC);
-	else
-		h->ae_algo->ops->set_promisc_mode(h, 1);
+	h->ae_algo->ops->set_promisc_mode(h, en);
 
 	return ret;
 }
@@ -122,13 +115,13 @@ static int hns3_lp_up(struct net_device *ndev, enum hnae3_loop loop_mode)
 		return ret;
 	}
 
-	ret = hns3_lp_setup(ndev, loop_mode);
+	ret = hns3_lp_setup(ndev, loop_mode, true);
 	usleep_range(10000, 20000);
 
 	return ret;
 }
 
-static int hns3_lp_down(struct net_device *ndev)
+static int hns3_lp_down(struct net_device *ndev, enum hnae3_loop loop_mode)
 {
 	struct hnae3_handle *h = hns3_get_handle(ndev);
 	int ret;
@@ -136,7 +129,7 @@ static int hns3_lp_down(struct net_device *ndev)
 	if (!h->ae_algo->ops->stop)
 		return -EOPNOTSUPP;
 
-	ret = hns3_lp_setup(ndev, HNAE3_MAC_LOOP_NONE);
+	ret = hns3_lp_setup(ndev, loop_mode, false);
 	if (ret) {
 		netdev_err(ndev, "lb_setup return error: %d\n", ret);
 		return ret;
@@ -332,7 +325,7 @@ static void hns3_self_test(struct net_device *ndev,
 		data[test_index] = hns3_lp_up(ndev, loop_type);
 		if (!data[test_index]) {
 			data[test_index] = hns3_lp_run_test(ndev, loop_type);
-			hns3_lp_down(ndev);
+			hns3_lp_down(ndev, loop_type);
 		}
 
 		if (data[test_index])
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 084b904..316ec842 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3682,48 +3682,50 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable)
 			"mac enable fail, ret =%d.\n", ret);
 }
 
-static int hclge_set_loopback(struct hnae3_handle *handle,
-			      enum hnae3_loop loop_mode, bool en)
+static int hclge_set_mac_loopback(struct hclge_dev *hdev, bool en)
 {
-	struct hclge_vport *vport = hclge_get_vport(handle);
 	struct hclge_config_mac_mode_cmd *req;
-	struct hclge_dev *hdev = vport->back;
 	struct hclge_desc desc;
 	u32 loop_en;
 	int ret;
 
-	switch (loop_mode) {
-	case HNAE3_MAC_INTER_LOOP_MAC:
-		req = (struct hclge_config_mac_mode_cmd *)&desc.data[0];
-		/* 1 Read out the MAC mode config at first */
-		hclge_cmd_setup_basic_desc(&desc,
-					   HCLGE_OPC_CONFIG_MAC_MODE,
-					   true);
-		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-		if (ret) {
-			dev_err(&hdev->pdev->dev,
-				"mac loopback get fail, ret =%d.\n",
-				ret);
-			return ret;
-		}
+	req = (struct hclge_config_mac_mode_cmd *)&desc.data[0];
+	/* 1 Read out the MAC mode config at first */
+	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAC_MODE, true);
+	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+	if (ret) {
+		dev_err(&hdev->pdev->dev,
+			"mac loopback get fail, ret =%d.\n", ret);
+		return ret;
+	}
 
-		/* 2 Then setup the loopback flag */
-		loop_en = le32_to_cpu(req->txrx_pad_fcs_loop_en);
-		if (en)
-			hnae_set_bit(loop_en, HCLGE_MAC_APP_LP_B, 1);
-		else
-			hnae_set_bit(loop_en, HCLGE_MAC_APP_LP_B, 0);
+	/* 2 Then setup the loopback flag */
+	loop_en = le32_to_cpu(req->txrx_pad_fcs_loop_en);
+	hnae_set_bit(loop_en, HCLGE_MAC_APP_LP_B, en ? 1 : 0);
 
-		req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);
+	req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);
 
-		/* 3 Config mac work mode with loopback flag
-		 * and its original configure parameters
-		 */
-		hclge_cmd_reuse_desc(&desc, false);
-		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
-		if (ret)
-			dev_err(&hdev->pdev->dev,
-				"mac loopback set fail, ret =%d.\n", ret);
+	/* 3 Config mac work mode with loopback flag
+	 * and its original configure parameters
+	 */
+	hclge_cmd_reuse_desc(&desc, false);
+	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+	if (ret)
+		dev_err(&hdev->pdev->dev,
+			"mac loopback set fail, ret =%d.\n", ret);
+	return ret;
+}
+
+static int hclge_set_loopback(struct hnae3_handle *handle,
+			      enum hnae3_loop loop_mode, bool en)
+{
+	struct hclge_vport *vport = hclge_get_vport(handle);
+	struct hclge_dev *hdev = vport->back;
+	int ret;
+
+	switch (loop_mode) {
+	case HNAE3_MAC_INTER_LOOP_MAC:
+		ret = hclge_set_mac_loopback(hdev, en);
 		break;
 	default:
 		ret = -ENOTSUPP;
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 3/4] net: hns3: fix for cleaning ring problem
From: Salil Mehta @ 2018-05-09 16:24 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
	linux-kernel, linuxarm, Yunsheng Lin
In-Reply-To: <20180509162441.18068-1-salil.mehta@huawei.com>

From: Yunsheng Lin <linyunsheng@huawei.com>

The head or tail in hardware is not longer valid when resetting,
current hns3_clear_all_ring use them to clean the ring, which
will cause problem during resetting.

This patch fixes it by using next_to_use and next_to_clean in
the ring struct.

Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 34 ++++++++++++++++++++++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index bd8e14b..4031174 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3203,9 +3203,35 @@ static void hns3_recover_hw_addr(struct net_device *ndev)
 		hns3_nic_mc_sync(ndev, ha->addr);
 }
 
-static void hns3_drop_skb_data(struct hns3_enet_ring *ring, struct sk_buff *skb)
+static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
 {
-	dev_kfree_skb_any(skb);
+	if (!HNAE3_IS_TX_RING(ring))
+		return;
+
+	while (ring->next_to_clean != ring->next_to_use) {
+		hns3_free_buffer_detach(ring, ring->next_to_clean);
+		ring_ptr_move_fw(ring, next_to_clean);
+	}
+}
+
+static void hns3_clear_rx_ring(struct hns3_enet_ring *ring)
+{
+	if (HNAE3_IS_TX_RING(ring))
+		return;
+
+	while (ring->next_to_use != ring->next_to_clean) {
+		/* When a buffer is not reused, it's memory has been
+		 * freed in hns3_handle_rx_bd or will be freed by
+		 * stack, so only need to unmap the buffer here.
+		 */
+		if (!ring->desc_cb[ring->next_to_use].reuse_flag) {
+			hns3_unmap_buffer(ring,
+					  &ring->desc_cb[ring->next_to_use]);
+			ring->desc_cb[ring->next_to_use].dma = 0;
+		}
+
+		ring_ptr_move_fw(ring, next_to_use);
+	}
 }
 
 static void hns3_clear_all_ring(struct hnae3_handle *h)
@@ -3219,13 +3245,13 @@ static void hns3_clear_all_ring(struct hnae3_handle *h)
 		struct hns3_enet_ring *ring;
 
 		ring = priv->ring_data[i].ring;
-		hns3_clean_tx_ring(ring, ring->desc_num);
+		hns3_clear_tx_ring(ring);
 		dev_queue = netdev_get_tx_queue(ndev,
 						priv->ring_data[i].queue_index);
 		netdev_tx_reset_queue(dev_queue);
 
 		ring = priv->ring_data[i + h->kinfo.num_tqps].ring;
-		hns3_clean_rx_ring(ring, ring->desc_num, hns3_drop_skb_data);
+		hns3_clear_rx_ring(ring);
 	}
 }
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 2/4] net: hns3: remove add/del_tunnel_udp in hns3_enet module
From: Salil Mehta @ 2018-05-09 16:24 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
	linux-kernel, linuxarm, Yunsheng Lin
In-Reply-To: <20180509162441.18068-1-salil.mehta@huawei.com>

From: Yunsheng Lin <linyunsheng@huawei.com>

The add/del_tunnel_udp is not implemented in hclge_main moulde,
the NETIF_F_RX_UDP_TUNNEL_PORT feature bit is added automatically
by stack when ndo_udp_tunnel_add is not null in dev->netdev_ops.

This patch removes the add/del_tunnel_udp related function, for
we do not support this feature now.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h     |  7 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 89 -------------------------
 2 files changed, 96 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 37ec1b3..804ea83 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -273,10 +273,6 @@ struct hnae3_ae_dev {
  *   Map rings to vector
  * unmap_ring_from_vector()
  *   Unmap rings from vector
- * add_tunnel_udp()
- *   Add tunnel information to hardware
- * del_tunnel_udp()
- *   Delete tunnel information from hardware
  * reset_queue()
  *   Reset queue
  * get_fw_version()
@@ -388,9 +384,6 @@ struct hnae3_ae_ops {
 				      int vector_num,
 				      struct hnae3_ring_chain_node *vr_chain);
 
-	int (*add_tunnel_udp)(struct hnae3_handle *handle, u16 port_num);
-	int (*del_tunnel_udp)(struct hnae3_handle *handle, u16 port_num);
-
 	void (*reset_queue)(struct hnae3_handle *handle, u16 queue_id);
 	u32 (*get_fw_version)(struct hnae3_handle *handle);
 	void (*get_mdix_mode)(struct hnae3_handle *handle,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a55c8f515..bd8e14b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -1244,93 +1244,6 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
 	stats->tx_compressed = netdev->stats.tx_compressed;
 }
 
-static void hns3_add_tunnel_port(struct net_device *netdev, u16 port,
-				 enum hns3_udp_tnl_type type)
-{
-	struct hns3_nic_priv *priv = netdev_priv(netdev);
-	struct hns3_udp_tunnel *udp_tnl = &priv->udp_tnl[type];
-	struct hnae3_handle *h = priv->ae_handle;
-
-	if (udp_tnl->used && udp_tnl->dst_port == port) {
-		udp_tnl->used++;
-		return;
-	}
-
-	if (udp_tnl->used) {
-		netdev_warn(netdev,
-			    "UDP tunnel [%d], port [%d] offload\n", type, port);
-		return;
-	}
-
-	udp_tnl->dst_port = port;
-	udp_tnl->used = 1;
-	/* TBD send command to hardware to add port */
-	if (h->ae_algo->ops->add_tunnel_udp)
-		h->ae_algo->ops->add_tunnel_udp(h, port);
-}
-
-static void hns3_del_tunnel_port(struct net_device *netdev, u16 port,
-				 enum hns3_udp_tnl_type type)
-{
-	struct hns3_nic_priv *priv = netdev_priv(netdev);
-	struct hns3_udp_tunnel *udp_tnl = &priv->udp_tnl[type];
-	struct hnae3_handle *h = priv->ae_handle;
-
-	if (!udp_tnl->used || udp_tnl->dst_port != port) {
-		netdev_warn(netdev,
-			    "Invalid UDP tunnel port %d\n", port);
-		return;
-	}
-
-	udp_tnl->used--;
-	if (udp_tnl->used)
-		return;
-
-	udp_tnl->dst_port = 0;
-	/* TBD send command to hardware to del port  */
-	if (h->ae_algo->ops->del_tunnel_udp)
-		h->ae_algo->ops->del_tunnel_udp(h, port);
-}
-
-/* hns3_nic_udp_tunnel_add - Get notifiacetion about UDP tunnel ports
- * @netdev: This physical ports's netdev
- * @ti: Tunnel information
- */
-static void hns3_nic_udp_tunnel_add(struct net_device *netdev,
-				    struct udp_tunnel_info *ti)
-{
-	u16 port_n = ntohs(ti->port);
-
-	switch (ti->type) {
-	case UDP_TUNNEL_TYPE_VXLAN:
-		hns3_add_tunnel_port(netdev, port_n, HNS3_UDP_TNL_VXLAN);
-		break;
-	case UDP_TUNNEL_TYPE_GENEVE:
-		hns3_add_tunnel_port(netdev, port_n, HNS3_UDP_TNL_GENEVE);
-		break;
-	default:
-		netdev_err(netdev, "unsupported tunnel type %d\n", ti->type);
-		break;
-	}
-}
-
-static void hns3_nic_udp_tunnel_del(struct net_device *netdev,
-				    struct udp_tunnel_info *ti)
-{
-	u16 port_n = ntohs(ti->port);
-
-	switch (ti->type) {
-	case UDP_TUNNEL_TYPE_VXLAN:
-		hns3_del_tunnel_port(netdev, port_n, HNS3_UDP_TNL_VXLAN);
-		break;
-	case UDP_TUNNEL_TYPE_GENEVE:
-		hns3_del_tunnel_port(netdev, port_n, HNS3_UDP_TNL_GENEVE);
-		break;
-	default:
-		break;
-	}
-}
-
 static int hns3_setup_tc(struct net_device *netdev, void *type_data)
 {
 	struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
@@ -1569,8 +1482,6 @@ static const struct net_device_ops hns3_nic_netdev_ops = {
 	.ndo_get_stats64	= hns3_nic_get_stats64,
 	.ndo_setup_tc		= hns3_nic_setup_tc,
 	.ndo_set_rx_mode	= hns3_nic_set_rx_mode,
-	.ndo_udp_tunnel_add	= hns3_nic_udp_tunnel_add,
-	.ndo_udp_tunnel_del	= hns3_nic_udp_tunnel_del,
 	.ndo_vlan_rx_add_vid	= hns3_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= hns3_vlan_rx_kill_vid,
 	.ndo_set_vf_vlan	= hns3_ndo_set_vf_vlan,
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 1/4] net: hns3: Fix for setting mac address when resetting
From: Salil Mehta @ 2018-05-09 16:24 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
	linux-kernel, linuxarm, Yunsheng Lin
In-Reply-To: <20180509162441.18068-1-salil.mehta@huawei.com>

From: Yunsheng Lin <linyunsheng@huawei.com>

When hns3_init_mac_addr is called during reset process, it will
get the mac address from NCL_CONFIG and set it to hardware. If
user has changed the mac address, then the mac address set by
user is lost during resetting.

This patch fixes it by not getting the mac address from NCL_CONFIG
when resetting.

Fixes: 424eb834a9be ("net: hns3: Unified HNS3 {VF|PF} Ethernet Driver for hip08 SoC")
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 729bcab..a55c8f515 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3046,13 +3046,13 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
 }
 
 /* Set mac addr if it is configured. or leave it to the AE driver */
-static void hns3_init_mac_addr(struct net_device *netdev)
+static void hns3_init_mac_addr(struct net_device *netdev, bool init)
 {
 	struct hns3_nic_priv *priv = netdev_priv(netdev);
 	struct hnae3_handle *h = priv->ae_handle;
 	u8 mac_addr_temp[ETH_ALEN];
 
-	if (h->ae_algo->ops->get_mac_addr) {
+	if (h->ae_algo->ops->get_mac_addr && init) {
 		h->ae_algo->ops->get_mac_addr(h, mac_addr_temp);
 		ether_addr_copy(netdev->dev_addr, mac_addr_temp);
 	}
@@ -3106,7 +3106,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
 	handle->kinfo.netdev = netdev;
 	handle->priv = (void *)priv;
 
-	hns3_init_mac_addr(netdev);
+	hns3_init_mac_addr(netdev, true);
 
 	hns3_set_default_feature(netdev);
 
@@ -3353,7 +3353,7 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
 	struct hns3_nic_priv *priv = netdev_priv(netdev);
 	int ret;
 
-	hns3_init_mac_addr(netdev);
+	hns3_init_mac_addr(netdev, false);
 	hns3_nic_set_rx_mode(netdev);
 	hns3_recover_hw_addr(netdev);
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 0/4] Misc bug fixes for HNS3 Ethernet Driver
From: Salil Mehta @ 2018-05-09 16:24 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, lipeng321, mehta.salil, netdev,
	linux-kernel, linuxarm

Fixes to some of the bugs found during system test, internal review
and clean-up

Yunsheng Lin (4):
  net: hns3: Fix for setting mac address when resetting
  net: hns3: remove add/del_tunnel_udp in hns3_enet module
  net: hns3: fix for cleaning ring problem
  net: hns3: refactor the loopback related function

 drivers/net/ethernet/hisilicon/hns3/hnae3.h        |   7 --
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c    | 131 ++++++---------------
 drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c |  21 ++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    |  68 +++++------
 4 files changed, 76 insertions(+), 151 deletions(-)

-- 
2.7.4

^ permalink raw reply

* Re: [PATCH] ixgbe: fix memory leak on ipsec allocation
From: Shannon Nelson @ 2018-05-09 16:22 UTC (permalink / raw)
  To: Colin King, Jeff Kirsher, David S . Miller, intel-wired-lan,
	netdev
  Cc: kernel-janitors, linux-kernel
In-Reply-To: <20180509135848.20530-1-colin.king@canonical.com>

On 5/9/2018 6:58 AM, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
> 
> The error clean up path kfree's adapter->ipsec and should be
> instead kfree'ing ipsec. Fix this.  Also, the err1 error exit path
> does not need to kfree ipsec because this failure path was for
> the failed allocation of ipsec.
> 
> Detected by CoverityScan, CID#146424 ("Resource Leak")
> 
> Fixes: 63a67fe229ea ("ixgbe: add ipsec offload add and remove SA")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Yep, thanks, good catch.

Acked-by: Shannon Nelson <shannon.nelson@oracle.com>


> ---
>   drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> index 41af2b81e960..195c0b65eee2 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
> @@ -919,8 +919,8 @@ void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter)
>   	kfree(ipsec->ip_tbl);
>   	kfree(ipsec->rx_tbl);
>   	kfree(ipsec->tx_tbl);
> +	kfree(ipsec);
>   err1:
> -	kfree(adapter->ipsec);
>   	netdev_err(adapter->netdev, "Unable to allocate memory for SA tables");
>   }
>   
> 

^ permalink raw reply

* Re: [PATCH bpf] nfp: bpf: allow zero-length capabilities
From: Daniel Borkmann @ 2018-05-09 16:18 UTC (permalink / raw)
  To: Jakub Kicinski, alexei.starovoitov; +Cc: oss-drivers, netdev
In-Reply-To: <20180509024241.24032-1-jakub.kicinski@netronome.com>

On 05/09/2018 04:42 AM, Jakub Kicinski wrote:
> Some BPF capabilities carry no value, they simply indicate feature
> is present.  Our capability parsing loop will exit early if last
> capability is zero-length because it's looking for more than 8 bytes
> of data (8B is our TLV header length).  Allow the last capability to
> be zero-length.
> 
> This bug would lead to driver failing to probe with the following error
> if the last capability FW advertises is zero-length:
> 
>     nfp: BPF capabilities left after parsing, parsed:92 total length:100
>     nfp: invalid BPF capabilities at offset:92
> 
> Note the "parsed" and "length" values are 8 apart.
> 
> No shipping FW runs into this issue, but we can't guarantee that will
> remain the case.
> 
> Fixes: 77a844ee650c ("nfp: bpf: prepare for parsing BPF FW capabilities")
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>

Applied to bpf tree, thanks!

^ permalink raw reply

* Re: [PATCH bpf-next] xsk: fix 64-bit division
From: Daniel Borkmann @ 2018-05-09 16:13 UTC (permalink / raw)
  To: Randy Dunlap, Björn Töpel, ast, netdev
  Cc: Björn Töpel, Stephen Rothwell, magnus.karlsson,
	linux-next, linux-kernel
In-Reply-To: <baf737cf-a0c4-b542-8d37-fd9cdfe7101d@infradead.org>

On 05/07/2018 08:25 PM, Randy Dunlap wrote:
> On 05/07/2018 10:43 AM, Björn Töpel wrote:
>> From: Björn Töpel <bjorn.topel@intel.com>
>>
>> i386 builds report:
>>   net/xdp/xdp_umem.o: In function `xdp_umem_reg':
>>   xdp_umem.c:(.text+0x47e): undefined reference to `__udivdi3'
>>
>> This fix uses div_u64 instead of the GCC built-in.
>>
>> Fixes: c0c77d8fb787 ("xsk: add user memory registration support sockopt")
>> Signed-off-by: Björn Töpel <bjorn.topel@intel.com>
> 
> I don't know why the subject says xsk (instead of xdp), but anyway:
> 
> Reported-by: Randy Dunlap <rdunlap@infradead.org>
> Tested-by: Randy Dunlap <rdunlap@infradead.org>

Applied to bpf-next, thanks everyone!

^ permalink raw reply

* Re: KASAN: use-after-free Read in __dev_queue_xmit
From: Willem de Bruijn @ 2018-05-09 16:11 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Eric Dumazet, Eric Dumazet, syzbot, alexander.deucher,
	Andrey Konovalov, Anoob Soman, chris, David Miller,
	Reshetova, Elena, Greg Kroah-Hartman, Kees Cook, LKML,
	Mike Maloney, mchehab, netdev, Rosen, Rami, Sowmini Varadhan,
	syzkaller-bugs, Willem de Bruijn
In-Reply-To: <20180509073754.GG711@sol.localdomain>

On Wed, May 9, 2018 at 3:37 AM, Eric Biggers <ebiggers3@gmail.com> wrote:
> On Wed, Jan 03, 2018 at 10:53:14PM -0800, Eric Dumazet wrote:
>> On Wed, 2018-01-03 at 21:13 -0800, Eric Dumazet wrote:
>> > Note: all commands must start from beginning of the line in the email body.
>> >
>> > I guess skb_probe_transport_header() should be hardened to reject malicious
>> > packets given by user space, instead of being gentle.
>>
>> Although bug triggered for this particular repro is in flow dissector
>> :/
>>
>> I will test :
>>
>> diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
>> index 15ce300637650e17fcab7e378b20fe7972686d46..544bddf08e13c7f6e47aadc737244c9ba5af56b2 100644
>> --- a/net/core/flow_dissector.c
>> +++ b/net/core/flow_dissector.c
>> @@ -976,8 +976,8 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
>>  out_good:
>>         ret = true;
>>
>> -       key_control->thoff = (u16)nhoff;
>>  out:
>> +       key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
>>         key_basic->n_proto = proto;
>>         key_basic->ip_proto = ip_proto;
>>
>> @@ -985,7 +985,6 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
>>
>>  out_bad:
>>         ret = false;
>> -       key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
>>         goto out;
>>  }
>>  EXPORT_SYMBOL(__skb_flow_dissect);
>
> Fix for this was commit d0c081b49137cd:
>
> #syz fix: flow_dissector: properly cap thoff field
>
> But a crash with the same signature is still occurring, so it should eventually
> get reported again.  C reproducer is here, it works on Linus' tree (commit
> 036db8bd963): https://syzkaller.appspot.com/text?tag=ReproC&x=105b1ae7800000

This appears to be a separate issue.

This reproducer requires a setsockopt SOL_SOCKET/SO_TIMESTAMPING
to trigger the use-after-free. And the freed path also points at a timestamping
skb:

[   31.963619] Freed by task 2672:
[   31.964006]  __kasan_slab_free+0x125/0x170
[   31.964509]  kfree+0x8b/0x1a0
[   31.964875]  skb_free_head+0x6f/0xa0
[   31.965314]  skb_release_data+0x420/0x5a0
[   31.965802]  skb_release_all+0x46/0x60
[   31.966260]  kfree_skb+0x91/0x1c0
[   31.966669]  __skb_complete_tx_timestamp+0x2e9/0x3d0
[   31.967273]  __skb_tstamp_tx+0x3b3/0x620
[   31.967774]  __dev_queue_xmit+0xed5/0x1a20
[   31.968300]  packet_sendmsg+0x36fd/0x5400
[   31.968821]  sock_sendmsg+0xc0/0x100
[   31.969284]  ___sys_sendmsg+0x367/0x880
[   31.969777]  __sys_sendmmsg+0x178/0x410
[   31.970267]  __x64_sys_sendmmsg+0x99/0x100
[   31.970789]  do_syscall_64+0x9a/0x2c0
[   31.971260]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

The data skb itself is zero bytes, it appears.

^ permalink raw reply

* Re: [PATCH bpf-next 0/2] nfp: bpf: add programmable RSS support
From: Daniel Borkmann @ 2018-05-09 16:09 UTC (permalink / raw)
  To: Alexei Starovoitov, Jakub Kicinski; +Cc: davem, netdev, oss-drivers
In-Reply-To: <20180509024215.xnlajxrua7jluoon@ast-mbp>

On 05/09/2018 04:42 AM, Alexei Starovoitov wrote:
> On Tue, May 08, 2018 at 07:37:05PM -0700, Jakub Kicinski wrote:
>> Hi!
>>
>> This small series adds a feature which extends BPF offload beyond
>> a pure host processing offload and firmly into the realm of
>> heterogeneous processing.  Allowing offloaded XDP programs to set
>> the RX queue index opens the door for defining fully programmable
>> RSS/n-tuple filter replacement.  In fact the device datapath will
>> skip the RSS processing completely if BPF decided on the queue
>> already, making the XDP program replace part of the standard NIC
>> datapath.
> 
> Absolutely love it!
> Huge feature enabled by such tiny diff.
> 
> For the set:
> Acked-by: Alexei Starovoitov <ast@kernel.org>

Second that! Applied to bpf-next, thanks Jakub!

^ permalink raw reply

* Re: [PATCH bpf-next 0/6] Introduce BTF ID
From: Daniel Borkmann @ 2018-05-09 16:08 UTC (permalink / raw)
  To: Martin KaFai Lau, netdev; +Cc: Alexei Starovoitov, kernel-team
In-Reply-To: <20180504214955.1058805-1-kafai@fb.com>

On 05/04/2018 11:49 PM, Martin KaFai Lau wrote:
> This series introduces BTF ID which is exposed through
> the new BPF_BTF_GET_FD_BY_ID cmd, new "struct bpf_btf_info"
> and new members in the "struct bpf_map_info".
> 
> Please see individual patch for details.

Applied to bpf-next, thanks Martin!

^ permalink raw reply

* Re: [bpf-next v2 8/9] bpf: Provide helper to do forwarding lookups in kernel FIB table
From: David Ahern @ 2018-05-09 16:05 UTC (permalink / raw)
  To: Daniel Borkmann, netdev, borkmann, ast
  Cc: davem, shm, roopa, brouer, toke, john.fastabend
In-Reply-To: <433c2320-ed9b-446e-6e29-92075f947251@iogearbox.net>

On 5/9/18 2:15 AM, Daniel Borkmann wrote:
> 
> Ohh well, this is causing allmodconfig build warnings (e.g. on x86) as reported today:

lovely.

> 
> In file included from include/linux/dma-mapping.h:5:0,
>                  from include/linux/skbuff.h:34,
>                  from include/linux/if_ether.h:23,
>                  from include/uapi/linux/bpf.h:13,
>                  from include/linux/bpf-cgroup.h:6,
>                  from include/linux/cgroup-defs.h:22,
>                  from include/linux/cgroup.h:28,
>                  from include/linux/perf_event.h:57,
>                  from include/linux/trace_events.h:10,
>                  from include/trace/trace_events.h:20,
>                  from include/trace/define_trace.h:96,
>                  from drivers/android/binder_trace.h:387,
>                  from drivers/android/binder.c:5702:
> include/linux/sizes.h:24:0: warning: "SZ_1K" redefined
>  #define SZ_1K    0x00000400
> drivers/android/binder.c:116:0: note: this is the location of the previous definition
>  #define SZ_1K                               0x400

binder.c has very few recent commits to it. Are you ok with me
submitting the change with the others in this set (with proper cc's of
course)?

> fs/ecryptfs/miscdev.c:206:0: warning: "PKT_TYPE_OFFSET" redefined
>  #define PKT_TYPE_OFFSET  0
> In file included from include/linux/if_ether.h:23:0,
>                  from include/uapi/linux/bpf.h:13,
>                  from include/linux/bpf-cgroup.h:6,
>                  from include/linux/cgroup-defs.h:22,
>                  from include/linux/cgroup.h:28,
>                  from include/linux/writeback.h:183,
>                  from include/linux/backing-dev.h:16,
>                  from fs/ecryptfs/ecryptfs_kernel.h:41,
>                  from fs/ecryptfs/miscdev.c:30:
> include/linux/skbuff.h:753:0: note: this is the location of the previous definition
>  #define PKT_TYPE_OFFSET() offsetof(struct sk_buff, __pkt_type_offset)

And this one I renamed to SKB_PKT_TYPE_OFFSET

With that it compiles cleanly.

> 
> Lets get a clean, proper version of the whole series into bpf-next. I've dropped it
> from there right now and waiting for your v3 respin to apply with the above fixed.
> 
> Thank you.
> 

^ permalink raw reply

* [PATCH net-next] hv_netvsc: typo in NDIS RSS parameters structure
From: Stephen Hemminger @ 2018-05-09 16:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger

Fix simple misspelling kashkey_offset should be hashkey_offset.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h   | 2 +-
 drivers/net/hyperv/rndis_filter.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 6ebe39a3dde6..1be34d2e3563 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -110,7 +110,7 @@ struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
 	u16 hashkey_size;
 
 	/* The offset of the secret key from the beginning of this structure */
-	u32 kashkey_offset;
+	u32 hashkey_offset;
 
 	u32 processor_masks_offset;
 	u32 num_processor_masks;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 3b6dbacaf77d..3cb2c4666b2c 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -752,7 +752,7 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev,
 	rssp->indirect_tabsize = 4*ITAB_NUM;
 	rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
 	rssp->hashkey_size = NETVSC_HASH_KEYLEN;
-	rssp->kashkey_offset = rssp->indirect_taboffset +
+	rssp->hashkey_offset = rssp->indirect_taboffset +
 			       rssp->indirect_tabsize;
 
 	/* Set indirection table entries */
@@ -761,7 +761,7 @@ int rndis_filter_set_rss_param(struct rndis_device *rdev,
 		itab[i] = rdev->rx_table[i];
 
 	/* Set hask key values */
-	keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
+	keyp = (u8 *)((unsigned long)rssp + rssp->hashkey_offset);
 	memcpy(keyp, rss_key, NETVSC_HASH_KEYLEN);
 
 	ret = rndis_filter_send_request(rdev, request);
-- 
2.17.0

^ permalink raw reply related

* Re: [net-next PATCH v2 0/8] UDP GSO Segmentation clean-ups
From: Alexander Duyck @ 2018-05-09 15:58 UTC (permalink / raw)
  To: Willem de Bruijn; +Cc: Network Development, Willem de Bruijn, David Miller
In-Reply-To: <CAF=yD-+=9EUjiT=ZG+G=phQcHmD8s3e6mydhBehddVCqL0pEGg@mail.gmail.com>

On Wed, May 9, 2018 at 8:39 AM, Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
> On Mon, May 7, 2018 at 2:02 PM, Alexander Duyck
> <alexander.duyck@gmail.com> wrote:
>> On Sat, May 5, 2018 at 3:06 AM, Willem de Bruijn
>> <willemdebruijn.kernel@gmail.com> wrote:
>>> On Fri, May 4, 2018 at 8:28 PM, Alexander Duyck
>>> <alexander.duyck@gmail.com> wrote:
>>>> This patch set addresses a number of issues I found while sorting out
>>>> enabling UDP GSO Segmentation support for ixgbe/ixgbevf. Specifically there
>>>> were a number of issues related to the checksum and such that seemed to
>>>> cause either minor irregularities or kernel panics in the case of the
>>>> offload request being allowed to traverse between name spaces.
>>>
>>> Were you able to traverse GSO packets between network namespace before
>>> adding to NETIF_F_GSO_SOFTWARE? It does appear that veth includes
>>> NETIF_F_GSO_ENCAP_ALL, which also allows GSO.
>>
>> Without that change the tunnel wouldn't pass the requests between
>> namespaces. However with it I was able to easily test the software
>> checksum code as otherwise the socket was returning EIO when the
>> hardware checksum was disabled.
>>
>>> In either case, it should not be possible for GSO packets to arrive on a veth
>>> device, as that can result in queuing the GSO packet to a recipient socket.
>>> In this regard veth is like loopback and must exclude GSO support.
>>>
>>> I'll take a look.
>>
>> I suspect it was probably sending veth UDP segmentation offload
>> requests. For now I can probably drop he patch that was adding it and
>> it can be added later to individual drivers if needed.
>
> I just tested udpgso_bench_tx over veth (on a commit without your
> patchset).
>
> Having NETIF_F_GSO_UDP_L4 in NETIF_F_GSO_ENCAP_ALL
> and NETIF_F_GSO_ENCAP_ALL in VETH_FEATURES is
> sufficient to receive large packets on the veth peer.
>
> This is clearly a bug, as is for any device that may loop packets
> onto a local socket. Such as macvlan in bridge mode.
>
> I will have to revise commit 83aa025f535f ("udp: add gso support
> to virtual devices")
>
> It remains useful to have this capability on the bonding device. I
> might remove the flag from NETIF_F_GSO_ENCAP_ALL and add
> it specifically to that device.
>
> This is also all relevant to future work of NETIF_F_GSO_SOFTWARE.

Sounds like a plan. In the meantime I am going to see about getting
some internal paperwork taken care of to get UDP GSO added to
ixgbe/ixgbevf as an official feature.

I need to finish up some work I am doing on macvlan over the next
couple of weeks so I won't be focusing on this code for the next month
or so.

Thanks.

- Alex

^ permalink raw reply

* Re: [PATCH ghak81 RFC V1 0/5] audit: group task params
From: Paul Moore @ 2018-05-09 15:53 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: Linux-Audit Mailing List, LKML,
	Linux NetDev Upstream Mailing List, Netfilter Devel List,
	Linux Security Module list, Integrity Measurement Architecture,
	SElinux list, Eric Paris, Steve Grubb, Ingo Molnar, David Howells
In-Reply-To: <cover.1525466167.git.rgb@redhat.com>

On Fri, May 4, 2018 at 4:54 PM, Richard Guy Briggs <rgb@redhat.com> wrote:
> Group the audit parameters for each task into one structure.
> In particular, remove the loginuid and sessionid values and the audit
> context pointer from the task structure, replacing them with an audit
> task information structure to contain them.  Use access functions to
> access audit values.
>
> Note:  Use static allocation of the audit task information structure
> initially.  Dynamic allocation was considered and attempted, but isn't
> ready yet.  Static allocation has the limitation that future audit task
> information structure changes would cause a visible change to the rest
> of the kernel, whereas dynamic allocation would mostly hide any future
> changes.
>
> The first four access normalization patches could stand alone.

I agree that the first four patches have some standalone value, and
since we are currently at -rc4, did you want to post another patchset
of just those four patches with feedback incorporated?  I imagine that
should be quick work, and that way they aren't help up with any
problems/discussion regarding the take_struct changes.

> Passes audit-testsuite.
>
> Richard Guy Briggs (5):
>   audit: normalize loginuid read access
>   audit: convert sessionid unset to a macro
>   audit: use inline function to get audit context
>   audit: use inline function to set audit context
>   audit: collect audit task parameters
>
>  MAINTAINERS                          |  2 +-
>  include/linux/audit.h                | 30 ++++++++++---
>  include/linux/audit_task.h           | 31 ++++++++++++++
>  include/linux/sched.h                |  6 +--
>  include/net/xfrm.h                   |  4 +-
>  include/uapi/linux/audit.h           |  1 +
>  init/init_task.c                     |  8 +++-
>  kernel/audit.c                       |  4 +-
>  kernel/audit_watch.c                 |  2 +-
>  kernel/auditsc.c                     | 82 ++++++++++++++++++------------------
>  kernel/fork.c                        |  2 +-
>  net/bridge/netfilter/ebtables.c      |  2 +-
>  net/core/dev.c                       |  2 +-
>  net/netfilter/x_tables.c             |  2 +-
>  net/netlabel/netlabel_user.c         |  2 +-
>  security/integrity/ima/ima_api.c     |  2 +-
>  security/integrity/integrity_audit.c |  2 +-
>  security/lsm_audit.c                 |  2 +-
>  security/selinux/hooks.c             |  4 +-
>  security/selinux/selinuxfs.c         |  6 +--
>  security/selinux/ss/services.c       | 12 +++---
>  21 files changed, 129 insertions(+), 79 deletions(-)
>  create mode 100644 include/linux/audit_task.h
>
> --
> 1.8.3.1
>



-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH ghak81 RFC V1 5/5] audit: collect audit task parameters
From: Paul Moore @ 2018-05-09 15:46 UTC (permalink / raw)
  To: Richard Guy Briggs
  Cc: Linux-Audit Mailing List, LKML,
	Linux NetDev Upstream Mailing List, Netfilter Devel List,
	Linux Security Module list, Integrity Measurement Architecture,
	SElinux list, Eric Paris, Steve Grubb, Ingo Molnar, David Howells
In-Reply-To: <5b0e0eef72b5137830f9f6c67908e5252dbf48f5.1525466167.git.rgb@redhat.com>

On Fri, May 4, 2018 at 4:54 PM, Richard Guy Briggs <rgb@redhat.com> wrote:
> The audit-related parameters in struct task_struct should ideally be
> collected together and accessed through a standard audit API.
>
> Collect the existing loginuid, sessionid and audit_context together in a
> new struct audit_task_info pointer called "audit" in struct task_struct.
>
> Use kmem_cache to manage this pool of memory.
> Un-inline audit_free() to be able to always recover that memory.
>
> See: https://github.com/linux-audit/audit-kernel/issues/81
>
> Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
> ---
>  MAINTAINERS                |  2 +-
>  include/linux/audit.h      |  8 ++++----
>  include/linux/audit_task.h | 31 +++++++++++++++++++++++++++++++
>  include/linux/sched.h      |  6 ++----
>  init/init_task.c           |  8 ++++++--
>  kernel/auditsc.c           |  4 ++--
>  6 files changed, 46 insertions(+), 13 deletions(-)
>  create mode 100644 include/linux/audit_task.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0a1410d..8c7992d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2510,7 +2510,7 @@ L:        linux-audit@redhat.com (moderated for non-subscribers)
>  W:     https://github.com/linux-audit
>  T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit.git
>  S:     Supported
> -F:     include/linux/audit.h
> +F:     include/linux/audit*.h
>  F:     include/uapi/linux/audit.h
>  F:     kernel/audit*
>
> diff --git a/include/linux/audit.h b/include/linux/audit.h
> index dba0d45..1324969 100644
> --- a/include/linux/audit.h
> +++ b/include/linux/audit.h
> @@ -237,11 +237,11 @@ extern void __audit_inode_child(struct inode *parent,
>
>  static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx)
>  {
> -       task->audit_context = ctx;
> +       task->audit.ctx = ctx;
>  }
>  static inline struct audit_context *audit_context(struct task_struct *task)
>  {
> -       return task->audit_context;
> +       return task->audit.ctx;
>  }
>  static inline bool audit_dummy_context(void)
>  {
> @@ -330,12 +330,12 @@ extern int auditsc_get_stamp(struct audit_context *ctx,
>
>  static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
>  {
> -       return tsk->loginuid;
> +       return tsk->audit.loginuid;
>  }
>
>  static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
>  {
> -       return tsk->sessionid;
> +       return tsk->audit.sessionid;
>  }
>
>  extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
> diff --git a/include/linux/audit_task.h b/include/linux/audit_task.h
> new file mode 100644
> index 0000000..d4b3a20
> --- /dev/null
> +++ b/include/linux/audit_task.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* audit_task.h -- definition of audit_task_info structure
> + *
> + * Copyright 2018 Red Hat Inc., Raleigh, North Carolina.
> + * All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * Written by Richard Guy Briggs <rgb@redhat.com>
> + *
> + */
> +
> +#ifndef _LINUX_AUDIT_TASK_H_
> +#define _LINUX_AUDIT_TASK_H_
> +
> +struct audit_context;
> +struct audit_task_info {
> +       kuid_t                  loginuid;
> +       unsigned int            sessionid;
> +       struct audit_context    *ctx;
> +};
> +
> +#endif
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index b3d697f..b58eca0 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -27,9 +27,9 @@
>  #include <linux/signal_types.h>
>  #include <linux/mm_types_task.h>
>  #include <linux/task_io_accounting.h>
> +#include <linux/audit_task.h>
>
>  /* task_struct member predeclarations (sorted alphabetically): */
> -struct audit_context;
>  struct backing_dev_info;
>  struct bio_list;
>  struct blk_plug;
> @@ -832,10 +832,8 @@ struct task_struct {
>
>         struct callback_head            *task_works;
>
> -       struct audit_context            *audit_context;
>  #ifdef CONFIG_AUDITSYSCALL
> -       kuid_t                          loginuid;
> -       unsigned int                    sessionid;
> +       struct audit_task_info          audit;
>  #endif

Considering that the audit_context pointer is now in the
audit_task_info struct, should the audit_task_info struct be placed
outside the CONFIG_AUDITSYSCALL protections?  Or rather, shouldn't the
CONFIG_AUDITSYSCALL protections be moved inside audit_task_info or
removed entirely?

> diff --git a/init/init_task.c b/init/init_task.c
> index c788f91..d33260d 100644
> --- a/init/init_task.c
> +++ b/init/init_task.c
> @@ -9,6 +9,7 @@
>  #include <linux/init.h>
>  #include <linux/fs.h>
>  #include <linux/mm.h>
> +#include <linux/audit.h>
>
>  #include <asm/pgtable.h>
>  #include <linux/uaccess.h>
> @@ -118,8 +119,11 @@ struct task_struct init_task
>         .thread_group   = LIST_HEAD_INIT(init_task.thread_group),
>         .thread_node    = LIST_HEAD_INIT(init_signals.thread_head),
>  #ifdef CONFIG_AUDITSYSCALL
> -       .loginuid       = INVALID_UID,
> -       .sessionid      = AUDIT_SID_UNSET,
> +       .audit          = {
> +               .loginuid       = INVALID_UID,
> +               .sessionid      = AUDIT_SID_UNSET,
> +               .ctx            = NULL,
> +       },
>  #endif
>  #ifdef CONFIG_PERF_EVENTS
>         .perf_event_mutex = __MUTEX_INITIALIZER(init_task.perf_event_mutex),
> diff --git a/kernel/auditsc.c b/kernel/auditsc.c
> index f294e4a..b5d8bff 100644
> --- a/kernel/auditsc.c
> +++ b/kernel/auditsc.c
> @@ -2068,8 +2068,8 @@ int audit_set_loginuid(kuid_t loginuid)
>                         sessionid = (unsigned int)atomic_inc_return(&session_id);
>         }
>
> -       task->sessionid = sessionid;
> -       task->loginuid = loginuid;
> +       task->audit.sessionid = sessionid;
> +       task->audit.loginuid = loginuid;
>  out:
>         audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc);
>         return rc;
> --
> 1.8.3.1

-- 
paul moore
www.paul-moore.com

^ permalink raw reply

* Re: [PATCH v2 net-next] drivers: net: davinci_mdio: prevent spurious timeout
From: Sekhar Nori @ 2018-05-09 15:46 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: David S . Miller, Grygorii Strashko, linux-omap, netdev
In-Reply-To: <20180509133014.GD14276@lunn.ch>

On Wednesday 09 May 2018 07:00 PM, Andrew Lunn wrote:
> On Wed, May 09, 2018 at 04:30:24PM +0530, Sekhar Nori wrote:
>> A well timed kernel preemption in the time_after() loop
>> in wait_for_idle() can result in a spurious timeout
>> error to be returned.
>>
>> Fix it by using readl_poll_timeout() which takes care of
>> this issue.
>>
>> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
>> ---
>> v2: use readl_poll_timeout() per suggestion from Andrew.
>>
>> The issue has not been personally observed by me, but has
>> been reported by users. Sending for next-next given the
>> non-critical nature. There is seems to be no easy way to
>> reproduce this.
>>
>>  drivers/net/ethernet/ti/davinci_mdio.c | 15 +++++++++------
>>  1 file changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
>> index 3c33f4504d8e..d073432a5dbe 100644
>> --- a/drivers/net/ethernet/ti/davinci_mdio.c
>> +++ b/drivers/net/ethernet/ti/davinci_mdio.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/clk.h>
>>  #include <linux/err.h>
>>  #include <linux/io.h>
>> +#include <linux/iopoll.h>
>>  #include <linux/pm_runtime.h>
>>  #include <linux/davinci_emac.h>
>>  #include <linux/of.h>
>> @@ -227,14 +228,16 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
>>  static inline int wait_for_idle(struct davinci_mdio_data *data)
>>  {
>>  	struct davinci_mdio_regs __iomem *regs = data->regs;
>> -	unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT);
>> +	u32 val, ret;
>>  
>> -	while (time_after(timeout, jiffies)) {
>> -		if (__raw_readl(&regs->control) & CONTROL_IDLE)
>> -			return 0;
>> +	ret = readl_poll_timeout(&regs->control, val, val & CONTROL_IDLE,
>> +				 0, MDIO_TIMEOUT * 1000);
>> +	if (ret) {
>> +		dev_err(data->dev, "timed out waiting for idle\n");
>> +		return ret;
>>  	}
>> -	dev_err(data->dev, "timed out waiting for idle\n");
>> -	return -ETIMEDOUT;
>> +
>> +	return 0;
>>  }
> 
> Hi Sekhar
> 
> You could simplify this to:
> 
>> +	if (ret)
>> +		dev_err(data->dev, "timed out waiting for idle\n");
>> +	return ret;
> 
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>

Indeed. v3 sent.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH v3 next-next] drivers: net: davinci_mdio: prevent spurious timeout
From: Sekhar Nori @ 2018-05-09 15:45 UTC (permalink / raw)
  To: David S . Miller
  Cc: Grygorii Strashko, linux-omap, netdev, Andrew Lunn, Sekhar Nori

A well timed kernel preemption in the time_after() loop
in wait_for_idle() can result in a spurious timeout
error to be returned.

Fix it by using readl_poll_timeout() which takes care of
this issue.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
---
v3: simplify return path based on comment from Andrew

The issue has not been personally observed by me, but has
been reported by users. Sending for next-next given the
non-critical nature. There is seems to be no easy way to
reproduce this.

 drivers/net/ethernet/ti/davinci_mdio.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c
index 3c33f4504d8e..98a1c97fb95e 100644
--- a/drivers/net/ethernet/ti/davinci_mdio.c
+++ b/drivers/net/ethernet/ti/davinci_mdio.c
@@ -34,6 +34,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/pm_runtime.h>
 #include <linux/davinci_emac.h>
 #include <linux/of.h>
@@ -227,14 +228,14 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data)
 static inline int wait_for_idle(struct davinci_mdio_data *data)
 {
 	struct davinci_mdio_regs __iomem *regs = data->regs;
-	unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT);
+	u32 val, ret;
 
-	while (time_after(timeout, jiffies)) {
-		if (__raw_readl(&regs->control) & CONTROL_IDLE)
-			return 0;
-	}
-	dev_err(data->dev, "timed out waiting for idle\n");
-	return -ETIMEDOUT;
+	ret = readl_poll_timeout(&regs->control, val, val & CONTROL_IDLE,
+				 0, MDIO_TIMEOUT * 1000);
+	if (ret)
+		dev_err(data->dev, "timed out waiting for idle\n");
+
+	return ret;
 }
 
 static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
-- 
2.16.2

^ permalink raw reply related

* Re: [net-next PATCH v2 0/8] UDP GSO Segmentation clean-ups
From: Willem de Bruijn @ 2018-05-09 15:39 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: Network Development, Willem de Bruijn, David Miller
In-Reply-To: <CAKgT0UeKY_O16yPtArJeRa6-+zT4BDoYP-iFVK8YyccL0ZcQow@mail.gmail.com>

On Mon, May 7, 2018 at 2:02 PM, Alexander Duyck
<alexander.duyck@gmail.com> wrote:
> On Sat, May 5, 2018 at 3:06 AM, Willem de Bruijn
> <willemdebruijn.kernel@gmail.com> wrote:
>> On Fri, May 4, 2018 at 8:28 PM, Alexander Duyck
>> <alexander.duyck@gmail.com> wrote:
>>> This patch set addresses a number of issues I found while sorting out
>>> enabling UDP GSO Segmentation support for ixgbe/ixgbevf. Specifically there
>>> were a number of issues related to the checksum and such that seemed to
>>> cause either minor irregularities or kernel panics in the case of the
>>> offload request being allowed to traverse between name spaces.
>>
>> Were you able to traverse GSO packets between network namespace before
>> adding to NETIF_F_GSO_SOFTWARE? It does appear that veth includes
>> NETIF_F_GSO_ENCAP_ALL, which also allows GSO.
>
> Without that change the tunnel wouldn't pass the requests between
> namespaces. However with it I was able to easily test the software
> checksum code as otherwise the socket was returning EIO when the
> hardware checksum was disabled.
>
>> In either case, it should not be possible for GSO packets to arrive on a veth
>> device, as that can result in queuing the GSO packet to a recipient socket.
>> In this regard veth is like loopback and must exclude GSO support.
>>
>> I'll take a look.
>
> I suspect it was probably sending veth UDP segmentation offload
> requests. For now I can probably drop he patch that was adding it and
> it can be added later to individual drivers if needed.

I just tested udpgso_bench_tx over veth (on a commit without your
patchset).

Having NETIF_F_GSO_UDP_L4 in NETIF_F_GSO_ENCAP_ALL
and NETIF_F_GSO_ENCAP_ALL in VETH_FEATURES is
sufficient to receive large packets on the veth peer.

This is clearly a bug, as is for any device that may loop packets
onto a local socket. Such as macvlan in bridge mode.

I will have to revise commit 83aa025f535f ("udp: add gso support
to virtual devices")

It remains useful to have this capability on the bonding device. I
might remove the flag from NETIF_F_GSO_ENCAP_ALL and add
it specifically to that device.

This is also all relevant to future work of NETIF_F_GSO_SOFTWARE.

^ permalink raw reply

* [PATCH net-next 3/3] net: dsa: mv88e6xxx: add RMU disable op
From: Vivien Didelot @ 2018-05-09 15:38 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, kernel, Vivien Didelot, davem, andrew, f.fainelli
In-Reply-To: <20180509153851.10207-1-vivien.didelot@savoirfairelinux.com>

The RMU mode bits moved a lot within the Global Control 2 register of
the Marvell switch families. Add an .rmu_disable op to support at least
3 known alternatives.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    | 24 ++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/chip.h    |  3 +++
 drivers/net/dsa/mv88e6xxx/global1.c | 18 ++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/global1.h | 20 ++++++++++++++++++++
 4 files changed, 65 insertions(+)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index b4e27f9fd3af..9c3cb6079b40 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1069,6 +1069,14 @@ static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
 	return 0;
 }
 
+static int mv88e6xxx_rmu_setup(struct mv88e6xxx_chip *chip)
+{
+	if (chip->info->ops->rmu_disable)
+		return chip->info->ops->rmu_disable(chip);
+
+	return 0;
+}
+
 static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
 {
 	if (chip->info->ops->pot_clear)
@@ -2263,6 +2271,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	err = mv88e6xxx_rmu_setup(chip);
+	if (err)
+		goto unlock;
+
 	err = mv88e6xxx_rsvd2cpu_setup(chip);
 	if (err)
 		goto unlock;
@@ -2530,6 +2542,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
 	.ppu_enable = mv88e6185_g1_ppu_enable,
 	.ppu_disable = mv88e6185_g1_ppu_disable,
 	.reset = mv88e6185_g1_reset,
+	.rmu_disable = mv88e6085_g1_rmu_disable,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 };
@@ -2587,6 +2600,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6085_g1_rmu_disable,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 };
@@ -2814,6 +2828,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
@@ -2886,6 +2901,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
@@ -2951,6 +2967,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -2987,6 +3004,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3023,6 +3041,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3060,6 +3079,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
@@ -3098,6 +3118,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3314,6 +3335,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_power = mv88e6352_serdes_power,
@@ -3357,6 +3379,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3397,6 +3420,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 62234c2287a2..a1bedb0a888b 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -432,6 +432,9 @@ struct mv88e6xxx_ops {
 
 	/* Interface to the AVB/PTP registers */
 	const struct mv88e6xxx_avb_ops *avb_ops;
+
+	/* Remote Management Unit operations */
+	int (*rmu_disable)(struct mv88e6xxx_chip *chip);
 };
 
 struct mv88e6xxx_irq_ops {
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index 89c6330c53eb..244ee1ff9edc 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -373,6 +373,24 @@ int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port)
 	return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask));
 }
 
+int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6xxx_g1_ctl2_mask(chip, MV88E6085_G1_CTL2_P10RM |
+				      MV88E6085_G1_CTL2_RM_ENABLE, 0);
+}
+
+int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6xxx_g1_ctl2_mask(chip, MV88E6352_G1_CTL2_RMU_MODE_MASK,
+				      MV88E6352_G1_CTL2_RMU_MODE_DISABLED);
+}
+
+int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip *chip)
+{
+	return mv88e6xxx_g1_ctl2_mask(chip, MV88E6390_G1_CTL2_RMU_MODE_MASK,
+				      MV88E6390_G1_CTL2_RMU_MODE_DISABLED);
+}
+
 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
 {
 	u16 val;
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 8b043e813761..e186a026e1b1 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -207,6 +207,22 @@
 #define MV88E6185_G1_CTL2_CASCADE_PORT_MASK	0xf000
 #define MV88E6185_G1_CTL2_CASCADE_PORT_NONE	0xe000
 #define MV88E6185_G1_CTL2_CASCADE_PORT_MULTI	0xf000
+#define MV88E6352_G1_CTL2_RMU_MODE_MASK		0x3000
+#define MV88E6352_G1_CTL2_RMU_MODE_DISABLED	0x0000
+#define MV88E6352_G1_CTL2_RMU_MODE_PORT_4	0x1000
+#define MV88E6352_G1_CTL2_RMU_MODE_PORT_5	0x2000
+#define MV88E6352_G1_CTL2_RMU_MODE_PORT_6	0x3000
+#define MV88E6085_G1_CTL2_DA_CHECK		0x4000
+#define MV88E6085_G1_CTL2_P10RM			0x2000
+#define MV88E6085_G1_CTL2_RM_ENABLE		0x1000
+#define MV88E6352_G1_CTL2_DA_CHECK		0x0800
+#define MV88E6390_G1_CTL2_RMU_MODE_MASK		0x0700
+#define MV88E6390_G1_CTL2_RMU_MODE_PORT_0	0x0000
+#define MV88E6390_G1_CTL2_RMU_MODE_PORT_1	0x0100
+#define MV88E6390_G1_CTL2_RMU_MODE_PORT_9	0x0200
+#define MV88E6390_G1_CTL2_RMU_MODE_PORT_10	0x0300
+#define MV88E6390_G1_CTL2_RMU_MODE_ALL_DSA	0x0600
+#define MV88E6390_G1_CTL2_RMU_MODE_DISABLED	0x0700
 #define MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK	0x001f
 
 /* Offset 0x1D: Stats Operation Register */
@@ -257,6 +273,10 @@ int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
 
 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port);
 
+int mv88e6085_g1_rmu_disable(struct mv88e6xxx_chip *chip);
+int mv88e6352_g1_rmu_disable(struct mv88e6xxx_chip *chip);
+int mv88e6390_g1_rmu_disable(struct mv88e6xxx_chip *chip);
+
 int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index);
 
 int mv88e6xxx_g1_atu_set_learn2all(struct mv88e6xxx_chip *chip, bool learn2all);
-- 
2.17.0

^ permalink raw reply related

* [PATCH net-next 2/3] net: dsa: mv88e6xxx: set device number
From: Vivien Didelot @ 2018-05-09 15:38 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, kernel, Vivien Didelot, davem, andrew, f.fainelli
In-Reply-To: <20180509153851.10207-1-vivien.didelot@savoirfairelinux.com>

All Marvell switches supported by mv88e6xxx have to set their device
number in the Global Control 2 register. Extract this in a read then
write function, called from the device mapping setup code.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    | 11 ++++-------
 drivers/net/dsa/mv88e6xxx/global1.c |  7 +++++++
 drivers/net/dsa/mv88e6xxx/global1.h |  3 +++
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 04453440a139..b4e27f9fd3af 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1053,6 +1053,10 @@ static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
 			return err;
 	}
 
+	err = mv88e6xxx_g1_set_device_number(chip, chip->ds->index);
+	if (err)
+		return err;
+
 	return 0;
 }
 
@@ -2160,15 +2164,8 @@ static int mv88e6xxx_set_ageing_time(struct dsa_switch *ds,
 
 static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
 {
-	struct dsa_switch *ds = chip->ds;
 	int err;
 
-	/* Disable remote management, and set the switch's DSA device number. */
-	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2,
-				 (ds->index & 0x1f));
-	if (err)
-		return err;
-
 	/* Configure the IP ToS mapping registers. */
 	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_IP_PRI_0, 0x0000);
 	if (err)
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index 6eb4eca7ca5b..89c6330c53eb 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -389,6 +389,13 @@ int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
 	return err;
 }
 
+int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index)
+{
+	return mv88e6xxx_g1_ctl2_mask(chip,
+				      MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK,
+				      index);
+}
+
 /* Offset 0x1d: Statistics Operation 2 */
 
 int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip)
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index bcbb8046ad63..8b043e813761 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -207,6 +207,7 @@
 #define MV88E6185_G1_CTL2_CASCADE_PORT_MASK	0xf000
 #define MV88E6185_G1_CTL2_CASCADE_PORT_NONE	0xe000
 #define MV88E6185_G1_CTL2_CASCADE_PORT_MULTI	0xf000
+#define MV88E6XXX_G1_CTL2_DEVICE_NUMBER_MASK	0x001f
 
 /* Offset 0x1D: Stats Operation Register */
 #define MV88E6XXX_G1_STATS_OP			0x1d
@@ -256,6 +257,8 @@ int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
 
 int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port);
 
+int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index);
+
 int mv88e6xxx_g1_atu_set_learn2all(struct mv88e6xxx_chip *chip, bool learn2all);
 int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip,
 				  unsigned int msecs);
-- 
2.17.0

^ permalink raw reply related

* [PATCH net-next 1/3] net: dsa: mv88e6xxx: add a cascade port op
From: Vivien Didelot @ 2018-05-09 15:38 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, kernel, Vivien Didelot, davem, andrew, f.fainelli
In-Reply-To: <20180509153851.10207-1-vivien.didelot@savoirfairelinux.com>

Only the 88E6185 family has bits 15:12 Cascade Port bits in the Global
Control 2 register. Hence inconsistent values are actually written in
this register for other families.

Add a .set_cascade_port operation to isolate the 88E6185 case, and call
it from the device mapping setup function.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    | 10 +++++++++-
 drivers/net/dsa/mv88e6xxx/chip.h    |  6 ++++++
 drivers/net/dsa/mv88e6xxx/global1.c | 23 +++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/global1.h |  7 +++++--
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 9d62e4acc01b..04453440a139 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1046,6 +1046,13 @@ static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
 			return err;
 	}
 
+	if (chip->info->ops->set_cascade_port) {
+		port = MV88E6XXX_CASCADE_PORT_MULTIPLE;
+		err = chip->info->ops->set_cascade_port(chip, port);
+		if (err)
+			return err;
+	}
+
 	return 0;
 }
 
@@ -2158,7 +2165,6 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
 
 	/* Disable remote management, and set the switch's DSA device number. */
 	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2,
-				 MV88E6XXX_G1_CTL2_MULTIPLE_CASCADE |
 				 (ds->index & 0x1f));
 	if (err)
 		return err;
@@ -2642,6 +2648,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
 	.ppu_enable = mv88e6185_g1_ppu_enable,
+	.set_cascade_port = mv88e6185_g1_set_cascade_port,
 	.ppu_disable = mv88e6185_g1_ppu_disable,
 	.reset = mv88e6185_g1_reset,
 	.vtu_getnext = mv88e6185_g1_vtu_getnext,
@@ -2909,6 +2916,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
 	.set_egress_port = mv88e6095_g1_set_egress_port,
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6185_g2_mgmt_rsvd2cpu,
+	.set_cascade_port = mv88e6185_g1_set_cascade_port,
 	.ppu_enable = mv88e6185_g1_ppu_enable,
 	.ppu_disable = mv88e6185_g1_ppu_disable,
 	.reset = mv88e6185_g1_reset,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index 4163c8099d0b..62234c2287a2 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -401,6 +401,12 @@ struct mv88e6xxx_ops {
 			       uint64_t *data);
 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
 	int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
+
+#define MV88E6XXX_CASCADE_PORT_NONE		0xe
+#define MV88E6XXX_CASCADE_PORT_MULTIPLE		0xf
+
+	int (*set_cascade_port)(struct mv88e6xxx_chip *chip, int port);
+
 	const struct mv88e6xxx_irq_ops *watchdog_ops;
 
 	int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index b43bd6476632..6eb4eca7ca5b 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -350,6 +350,29 @@ int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
 
 /* Offset 0x1c: Global Control 2 */
 
+static int mv88e6xxx_g1_ctl2_mask(struct mv88e6xxx_chip *chip, u16 mask,
+				  u16 val)
+{
+	u16 reg;
+	int err;
+
+	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL2, &reg);
+	if (err)
+		return err;
+
+	reg &= ~mask;
+	reg |= val & mask;
+
+	return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL2, reg);
+}
+
+int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port)
+{
+	const u16 mask = MV88E6185_G1_CTL2_CASCADE_PORT_MASK;
+
+	return mv88e6xxx_g1_ctl2_mask(chip, mask, port << __bf_shf(mask));
+}
+
 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
 {
 	u16 val;
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 6aee7316fea6..bcbb8046ad63 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -201,11 +201,12 @@
 
 /* Offset 0x1C: Global Control 2 */
 #define MV88E6XXX_G1_CTL2			0x1c
-#define MV88E6XXX_G1_CTL2_NO_CASCADE		0xe000
-#define MV88E6XXX_G1_CTL2_MULTIPLE_CASCADE	0xf000
 #define MV88E6XXX_G1_CTL2_HIST_RX		0x0040
 #define MV88E6XXX_G1_CTL2_HIST_TX		0x0080
 #define MV88E6XXX_G1_CTL2_HIST_RX_TX		0x00c0
+#define MV88E6185_G1_CTL2_CASCADE_PORT_MASK	0xf000
+#define MV88E6185_G1_CTL2_CASCADE_PORT_NONE	0xe000
+#define MV88E6185_G1_CTL2_CASCADE_PORT_MULTI	0xf000
 
 /* Offset 0x1D: Stats Operation Register */
 #define MV88E6XXX_G1_STATS_OP			0x1d
@@ -253,6 +254,8 @@ int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
 
+int mv88e6185_g1_set_cascade_port(struct mv88e6xxx_chip *chip, int port);
+
 int mv88e6xxx_g1_atu_set_learn2all(struct mv88e6xxx_chip *chip, bool learn2all);
 int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip,
 				  unsigned int msecs);
-- 
2.17.0

^ permalink raw reply related

* [PATCH net-next 0/3] net: dsa: mv88e6xxx: cleanup Global Control 2 register
From: Vivien Didelot @ 2018-05-09 15:38 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, kernel, Vivien Didelot, davem, andrew, f.fainelli

The mv88e6xxx driver still writes arbitrary values in the Global 1
Control 2 register at setup, which layout differs a lot between chips.
This results in an inconsistent configuration, for example with the
Remote Management Unit (RMU).

The first patch adds an operation for the Cascade Port bits, the second
patch sets the device number in the device mapping function and the
third patch adds an operation to correctly disable the RMU.

Vivien Didelot (3):
  net: dsa: mv88e6xxx: add a cascade port op
  net: dsa: mv88e6xxx: set device number
  net: dsa: mv88e6xxx: add RMU disable op

 drivers/net/dsa/mv88e6xxx/chip.c    | 45 ++++++++++++++++++++++-----
 drivers/net/dsa/mv88e6xxx/chip.h    |  9 ++++++
 drivers/net/dsa/mv88e6xxx/global1.c | 48 +++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/global1.h | 30 ++++++++++++++++--
 4 files changed, 122 insertions(+), 10 deletions(-)

-- 
2.17.0

^ permalink raw reply

* [PATCH net] net/mlx4_en: Verify coalescing parameters are in range
From: Tariq Toukan @ 2018-05-09 15:35 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Moshe Shemesh, Tariq Toukan

From: Moshe Shemesh <moshe@mellanox.com>

Add check of coalescing parameters received through ethtool are within
range of values supported by the HW.
Driver gets the coalescing rx/tx-usecs and rx/tx-frames as set by the
users through ethtool. The ethtool support up to 32 bit value for each.
However, mlx4 modify cq limits the coalescing time parameter and
coalescing frames parameters to 16 bits.
Return out of range error if user tries to set these parameters to
higher values.
Change type of sample-interval and adaptive_rx_coal parameters in mlx4
driver to u32 as the ethtool holds them as u32 and these parameters are
not limited due to mlx4 HW.

Fixes: c27a02cd94d6 ('mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC')
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 16 ++++++++++++++++
 drivers/net/ethernet/mellanox/mlx4/mlx4_en.h    |  7 +++++--
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index a30a2e95d13f..f11b45001cad 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -1027,6 +1027,22 @@ static int mlx4_en_set_coalesce(struct net_device *dev,
 	if (!coal->tx_max_coalesced_frames_irq)
 		return -EINVAL;
 
+	if (coal->tx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME ||
+	    coal->rx_coalesce_usecs > MLX4_EN_MAX_COAL_TIME ||
+	    coal->rx_coalesce_usecs_low > MLX4_EN_MAX_COAL_TIME ||
+	    coal->rx_coalesce_usecs_high > MLX4_EN_MAX_COAL_TIME) {
+		netdev_info(dev, "%s: maximum coalesce time supported is %d usecs\n",
+			    __func__, MLX4_EN_MAX_COAL_TIME);
+		return -ERANGE;
+	}
+
+	if (coal->tx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS ||
+	    coal->rx_max_coalesced_frames > MLX4_EN_MAX_COAL_PKTS) {
+		netdev_info(dev, "%s: maximum coalesced frames supported is %d\n",
+			    __func__, MLX4_EN_MAX_COAL_PKTS);
+		return -ERANGE;
+	}
+
 	priv->rx_frames = (coal->rx_max_coalesced_frames ==
 			   MLX4_EN_AUTO_CONF) ?
 				MLX4_EN_RX_COAL_TARGET :
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index f7c81133594f..ace6545f82e6 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -132,6 +132,9 @@
 #define MLX4_EN_TX_COAL_PKTS	16
 #define MLX4_EN_TX_COAL_TIME	0x10
 
+#define MLX4_EN_MAX_COAL_PKTS	U16_MAX
+#define MLX4_EN_MAX_COAL_TIME	U16_MAX
+
 #define MLX4_EN_RX_RATE_LOW		400000
 #define MLX4_EN_RX_COAL_TIME_LOW	0
 #define MLX4_EN_RX_RATE_HIGH		450000
@@ -552,8 +555,8 @@ struct mlx4_en_priv {
 	u16 rx_usecs_low;
 	u32 pkt_rate_high;
 	u16 rx_usecs_high;
-	u16 sample_interval;
-	u16 adaptive_rx_coal;
+	u32 sample_interval;
+	u32 adaptive_rx_coal;
 	u32 msg_enable;
 	u32 loopback_ok;
 	u32 validate_loopback;
-- 
1.8.3.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox