mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	Remove already applied patches
This commit is contained in:
		
							parent
							
								
									c83c43fe97
								
							
						
					
					
						commit
						2983359abc
					
				
					 44 changed files with 0 additions and 4040 deletions
				
			
		| 
						 | 
				
			
			@ -1,228 +0,0 @@
 | 
			
		|||
From 93d6f0841eef6304c13803a84588f00476b06a14 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Hannes Reinecke <hare@suse.de>
 | 
			
		||||
Date: Wed, 24 Jul 2019 11:00:55 +0200
 | 
			
		||||
Subject: [PATCH 768/826] scsi: fcoe: Embed fc_rport_priv in fcoe_rport
 | 
			
		||||
 structure
 | 
			
		||||
 | 
			
		||||
commit 023358b136d490ca91735ac6490db3741af5a8bd upstream.
 | 
			
		||||
 | 
			
		||||
Gcc-9 complains for a memset across pointer boundaries, which happens as
 | 
			
		||||
the code tries to allocate a flexible array on the stack.  Turns out we
 | 
			
		||||
cannot do this without relying on gcc-isms, so with this patch we'll embed
 | 
			
		||||
the fc_rport_priv structure into fcoe_rport, can use the normal
 | 
			
		||||
'container_of' outcast, and will only have to do a memset over one
 | 
			
		||||
structure.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
 | 
			
		||||
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/scsi/fcoe/fcoe_ctlr.c | 51 ++++++++++++++---------------------
 | 
			
		||||
 drivers/scsi/libfc/fc_rport.c |  5 +++-
 | 
			
		||||
 include/scsi/libfcoe.h        |  1 +
 | 
			
		||||
 3 files changed, 25 insertions(+), 32 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
 | 
			
		||||
index 7dc4ffa24430..24cbd0a2cc69 100644
 | 
			
		||||
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
 | 
			
		||||
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
 | 
			
		||||
@@ -2017,7 +2017,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
 | 
			
		||||
  */
 | 
			
		||||
 static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata)
 | 
			
		||||
 {
 | 
			
		||||
-	return (struct fcoe_rport *)(rdata + 1);
 | 
			
		||||
+	return container_of(rdata, struct fcoe_rport, rdata);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
@@ -2281,7 +2281,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
 | 
			
		||||
  */
 | 
			
		||||
 static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
 | 
			
		||||
 			      struct sk_buff *skb,
 | 
			
		||||
-			      struct fc_rport_priv *rdata)
 | 
			
		||||
+			      struct fcoe_rport *frport)
 | 
			
		||||
 {
 | 
			
		||||
 	struct fip_header *fiph;
 | 
			
		||||
 	struct fip_desc *desc = NULL;
 | 
			
		||||
@@ -2289,16 +2289,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
 | 
			
		||||
 	struct fip_wwn_desc *wwn = NULL;
 | 
			
		||||
 	struct fip_vn_desc *vn = NULL;
 | 
			
		||||
 	struct fip_size_desc *size = NULL;
 | 
			
		||||
-	struct fcoe_rport *frport;
 | 
			
		||||
 	size_t rlen;
 | 
			
		||||
 	size_t dlen;
 | 
			
		||||
 	u32 desc_mask = 0;
 | 
			
		||||
 	u32 dtype;
 | 
			
		||||
 	u8 sub;
 | 
			
		||||
 
 | 
			
		||||
-	memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
 | 
			
		||||
-	frport = fcoe_ctlr_rport(rdata);
 | 
			
		||||
-
 | 
			
		||||
 	fiph = (struct fip_header *)skb->data;
 | 
			
		||||
 	frport->flags = ntohs(fiph->fip_flags);
 | 
			
		||||
 
 | 
			
		||||
@@ -2361,15 +2357,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
 | 
			
		||||
 			if (dlen != sizeof(struct fip_wwn_desc))
 | 
			
		||||
 				goto len_err;
 | 
			
		||||
 			wwn = (struct fip_wwn_desc *)desc;
 | 
			
		||||
-			rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn);
 | 
			
		||||
+			frport->rdata.ids.node_name =
 | 
			
		||||
+				get_unaligned_be64(&wwn->fd_wwn);
 | 
			
		||||
 			break;
 | 
			
		||||
 		case FIP_DT_VN_ID:
 | 
			
		||||
 			if (dlen != sizeof(struct fip_vn_desc))
 | 
			
		||||
 				goto len_err;
 | 
			
		||||
 			vn = (struct fip_vn_desc *)desc;
 | 
			
		||||
 			memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN);
 | 
			
		||||
-			rdata->ids.port_id = ntoh24(vn->fd_fc_id);
 | 
			
		||||
-			rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn);
 | 
			
		||||
+			frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id);
 | 
			
		||||
+			frport->rdata.ids.port_name =
 | 
			
		||||
+				get_unaligned_be64(&vn->fd_wwpn);
 | 
			
		||||
 			break;
 | 
			
		||||
 		case FIP_DT_FC4F:
 | 
			
		||||
 			if (dlen != sizeof(struct fip_fc4_feat))
 | 
			
		||||
@@ -2750,10 +2748,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 | 
			
		||||
 {
 | 
			
		||||
 	struct fip_header *fiph;
 | 
			
		||||
 	enum fip_vn2vn_subcode sub;
 | 
			
		||||
-	struct {
 | 
			
		||||
-		struct fc_rport_priv rdata;
 | 
			
		||||
-		struct fcoe_rport frport;
 | 
			
		||||
-	} buf;
 | 
			
		||||
+	struct fcoe_rport frport = { };
 | 
			
		||||
 	int rc, vlan_id = 0;
 | 
			
		||||
 
 | 
			
		||||
 	fiph = (struct fip_header *)skb->data;
 | 
			
		||||
@@ -2769,7 +2764,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 | 
			
		||||
 		goto drop;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata);
 | 
			
		||||
+	rc = fcoe_ctlr_vn_parse(fip, skb, &frport);
 | 
			
		||||
 	if (rc) {
 | 
			
		||||
 		LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc);
 | 
			
		||||
 		goto drop;
 | 
			
		||||
@@ -2778,19 +2773,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 | 
			
		||||
 	mutex_lock(&fip->ctlr_mutex);
 | 
			
		||||
 	switch (sub) {
 | 
			
		||||
 	case FIP_SC_VN_PROBE_REQ:
 | 
			
		||||
-		fcoe_ctlr_vn_probe_req(fip, &buf.rdata);
 | 
			
		||||
+		fcoe_ctlr_vn_probe_req(fip, &frport.rdata);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case FIP_SC_VN_PROBE_REP:
 | 
			
		||||
-		fcoe_ctlr_vn_probe_reply(fip, &buf.rdata);
 | 
			
		||||
+		fcoe_ctlr_vn_probe_reply(fip, &frport.rdata);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case FIP_SC_VN_CLAIM_NOTIFY:
 | 
			
		||||
-		fcoe_ctlr_vn_claim_notify(fip, &buf.rdata);
 | 
			
		||||
+		fcoe_ctlr_vn_claim_notify(fip, &frport.rdata);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case FIP_SC_VN_CLAIM_REP:
 | 
			
		||||
-		fcoe_ctlr_vn_claim_resp(fip, &buf.rdata);
 | 
			
		||||
+		fcoe_ctlr_vn_claim_resp(fip, &frport.rdata);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case FIP_SC_VN_BEACON:
 | 
			
		||||
-		fcoe_ctlr_vn_beacon(fip, &buf.rdata);
 | 
			
		||||
+		fcoe_ctlr_vn_beacon(fip, &frport.rdata);
 | 
			
		||||
 		break;
 | 
			
		||||
 	default:
 | 
			
		||||
 		LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub);
 | 
			
		||||
@@ -2814,22 +2809,18 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 | 
			
		||||
  */
 | 
			
		||||
 static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
 | 
			
		||||
 			      struct sk_buff *skb,
 | 
			
		||||
-			      struct fc_rport_priv *rdata)
 | 
			
		||||
+			      struct fcoe_rport *frport)
 | 
			
		||||
 {
 | 
			
		||||
 	struct fip_header *fiph;
 | 
			
		||||
 	struct fip_desc *desc = NULL;
 | 
			
		||||
 	struct fip_mac_desc *macd = NULL;
 | 
			
		||||
 	struct fip_wwn_desc *wwn = NULL;
 | 
			
		||||
-	struct fcoe_rport *frport;
 | 
			
		||||
 	size_t rlen;
 | 
			
		||||
 	size_t dlen;
 | 
			
		||||
 	u32 desc_mask = 0;
 | 
			
		||||
 	u32 dtype;
 | 
			
		||||
 	u8 sub;
 | 
			
		||||
 
 | 
			
		||||
-	memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
 | 
			
		||||
-	frport = fcoe_ctlr_rport(rdata);
 | 
			
		||||
-
 | 
			
		||||
 	fiph = (struct fip_header *)skb->data;
 | 
			
		||||
 	frport->flags = ntohs(fiph->fip_flags);
 | 
			
		||||
 
 | 
			
		||||
@@ -2883,7 +2874,8 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
 | 
			
		||||
 			if (dlen != sizeof(struct fip_wwn_desc))
 | 
			
		||||
 				goto len_err;
 | 
			
		||||
 			wwn = (struct fip_wwn_desc *)desc;
 | 
			
		||||
-			rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn);
 | 
			
		||||
+			frport->rdata.ids.node_name =
 | 
			
		||||
+				get_unaligned_be64(&wwn->fd_wwn);
 | 
			
		||||
 			break;
 | 
			
		||||
 		default:
 | 
			
		||||
 			LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
 | 
			
		||||
@@ -2994,22 +2986,19 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
 | 
			
		||||
 {
 | 
			
		||||
 	struct fip_header *fiph;
 | 
			
		||||
 	enum fip_vlan_subcode sub;
 | 
			
		||||
-	struct {
 | 
			
		||||
-		struct fc_rport_priv rdata;
 | 
			
		||||
-		struct fcoe_rport frport;
 | 
			
		||||
-	} buf;
 | 
			
		||||
+	struct fcoe_rport frport = { };
 | 
			
		||||
 	int rc;
 | 
			
		||||
 
 | 
			
		||||
 	fiph = (struct fip_header *)skb->data;
 | 
			
		||||
 	sub = fiph->fip_subcode;
 | 
			
		||||
-	rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata);
 | 
			
		||||
+	rc = fcoe_ctlr_vlan_parse(fip, skb, &frport);
 | 
			
		||||
 	if (rc) {
 | 
			
		||||
 		LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc);
 | 
			
		||||
 		goto drop;
 | 
			
		||||
 	}
 | 
			
		||||
 	mutex_lock(&fip->ctlr_mutex);
 | 
			
		||||
 	if (sub == FIP_SC_VL_REQ)
 | 
			
		||||
-		fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata);
 | 
			
		||||
+		fcoe_ctlr_vlan_disc_reply(fip, &frport.rdata);
 | 
			
		||||
 	mutex_unlock(&fip->ctlr_mutex);
 | 
			
		||||
 
 | 
			
		||||
 drop:
 | 
			
		||||
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
 | 
			
		||||
index 3d51a936f6d5..90a748551ede 100644
 | 
			
		||||
--- a/drivers/scsi/libfc/fc_rport.c
 | 
			
		||||
+++ b/drivers/scsi/libfc/fc_rport.c
 | 
			
		||||
@@ -140,6 +140,7 @@ EXPORT_SYMBOL(fc_rport_lookup);
 | 
			
		||||
 struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id)
 | 
			
		||||
 {
 | 
			
		||||
 	struct fc_rport_priv *rdata;
 | 
			
		||||
+	size_t rport_priv_size = sizeof(*rdata);
 | 
			
		||||
 
 | 
			
		||||
 	lockdep_assert_held(&lport->disc.disc_mutex);
 | 
			
		||||
 
 | 
			
		||||
@@ -147,7 +148,9 @@ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id)
 | 
			
		||||
 	if (rdata)
 | 
			
		||||
 		return rdata;
 | 
			
		||||
 
 | 
			
		||||
-	rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL);
 | 
			
		||||
+	if (lport->rport_priv_size > 0)
 | 
			
		||||
+		rport_priv_size = lport->rport_priv_size;
 | 
			
		||||
+	rdata = kzalloc(rport_priv_size, GFP_KERNEL);
 | 
			
		||||
 	if (!rdata)
 | 
			
		||||
 		return NULL;
 | 
			
		||||
 
 | 
			
		||||
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
 | 
			
		||||
index bb8092fa1e36..58507c7783cf 100644
 | 
			
		||||
--- a/include/scsi/libfcoe.h
 | 
			
		||||
+++ b/include/scsi/libfcoe.h
 | 
			
		||||
@@ -241,6 +241,7 @@ struct fcoe_fcf {
 | 
			
		||||
  * @vn_mac:	VN_Node assigned MAC address for data
 | 
			
		||||
  */
 | 
			
		||||
 struct fcoe_rport {
 | 
			
		||||
+	struct fc_rport_priv rdata;
 | 
			
		||||
 	unsigned long time;
 | 
			
		||||
 	u16 fcoe_len;
 | 
			
		||||
 	u16 flags;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
From a152a7b411a54b73707f37ab753cd907c3edfc56 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Linus Torvalds <torvalds@linux-foundation.org>
 | 
			
		||||
Date: Wed, 1 May 2019 11:07:40 -0700
 | 
			
		||||
Subject: [PATCH 769/826] gcc-9: don't warn about uninitialized variable
 | 
			
		||||
 | 
			
		||||
commit cf676908846a06443fa5e6724ca3f5dd7460eca1 upstream.
 | 
			
		||||
 | 
			
		||||
I'm not sure what made gcc warn about this code now.  The 'ret' variable
 | 
			
		||||
does end up initialized in all cases, but it's definitely not obvious,
 | 
			
		||||
so the compiler is quite reasonable to warn about this.
 | 
			
		||||
 | 
			
		||||
So just add initialization to make it all much more obvious both to
 | 
			
		||||
compilers and to humans.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/i2c/i2c-core-base.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
 | 
			
		||||
index 5b0e1d9e5adc..1de10e5c70d7 100644
 | 
			
		||||
--- a/drivers/i2c/i2c-core-base.c
 | 
			
		||||
+++ b/drivers/i2c/i2c-core-base.c
 | 
			
		||||
@@ -185,7 +185,7 @@ static int i2c_generic_bus_free(struct i2c_adapter *adap)
 | 
			
		||||
 int i2c_generic_scl_recovery(struct i2c_adapter *adap)
 | 
			
		||||
 {
 | 
			
		||||
 	struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
 | 
			
		||||
-	int i = 0, scl = 1, ret;
 | 
			
		||||
+	int i = 0, scl = 1, ret = 0;
 | 
			
		||||
 
 | 
			
		||||
 	if (bri->prepare_recovery)
 | 
			
		||||
 		bri->prepare_recovery(adap);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,138 +0,0 @@
 | 
			
		|||
From 7c43f84efd6d01fc646feb67d2b2b500435b191a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Alexander Duyck <alexander.h.duyck@linux.intel.com>
 | 
			
		||||
Date: Mon, 5 Aug 2019 18:31:45 -0700
 | 
			
		||||
Subject: [PATCH 770/826] driver core: Establish order of operations for
 | 
			
		||||
 device_add and device_del via bitflag
 | 
			
		||||
 | 
			
		||||
commit 3451a495ef244a88ed6317a035299d835554d579 upstream.
 | 
			
		||||
 | 
			
		||||
Add an additional bit flag to the device_private struct named "dead".
 | 
			
		||||
 | 
			
		||||
This additional flag provides a guarantee that when a device_del is
 | 
			
		||||
executed on a given interface an async worker will not attempt to attach
 | 
			
		||||
the driver following the earlier device_del call. Previously this
 | 
			
		||||
guarantee was not present and could result in the device_del call
 | 
			
		||||
attempting to remove a driver from an interface only to have the async
 | 
			
		||||
worker attempt to probe the driver later when it finally completes the
 | 
			
		||||
asynchronous probe call.
 | 
			
		||||
 | 
			
		||||
One additional change added was that I pulled the check for dev->driver
 | 
			
		||||
out of the __device_attach_driver call and instead placed it in the
 | 
			
		||||
__device_attach_async_helper call. This was motivated by the fact that the
 | 
			
		||||
only other caller of this, __device_attach, had already taken the
 | 
			
		||||
device_lock() and checked for dev->driver. Instead of testing for this
 | 
			
		||||
twice in this path it makes more sense to just consolidate the dev->dead
 | 
			
		||||
and dev->driver checks together into one set of checks.
 | 
			
		||||
 | 
			
		||||
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 | 
			
		||||
Signed-off-by: Alexander Duyck <alexander.h.duyck@linux.intel.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/base/base.h |  4 ++++
 | 
			
		||||
 drivers/base/core.c | 11 +++++++++++
 | 
			
		||||
 drivers/base/dd.c   | 22 +++++++++++-----------
 | 
			
		||||
 3 files changed, 26 insertions(+), 11 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/base/base.h b/drivers/base/base.h
 | 
			
		||||
index 7a419a7a6235..559b047de9f7 100644
 | 
			
		||||
--- a/drivers/base/base.h
 | 
			
		||||
+++ b/drivers/base/base.h
 | 
			
		||||
@@ -66,6 +66,9 @@ struct driver_private {
 | 
			
		||||
  *	probed first.
 | 
			
		||||
  * @device - pointer back to the struct device that this structure is
 | 
			
		||||
  * associated with.
 | 
			
		||||
+ * @dead - This device is currently either in the process of or has been
 | 
			
		||||
+ *	removed from the system. Any asynchronous events scheduled for this
 | 
			
		||||
+ *	device should exit without taking any action.
 | 
			
		||||
  *
 | 
			
		||||
  * Nothing outside of the driver core should ever touch these fields.
 | 
			
		||||
  */
 | 
			
		||||
@@ -76,6 +79,7 @@ struct device_private {
 | 
			
		||||
 	struct klist_node knode_bus;
 | 
			
		||||
 	struct list_head deferred_probe;
 | 
			
		||||
 	struct device *device;
 | 
			
		||||
+	u8 dead:1;
 | 
			
		||||
 };
 | 
			
		||||
 #define to_device_private_parent(obj)	\
 | 
			
		||||
 	container_of(obj, struct device_private, knode_parent)
 | 
			
		||||
diff --git a/drivers/base/core.c b/drivers/base/core.c
 | 
			
		||||
index 92e2c32c2227..37a90d72f373 100644
 | 
			
		||||
--- a/drivers/base/core.c
 | 
			
		||||
+++ b/drivers/base/core.c
 | 
			
		||||
@@ -2050,6 +2050,17 @@ void device_del(struct device *dev)
 | 
			
		||||
 	struct kobject *glue_dir = NULL;
 | 
			
		||||
 	struct class_interface *class_intf;
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Hold the device lock and set the "dead" flag to guarantee that
 | 
			
		||||
+	 * the update behavior is consistent with the other bitfields near
 | 
			
		||||
+	 * it and that we cannot have an asynchronous probe routine trying
 | 
			
		||||
+	 * to run while we are tearing out the bus/class/sysfs from
 | 
			
		||||
+	 * underneath the device.
 | 
			
		||||
+	 */
 | 
			
		||||
+	device_lock(dev);
 | 
			
		||||
+	dev->p->dead = true;
 | 
			
		||||
+	device_unlock(dev);
 | 
			
		||||
+
 | 
			
		||||
 	/* Notify clients of device removal.  This call must come
 | 
			
		||||
 	 * before dpm_sysfs_remove().
 | 
			
		||||
 	 */
 | 
			
		||||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
 | 
			
		||||
index d48b310c4760..11d24a552ee4 100644
 | 
			
		||||
--- a/drivers/base/dd.c
 | 
			
		||||
+++ b/drivers/base/dd.c
 | 
			
		||||
@@ -725,15 +725,6 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
 | 
			
		||||
 	bool async_allowed;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * Check if device has already been claimed. This may
 | 
			
		||||
-	 * happen with driver loading, device discovery/registration,
 | 
			
		||||
-	 * and deferred probe processing happens all at once with
 | 
			
		||||
-	 * multiple threads.
 | 
			
		||||
-	 */
 | 
			
		||||
-	if (dev->driver)
 | 
			
		||||
-		return -EBUSY;
 | 
			
		||||
-
 | 
			
		||||
 	ret = driver_match_device(drv, dev);
 | 
			
		||||
 	if (ret == 0) {
 | 
			
		||||
 		/* no match */
 | 
			
		||||
@@ -768,6 +759,15 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
 | 
			
		||||
 
 | 
			
		||||
 	device_lock(dev);
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Check if device has already been removed or claimed. This may
 | 
			
		||||
+	 * happen with driver loading, device discovery/registration,
 | 
			
		||||
+	 * and deferred probe processing happens all at once with
 | 
			
		||||
+	 * multiple threads.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (dev->p->dead || dev->driver)
 | 
			
		||||
+		goto out_unlock;
 | 
			
		||||
+
 | 
			
		||||
 	if (dev->parent)
 | 
			
		||||
 		pm_runtime_get_sync(dev->parent);
 | 
			
		||||
 
 | 
			
		||||
@@ -778,7 +778,7 @@ static void __device_attach_async_helper(void *_dev, async_cookie_t cookie)
 | 
			
		||||
 
 | 
			
		||||
 	if (dev->parent)
 | 
			
		||||
 		pm_runtime_put(dev->parent);
 | 
			
		||||
-
 | 
			
		||||
+out_unlock:
 | 
			
		||||
 	device_unlock(dev);
 | 
			
		||||
 
 | 
			
		||||
 	put_device(dev);
 | 
			
		||||
@@ -891,7 +891,7 @@ static int __driver_attach(struct device *dev, void *data)
 | 
			
		||||
 	if (dev->parent && dev->bus->need_parent_lock)
 | 
			
		||||
 		device_lock(dev->parent);
 | 
			
		||||
 	device_lock(dev);
 | 
			
		||||
-	if (!dev->driver)
 | 
			
		||||
+	if (!dev->p->dead && !dev->driver)
 | 
			
		||||
 		driver_probe_device(drv, dev);
 | 
			
		||||
 	device_unlock(dev);
 | 
			
		||||
 	if (dev->parent && dev->bus->need_parent_lock)
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,102 +0,0 @@
 | 
			
		|||
From c23106d4276d7d03f1b3e9dfca40fcf793a6ebab Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Date: Mon, 5 Aug 2019 18:31:51 -0700
 | 
			
		||||
Subject: [PATCH 771/826] drivers/base: Introduce kill_device()
 | 
			
		||||
 | 
			
		||||
commit 00289cd87676e14913d2d8492d1ce05c4baafdae upstream.
 | 
			
		||||
 | 
			
		||||
The libnvdimm subsystem arranges for devices to be destroyed as a result
 | 
			
		||||
of a sysfs operation. Since device_unregister() cannot be called from
 | 
			
		||||
an actively running sysfs attribute of the same device libnvdimm
 | 
			
		||||
arranges for device_unregister() to be performed in an out-of-line async
 | 
			
		||||
context.
 | 
			
		||||
 | 
			
		||||
The driver core maintains a 'dead' state for coordinating its own racing
 | 
			
		||||
async registration / de-registration requests. Rather than add local
 | 
			
		||||
'dead' state tracking infrastructure to libnvdimm device objects, export
 | 
			
		||||
the existing state tracking via a new kill_device() helper.
 | 
			
		||||
 | 
			
		||||
The kill_device() helper simply marks the device as dead, i.e. that it
 | 
			
		||||
is on its way to device_del(), or returns that the device was already
 | 
			
		||||
dead. This can be used in advance of calling device_unregister() for
 | 
			
		||||
subsystems like libnvdimm that might need to handle multiple user
 | 
			
		||||
threads racing to delete a device.
 | 
			
		||||
 | 
			
		||||
This refactoring does not change any behavior, but it is a pre-requisite
 | 
			
		||||
for follow-on fixes and therefore marked for -stable.
 | 
			
		||||
 | 
			
		||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
 | 
			
		||||
Fixes: 4d88a97aa9e8 ("libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver...")
 | 
			
		||||
Cc: <stable@vger.kernel.org>
 | 
			
		||||
Tested-by: Jane Chu <jane.chu@oracle.com>
 | 
			
		||||
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
Link: https://lore.kernel.org/r/156341207332.292348.14959761496009347574.stgit@dwillia2-desk3.amr.corp.intel.com
 | 
			
		||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/base/core.c    | 27 +++++++++++++++++++--------
 | 
			
		||||
 include/linux/device.h |  1 +
 | 
			
		||||
 2 files changed, 20 insertions(+), 8 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/base/core.c b/drivers/base/core.c
 | 
			
		||||
index 37a90d72f373..e1a8d5c06f65 100644
 | 
			
		||||
--- a/drivers/base/core.c
 | 
			
		||||
+++ b/drivers/base/core.c
 | 
			
		||||
@@ -2031,6 +2031,24 @@ void put_device(struct device *dev)
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL_GPL(put_device);
 | 
			
		||||
 
 | 
			
		||||
+bool kill_device(struct device *dev)
 | 
			
		||||
+{
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Require the device lock and set the "dead" flag to guarantee that
 | 
			
		||||
+	 * the update behavior is consistent with the other bitfields near
 | 
			
		||||
+	 * it and that we cannot have an asynchronous probe routine trying
 | 
			
		||||
+	 * to run while we are tearing out the bus/class/sysfs from
 | 
			
		||||
+	 * underneath the device.
 | 
			
		||||
+	 */
 | 
			
		||||
+	lockdep_assert_held(&dev->mutex);
 | 
			
		||||
+
 | 
			
		||||
+	if (dev->p->dead)
 | 
			
		||||
+		return false;
 | 
			
		||||
+	dev->p->dead = true;
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+EXPORT_SYMBOL_GPL(kill_device);
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * device_del - delete device from system.
 | 
			
		||||
  * @dev: device.
 | 
			
		||||
@@ -2050,15 +2068,8 @@ void device_del(struct device *dev)
 | 
			
		||||
 	struct kobject *glue_dir = NULL;
 | 
			
		||||
 	struct class_interface *class_intf;
 | 
			
		||||
 
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * Hold the device lock and set the "dead" flag to guarantee that
 | 
			
		||||
-	 * the update behavior is consistent with the other bitfields near
 | 
			
		||||
-	 * it and that we cannot have an asynchronous probe routine trying
 | 
			
		||||
-	 * to run while we are tearing out the bus/class/sysfs from
 | 
			
		||||
-	 * underneath the device.
 | 
			
		||||
-	 */
 | 
			
		||||
 	device_lock(dev);
 | 
			
		||||
-	dev->p->dead = true;
 | 
			
		||||
+	kill_device(dev);
 | 
			
		||||
 	device_unlock(dev);
 | 
			
		||||
 
 | 
			
		||||
 	/* Notify clients of device removal.  This call must come
 | 
			
		||||
diff --git a/include/linux/device.h b/include/linux/device.h
 | 
			
		||||
index 3f1066a9e1c3..19dd8852602c 100644
 | 
			
		||||
--- a/include/linux/device.h
 | 
			
		||||
+++ b/include/linux/device.h
 | 
			
		||||
@@ -1332,6 +1332,7 @@ extern int (*platform_notify_remove)(struct device *dev);
 | 
			
		||||
  */
 | 
			
		||||
 extern struct device *get_device(struct device *dev);
 | 
			
		||||
 extern void put_device(struct device *dev);
 | 
			
		||||
+extern bool kill_device(struct device *dev);
 | 
			
		||||
 
 | 
			
		||||
 #ifdef CONFIG_DEVTMPFS
 | 
			
		||||
 extern int devtmpfs_create_node(struct device *dev);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,96 +0,0 @@
 | 
			
		|||
From d16bbdbbcb5002c5366cbf6402561d0350afd5fe Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Date: Mon, 5 Aug 2019 18:31:56 -0700
 | 
			
		||||
Subject: [PATCH 772/826] libnvdimm/bus: Prevent duplicate device_unregister()
 | 
			
		||||
 calls
 | 
			
		||||
 | 
			
		||||
commit 8aac0e2338916e273ccbd438a2b7a1e8c61749f5 upstream.
 | 
			
		||||
 | 
			
		||||
A multithreaded namespace creation/destruction stress test currently
 | 
			
		||||
fails with signatures like the following:
 | 
			
		||||
 | 
			
		||||
    sysfs group 'power' not found for kobject 'dax1.1'
 | 
			
		||||
    RIP: 0010:sysfs_remove_group+0x76/0x80
 | 
			
		||||
    Call Trace:
 | 
			
		||||
     device_del+0x73/0x370
 | 
			
		||||
     device_unregister+0x16/0x50
 | 
			
		||||
     nd_async_device_unregister+0x1e/0x30 [libnvdimm]
 | 
			
		||||
     async_run_entry_fn+0x39/0x160
 | 
			
		||||
     process_one_work+0x23c/0x5e0
 | 
			
		||||
     worker_thread+0x3c/0x390
 | 
			
		||||
 | 
			
		||||
    BUG: kernel NULL pointer dereference, address: 0000000000000020
 | 
			
		||||
    RIP: 0010:klist_put+0x1b/0x6c
 | 
			
		||||
    Call Trace:
 | 
			
		||||
     klist_del+0xe/0x10
 | 
			
		||||
     device_del+0x8a/0x2c9
 | 
			
		||||
     ? __switch_to_asm+0x34/0x70
 | 
			
		||||
     ? __switch_to_asm+0x40/0x70
 | 
			
		||||
     device_unregister+0x44/0x4f
 | 
			
		||||
     nd_async_device_unregister+0x22/0x2d [libnvdimm]
 | 
			
		||||
     async_run_entry_fn+0x47/0x15a
 | 
			
		||||
     process_one_work+0x1a2/0x2eb
 | 
			
		||||
     worker_thread+0x1b8/0x26e
 | 
			
		||||
 | 
			
		||||
Use the kill_device() helper to atomically resolve the race of multiple
 | 
			
		||||
threads issuing kill, device_unregister(), requests.
 | 
			
		||||
 | 
			
		||||
Reported-by: Jane Chu <jane.chu@oracle.com>
 | 
			
		||||
Reported-by: Erwin Tsaur <erwin.tsaur@oracle.com>
 | 
			
		||||
Fixes: 4d88a97aa9e8 ("libnvdimm, nvdimm: dimm driver and base libnvdimm device-driver...")
 | 
			
		||||
Cc: <stable@vger.kernel.org>
 | 
			
		||||
Link: https://github.com/pmem/ndctl/issues/96
 | 
			
		||||
Tested-by: Tested-by: Jane Chu <jane.chu@oracle.com>
 | 
			
		||||
Link: https://lore.kernel.org/r/156341207846.292348.10435719262819764054.stgit@dwillia2-desk3.amr.corp.intel.com
 | 
			
		||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvdimm/bus.c | 25 +++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 25 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
 | 
			
		||||
index ee39e2c1644a..11cfd23e5aff 100644
 | 
			
		||||
--- a/drivers/nvdimm/bus.c
 | 
			
		||||
+++ b/drivers/nvdimm/bus.c
 | 
			
		||||
@@ -528,13 +528,38 @@ EXPORT_SYMBOL(nd_device_register);
 | 
			
		||||
 
 | 
			
		||||
 void nd_device_unregister(struct device *dev, enum nd_async_mode mode)
 | 
			
		||||
 {
 | 
			
		||||
+	bool killed;
 | 
			
		||||
+
 | 
			
		||||
 	switch (mode) {
 | 
			
		||||
 	case ND_ASYNC:
 | 
			
		||||
+		/*
 | 
			
		||||
+		 * In the async case this is being triggered with the
 | 
			
		||||
+		 * device lock held and the unregistration work needs to
 | 
			
		||||
+		 * be moved out of line iff this is thread has won the
 | 
			
		||||
+		 * race to schedule the deletion.
 | 
			
		||||
+		 */
 | 
			
		||||
+		if (!kill_device(dev))
 | 
			
		||||
+			return;
 | 
			
		||||
+
 | 
			
		||||
 		get_device(dev);
 | 
			
		||||
 		async_schedule_domain(nd_async_device_unregister, dev,
 | 
			
		||||
 				&nd_async_domain);
 | 
			
		||||
 		break;
 | 
			
		||||
 	case ND_SYNC:
 | 
			
		||||
+		/*
 | 
			
		||||
+		 * In the sync case the device is being unregistered due
 | 
			
		||||
+		 * to a state change of the parent. Claim the kill state
 | 
			
		||||
+		 * to synchronize against other unregistration requests,
 | 
			
		||||
+		 * or otherwise let the async path handle it if the
 | 
			
		||||
+		 * unregistration was already queued.
 | 
			
		||||
+		 */
 | 
			
		||||
+		device_lock(dev);
 | 
			
		||||
+		killed = kill_device(dev);
 | 
			
		||||
+		device_unlock(dev);
 | 
			
		||||
+
 | 
			
		||||
+		if (!killed)
 | 
			
		||||
+			return;
 | 
			
		||||
+
 | 
			
		||||
 		nd_synchronize();
 | 
			
		||||
 		device_unregister(dev);
 | 
			
		||||
 		break;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,94 +0,0 @@
 | 
			
		|||
From 3248536919c17855ef5f2bc736d9565d9580706a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Date: Mon, 5 Aug 2019 18:32:02 -0700
 | 
			
		||||
Subject: [PATCH 773/826] libnvdimm/region: Register badblocks before
 | 
			
		||||
 namespaces
 | 
			
		||||
 | 
			
		||||
commit 700cd033a82d466ad8f9615f9985525e45f8960a upstream.
 | 
			
		||||
 | 
			
		||||
Namespace activation expects to be able to reference region badblocks.
 | 
			
		||||
The following warning sometimes triggers when asynchronous namespace
 | 
			
		||||
activation races in front of the completion of namespace probing. Move
 | 
			
		||||
all possible namespace probing after region badblocks initialization.
 | 
			
		||||
 | 
			
		||||
Otherwise, lockdep sometimes catches the uninitialized state of the
 | 
			
		||||
badblocks seqlock with stack trace signatures like:
 | 
			
		||||
 | 
			
		||||
    INFO: trying to register non-static key.
 | 
			
		||||
    pmem2: detected capacity change from 0 to 136365211648
 | 
			
		||||
    the code is fine but needs lockdep annotation.
 | 
			
		||||
    turning off the locking correctness validator.
 | 
			
		||||
    CPU: 9 PID: 358 Comm: kworker/u80:5 Tainted: G           OE     5.2.0-rc4+ #3382
 | 
			
		||||
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
 | 
			
		||||
    Workqueue: events_unbound async_run_entry_fn
 | 
			
		||||
    Call Trace:
 | 
			
		||||
     dump_stack+0x85/0xc0
 | 
			
		||||
    pmem1.12: detected capacity change from 0 to 8589934592
 | 
			
		||||
     register_lock_class+0x56a/0x570
 | 
			
		||||
     ? check_object+0x140/0x270
 | 
			
		||||
     __lock_acquire+0x80/0x1710
 | 
			
		||||
     ? __mutex_lock+0x39d/0x910
 | 
			
		||||
     lock_acquire+0x9e/0x180
 | 
			
		||||
     ? nd_pfn_validate+0x28f/0x440 [libnvdimm]
 | 
			
		||||
     badblocks_check+0x93/0x1f0
 | 
			
		||||
     ? nd_pfn_validate+0x28f/0x440 [libnvdimm]
 | 
			
		||||
     nd_pfn_validate+0x28f/0x440 [libnvdimm]
 | 
			
		||||
     ? lockdep_hardirqs_on+0xf0/0x180
 | 
			
		||||
     nd_dax_probe+0x9a/0x120 [libnvdimm]
 | 
			
		||||
     nd_pmem_probe+0x6d/0x180 [nd_pmem]
 | 
			
		||||
     nvdimm_bus_probe+0x90/0x2c0 [libnvdimm]
 | 
			
		||||
 | 
			
		||||
Fixes: 48af2f7e52f4 ("libnvdimm, pfn: during init, clear errors...")
 | 
			
		||||
Cc: <stable@vger.kernel.org>
 | 
			
		||||
Cc: Vishal Verma <vishal.l.verma@intel.com>
 | 
			
		||||
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
 | 
			
		||||
Link: https://lore.kernel.org/r/156341208365.292348.1547528796026249120.stgit@dwillia2-desk3.amr.corp.intel.com
 | 
			
		||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvdimm/region.c | 22 +++++++++++-----------
 | 
			
		||||
 1 file changed, 11 insertions(+), 11 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c
 | 
			
		||||
index b9ca0033cc99..f9130cc157e8 100644
 | 
			
		||||
--- a/drivers/nvdimm/region.c
 | 
			
		||||
+++ b/drivers/nvdimm/region.c
 | 
			
		||||
@@ -42,17 +42,6 @@ static int nd_region_probe(struct device *dev)
 | 
			
		||||
 	if (rc)
 | 
			
		||||
 		return rc;
 | 
			
		||||
 
 | 
			
		||||
-	rc = nd_region_register_namespaces(nd_region, &err);
 | 
			
		||||
-	if (rc < 0)
 | 
			
		||||
-		return rc;
 | 
			
		||||
-
 | 
			
		||||
-	ndrd = dev_get_drvdata(dev);
 | 
			
		||||
-	ndrd->ns_active = rc;
 | 
			
		||||
-	ndrd->ns_count = rc + err;
 | 
			
		||||
-
 | 
			
		||||
-	if (rc && err && rc == err)
 | 
			
		||||
-		return -ENODEV;
 | 
			
		||||
-
 | 
			
		||||
 	if (is_nd_pmem(&nd_region->dev)) {
 | 
			
		||||
 		struct resource ndr_res;
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +57,17 @@ static int nd_region_probe(struct device *dev)
 | 
			
		||||
 		nvdimm_badblocks_populate(nd_region, &nd_region->bb, &ndr_res);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	rc = nd_region_register_namespaces(nd_region, &err);
 | 
			
		||||
+	if (rc < 0)
 | 
			
		||||
+		return rc;
 | 
			
		||||
+
 | 
			
		||||
+	ndrd = dev_get_drvdata(dev);
 | 
			
		||||
+	ndrd->ns_active = rc;
 | 
			
		||||
+	ndrd->ns_count = rc + err;
 | 
			
		||||
+
 | 
			
		||||
+	if (rc && err && rc == err)
 | 
			
		||||
+		return -ENODEV;
 | 
			
		||||
+
 | 
			
		||||
 	nd_region->btt_seed = nd_btt_create(nd_region);
 | 
			
		||||
 	nd_region->pfn_seed = nd_pfn_create(nd_region);
 | 
			
		||||
 	nd_region->dax_seed = nd_dax_create(nd_region);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,165 +0,0 @@
 | 
			
		|||
From 7f000e7b44901519b41bbe6352a9fb0afc5b6d18 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Date: Mon, 5 Aug 2019 18:32:07 -0700
 | 
			
		||||
Subject: [PATCH 774/826] libnvdimm/bus: Prepare the nd_ioctl() path to be
 | 
			
		||||
 re-entrant
 | 
			
		||||
 | 
			
		||||
commit 6de5d06e657acdbcf9637dac37916a4a5309e0f4 upstream.
 | 
			
		||||
 | 
			
		||||
In preparation for not holding a lock over the execution of nd_ioctl(),
 | 
			
		||||
update the implementation to allow multiple threads to be attempting
 | 
			
		||||
ioctls at the same time. The bus lock still prevents multiple in-flight
 | 
			
		||||
->ndctl() invocations from corrupting each other's state, but static
 | 
			
		||||
global staging buffers are moved to the heap.
 | 
			
		||||
 | 
			
		||||
Reported-by: Vishal Verma <vishal.l.verma@intel.com>
 | 
			
		||||
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
 | 
			
		||||
Tested-by: Vishal Verma <vishal.l.verma@intel.com>
 | 
			
		||||
Link: https://lore.kernel.org/r/156341208947.292348.10560140326807607481.stgit@dwillia2-desk3.amr.corp.intel.com
 | 
			
		||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvdimm/bus.c | 59 +++++++++++++++++++++++++++-----------------
 | 
			
		||||
 1 file changed, 37 insertions(+), 22 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
 | 
			
		||||
index 11cfd23e5aff..5abcdb4faa64 100644
 | 
			
		||||
--- a/drivers/nvdimm/bus.c
 | 
			
		||||
+++ b/drivers/nvdimm/bus.c
 | 
			
		||||
@@ -951,20 +951,19 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		int read_only, unsigned int ioctl_cmd, unsigned long arg)
 | 
			
		||||
 {
 | 
			
		||||
 	struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
 | 
			
		||||
-	static char out_env[ND_CMD_MAX_ENVELOPE];
 | 
			
		||||
-	static char in_env[ND_CMD_MAX_ENVELOPE];
 | 
			
		||||
 	const struct nd_cmd_desc *desc = NULL;
 | 
			
		||||
 	unsigned int cmd = _IOC_NR(ioctl_cmd);
 | 
			
		||||
 	struct device *dev = &nvdimm_bus->dev;
 | 
			
		||||
 	void __user *p = (void __user *) arg;
 | 
			
		||||
+	char *out_env = NULL, *in_env = NULL;
 | 
			
		||||
 	const char *cmd_name, *dimm_name;
 | 
			
		||||
 	u32 in_len = 0, out_len = 0;
 | 
			
		||||
 	unsigned int func = cmd;
 | 
			
		||||
 	unsigned long cmd_mask;
 | 
			
		||||
 	struct nd_cmd_pkg pkg;
 | 
			
		||||
 	int rc, i, cmd_rc;
 | 
			
		||||
+	void *buf = NULL;
 | 
			
		||||
 	u64 buf_len = 0;
 | 
			
		||||
-	void *buf;
 | 
			
		||||
 
 | 
			
		||||
 	if (nvdimm) {
 | 
			
		||||
 		desc = nd_cmd_dimm_desc(cmd);
 | 
			
		||||
@@ -1004,6 +1003,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
 	/* process an input envelope */
 | 
			
		||||
+	in_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL);
 | 
			
		||||
+	if (!in_env)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
 	for (i = 0; i < desc->in_num; i++) {
 | 
			
		||||
 		u32 in_size, copy;
 | 
			
		||||
 
 | 
			
		||||
@@ -1011,14 +1013,17 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		if (in_size == UINT_MAX) {
 | 
			
		||||
 			dev_err(dev, "%s:%s unknown input size cmd: %s field: %d\n",
 | 
			
		||||
 					__func__, dimm_name, cmd_name, i);
 | 
			
		||||
-			return -ENXIO;
 | 
			
		||||
+			rc = -ENXIO;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
-		if (in_len < sizeof(in_env))
 | 
			
		||||
-			copy = min_t(u32, sizeof(in_env) - in_len, in_size);
 | 
			
		||||
+		if (in_len < ND_CMD_MAX_ENVELOPE)
 | 
			
		||||
+			copy = min_t(u32, ND_CMD_MAX_ENVELOPE - in_len, in_size);
 | 
			
		||||
 		else
 | 
			
		||||
 			copy = 0;
 | 
			
		||||
-		if (copy && copy_from_user(&in_env[in_len], p + in_len, copy))
 | 
			
		||||
-			return -EFAULT;
 | 
			
		||||
+		if (copy && copy_from_user(&in_env[in_len], p + in_len, copy)) {
 | 
			
		||||
+			rc = -EFAULT;
 | 
			
		||||
+			goto out;
 | 
			
		||||
+		}
 | 
			
		||||
 		in_len += in_size;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1030,6 +1035,12 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* process an output envelope */
 | 
			
		||||
+	out_env = kzalloc(ND_CMD_MAX_ENVELOPE, GFP_KERNEL);
 | 
			
		||||
+	if (!out_env) {
 | 
			
		||||
+		rc = -ENOMEM;
 | 
			
		||||
+		goto out;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	for (i = 0; i < desc->out_num; i++) {
 | 
			
		||||
 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
 | 
			
		||||
 				(u32 *) in_env, (u32 *) out_env, 0);
 | 
			
		||||
@@ -1038,15 +1049,18 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		if (out_size == UINT_MAX) {
 | 
			
		||||
 			dev_dbg(dev, "%s unknown output size cmd: %s field: %d\n",
 | 
			
		||||
 					dimm_name, cmd_name, i);
 | 
			
		||||
-			return -EFAULT;
 | 
			
		||||
+			rc = -EFAULT;
 | 
			
		||||
+			goto out;
 | 
			
		||||
 		}
 | 
			
		||||
-		if (out_len < sizeof(out_env))
 | 
			
		||||
-			copy = min_t(u32, sizeof(out_env) - out_len, out_size);
 | 
			
		||||
+		if (out_len < ND_CMD_MAX_ENVELOPE)
 | 
			
		||||
+			copy = min_t(u32, ND_CMD_MAX_ENVELOPE - out_len, out_size);
 | 
			
		||||
 		else
 | 
			
		||||
 			copy = 0;
 | 
			
		||||
 		if (copy && copy_from_user(&out_env[out_len],
 | 
			
		||||
-					p + in_len + out_len, copy))
 | 
			
		||||
-			return -EFAULT;
 | 
			
		||||
+					p + in_len + out_len, copy)) {
 | 
			
		||||
+			rc = -EFAULT;
 | 
			
		||||
+			goto out;
 | 
			
		||||
+		}
 | 
			
		||||
 		out_len += out_size;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1054,12 +1068,15 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 	if (buf_len > ND_IOCTL_MAX_BUFLEN) {
 | 
			
		||||
 		dev_dbg(dev, "%s cmd: %s buf_len: %llu > %d\n", dimm_name,
 | 
			
		||||
 				cmd_name, buf_len, ND_IOCTL_MAX_BUFLEN);
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
+		rc = -EINVAL;
 | 
			
		||||
+		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	buf = vmalloc(buf_len);
 | 
			
		||||
-	if (!buf)
 | 
			
		||||
-		return -ENOMEM;
 | 
			
		||||
+	if (!buf) {
 | 
			
		||||
+		rc = -ENOMEM;
 | 
			
		||||
+		goto out;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (copy_from_user(buf, p, buf_len)) {
 | 
			
		||||
 		rc = -EFAULT;
 | 
			
		||||
@@ -1081,17 +1098,15 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		nvdimm_account_cleared_poison(nvdimm_bus, clear_err->address,
 | 
			
		||||
 				clear_err->cleared);
 | 
			
		||||
 	}
 | 
			
		||||
-	nvdimm_bus_unlock(&nvdimm_bus->dev);
 | 
			
		||||
 
 | 
			
		||||
 	if (copy_to_user(p, buf, buf_len))
 | 
			
		||||
 		rc = -EFAULT;
 | 
			
		||||
 
 | 
			
		||||
-	vfree(buf);
 | 
			
		||||
-	return rc;
 | 
			
		||||
-
 | 
			
		||||
- out_unlock:
 | 
			
		||||
+out_unlock:
 | 
			
		||||
 	nvdimm_bus_unlock(&nvdimm_bus->dev);
 | 
			
		||||
- out:
 | 
			
		||||
+out:
 | 
			
		||||
+	kfree(in_env);
 | 
			
		||||
+	kfree(out_env);
 | 
			
		||||
 	vfree(buf);
 | 
			
		||||
 	return rc;
 | 
			
		||||
 }
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,153 +0,0 @@
 | 
			
		|||
From 2364ed0d8ed11e30757563312587516911c88ae3 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Date: Mon, 5 Aug 2019 18:32:13 -0700
 | 
			
		||||
Subject: [PATCH 775/826] libnvdimm/bus: Fix wait_nvdimm_bus_probe_idle() ABBA
 | 
			
		||||
 deadlock
 | 
			
		||||
 | 
			
		||||
commit ca6bf264f6d856f959c4239cda1047b587745c67 upstream.
 | 
			
		||||
 | 
			
		||||
A multithreaded namespace creation/destruction stress test currently
 | 
			
		||||
deadlocks with the following lockup signature:
 | 
			
		||||
 | 
			
		||||
    INFO: task ndctl:2924 blocked for more than 122 seconds.
 | 
			
		||||
          Tainted: G           OE     5.2.0-rc4+ #3382
 | 
			
		||||
    "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
 | 
			
		||||
    ndctl           D    0  2924   1176 0x00000000
 | 
			
		||||
    Call Trace:
 | 
			
		||||
     ? __schedule+0x27e/0x780
 | 
			
		||||
     schedule+0x30/0xb0
 | 
			
		||||
     wait_nvdimm_bus_probe_idle+0x8a/0xd0 [libnvdimm]
 | 
			
		||||
     ? finish_wait+0x80/0x80
 | 
			
		||||
     uuid_store+0xe6/0x2e0 [libnvdimm]
 | 
			
		||||
     kernfs_fop_write+0xf0/0x1a0
 | 
			
		||||
     vfs_write+0xb7/0x1b0
 | 
			
		||||
     ksys_write+0x5c/0xd0
 | 
			
		||||
     do_syscall_64+0x60/0x240
 | 
			
		||||
 | 
			
		||||
     INFO: task ndctl:2923 blocked for more than 122 seconds.
 | 
			
		||||
           Tainted: G           OE     5.2.0-rc4+ #3382
 | 
			
		||||
     "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
 | 
			
		||||
     ndctl           D    0  2923   1175 0x00000000
 | 
			
		||||
     Call Trace:
 | 
			
		||||
      ? __schedule+0x27e/0x780
 | 
			
		||||
      ? __mutex_lock+0x489/0x910
 | 
			
		||||
      schedule+0x30/0xb0
 | 
			
		||||
      schedule_preempt_disabled+0x11/0x20
 | 
			
		||||
      __mutex_lock+0x48e/0x910
 | 
			
		||||
      ? nvdimm_namespace_common_probe+0x95/0x4d0 [libnvdimm]
 | 
			
		||||
      ? __lock_acquire+0x23f/0x1710
 | 
			
		||||
      ? nvdimm_namespace_common_probe+0x95/0x4d0 [libnvdimm]
 | 
			
		||||
      nvdimm_namespace_common_probe+0x95/0x4d0 [libnvdimm]
 | 
			
		||||
      __dax_pmem_probe+0x5e/0x210 [dax_pmem_core]
 | 
			
		||||
      ? nvdimm_bus_probe+0x1d0/0x2c0 [libnvdimm]
 | 
			
		||||
      dax_pmem_probe+0xc/0x20 [dax_pmem]
 | 
			
		||||
      nvdimm_bus_probe+0x90/0x2c0 [libnvdimm]
 | 
			
		||||
      really_probe+0xef/0x390
 | 
			
		||||
      driver_probe_device+0xb4/0x100
 | 
			
		||||
 | 
			
		||||
In this sequence an 'nd_dax' device is being probed and trying to take
 | 
			
		||||
the lock on its backing namespace to validate that the 'nd_dax' device
 | 
			
		||||
indeed has exclusive access to the backing namespace. Meanwhile, another
 | 
			
		||||
thread is trying to update the uuid property of that same backing
 | 
			
		||||
namespace. So one thread is in the probe path trying to acquire the
 | 
			
		||||
lock, and the other thread has acquired the lock and tries to flush the
 | 
			
		||||
probe path.
 | 
			
		||||
 | 
			
		||||
Fix this deadlock by not holding the namespace device_lock over the
 | 
			
		||||
wait_nvdimm_bus_probe_idle() synchronization step. In turn this requires
 | 
			
		||||
the device_lock to be held on entry to wait_nvdimm_bus_probe_idle() and
 | 
			
		||||
subsequently dropped internally to wait_nvdimm_bus_probe_idle().
 | 
			
		||||
 | 
			
		||||
Cc: <stable@vger.kernel.org>
 | 
			
		||||
Fixes: bf9bccc14c05 ("libnvdimm: pmem label sets and namespace instantiation")
 | 
			
		||||
Cc: Vishal Verma <vishal.l.verma@intel.com>
 | 
			
		||||
Tested-by: Jane Chu <jane.chu@oracle.com>
 | 
			
		||||
Link: https://lore.kernel.org/r/156341210094.292348.2384694131126767789.stgit@dwillia2-desk3.amr.corp.intel.com
 | 
			
		||||
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
 | 
			
		||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvdimm/bus.c         | 14 +++++++++-----
 | 
			
		||||
 drivers/nvdimm/region_devs.c |  4 ++++
 | 
			
		||||
 2 files changed, 13 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
 | 
			
		||||
index 5abcdb4faa64..2ba22cd1331b 100644
 | 
			
		||||
--- a/drivers/nvdimm/bus.c
 | 
			
		||||
+++ b/drivers/nvdimm/bus.c
 | 
			
		||||
@@ -865,10 +865,12 @@ void wait_nvdimm_bus_probe_idle(struct device *dev)
 | 
			
		||||
 	do {
 | 
			
		||||
 		if (nvdimm_bus->probe_active == 0)
 | 
			
		||||
 			break;
 | 
			
		||||
-		nvdimm_bus_unlock(&nvdimm_bus->dev);
 | 
			
		||||
+		nvdimm_bus_unlock(dev);
 | 
			
		||||
+		device_unlock(dev);
 | 
			
		||||
 		wait_event(nvdimm_bus->wait,
 | 
			
		||||
 				nvdimm_bus->probe_active == 0);
 | 
			
		||||
-		nvdimm_bus_lock(&nvdimm_bus->dev);
 | 
			
		||||
+		device_lock(dev);
 | 
			
		||||
+		nvdimm_bus_lock(dev);
 | 
			
		||||
 	} while (true);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -994,7 +996,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		case ND_CMD_ARS_START:
 | 
			
		||||
 		case ND_CMD_CLEAR_ERROR:
 | 
			
		||||
 		case ND_CMD_CALL:
 | 
			
		||||
-			dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
 | 
			
		||||
+			dev_dbg(dev, "'%s' command while read-only.\n",
 | 
			
		||||
 					nvdimm ? nvdimm_cmd_name(cmd)
 | 
			
		||||
 					: nvdimm_bus_cmd_name(cmd));
 | 
			
		||||
 			return -EPERM;
 | 
			
		||||
@@ -1083,7 +1085,8 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		goto out;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	nvdimm_bus_lock(&nvdimm_bus->dev);
 | 
			
		||||
+	device_lock(dev);
 | 
			
		||||
+	nvdimm_bus_lock(dev);
 | 
			
		||||
 	rc = nd_cmd_clear_to_send(nvdimm_bus, nvdimm, func, buf);
 | 
			
		||||
 	if (rc)
 | 
			
		||||
 		goto out_unlock;
 | 
			
		||||
@@ -1103,7 +1106,8 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 | 
			
		||||
 		rc = -EFAULT;
 | 
			
		||||
 
 | 
			
		||||
 out_unlock:
 | 
			
		||||
-	nvdimm_bus_unlock(&nvdimm_bus->dev);
 | 
			
		||||
+	nvdimm_bus_unlock(dev);
 | 
			
		||||
+	device_unlock(dev);
 | 
			
		||||
 out:
 | 
			
		||||
 	kfree(in_env);
 | 
			
		||||
 	kfree(out_env);
 | 
			
		||||
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
 | 
			
		||||
index e7377f1028ef..0303296e6d5b 100644
 | 
			
		||||
--- a/drivers/nvdimm/region_devs.c
 | 
			
		||||
+++ b/drivers/nvdimm/region_devs.c
 | 
			
		||||
@@ -425,10 +425,12 @@ static ssize_t available_size_show(struct device *dev,
 | 
			
		||||
 	 * memory nvdimm_bus_lock() is dropped, but that's userspace's
 | 
			
		||||
 	 * problem to not race itself.
 | 
			
		||||
 	 */
 | 
			
		||||
+	device_lock(dev);
 | 
			
		||||
 	nvdimm_bus_lock(dev);
 | 
			
		||||
 	wait_nvdimm_bus_probe_idle(dev);
 | 
			
		||||
 	available = nd_region_available_dpa(nd_region);
 | 
			
		||||
 	nvdimm_bus_unlock(dev);
 | 
			
		||||
+	device_unlock(dev);
 | 
			
		||||
 
 | 
			
		||||
 	return sprintf(buf, "%llu\n", available);
 | 
			
		||||
 }
 | 
			
		||||
@@ -440,10 +442,12 @@ static ssize_t max_available_extent_show(struct device *dev,
 | 
			
		||||
 	struct nd_region *nd_region = to_nd_region(dev);
 | 
			
		||||
 	unsigned long long available = 0;
 | 
			
		||||
 
 | 
			
		||||
+	device_lock(dev);
 | 
			
		||||
 	nvdimm_bus_lock(dev);
 | 
			
		||||
 	wait_nvdimm_bus_probe_idle(dev);
 | 
			
		||||
 	available = nd_region_allocatable_dpa(nd_region);
 | 
			
		||||
 	nvdimm_bus_unlock(dev);
 | 
			
		||||
+	device_unlock(dev);
 | 
			
		||||
 
 | 
			
		||||
 	return sprintf(buf, "%llu\n", available);
 | 
			
		||||
 }
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,52 +0,0 @@
 | 
			
		|||
From e830c2c3c1748613cdcd0df85e6edcd8b59d9336 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Aaron Armstrong Skomra <skomra@gmail.com>
 | 
			
		||||
Date: Tue, 23 Jul 2019 11:09:15 -0700
 | 
			
		||||
Subject: [PATCH 776/826] HID: wacom: fix bit shift for Cintiq Companion 2
 | 
			
		||||
 | 
			
		||||
commit 693c3dab4e50403f91bca4b52fc6d8562a3180f6 upstream.
 | 
			
		||||
 | 
			
		||||
The bit indicating BTN_6 on this device is overshifted
 | 
			
		||||
by 2 bits, resulting in the incorrect button being
 | 
			
		||||
reported.
 | 
			
		||||
 | 
			
		||||
Also fix copy-paste mistake in comments.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
 | 
			
		||||
Reviewed-by: Ping Cheng <ping.cheng@wacom.com>
 | 
			
		||||
Link: https://github.com/linuxwacom/xf86-input-wacom/issues/71
 | 
			
		||||
Fixes: c7f0522a1ad1 ("HID: wacom: Slim down wacom_intuos_pad processing")
 | 
			
		||||
Cc: <stable@vger.kernel.org> # v4.5+
 | 
			
		||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/hid/wacom_wac.c | 12 ++++++------
 | 
			
		||||
 1 file changed, 6 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
 | 
			
		||||
index 0ae848369474..e56dc97fe4b6 100644
 | 
			
		||||
--- a/drivers/hid/wacom_wac.c
 | 
			
		||||
+++ b/drivers/hid/wacom_wac.c
 | 
			
		||||
@@ -537,14 +537,14 @@ static int wacom_intuos_pad(struct wacom_wac *wacom)
 | 
			
		||||
 		 */
 | 
			
		||||
 		buttons = (data[4] << 1) | (data[3] & 0x01);
 | 
			
		||||
 	} else if (features->type == CINTIQ_COMPANION_2) {
 | 
			
		||||
-		/* d-pad right  -> data[4] & 0x10
 | 
			
		||||
-		 * d-pad up     -> data[4] & 0x20
 | 
			
		||||
-		 * d-pad left   -> data[4] & 0x40
 | 
			
		||||
-		 * d-pad down   -> data[4] & 0x80
 | 
			
		||||
-		 * d-pad center -> data[3] & 0x01
 | 
			
		||||
+		/* d-pad right  -> data[2] & 0x10
 | 
			
		||||
+		 * d-pad up     -> data[2] & 0x20
 | 
			
		||||
+		 * d-pad left   -> data[2] & 0x40
 | 
			
		||||
+		 * d-pad down   -> data[2] & 0x80
 | 
			
		||||
+		 * d-pad center -> data[1] & 0x01
 | 
			
		||||
 		 */
 | 
			
		||||
 		buttons = ((data[2] >> 4) << 7) |
 | 
			
		||||
-		          ((data[1] & 0x04) << 6) |
 | 
			
		||||
+		          ((data[1] & 0x04) << 4) |
 | 
			
		||||
 		          ((data[2] & 0x0F) << 2) |
 | 
			
		||||
 		          (data[1] & 0x03);
 | 
			
		||||
 	} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,50 +0,0 @@
 | 
			
		|||
From 608cfdfa9eb712a54900859dabae5c5c19a2a93c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Sebastian Parschauer <s.parschauer@gmx.de>
 | 
			
		||||
Date: Wed, 24 Jul 2019 20:40:03 +0200
 | 
			
		||||
Subject: [PATCH 777/826] HID: Add quirk for HP X1200 PIXART OEM mouse
 | 
			
		||||
 | 
			
		||||
commit 49869d2ea9eecc105a10724c1abf035151a3c4e2 upstream.
 | 
			
		||||
 | 
			
		||||
The PixArt OEM mice are known for disconnecting every minute in
 | 
			
		||||
runlevel 1 or 3 if they are not always polled. So add quirk
 | 
			
		||||
ALWAYS_POLL for this one as well.
 | 
			
		||||
 | 
			
		||||
Jonathan Teh (@jonathan-teh) reported and tested the quirk.
 | 
			
		||||
Reference: https://github.com/sriemer/fix-linux-mouse/issues/15
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Sebastian Parschauer <s.parschauer@gmx.de>
 | 
			
		||||
CC: stable@vger.kernel.org
 | 
			
		||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/hid/hid-ids.h    | 1 +
 | 
			
		||||
 drivers/hid/hid-quirks.c | 1 +
 | 
			
		||||
 2 files changed, 2 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
 | 
			
		||||
index 50b3c0d89c9c..2898bb061945 100644
 | 
			
		||||
--- a/drivers/hid/hid-ids.h
 | 
			
		||||
+++ b/drivers/hid/hid-ids.h
 | 
			
		||||
@@ -559,6 +559,7 @@
 | 
			
		||||
 #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A	0x0b4a
 | 
			
		||||
 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE		0x134a
 | 
			
		||||
 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A	0x094a
 | 
			
		||||
+#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641	0x0641
 | 
			
		||||
 
 | 
			
		||||
 #define USB_VENDOR_ID_HUION		0x256c
 | 
			
		||||
 #define USB_DEVICE_ID_HUION_TABLET	0x006e
 | 
			
		||||
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
 | 
			
		||||
index 91e86af44a04..d29c7c9cd185 100644
 | 
			
		||||
--- a/drivers/hid/hid-quirks.c
 | 
			
		||||
+++ b/drivers/hid/hid-quirks.c
 | 
			
		||||
@@ -94,6 +94,7 @@ static const struct hid_device_id hid_quirks[] = {
 | 
			
		||||
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL },
 | 
			
		||||
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
 | 
			
		||||
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
 | 
			
		||||
+	{ HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL },
 | 
			
		||||
 	{ HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT },
 | 
			
		||||
 	{ HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT },
 | 
			
		||||
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT },
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
From 8440cdc77577e5177153e121229cff73c0ba4e6c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
Date: Wed, 7 Aug 2019 18:44:12 +0200
 | 
			
		||||
Subject: [PATCH 778/826] IB: directly cast the sockaddr union to aockaddr
 | 
			
		||||
 | 
			
		||||
Like commit 641114d2af31 ("RDMA: Directly cast the sockaddr union to
 | 
			
		||||
sockaddr") we need to quiet gcc 9 from warning about this crazy union.
 | 
			
		||||
That commit did not fix all of the warnings in 4.19 and older kernels
 | 
			
		||||
because the logic in roce_resolve_route_from_path() was rewritten
 | 
			
		||||
between 4.19 and 5.2 when that change happened.
 | 
			
		||||
 | 
			
		||||
Cc: Jason Gunthorpe <jgg@mellanox.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/infiniband/core/sa_query.c | 9 ++++-----
 | 
			
		||||
 1 file changed, 4 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
 | 
			
		||||
index 7b794a14d6e8..8be082edf986 100644
 | 
			
		||||
--- a/drivers/infiniband/core/sa_query.c
 | 
			
		||||
+++ b/drivers/infiniband/core/sa_query.c
 | 
			
		||||
@@ -1232,7 +1232,6 @@ static int roce_resolve_route_from_path(struct sa_path_rec *rec,
 | 
			
		||||
 {
 | 
			
		||||
 	struct rdma_dev_addr dev_addr = {};
 | 
			
		||||
 	union {
 | 
			
		||||
-		struct sockaddr     _sockaddr;
 | 
			
		||||
 		struct sockaddr_in  _sockaddr_in;
 | 
			
		||||
 		struct sockaddr_in6 _sockaddr_in6;
 | 
			
		||||
 	} sgid_addr, dgid_addr;
 | 
			
		||||
@@ -1249,12 +1248,12 @@ static int roce_resolve_route_from_path(struct sa_path_rec *rec,
 | 
			
		||||
 	 */
 | 
			
		||||
 	dev_addr.net = &init_net;
 | 
			
		||||
 
 | 
			
		||||
-	rdma_gid2ip(&sgid_addr._sockaddr, &rec->sgid);
 | 
			
		||||
-	rdma_gid2ip(&dgid_addr._sockaddr, &rec->dgid);
 | 
			
		||||
+	rdma_gid2ip((struct sockaddr *)&sgid_addr, &rec->sgid);
 | 
			
		||||
+	rdma_gid2ip((struct sockaddr *)&dgid_addr, &rec->dgid);
 | 
			
		||||
 
 | 
			
		||||
 	/* validate the route */
 | 
			
		||||
-	ret = rdma_resolve_ip_route(&sgid_addr._sockaddr,
 | 
			
		||||
-				    &dgid_addr._sockaddr, &dev_addr);
 | 
			
		||||
+	ret = rdma_resolve_ip_route((struct sockaddr *)&sgid_addr,
 | 
			
		||||
+				    (struct sockaddr *)&dgid_addr, &dev_addr);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,65 +0,0 @@
 | 
			
		|||
From cb4626784f398ae9222ed5e70ab79a2c74d9c74c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
 | 
			
		||||
Date: Tue, 30 Jul 2019 22:21:41 -0500
 | 
			
		||||
Subject: [PATCH 779/826] atm: iphase: Fix Spectre v1 vulnerability
 | 
			
		||||
 | 
			
		||||
[ Upstream commit ea443e5e98b5b74e317ef3d26bcaea54931ccdee ]
 | 
			
		||||
 | 
			
		||||
board is controlled by user-space, hence leading to a potential
 | 
			
		||||
exploitation of the Spectre variant 1 vulnerability.
 | 
			
		||||
 | 
			
		||||
This issue was detected with the help of Smatch:
 | 
			
		||||
 | 
			
		||||
drivers/atm/iphase.c:2765 ia_ioctl() warn: potential spectre issue 'ia_dev' [r] (local cap)
 | 
			
		||||
drivers/atm/iphase.c:2774 ia_ioctl() warn: possible spectre second half.  'iadev'
 | 
			
		||||
drivers/atm/iphase.c:2782 ia_ioctl() warn: possible spectre second half.  'iadev'
 | 
			
		||||
drivers/atm/iphase.c:2816 ia_ioctl() warn: possible spectre second half.  'iadev'
 | 
			
		||||
drivers/atm/iphase.c:2823 ia_ioctl() warn: possible spectre second half.  'iadev'
 | 
			
		||||
drivers/atm/iphase.c:2830 ia_ioctl() warn: potential spectre issue '_ia_dev' [r] (local cap)
 | 
			
		||||
drivers/atm/iphase.c:2845 ia_ioctl() warn: possible spectre second half.  'iadev'
 | 
			
		||||
drivers/atm/iphase.c:2856 ia_ioctl() warn: possible spectre second half.  'iadev'
 | 
			
		||||
 | 
			
		||||
Fix this by sanitizing board before using it to index ia_dev and _ia_dev
 | 
			
		||||
 | 
			
		||||
Notice that given that speculation windows are large, the policy is
 | 
			
		||||
to kill the speculation on the first load and not worry if it can be
 | 
			
		||||
completed with a dependent load/store [1].
 | 
			
		||||
 | 
			
		||||
[1] https://lore.kernel.org/lkml/20180423164740.GY17484@dhcp22.suse.cz/
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/atm/iphase.c | 8 ++++++--
 | 
			
		||||
 1 file changed, 6 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
 | 
			
		||||
index 82532c299bb5..008905d4152a 100644
 | 
			
		||||
--- a/drivers/atm/iphase.c
 | 
			
		||||
+++ b/drivers/atm/iphase.c
 | 
			
		||||
@@ -63,6 +63,7 @@
 | 
			
		||||
 #include <asm/byteorder.h>  
 | 
			
		||||
 #include <linux/vmalloc.h>
 | 
			
		||||
 #include <linux/jiffies.h>
 | 
			
		||||
+#include <linux/nospec.h>
 | 
			
		||||
 #include "iphase.h"		  
 | 
			
		||||
 #include "suni.h"		  
 | 
			
		||||
 #define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
 | 
			
		||||
@@ -2760,8 +2761,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
 | 
			
		||||
    }
 | 
			
		||||
    if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; 
 | 
			
		||||
    board = ia_cmds.status;
 | 
			
		||||
-   if ((board < 0) || (board > iadev_count))
 | 
			
		||||
-         board = 0;    
 | 
			
		||||
+
 | 
			
		||||
+	if ((board < 0) || (board > iadev_count))
 | 
			
		||||
+		board = 0;
 | 
			
		||||
+	board = array_index_nospec(board, iadev_count + 1);
 | 
			
		||||
+
 | 
			
		||||
    iadev = ia_dev[board];
 | 
			
		||||
    switch (ia_cmds.cmd) {
 | 
			
		||||
    case MEMDUMP:
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,39 +0,0 @@
 | 
			
		|||
From 774358df88f7259dafebb5876de4196826ca75a7 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Sudarsana Reddy Kalluru <skalluru@marvell.com>
 | 
			
		||||
Date: Tue, 23 Jul 2019 19:32:41 -0700
 | 
			
		||||
Subject: [PATCH 780/826] bnx2x: Disable multi-cos feature.
 | 
			
		||||
 | 
			
		||||
[ Upstream commit d1f0b5dce8fda09a7f5f04c1878f181d548e42f5 ]
 | 
			
		||||
 | 
			
		||||
Commit 3968d38917eb ("bnx2x: Fix Multi-Cos.") which enabled multi-cos
 | 
			
		||||
feature after prolonged time in driver added some regression causing
 | 
			
		||||
numerous issues (sudden reboots, tx timeout etc.) reported by customers.
 | 
			
		||||
We plan to backout this commit and submit proper fix once we have root
 | 
			
		||||
cause of issues reported with this feature enabled.
 | 
			
		||||
 | 
			
		||||
Fixes: 3968d38917eb ("bnx2x: Fix Multi-Cos.")
 | 
			
		||||
Signed-off-by: Sudarsana Reddy Kalluru <skalluru@marvell.com>
 | 
			
		||||
Signed-off-by: Manish Chopra <manishc@marvell.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 3 +--
 | 
			
		||||
 1 file changed, 1 insertion(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
 | 
			
		||||
index 3edb81a4f075..33baa17fa9d5 100644
 | 
			
		||||
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
 | 
			
		||||
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
 | 
			
		||||
@@ -1936,8 +1936,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* select a non-FCoE queue */
 | 
			
		||||
-	return fallback(dev, skb, NULL) %
 | 
			
		||||
-	       (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
 | 
			
		||||
+	return fallback(dev, skb, NULL) % (BNX2X_NUM_ETH_QUEUES(bp));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void bnx2x_set_num_queues(struct bnx2x *bp)
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,40 +0,0 @@
 | 
			
		|||
From c4c8899376c2eb363c70b0b200434cc9abd3d34e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cong Wang <xiyou.wangcong@gmail.com>
 | 
			
		||||
Date: Mon, 22 Jul 2019 21:43:00 -0700
 | 
			
		||||
Subject: [PATCH 781/826] ife: error out when nla attributes are empty
 | 
			
		||||
 | 
			
		||||
[ Upstream commit c8ec4632c6ac9cda0e8c3d51aa41eeab66585bd5 ]
 | 
			
		||||
 | 
			
		||||
act_ife at least requires TCA_IFE_PARMS, so we have to bail out
 | 
			
		||||
when there is no attribute passed in.
 | 
			
		||||
 | 
			
		||||
Reported-by: syzbot+fbb5b288c9cb6a2eeac4@syzkaller.appspotmail.com
 | 
			
		||||
Fixes: ef6980b6becb ("introduce IFE action")
 | 
			
		||||
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
 | 
			
		||||
Cc: Jiri Pirko <jiri@resnulli.us>
 | 
			
		||||
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/sched/act_ife.c | 5 +++++
 | 
			
		||||
 1 file changed, 5 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
 | 
			
		||||
index 06a3d4801878..915b6e94da63 100644
 | 
			
		||||
--- a/net/sched/act_ife.c
 | 
			
		||||
+++ b/net/sched/act_ife.c
 | 
			
		||||
@@ -484,6 +484,11 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	int ret = 0;
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
+	if (!nla) {
 | 
			
		||||
+		NL_SET_ERR_MSG_MOD(extack, "IFE requires attributes to be passed");
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	err = nla_parse_nested(tb, TCA_IFE_MAX, nla, ife_policy, NULL);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,43 +0,0 @@
 | 
			
		|||
From fdcefa46c5c22fdff4960c6bdabf245af667ceaf Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
 | 
			
		||||
Date: Wed, 24 Jul 2019 20:00:42 +0800
 | 
			
		||||
Subject: [PATCH 782/826] ip6_gre: reload ipv6h in prepare_ip6gre_xmit_ipv6
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 3bc817d665ac6d9de89f59df522ad86f5b5dfc03 ]
 | 
			
		||||
 | 
			
		||||
Since ip6_tnl_parse_tlv_enc_lim() can call pskb_may_pull()
 | 
			
		||||
which may change skb->data, so we need to re-load ipv6h at
 | 
			
		||||
the right place.
 | 
			
		||||
 | 
			
		||||
Fixes: 898b29798e36 ("ip6_gre: Refactor ip6gre xmit codes")
 | 
			
		||||
Cc: William Tu <u9012063@gmail.com>
 | 
			
		||||
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
 | 
			
		||||
Acked-by: William Tu <u9012063@gmail.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/ipv6/ip6_gre.c | 3 ++-
 | 
			
		||||
 1 file changed, 2 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
 | 
			
		||||
index 01ecd510014f..a53ef079a539 100644
 | 
			
		||||
--- a/net/ipv6/ip6_gre.c
 | 
			
		||||
+++ b/net/ipv6/ip6_gre.c
 | 
			
		||||
@@ -680,12 +680,13 @@ static int prepare_ip6gre_xmit_ipv6(struct sk_buff *skb,
 | 
			
		||||
 				    struct flowi6 *fl6, __u8 *dsfield,
 | 
			
		||||
 				    int *encap_limit)
 | 
			
		||||
 {
 | 
			
		||||
-	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
 | 
			
		||||
+	struct ipv6hdr *ipv6h;
 | 
			
		||||
 	struct ip6_tnl *t = netdev_priv(dev);
 | 
			
		||||
 	__u16 offset;
 | 
			
		||||
 
 | 
			
		||||
 	offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb));
 | 
			
		||||
 	/* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */
 | 
			
		||||
+	ipv6h = ipv6_hdr(skb);
 | 
			
		||||
 
 | 
			
		||||
 	if (offset > 0) {
 | 
			
		||||
 		struct ipv6_tlv_tnl_enc_lim *tel;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
From f186fb5ccf699487a38b5b924fa6068274ae7d4f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
 | 
			
		||||
Date: Thu, 25 Jul 2019 11:07:56 +0800
 | 
			
		||||
Subject: [PATCH 784/826] ipip: validate header length in ipip_tunnel_xmit
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 47d858d0bdcd47cc1c6c9eeca91b091dd9e55637 ]
 | 
			
		||||
 | 
			
		||||
We need the same checks introduced by commit cb9f1b783850
 | 
			
		||||
("ip: validate header length on virtual device xmit") for
 | 
			
		||||
ipip tunnel.
 | 
			
		||||
 | 
			
		||||
Fixes: cb9f1b783850b ("ip: validate header length on virtual device xmit")
 | 
			
		||||
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/ipv4/ipip.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
 | 
			
		||||
index c891235b4966..4368282eb6f8 100644
 | 
			
		||||
--- a/net/ipv4/ipip.c
 | 
			
		||||
+++ b/net/ipv4/ipip.c
 | 
			
		||||
@@ -281,6 +281,9 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb,
 | 
			
		||||
 	const struct iphdr  *tiph = &tunnel->parms.iph;
 | 
			
		||||
 	u8 ipproto;
 | 
			
		||||
 
 | 
			
		||||
+	if (!pskb_inet_may_pull(skb))
 | 
			
		||||
+		goto tx_error;
 | 
			
		||||
+
 | 
			
		||||
 	switch (skb->protocol) {
 | 
			
		||||
 	case htons(ETH_P_IP):
 | 
			
		||||
 		ipproto = IPPROTO_IPIP;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,36 +0,0 @@
 | 
			
		|||
From 3c46905fb182334eaa6737e8faa9f6067a45c027 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
Date: Wed, 31 Jul 2019 09:33:14 +0300
 | 
			
		||||
Subject: [PATCH 785/826] mlxsw: spectrum: Fix error path in
 | 
			
		||||
 mlxsw_sp_module_init()
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 28fe79000e9b0a6f99959869947f1ca305f14599 ]
 | 
			
		||||
 | 
			
		||||
In case of sp2 pci driver registration fail, fix the error path to
 | 
			
		||||
start with sp1 pci driver unregister.
 | 
			
		||||
 | 
			
		||||
Fixes: c3ab435466d5 ("mlxsw: spectrum: Extend to support Spectrum-2 ASIC")
 | 
			
		||||
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
 | 
			
		||||
index 0cab06046e5d..ee126bcf7c35 100644
 | 
			
		||||
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
 | 
			
		||||
@@ -5032,7 +5032,7 @@ static int __init mlxsw_sp_module_init(void)
 | 
			
		||||
 	return 0;
 | 
			
		||||
 
 | 
			
		||||
 err_sp2_pci_driver_register:
 | 
			
		||||
-	mlxsw_pci_driver_unregister(&mlxsw_sp2_pci_driver);
 | 
			
		||||
+	mlxsw_pci_driver_unregister(&mlxsw_sp1_pci_driver);
 | 
			
		||||
 err_sp1_pci_driver_register:
 | 
			
		||||
 	mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
 | 
			
		||||
 err_sp2_core_driver_register:
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,115 +0,0 @@
 | 
			
		|||
From ffab47bf69df0f340d56ded363bac09950ae2395 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Matteo Croce <mcroce@redhat.com>
 | 
			
		||||
Date: Thu, 1 Aug 2019 14:13:30 +0200
 | 
			
		||||
Subject: [PATCH 786/826] mvpp2: fix panic on module removal
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 944a83a2669ae8aa2c7664e79376ca7468eb0a2b ]
 | 
			
		||||
 | 
			
		||||
mvpp2 uses a delayed workqueue to gather traffic statistics.
 | 
			
		||||
On module removal the workqueue can be destroyed before calling
 | 
			
		||||
cancel_delayed_work_sync() on its works.
 | 
			
		||||
Fix it by moving the destroy_workqueue() call after mvpp2_port_remove().
 | 
			
		||||
Also remove an unneeded call to flush_workqueue()
 | 
			
		||||
 | 
			
		||||
    # rmmod mvpp2
 | 
			
		||||
    [ 2743.311722] mvpp2 f4000000.ethernet eth1: phy link down 10gbase-kr/10Gbps/Full
 | 
			
		||||
    [ 2743.320063] mvpp2 f4000000.ethernet eth1: Link is Down
 | 
			
		||||
    [ 2743.572263] mvpp2 f4000000.ethernet eth2: phy link down sgmii/1Gbps/Full
 | 
			
		||||
    [ 2743.580076] mvpp2 f4000000.ethernet eth2: Link is Down
 | 
			
		||||
    [ 2744.102169] mvpp2 f2000000.ethernet eth0: phy link down 10gbase-kr/10Gbps/Full
 | 
			
		||||
    [ 2744.110441] mvpp2 f2000000.ethernet eth0: Link is Down
 | 
			
		||||
    [ 2744.115614] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
 | 
			
		||||
    [ 2744.115615] Mem abort info:
 | 
			
		||||
    [ 2744.115616]   ESR = 0x96000005
 | 
			
		||||
    [ 2744.115617]   Exception class = DABT (current EL), IL = 32 bits
 | 
			
		||||
    [ 2744.115618]   SET = 0, FnV = 0
 | 
			
		||||
    [ 2744.115619]   EA = 0, S1PTW = 0
 | 
			
		||||
    [ 2744.115620] Data abort info:
 | 
			
		||||
    [ 2744.115621]   ISV = 0, ISS = 0x00000005
 | 
			
		||||
    [ 2744.115622]   CM = 0, WnR = 0
 | 
			
		||||
    [ 2744.115624] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000422681000
 | 
			
		||||
    [ 2744.115626] [0000000000000000] pgd=0000000000000000, pud=0000000000000000
 | 
			
		||||
    [ 2744.115630] Internal error: Oops: 96000005 [#1] SMP
 | 
			
		||||
    [ 2744.115632] Modules linked in: mvpp2(-) algif_hash af_alg nls_iso8859_1 nls_cp437 vfat fat xhci_plat_hcd m25p80 spi_nor xhci_hcd mtd usbcore i2c_mv64xxx sfp usb_common marvell10g phy_generic spi_orion mdio_i2c i2c_core mvmdio phylink sbsa_gwdt ip_tables x_tables autofs4 [last unloaded: mvpp2]
 | 
			
		||||
    [ 2744.115654] CPU: 3 PID: 8357 Comm: kworker/3:2 Not tainted 5.3.0-rc2 #1
 | 
			
		||||
    [ 2744.115655] Hardware name: Marvell 8040 MACCHIATOBin Double-shot (DT)
 | 
			
		||||
    [ 2744.115665] Workqueue: events_power_efficient phylink_resolve [phylink]
 | 
			
		||||
    [ 2744.115669] pstate: a0000085 (NzCv daIf -PAN -UAO)
 | 
			
		||||
    [ 2744.115675] pc : __queue_work+0x9c/0x4d8
 | 
			
		||||
    [ 2744.115677] lr : __queue_work+0x170/0x4d8
 | 
			
		||||
    [ 2744.115678] sp : ffffff801001bd50
 | 
			
		||||
    [ 2744.115680] x29: ffffff801001bd50 x28: ffffffc422597600
 | 
			
		||||
    [ 2744.115684] x27: ffffff80109ae6f0 x26: ffffff80108e4018
 | 
			
		||||
    [ 2744.115688] x25: 0000000000000003 x24: 0000000000000004
 | 
			
		||||
    [ 2744.115691] x23: ffffff80109ae6e0 x22: 0000000000000017
 | 
			
		||||
    [ 2744.115694] x21: ffffffc42c030000 x20: ffffffc42209e8f8
 | 
			
		||||
    [ 2744.115697] x19: 0000000000000000 x18: 0000000000000000
 | 
			
		||||
    [ 2744.115699] x17: 0000000000000000 x16: 0000000000000000
 | 
			
		||||
    [ 2744.115701] x15: 0000000000000010 x14: ffffffffffffffff
 | 
			
		||||
    [ 2744.115702] x13: ffffff8090e2b95f x12: ffffff8010e2b967
 | 
			
		||||
    [ 2744.115704] x11: ffffff8010906000 x10: 0000000000000040
 | 
			
		||||
    [ 2744.115706] x9 : ffffff80109223b8 x8 : ffffff80109223b0
 | 
			
		||||
    [ 2744.115707] x7 : ffffffc42bc00068 x6 : 0000000000000000
 | 
			
		||||
    [ 2744.115709] x5 : ffffffc42bc00000 x4 : 0000000000000000
 | 
			
		||||
    [ 2744.115710] x3 : 0000000000000000 x2 : 0000000000000000
 | 
			
		||||
    [ 2744.115712] x1 : 0000000000000008 x0 : ffffffc42c030000
 | 
			
		||||
    [ 2744.115714] Call trace:
 | 
			
		||||
    [ 2744.115716]  __queue_work+0x9c/0x4d8
 | 
			
		||||
    [ 2744.115718]  delayed_work_timer_fn+0x28/0x38
 | 
			
		||||
    [ 2744.115722]  call_timer_fn+0x3c/0x180
 | 
			
		||||
    [ 2744.115723]  expire_timers+0x60/0x168
 | 
			
		||||
    [ 2744.115724]  run_timer_softirq+0xbc/0x1e8
 | 
			
		||||
    [ 2744.115727]  __do_softirq+0x128/0x320
 | 
			
		||||
    [ 2744.115731]  irq_exit+0xa4/0xc0
 | 
			
		||||
    [ 2744.115734]  __handle_domain_irq+0x70/0xc0
 | 
			
		||||
    [ 2744.115735]  gic_handle_irq+0x58/0xa8
 | 
			
		||||
    [ 2744.115737]  el1_irq+0xb8/0x140
 | 
			
		||||
    [ 2744.115738]  console_unlock+0x3a0/0x568
 | 
			
		||||
    [ 2744.115740]  vprintk_emit+0x200/0x2a0
 | 
			
		||||
    [ 2744.115744]  dev_vprintk_emit+0x1c8/0x1e4
 | 
			
		||||
    [ 2744.115747]  dev_printk_emit+0x6c/0x7c
 | 
			
		||||
    [ 2744.115751]  __netdev_printk+0x104/0x1d8
 | 
			
		||||
    [ 2744.115752]  netdev_printk+0x60/0x70
 | 
			
		||||
    [ 2744.115756]  phylink_resolve+0x38c/0x3c8 [phylink]
 | 
			
		||||
    [ 2744.115758]  process_one_work+0x1f8/0x448
 | 
			
		||||
    [ 2744.115760]  worker_thread+0x54/0x500
 | 
			
		||||
    [ 2744.115762]  kthread+0x12c/0x130
 | 
			
		||||
    [ 2744.115764]  ret_from_fork+0x10/0x1c
 | 
			
		||||
    [ 2744.115768] Code: aa1403e0 97fffbbe aa0003f5 b4000700 (f9400261)
 | 
			
		||||
 | 
			
		||||
Fixes: 118d6298f6f0 ("net: mvpp2: add ethtool GOP statistics")
 | 
			
		||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 | 
			
		||||
Signed-off-by: Matteo Croce <mcroce@redhat.com>
 | 
			
		||||
Acked-by: Antoine Tenart <antoine.tenart@bootlin.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 5 ++---
 | 
			
		||||
 1 file changed, 2 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 | 
			
		||||
index df5b74f289e1..c357aafee106 100644
 | 
			
		||||
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 | 
			
		||||
@@ -5358,9 +5358,6 @@ static int mvpp2_remove(struct platform_device *pdev)
 | 
			
		||||
 
 | 
			
		||||
 	mvpp2_dbgfs_cleanup(priv);
 | 
			
		||||
 
 | 
			
		||||
-	flush_workqueue(priv->stats_queue);
 | 
			
		||||
-	destroy_workqueue(priv->stats_queue);
 | 
			
		||||
-
 | 
			
		||||
 	fwnode_for_each_available_child_node(fwnode, port_fwnode) {
 | 
			
		||||
 		if (priv->port_list[i]) {
 | 
			
		||||
 			mutex_destroy(&priv->port_list[i]->gather_stats_lock);
 | 
			
		||||
@@ -5369,6 +5366,8 @@ static int mvpp2_remove(struct platform_device *pdev)
 | 
			
		||||
 		i++;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	destroy_workqueue(priv->stats_queue);
 | 
			
		||||
+
 | 
			
		||||
 	for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) {
 | 
			
		||||
 		struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i];
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,88 +0,0 @@
 | 
			
		|||
From b3645a487373e2182bd9899a4fe3a2cbf2010e6e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Matteo Croce <mcroce@redhat.com>
 | 
			
		||||
Date: Sun, 28 Jul 2019 02:46:45 +0200
 | 
			
		||||
Subject: [PATCH 787/826] mvpp2: refactor MTU change code
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 230bd958c2c846ee292aa38bc6b006296c24ca01 ]
 | 
			
		||||
 | 
			
		||||
The MTU change code can call napi_disable() with the device already down,
 | 
			
		||||
leading to a deadlock. Also, lot of code is duplicated unnecessarily.
 | 
			
		||||
 | 
			
		||||
Rework mvpp2_change_mtu() to avoid the deadlock and remove duplicated code.
 | 
			
		||||
 | 
			
		||||
Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit")
 | 
			
		||||
Signed-off-by: Matteo Croce <mcroce@redhat.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 .../net/ethernet/marvell/mvpp2/mvpp2_main.c   | 41 ++++++-------------
 | 
			
		||||
 1 file changed, 13 insertions(+), 28 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 | 
			
		||||
index c357aafee106..6455511457ca 100644
 | 
			
		||||
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
 | 
			
		||||
@@ -3501,6 +3501,7 @@ static int mvpp2_set_mac_address(struct net_device *dev, void *p)
 | 
			
		||||
 static int mvpp2_change_mtu(struct net_device *dev, int mtu)
 | 
			
		||||
 {
 | 
			
		||||
 	struct mvpp2_port *port = netdev_priv(dev);
 | 
			
		||||
+	bool running = netif_running(dev);
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
 	if (!IS_ALIGNED(MVPP2_RX_PKT_SIZE(mtu), 8)) {
 | 
			
		||||
@@ -3509,40 +3510,24 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu)
 | 
			
		||||
 		mtu = ALIGN(MVPP2_RX_PKT_SIZE(mtu), 8);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	if (!netif_running(dev)) {
 | 
			
		||||
-		err = mvpp2_bm_update_mtu(dev, mtu);
 | 
			
		||||
-		if (!err) {
 | 
			
		||||
-			port->pkt_size =  MVPP2_RX_PKT_SIZE(mtu);
 | 
			
		||||
-			return 0;
 | 
			
		||||
-		}
 | 
			
		||||
-
 | 
			
		||||
-		/* Reconfigure BM to the original MTU */
 | 
			
		||||
-		err = mvpp2_bm_update_mtu(dev, dev->mtu);
 | 
			
		||||
-		if (err)
 | 
			
		||||
-			goto log_error;
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
-	mvpp2_stop_dev(port);
 | 
			
		||||
+	if (running)
 | 
			
		||||
+		mvpp2_stop_dev(port);
 | 
			
		||||
 
 | 
			
		||||
 	err = mvpp2_bm_update_mtu(dev, mtu);
 | 
			
		||||
-	if (!err) {
 | 
			
		||||
+	if (err) {
 | 
			
		||||
+		netdev_err(dev, "failed to change MTU\n");
 | 
			
		||||
+		/* Reconfigure BM to the original MTU */
 | 
			
		||||
+		mvpp2_bm_update_mtu(dev, dev->mtu);
 | 
			
		||||
+	} else {
 | 
			
		||||
 		port->pkt_size =  MVPP2_RX_PKT_SIZE(mtu);
 | 
			
		||||
-		goto out_start;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	/* Reconfigure BM to the original MTU */
 | 
			
		||||
-	err = mvpp2_bm_update_mtu(dev, dev->mtu);
 | 
			
		||||
-	if (err)
 | 
			
		||||
-		goto log_error;
 | 
			
		||||
-
 | 
			
		||||
-out_start:
 | 
			
		||||
-	mvpp2_start_dev(port);
 | 
			
		||||
-	mvpp2_egress_enable(port);
 | 
			
		||||
-	mvpp2_ingress_enable(port);
 | 
			
		||||
+	if (running) {
 | 
			
		||||
+		mvpp2_start_dev(port);
 | 
			
		||||
+		mvpp2_egress_enable(port);
 | 
			
		||||
+		mvpp2_ingress_enable(port);
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
-	return 0;
 | 
			
		||||
-log_error:
 | 
			
		||||
-	netdev_err(dev, "failed to change MTU\n");
 | 
			
		||||
 	return err;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,47 +0,0 @@
 | 
			
		|||
From 639239be11ad95fab3266577e8d1efa1e8ec9672 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
 | 
			
		||||
Date: Mon, 29 Jul 2019 12:28:41 +0300
 | 
			
		||||
Subject: [PATCH 788/826] net: bridge: delete local fdb on device init failure
 | 
			
		||||
 | 
			
		||||
[ Upstream commit d7bae09fa008c6c9a489580db0a5a12063b97f97 ]
 | 
			
		||||
 | 
			
		||||
On initialization failure we have to delete the local fdb which was
 | 
			
		||||
inserted due to the default pvid creation. This problem has been present
 | 
			
		||||
since the inception of default_pvid. Note that currently there are 2 cases:
 | 
			
		||||
1) in br_dev_init() when br_multicast_init() fails
 | 
			
		||||
2) if register_netdevice() fails after calling ndo_init()
 | 
			
		||||
 | 
			
		||||
This patch takes care of both since br_vlan_flush() is called on both
 | 
			
		||||
occasions. Also the new fdb delete would be a no-op on normal bridge
 | 
			
		||||
device destruction since the local fdb would've been already flushed by
 | 
			
		||||
br_dev_delete(). This is not an issue for ports since nbp_vlan_init() is
 | 
			
		||||
called last when adding a port thus nothing can fail after it.
 | 
			
		||||
 | 
			
		||||
Reported-by: syzbot+88533dc8b582309bf3ee@syzkaller.appspotmail.com
 | 
			
		||||
Fixes: 5be5a2df40f0 ("bridge: Add filtering support for default_pvid")
 | 
			
		||||
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/bridge/br_vlan.c | 5 +++++
 | 
			
		||||
 1 file changed, 5 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
 | 
			
		||||
index 7df269092103..5f3950f00f73 100644
 | 
			
		||||
--- a/net/bridge/br_vlan.c
 | 
			
		||||
+++ b/net/bridge/br_vlan.c
 | 
			
		||||
@@ -677,6 +677,11 @@ void br_vlan_flush(struct net_bridge *br)
 | 
			
		||||
 
 | 
			
		||||
 	ASSERT_RTNL();
 | 
			
		||||
 
 | 
			
		||||
+	/* delete auto-added default pvid local fdb before flushing vlans
 | 
			
		||||
+	 * otherwise it will be leaked on bridge device init failure
 | 
			
		||||
+	 */
 | 
			
		||||
+	br_fdb_delete_by_port(br, NULL, 0, 1);
 | 
			
		||||
+
 | 
			
		||||
 	vg = br_vlan_group(br);
 | 
			
		||||
 	__vlan_flush(vg);
 | 
			
		||||
 	RCU_INIT_POINTER(br->vlgrp, NULL);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,62 +0,0 @@
 | 
			
		|||
From a19d4e34f092fdb74e39de0193627f16a38997b8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
 | 
			
		||||
Date: Tue, 30 Jul 2019 14:21:00 +0300
 | 
			
		||||
Subject: [PATCH 789/826] net: bridge: mcast: don't delete permanent entries
 | 
			
		||||
 when fast leave is enabled
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 5c725b6b65067909548ac9ca9bc777098ec9883d ]
 | 
			
		||||
 | 
			
		||||
When permanent entries were introduced by the commit below, they were
 | 
			
		||||
exempt from timing out and thus igmp leave wouldn't affect them unless
 | 
			
		||||
fast leave was enabled on the port which was added before permanent
 | 
			
		||||
entries existed. It shouldn't matter if fast leave is enabled or not
 | 
			
		||||
if the user added a permanent entry it shouldn't be deleted on igmp
 | 
			
		||||
leave.
 | 
			
		||||
 | 
			
		||||
Before:
 | 
			
		||||
$ echo 1 > /sys/class/net/eth4/brport/multicast_fast_leave
 | 
			
		||||
$ bridge mdb add dev br0 port eth4 grp 229.1.1.1 permanent
 | 
			
		||||
$ bridge mdb show
 | 
			
		||||
dev br0 port eth4 grp 229.1.1.1 permanent
 | 
			
		||||
 | 
			
		||||
< join and leave 229.1.1.1 on eth4 >
 | 
			
		||||
 | 
			
		||||
$ bridge mdb show
 | 
			
		||||
$
 | 
			
		||||
 | 
			
		||||
After:
 | 
			
		||||
$ echo 1 > /sys/class/net/eth4/brport/multicast_fast_leave
 | 
			
		||||
$ bridge mdb add dev br0 port eth4 grp 229.1.1.1 permanent
 | 
			
		||||
$ bridge mdb show
 | 
			
		||||
dev br0 port eth4 grp 229.1.1.1 permanent
 | 
			
		||||
 | 
			
		||||
< join and leave 229.1.1.1 on eth4 >
 | 
			
		||||
 | 
			
		||||
$ bridge mdb show
 | 
			
		||||
dev br0 port eth4 grp 229.1.1.1 permanent
 | 
			
		||||
 | 
			
		||||
Fixes: ccb1c31a7a87 ("bridge: add flags to distinguish permanent mdb entires")
 | 
			
		||||
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/bridge/br_multicast.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
 | 
			
		||||
index fb54d32321ec..6a362da211e1 100644
 | 
			
		||||
--- a/net/bridge/br_multicast.c
 | 
			
		||||
+++ b/net/bridge/br_multicast.c
 | 
			
		||||
@@ -1621,6 +1621,9 @@ br_multicast_leave_group(struct net_bridge *br,
 | 
			
		||||
 			if (!br_port_group_equal(p, port, src))
 | 
			
		||||
 				continue;
 | 
			
		||||
 
 | 
			
		||||
+			if (p->flags & MDB_PG_FLAGS_PERMANENT)
 | 
			
		||||
+				break;
 | 
			
		||||
+
 | 
			
		||||
 			rcu_assign_pointer(*pp, p->next);
 | 
			
		||||
 			hlist_del_init(&p->mglist);
 | 
			
		||||
 			del_timer(&p->timer);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,135 +0,0 @@
 | 
			
		|||
From edb7ad69c439cdb960d9f519233d8d9771e329b5 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
Date: Sun, 28 Jul 2019 14:56:36 +0200
 | 
			
		||||
Subject: [PATCH 790/826] net: fix ifindex collision during namespace removal
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 55b40dbf0e76b4bfb9d8b3a16a0208640a9a45df ]
 | 
			
		||||
 | 
			
		||||
Commit aca51397d014 ("netns: Fix arbitrary net_device-s corruptions
 | 
			
		||||
on net_ns stop.") introduced a possibility to hit a BUG in case device
 | 
			
		||||
is returning back to init_net and two following conditions are met:
 | 
			
		||||
1) dev->ifindex value is used in a name of another "dev%d"
 | 
			
		||||
   device in init_net.
 | 
			
		||||
2) dev->name is used by another device in init_net.
 | 
			
		||||
 | 
			
		||||
Under real life circumstances this is hard to get. Therefore this has
 | 
			
		||||
been present happily for over 10 years. To reproduce:
 | 
			
		||||
 | 
			
		||||
$ ip a
 | 
			
		||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 | 
			
		||||
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 | 
			
		||||
    inet 127.0.0.1/8 scope host lo
 | 
			
		||||
       valid_lft forever preferred_lft forever
 | 
			
		||||
    inet6 ::1/128 scope host
 | 
			
		||||
       valid_lft forever preferred_lft forever
 | 
			
		||||
2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether 86:89:3f:86:61:29 brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
3: enp0s2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
$ ip netns add ns1
 | 
			
		||||
$ ip -n ns1 link add dummy1ns1 type dummy
 | 
			
		||||
$ ip -n ns1 link add dummy2ns1 type dummy
 | 
			
		||||
$ ip link set enp0s2 netns ns1
 | 
			
		||||
$ ip -n ns1 link set enp0s2 name dummy0
 | 
			
		||||
[  100.858894] virtio_net virtio0 dummy0: renamed from enp0s2
 | 
			
		||||
$ ip link add dev4 type dummy
 | 
			
		||||
$ ip -n ns1 a
 | 
			
		||||
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 | 
			
		||||
2: dummy1ns1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether 16:63:4c:38:3e:ff brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
3: dummy2ns1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether aa:9e:86:dd:6b:5d brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
4: dummy0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
$ ip a
 | 
			
		||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 | 
			
		||||
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 | 
			
		||||
    inet 127.0.0.1/8 scope host lo
 | 
			
		||||
       valid_lft forever preferred_lft forever
 | 
			
		||||
    inet6 ::1/128 scope host
 | 
			
		||||
       valid_lft forever preferred_lft forever
 | 
			
		||||
2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether 86:89:3f:86:61:29 brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
4: dev4: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
 | 
			
		||||
    link/ether 5a:e1:4a:b6:ec:f8 brd ff:ff:ff:ff:ff:ff
 | 
			
		||||
$ ip netns del ns1
 | 
			
		||||
[  158.717795] default_device_exit: failed to move dummy0 to init_net: -17
 | 
			
		||||
[  158.719316] ------------[ cut here ]------------
 | 
			
		||||
[  158.720591] kernel BUG at net/core/dev.c:9824!
 | 
			
		||||
[  158.722260] invalid opcode: 0000 [#1] SMP KASAN PTI
 | 
			
		||||
[  158.723728] CPU: 0 PID: 56 Comm: kworker/u2:1 Not tainted 5.3.0-rc1+ #18
 | 
			
		||||
[  158.725422] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014
 | 
			
		||||
[  158.727508] Workqueue: netns cleanup_net
 | 
			
		||||
[  158.728915] RIP: 0010:default_device_exit.cold+0x1d/0x1f
 | 
			
		||||
[  158.730683] Code: 84 e8 18 c9 3e fe 0f 0b e9 70 90 ff ff e8 36 e4 52 fe 89 d9 4c 89 e2 48 c7 c6 80 d6 25 84 48 c7 c7 20 c0 25 84 e8 f4 c8 3e
 | 
			
		||||
[  158.736854] RSP: 0018:ffff8880347e7b90 EFLAGS: 00010282
 | 
			
		||||
[  158.738752] RAX: 000000000000003b RBX: 00000000ffffffef RCX: 0000000000000000
 | 
			
		||||
[  158.741369] RDX: 0000000000000000 RSI: ffffffff8128013d RDI: ffffed10068fcf64
 | 
			
		||||
[  158.743418] RBP: ffff888033550170 R08: 000000000000003b R09: fffffbfff0b94b9c
 | 
			
		||||
[  158.745626] R10: fffffbfff0b94b9b R11: ffffffff85ca5cdf R12: ffff888032f28000
 | 
			
		||||
[  158.748405] R13: dffffc0000000000 R14: ffff8880335501b8 R15: 1ffff110068fcf72
 | 
			
		||||
[  158.750638] FS:  0000000000000000(0000) GS:ffff888036000000(0000) knlGS:0000000000000000
 | 
			
		||||
[  158.752944] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 | 
			
		||||
[  158.755245] CR2: 00007fe8b45d21d0 CR3: 00000000340b4005 CR4: 0000000000360ef0
 | 
			
		||||
[  158.757654] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 | 
			
		||||
[  158.760012] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
 | 
			
		||||
[  158.762758] Call Trace:
 | 
			
		||||
[  158.763882]  ? dev_change_net_namespace+0xbb0/0xbb0
 | 
			
		||||
[  158.766148]  ? devlink_nl_cmd_set_doit+0x520/0x520
 | 
			
		||||
[  158.768034]  ? dev_change_net_namespace+0xbb0/0xbb0
 | 
			
		||||
[  158.769870]  ops_exit_list.isra.0+0xa8/0x150
 | 
			
		||||
[  158.771544]  cleanup_net+0x446/0x8f0
 | 
			
		||||
[  158.772945]  ? unregister_pernet_operations+0x4a0/0x4a0
 | 
			
		||||
[  158.775294]  process_one_work+0xa1a/0x1740
 | 
			
		||||
[  158.776896]  ? pwq_dec_nr_in_flight+0x310/0x310
 | 
			
		||||
[  158.779143]  ? do_raw_spin_lock+0x11b/0x280
 | 
			
		||||
[  158.780848]  worker_thread+0x9e/0x1060
 | 
			
		||||
[  158.782500]  ? process_one_work+0x1740/0x1740
 | 
			
		||||
[  158.784454]  kthread+0x31b/0x420
 | 
			
		||||
[  158.786082]  ? __kthread_create_on_node+0x3f0/0x3f0
 | 
			
		||||
[  158.788286]  ret_from_fork+0x3a/0x50
 | 
			
		||||
[  158.789871] ---[ end trace defd6c657c71f936 ]---
 | 
			
		||||
[  158.792273] RIP: 0010:default_device_exit.cold+0x1d/0x1f
 | 
			
		||||
[  158.795478] Code: 84 e8 18 c9 3e fe 0f 0b e9 70 90 ff ff e8 36 e4 52 fe 89 d9 4c 89 e2 48 c7 c6 80 d6 25 84 48 c7 c7 20 c0 25 84 e8 f4 c8 3e
 | 
			
		||||
[  158.804854] RSP: 0018:ffff8880347e7b90 EFLAGS: 00010282
 | 
			
		||||
[  158.807865] RAX: 000000000000003b RBX: 00000000ffffffef RCX: 0000000000000000
 | 
			
		||||
[  158.811794] RDX: 0000000000000000 RSI: ffffffff8128013d RDI: ffffed10068fcf64
 | 
			
		||||
[  158.816652] RBP: ffff888033550170 R08: 000000000000003b R09: fffffbfff0b94b9c
 | 
			
		||||
[  158.820930] R10: fffffbfff0b94b9b R11: ffffffff85ca5cdf R12: ffff888032f28000
 | 
			
		||||
[  158.825113] R13: dffffc0000000000 R14: ffff8880335501b8 R15: 1ffff110068fcf72
 | 
			
		||||
[  158.829899] FS:  0000000000000000(0000) GS:ffff888036000000(0000) knlGS:0000000000000000
 | 
			
		||||
[  158.834923] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 | 
			
		||||
[  158.838164] CR2: 00007fe8b45d21d0 CR3: 00000000340b4005 CR4: 0000000000360ef0
 | 
			
		||||
[  158.841917] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 | 
			
		||||
[  158.845149] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
 | 
			
		||||
 | 
			
		||||
Fix this by checking if a device with the same name exists in init_net
 | 
			
		||||
and fallback to original code - dev%d to allocate name - in case it does.
 | 
			
		||||
 | 
			
		||||
This was found using syzkaller.
 | 
			
		||||
 | 
			
		||||
Fixes: aca51397d014 ("netns: Fix arbitrary net_device-s corruptions on net_ns stop.")
 | 
			
		||||
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/core/dev.c | 2 ++
 | 
			
		||||
 1 file changed, 2 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/core/dev.c b/net/core/dev.c
 | 
			
		||||
index 138951d28643..e4b4cb40da00 100644
 | 
			
		||||
--- a/net/core/dev.c
 | 
			
		||||
+++ b/net/core/dev.c
 | 
			
		||||
@@ -9510,6 +9510,8 @@ static void __net_exit default_device_exit(struct net *net)
 | 
			
		||||
 
 | 
			
		||||
 		/* Push remaining network devices to init_net */
 | 
			
		||||
 		snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
 | 
			
		||||
+		if (__dev_get_by_name(&init_net, fb_name))
 | 
			
		||||
+			snprintf(fb_name, IFNAMSIZ, "dev%%d");
 | 
			
		||||
 		err = dev_change_net_namespace(dev, &init_net, fb_name);
 | 
			
		||||
 		if (err) {
 | 
			
		||||
 			pr_emerg("%s: failed to move %s to init_net: %d\n",
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,81 +0,0 @@
 | 
			
		|||
From 858f82c63667281719805a1b03a1405f14ac0269 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Qian Cai <cai@lca.pw>
 | 
			
		||||
Date: Thu, 1 Aug 2019 09:52:54 -0400
 | 
			
		||||
Subject: [PATCH 791/826] net/mlx5e: always initialize frag->last_in_page
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 60d60c8fbd8d1acf25b041ecd72ae4fa16e9405b ]
 | 
			
		||||
 | 
			
		||||
The commit 069d11465a80 ("net/mlx5e: RX, Enhance legacy Receive Queue
 | 
			
		||||
memory scheme") introduced an undefined behaviour below due to
 | 
			
		||||
"frag->last_in_page" is only initialized in mlx5e_init_frags_partition()
 | 
			
		||||
when,
 | 
			
		||||
 | 
			
		||||
if (next_frag.offset + frag_info[f].frag_stride > PAGE_SIZE)
 | 
			
		||||
 | 
			
		||||
or after bailed out the loop,
 | 
			
		||||
 | 
			
		||||
for (i = 0; i < mlx5_wq_cyc_get_size(&rq->wqe.wq); i++)
 | 
			
		||||
 | 
			
		||||
As the result, there could be some "frag" have uninitialized
 | 
			
		||||
value of "last_in_page".
 | 
			
		||||
 | 
			
		||||
Later, get_frag() obtains those "frag" and check "frag->last_in_page" in
 | 
			
		||||
mlx5e_put_rx_frag() and triggers the error during boot. Fix it by always
 | 
			
		||||
initializing "frag->last_in_page" to "false" in
 | 
			
		||||
mlx5e_init_frags_partition().
 | 
			
		||||
 | 
			
		||||
UBSAN: Undefined behaviour in
 | 
			
		||||
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c:325:12
 | 
			
		||||
load of value 170 is not a valid value for type 'bool' (aka '_Bool')
 | 
			
		||||
Call trace:
 | 
			
		||||
 dump_backtrace+0x0/0x264
 | 
			
		||||
 show_stack+0x20/0x2c
 | 
			
		||||
 dump_stack+0xb0/0x104
 | 
			
		||||
 __ubsan_handle_load_invalid_value+0x104/0x128
 | 
			
		||||
 mlx5e_handle_rx_cqe+0x8e8/0x12cc [mlx5_core]
 | 
			
		||||
 mlx5e_poll_rx_cq+0xca8/0x1a94 [mlx5_core]
 | 
			
		||||
 mlx5e_napi_poll+0x17c/0xa30 [mlx5_core]
 | 
			
		||||
 net_rx_action+0x248/0x940
 | 
			
		||||
 __do_softirq+0x350/0x7b8
 | 
			
		||||
 irq_exit+0x200/0x26c
 | 
			
		||||
 __handle_domain_irq+0xc8/0x128
 | 
			
		||||
 gic_handle_irq+0x138/0x228
 | 
			
		||||
 el1_irq+0xb8/0x140
 | 
			
		||||
 arch_cpu_idle+0x1a4/0x348
 | 
			
		||||
 do_idle+0x114/0x1b0
 | 
			
		||||
 cpu_startup_entry+0x24/0x28
 | 
			
		||||
 rest_init+0x1ac/0x1dc
 | 
			
		||||
 arch_call_rest_init+0x10/0x18
 | 
			
		||||
 start_kernel+0x4d4/0x57c
 | 
			
		||||
 | 
			
		||||
Fixes: 069d11465a80 ("net/mlx5e: RX, Enhance legacy Receive Queue memory scheme")
 | 
			
		||||
Signed-off-by: Qian Cai <cai@lca.pw>
 | 
			
		||||
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 5 ++---
 | 
			
		||||
 1 file changed, 2 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
 | 
			
		||||
index 0f1c296c3ce4..83ab2c0e6b61 100644
 | 
			
		||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
 | 
			
		||||
@@ -420,12 +420,11 @@ static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix)
 | 
			
		||||
 
 | 
			
		||||
 static void mlx5e_init_frags_partition(struct mlx5e_rq *rq)
 | 
			
		||||
 {
 | 
			
		||||
-	struct mlx5e_wqe_frag_info next_frag, *prev;
 | 
			
		||||
+	struct mlx5e_wqe_frag_info next_frag = {};
 | 
			
		||||
+	struct mlx5e_wqe_frag_info *prev = NULL;
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
 	next_frag.di = &rq->wqe.di[0];
 | 
			
		||||
-	next_frag.offset = 0;
 | 
			
		||||
-	prev = NULL;
 | 
			
		||||
 
 | 
			
		||||
 	for (i = 0; i < mlx5_wq_cyc_get_size(&rq->wqe.wq); i++) {
 | 
			
		||||
 		struct mlx5e_rq_frag_info *frag_info = &rq->wqe.info.arr[0];
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,46 +0,0 @@
 | 
			
		|||
From 4dddd08b571d73e9acb87b4b7fff763ba3e6d6cd Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mark Zhang <markz@mellanox.com>
 | 
			
		||||
Date: Tue, 9 Jul 2019 05:37:12 +0300
 | 
			
		||||
Subject: [PATCH 792/826] net/mlx5: Use reversed order when unregister devices
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 08aa5e7da6bce1a1963f63cf32c2e7ad434ad578 ]
 | 
			
		||||
 | 
			
		||||
When lag is active, which is controlled by the bonded mlx5e netdev, mlx5
 | 
			
		||||
interface unregestering must happen in the reverse order where rdma is
 | 
			
		||||
unregistered (unloaded) first, to guarantee all references to the lag
 | 
			
		||||
context in hardware is removed, then remove mlx5e netdev interface which
 | 
			
		||||
will cleanup the lag context from hardware.
 | 
			
		||||
 | 
			
		||||
Without this fix during destroy of LAG interface, we observed following
 | 
			
		||||
errors:
 | 
			
		||||
 * mlx5_cmd_check:752:(pid 12556): DESTROY_LAG(0x843) op_mod(0x0) failed,
 | 
			
		||||
   status bad parameter(0x3), syndrome (0xe4ac33)
 | 
			
		||||
 * mlx5_cmd_check:752:(pid 12556): DESTROY_LAG(0x843) op_mod(0x0) failed,
 | 
			
		||||
   status bad parameter(0x3), syndrome (0xa5aee8).
 | 
			
		||||
 | 
			
		||||
Fixes: a31208b1e11d ("net/mlx5_core: New init and exit flow for mlx5_core")
 | 
			
		||||
Reviewed-by: Parav Pandit <parav@mellanox.com>
 | 
			
		||||
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
 | 
			
		||||
Signed-off-by: Mark Zhang <markz@mellanox.com>
 | 
			
		||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/mellanox/mlx5/core/dev.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
 | 
			
		||||
index 1c225be9c7db..3692d6a1cce8 100644
 | 
			
		||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c
 | 
			
		||||
@@ -307,7 +307,7 @@ void mlx5_unregister_device(struct mlx5_core_dev *dev)
 | 
			
		||||
 	struct mlx5_interface *intf;
 | 
			
		||||
 
 | 
			
		||||
 	mutex_lock(&mlx5_intf_mutex);
 | 
			
		||||
-	list_for_each_entry(intf, &intf_list, list)
 | 
			
		||||
+	list_for_each_entry_reverse(intf, &intf_list, list)
 | 
			
		||||
 		mlx5_remove_device(intf, priv);
 | 
			
		||||
 	list_del(&priv->dev_list);
 | 
			
		||||
 	mutex_unlock(&mlx5_intf_mutex);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,60 +0,0 @@
 | 
			
		|||
From c8b05980c4bf7abfe9a016c34f8bf3bb5396cbfb Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
 | 
			
		||||
Date: Sat, 27 Jul 2019 11:40:11 +0200
 | 
			
		||||
Subject: [PATCH 793/826] net: phylink: Fix flow control for fixed-link
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 8aace4f3eba2a3ceb431e18683ea0e1ecbade5cd ]
 | 
			
		||||
 | 
			
		||||
In phylink_parse_fixedlink() the pl->link_config.advertising bits are AND
 | 
			
		||||
with pl->supported, pl->supported is zeroed and only the speed/duplex
 | 
			
		||||
modes and MII bits are set.
 | 
			
		||||
So pl->link_config.advertising always loses the flow control/pause bits.
 | 
			
		||||
 | 
			
		||||
By setting Pause and Asym_Pause bits in pl->supported, the flow control
 | 
			
		||||
work again when devicetree "pause" is set in fixes-link node and the MAC
 | 
			
		||||
advertise that is supports pause.
 | 
			
		||||
 | 
			
		||||
Results with this patch.
 | 
			
		||||
 | 
			
		||||
Legend:
 | 
			
		||||
- DT = 'Pause' is set in the fixed-link in devicetree.
 | 
			
		||||
- validate() = ‘Yes’ means phylink_set(mask, Pause) is set in the
 | 
			
		||||
  validate().
 | 
			
		||||
- flow = results reported my link is Up line.
 | 
			
		||||
 | 
			
		||||
+-----+------------+-------+
 | 
			
		||||
| DT  | validate() | flow  |
 | 
			
		||||
+-----+------------+-------+
 | 
			
		||||
| Yes | Yes        | rx/tx |
 | 
			
		||||
| No  | Yes        | off   |
 | 
			
		||||
| Yes | No         | off   |
 | 
			
		||||
+-----+------------+-------+
 | 
			
		||||
 | 
			
		||||
Fixes: 9525ae83959b ("phylink: add phylink infrastructure")
 | 
			
		||||
Signed-off-by: René van Dorst <opensource@vdorst.com>
 | 
			
		||||
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/phy/phylink.c | 2 ++
 | 
			
		||||
 1 file changed, 2 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
 | 
			
		||||
index e029c7977a56..2e8056d48f4a 100644
 | 
			
		||||
--- a/drivers/net/phy/phylink.c
 | 
			
		||||
+++ b/drivers/net/phy/phylink.c
 | 
			
		||||
@@ -226,6 +226,8 @@ static int phylink_parse_fixedlink(struct phylink *pl,
 | 
			
		||||
 			       __ETHTOOL_LINK_MODE_MASK_NBITS, true);
 | 
			
		||||
 	linkmode_zero(pl->supported);
 | 
			
		||||
 	phylink_set(pl->supported, MII);
 | 
			
		||||
+	phylink_set(pl->supported, Pause);
 | 
			
		||||
+	phylink_set(pl->supported, Asym_Pause);
 | 
			
		||||
 	if (s) {
 | 
			
		||||
 		__set_bit(s->bit, pl->supported);
 | 
			
		||||
 	} else {
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,92 +0,0 @@
 | 
			
		|||
From 44b96a38c2b5dd6e67039898201fdbcbaa4974ae Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
 | 
			
		||||
Date: Thu, 25 Jul 2019 12:07:12 -0600
 | 
			
		||||
Subject: [PATCH 794/826] net: qualcomm: rmnet: Fix incorrect UL checksum
 | 
			
		||||
 offload logic
 | 
			
		||||
 | 
			
		||||
[ Upstream commit a7cf3d24ee6081930feb4c830a7f6f16ebe31c49 ]
 | 
			
		||||
 | 
			
		||||
The udp_ip4_ind bit is set only for IPv4 UDP non-fragmented packets
 | 
			
		||||
so that the hardware can flip the checksum to 0xFFFF if the computed
 | 
			
		||||
checksum is 0 per RFC768.
 | 
			
		||||
 | 
			
		||||
However, this bit had to be set for IPv6 UDP non fragmented packets
 | 
			
		||||
as well per hardware requirements. Otherwise, IPv6 UDP packets
 | 
			
		||||
with computed checksum as 0 were transmitted by hardware and were
 | 
			
		||||
dropped in the network.
 | 
			
		||||
 | 
			
		||||
In addition to setting this bit for IPv6 UDP, the field is also
 | 
			
		||||
appropriately renamed to udp_ind as part of this change.
 | 
			
		||||
 | 
			
		||||
Fixes: 5eb5f8608ef1 ("net: qualcomm: rmnet: Add support for TX checksum offload")
 | 
			
		||||
Cc: Sean Tranchetti <stranche@codeaurora.org>
 | 
			
		||||
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h     |  2 +-
 | 
			
		||||
 .../net/ethernet/qualcomm/rmnet/rmnet_map_data.c    | 13 +++++++++----
 | 
			
		||||
 2 files changed, 10 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
 | 
			
		||||
index 884f1f52dcc2..70879a3ab567 100644
 | 
			
		||||
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
 | 
			
		||||
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map.h
 | 
			
		||||
@@ -59,7 +59,7 @@ struct rmnet_map_dl_csum_trailer {
 | 
			
		||||
 struct rmnet_map_ul_csum_header {
 | 
			
		||||
 	__be16 csum_start_offset;
 | 
			
		||||
 	u16 csum_insert_offset:14;
 | 
			
		||||
-	u16 udp_ip4_ind:1;
 | 
			
		||||
+	u16 udp_ind:1;
 | 
			
		||||
 	u16 csum_enabled:1;
 | 
			
		||||
 } __aligned(1);
 | 
			
		||||
 
 | 
			
		||||
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
 | 
			
		||||
index 57a9c314a665..b2090cedd2e9 100644
 | 
			
		||||
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
 | 
			
		||||
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c
 | 
			
		||||
@@ -215,9 +215,9 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr,
 | 
			
		||||
 	ul_header->csum_insert_offset = skb->csum_offset;
 | 
			
		||||
 	ul_header->csum_enabled = 1;
 | 
			
		||||
 	if (ip4h->protocol == IPPROTO_UDP)
 | 
			
		||||
-		ul_header->udp_ip4_ind = 1;
 | 
			
		||||
+		ul_header->udp_ind = 1;
 | 
			
		||||
 	else
 | 
			
		||||
-		ul_header->udp_ip4_ind = 0;
 | 
			
		||||
+		ul_header->udp_ind = 0;
 | 
			
		||||
 
 | 
			
		||||
 	/* Changing remaining fields to network order */
 | 
			
		||||
 	hdr++;
 | 
			
		||||
@@ -248,6 +248,7 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr,
 | 
			
		||||
 			      struct rmnet_map_ul_csum_header *ul_header,
 | 
			
		||||
 			      struct sk_buff *skb)
 | 
			
		||||
 {
 | 
			
		||||
+	struct ipv6hdr *ip6h = (struct ipv6hdr *)ip6hdr;
 | 
			
		||||
 	__be16 *hdr = (__be16 *)ul_header, offset;
 | 
			
		||||
 
 | 
			
		||||
 	offset = htons((__force u16)(skb_transport_header(skb) -
 | 
			
		||||
@@ -255,7 +256,11 @@ rmnet_map_ipv6_ul_csum_header(void *ip6hdr,
 | 
			
		||||
 	ul_header->csum_start_offset = offset;
 | 
			
		||||
 	ul_header->csum_insert_offset = skb->csum_offset;
 | 
			
		||||
 	ul_header->csum_enabled = 1;
 | 
			
		||||
-	ul_header->udp_ip4_ind = 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (ip6h->nexthdr == IPPROTO_UDP)
 | 
			
		||||
+		ul_header->udp_ind = 1;
 | 
			
		||||
+	else
 | 
			
		||||
+		ul_header->udp_ind = 0;
 | 
			
		||||
 
 | 
			
		||||
 	/* Changing remaining fields to network order */
 | 
			
		||||
 	hdr++;
 | 
			
		||||
@@ -428,7 +433,7 @@ void rmnet_map_checksum_uplink_packet(struct sk_buff *skb,
 | 
			
		||||
 	ul_header->csum_start_offset = 0;
 | 
			
		||||
 	ul_header->csum_insert_offset = 0;
 | 
			
		||||
 	ul_header->csum_enabled = 0;
 | 
			
		||||
-	ul_header->udp_ip4_ind = 0;
 | 
			
		||||
+	ul_header->udp_ind = 0;
 | 
			
		||||
 
 | 
			
		||||
 	priv->stats.csum_sw++;
 | 
			
		||||
 }
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,51 +0,0 @@
 | 
			
		|||
From d82dc254b9670068fe8c2652553eb144cfa26399 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Jia-Ju Bai <baijiaju1990@gmail.com>
 | 
			
		||||
Date: Mon, 29 Jul 2019 16:24:33 +0800
 | 
			
		||||
Subject: [PATCH 795/826] net: sched: Fix a possible null-pointer dereference
 | 
			
		||||
 in dequeue_func()
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 051c7b39be4a91f6b7d8c4548444e4b850f1f56c ]
 | 
			
		||||
 | 
			
		||||
In dequeue_func(), there is an if statement on line 74 to check whether
 | 
			
		||||
skb is NULL:
 | 
			
		||||
    if (skb)
 | 
			
		||||
 | 
			
		||||
When skb is NULL, it is used on line 77:
 | 
			
		||||
    prefetch(&skb->end);
 | 
			
		||||
 | 
			
		||||
Thus, a possible null-pointer dereference may occur.
 | 
			
		||||
 | 
			
		||||
To fix this bug, skb->end is used when skb is not NULL.
 | 
			
		||||
 | 
			
		||||
This bug is found by a static analysis tool STCheck written by us.
 | 
			
		||||
 | 
			
		||||
Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM")
 | 
			
		||||
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
 | 
			
		||||
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/sched/sch_codel.c | 6 +++---
 | 
			
		||||
 1 file changed, 3 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
 | 
			
		||||
index 17cd81f84b5d..77fae0b7c6ee 100644
 | 
			
		||||
--- a/net/sched/sch_codel.c
 | 
			
		||||
+++ b/net/sched/sch_codel.c
 | 
			
		||||
@@ -71,10 +71,10 @@ static struct sk_buff *dequeue_func(struct codel_vars *vars, void *ctx)
 | 
			
		||||
 	struct Qdisc *sch = ctx;
 | 
			
		||||
 	struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
 | 
			
		||||
 
 | 
			
		||||
-	if (skb)
 | 
			
		||||
+	if (skb) {
 | 
			
		||||
 		sch->qstats.backlog -= qdisc_pkt_len(skb);
 | 
			
		||||
-
 | 
			
		||||
-	prefetch(&skb->end); /* we'll need skb_shinfo() */
 | 
			
		||||
+		prefetch(&skb->end); /* we'll need skb_shinfo() */
 | 
			
		||||
+	}
 | 
			
		||||
 	return skb;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
From cb20f74135df76ab386afa3bb1ad1af6b995f697 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Roman Mashak <mrv@mojatatu.com>
 | 
			
		||||
Date: Fri, 2 Aug 2019 15:16:46 -0400
 | 
			
		||||
Subject: [PATCH 796/826] net sched: update vlan action for batched events
 | 
			
		||||
 operations
 | 
			
		||||
 | 
			
		||||
[ Upstream commit b35475c5491a14c8ce7a5046ef7bcda8a860581a ]
 | 
			
		||||
 | 
			
		||||
Add get_fill_size() routine used to calculate the action size
 | 
			
		||||
when building a batch of events.
 | 
			
		||||
 | 
			
		||||
Fixes: c7e2b9689 ("sched: introduce vlan action")
 | 
			
		||||
Signed-off-by: Roman Mashak <mrv@mojatatu.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/sched/act_vlan.c | 9 +++++++++
 | 
			
		||||
 1 file changed, 9 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
 | 
			
		||||
index 033d273afe50..20a7d4dc381c 100644
 | 
			
		||||
--- a/net/sched/act_vlan.c
 | 
			
		||||
+++ b/net/sched/act_vlan.c
 | 
			
		||||
@@ -296,6 +296,14 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index,
 | 
			
		||||
 	return tcf_idr_search(tn, a, index);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static size_t tcf_vlan_get_fill_size(const struct tc_action *act)
 | 
			
		||||
+{
 | 
			
		||||
+	return nla_total_size(sizeof(struct tc_vlan))
 | 
			
		||||
+		+ nla_total_size(sizeof(u16)) /* TCA_VLAN_PUSH_VLAN_ID */
 | 
			
		||||
+		+ nla_total_size(sizeof(u16)) /* TCA_VLAN_PUSH_VLAN_PROTOCOL */
 | 
			
		||||
+		+ nla_total_size(sizeof(u8)); /* TCA_VLAN_PUSH_VLAN_PRIORITY */
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static struct tc_action_ops act_vlan_ops = {
 | 
			
		||||
 	.kind		=	"vlan",
 | 
			
		||||
 	.type		=	TCA_ACT_VLAN,
 | 
			
		||||
@@ -305,6 +313,7 @@ static struct tc_action_ops act_vlan_ops = {
 | 
			
		||||
 	.init		=	tcf_vlan_init,
 | 
			
		||||
 	.cleanup	=	tcf_vlan_cleanup,
 | 
			
		||||
 	.walk		=	tcf_vlan_walker,
 | 
			
		||||
+	.get_fill_size	=	tcf_vlan_get_fill_size,
 | 
			
		||||
 	.lookup		=	tcf_vlan_search,
 | 
			
		||||
 	.size		=	sizeof(struct tcf_vlan),
 | 
			
		||||
 };
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,638 +0,0 @@
 | 
			
		|||
From 51d240a144a5742977b4a421ea42b7da5bf1439c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dmytro Linkin <dmitrolin@mellanox.com>
 | 
			
		||||
Date: Thu, 1 Aug 2019 13:02:51 +0000
 | 
			
		||||
Subject: [PATCH 797/826] net: sched: use temporary variable for actions
 | 
			
		||||
 indexes
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 7be8ef2cdbfe41a2e524b7c6cc3f8e6cfaa906e4 ]
 | 
			
		||||
 | 
			
		||||
Currently init call of all actions (except ipt) init their 'parm'
 | 
			
		||||
structure as a direct pointer to nla data in skb. This leads to race
 | 
			
		||||
condition when some of the filter actions were initialized successfully
 | 
			
		||||
(and were assigned with idr action index that was written directly
 | 
			
		||||
into nla data), but then were deleted and retried (due to following
 | 
			
		||||
action module missing or classifier-initiated retry), in which case
 | 
			
		||||
action init code tries to insert action to idr with index that was
 | 
			
		||||
assigned on previous iteration. During retry the index can be reused
 | 
			
		||||
by another action that was inserted concurrently, which causes
 | 
			
		||||
unintended action sharing between filters.
 | 
			
		||||
To fix described race condition, save action idr index to temporary
 | 
			
		||||
stack-allocated variable instead on nla data.
 | 
			
		||||
 | 
			
		||||
Fixes: 0190c1d452a9 ("net: sched: atomically check-allocate action")
 | 
			
		||||
Signed-off-by: Dmytro Linkin <dmitrolin@mellanox.com>
 | 
			
		||||
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
 | 
			
		||||
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/sched/act_bpf.c        |  9 +++++----
 | 
			
		||||
 net/sched/act_connmark.c   |  9 +++++----
 | 
			
		||||
 net/sched/act_csum.c       |  9 +++++----
 | 
			
		||||
 net/sched/act_gact.c       |  8 +++++---
 | 
			
		||||
 net/sched/act_ife.c        |  8 +++++---
 | 
			
		||||
 net/sched/act_mirred.c     | 13 +++++++------
 | 
			
		||||
 net/sched/act_nat.c        |  9 +++++----
 | 
			
		||||
 net/sched/act_pedit.c      | 10 ++++++----
 | 
			
		||||
 net/sched/act_police.c     |  8 +++++---
 | 
			
		||||
 net/sched/act_sample.c     | 10 +++++-----
 | 
			
		||||
 net/sched/act_simple.c     | 10 ++++++----
 | 
			
		||||
 net/sched/act_skbedit.c    | 11 ++++++-----
 | 
			
		||||
 net/sched/act_skbmod.c     | 11 ++++++-----
 | 
			
		||||
 net/sched/act_tunnel_key.c |  8 +++++---
 | 
			
		||||
 net/sched/act_vlan.c       | 16 +++++++++-------
 | 
			
		||||
 15 files changed, 85 insertions(+), 64 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c
 | 
			
		||||
index 0c68bc9cf0b4..20fae5ca87fa 100644
 | 
			
		||||
--- a/net/sched/act_bpf.c
 | 
			
		||||
+++ b/net/sched/act_bpf.c
 | 
			
		||||
@@ -287,6 +287,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tcf_bpf *prog;
 | 
			
		||||
 	bool is_bpf, is_ebpf;
 | 
			
		||||
 	int ret, res = 0;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -299,13 +300,13 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_ACT_BPF_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	ret = tcf_idr_check_alloc(tn, &parm->index, act, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	ret = tcf_idr_check_alloc(tn, &index, act, bind);
 | 
			
		||||
 	if (!ret) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, act,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, act,
 | 
			
		||||
 				     &act_bpf_ops, bind, true);
 | 
			
		||||
 		if (ret < 0) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c
 | 
			
		||||
index 6f0f273f1139..605436747978 100644
 | 
			
		||||
--- a/net/sched/act_connmark.c
 | 
			
		||||
+++ b/net/sched/act_connmark.c
 | 
			
		||||
@@ -104,6 +104,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tcf_connmark_info *ci;
 | 
			
		||||
 	struct tc_connmark *parm;
 | 
			
		||||
 	int ret = 0;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -117,13 +118,13 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_CONNMARK_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	ret = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	ret = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (!ret) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_connmark_ops, bind, false);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c
 | 
			
		||||
index b8a67ae3105a..40437197e053 100644
 | 
			
		||||
--- a/net/sched/act_csum.c
 | 
			
		||||
+++ b/net/sched/act_csum.c
 | 
			
		||||
@@ -55,6 +55,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tc_csum *parm;
 | 
			
		||||
 	struct tcf_csum *p;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (nla == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -66,13 +67,13 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	if (tb[TCA_CSUM_PARMS] == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	parm = nla_data(tb[TCA_CSUM_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (!err) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_csum_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
 | 
			
		||||
index cd1d9bd32ef9..72d3347bdd41 100644
 | 
			
		||||
--- a/net/sched/act_gact.c
 | 
			
		||||
+++ b/net/sched/act_gact.c
 | 
			
		||||
@@ -64,6 +64,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tc_gact *parm;
 | 
			
		||||
 	struct tcf_gact *gact;
 | 
			
		||||
 	int ret = 0;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 	int err;
 | 
			
		||||
 #ifdef CONFIG_GACT_PROB
 | 
			
		||||
 	struct tc_gact_p *p_parm = NULL;
 | 
			
		||||
@@ -79,6 +80,7 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	if (tb[TCA_GACT_PARMS] == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	parm = nla_data(tb[TCA_GACT_PARMS]);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
 
 | 
			
		||||
 #ifndef CONFIG_GACT_PROB
 | 
			
		||||
 	if (tb[TCA_GACT_PROB] != NULL)
 | 
			
		||||
@@ -91,12 +93,12 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	}
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (!err) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_gact_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c
 | 
			
		||||
index 915b6e94da63..24047e0e5db0 100644
 | 
			
		||||
--- a/net/sched/act_ife.c
 | 
			
		||||
+++ b/net/sched/act_ife.c
 | 
			
		||||
@@ -482,6 +482,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	u8 *saddr = NULL;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
 	int ret = 0;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla) {
 | 
			
		||||
@@ -509,7 +510,8 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	if (!p)
 | 
			
		||||
 		return -ENOMEM;
 | 
			
		||||
 
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0) {
 | 
			
		||||
 		kfree(p);
 | 
			
		||||
 		return err;
 | 
			
		||||
@@ -521,10 +523,10 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a, &act_ife_ops,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a, &act_ife_ops,
 | 
			
		||||
 				     bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			kfree(p);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
 | 
			
		||||
index f767e78e38c9..548614bd9366 100644
 | 
			
		||||
--- a/net/sched/act_mirred.c
 | 
			
		||||
+++ b/net/sched/act_mirred.c
 | 
			
		||||
@@ -104,6 +104,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct net_device *dev;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
 	int ret, err;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla) {
 | 
			
		||||
 		NL_SET_ERR_MSG_MOD(extack, "Mirred requires attributes to be passed");
 | 
			
		||||
@@ -117,8 +118,8 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 	parm = nla_data(tb[TCA_MIRRED_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -135,21 +136,21 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		if (exists)
 | 
			
		||||
 			tcf_idr_release(*a, bind);
 | 
			
		||||
 		else
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 		NL_SET_ERR_MSG_MOD(extack, "Unknown mirred option");
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
 		if (!parm->ifindex) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			NL_SET_ERR_MSG_MOD(extack, "Specified device does not exist");
 | 
			
		||||
 			return -EINVAL;
 | 
			
		||||
 		}
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_mirred_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
 | 
			
		||||
index 4313aa102440..619828920b97 100644
 | 
			
		||||
--- a/net/sched/act_nat.c
 | 
			
		||||
+++ b/net/sched/act_nat.c
 | 
			
		||||
@@ -45,6 +45,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
 | 
			
		||||
 	struct tc_nat *parm;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
 	struct tcf_nat *p;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (nla == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -56,13 +57,13 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
 | 
			
		||||
 	if (tb[TCA_NAT_PARMS] == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	parm = nla_data(tb[TCA_NAT_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (!err) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_nat_ops, bind, false);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
 | 
			
		||||
index ca535a8585bc..82d258b2a75a 100644
 | 
			
		||||
--- a/net/sched/act_pedit.c
 | 
			
		||||
+++ b/net/sched/act_pedit.c
 | 
			
		||||
@@ -149,6 +149,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tcf_pedit *p;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
 	int ksize;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla) {
 | 
			
		||||
 		NL_SET_ERR_MSG_MOD(extack, "Pedit requires attributes to be passed");
 | 
			
		||||
@@ -178,18 +179,19 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	if (IS_ERR(keys_ex))
 | 
			
		||||
 		return PTR_ERR(keys_ex);
 | 
			
		||||
 
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (!err) {
 | 
			
		||||
 		if (!parm->nkeys) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			NL_SET_ERR_MSG_MOD(extack, "Pedit requires keys to be passed");
 | 
			
		||||
 			ret = -EINVAL;
 | 
			
		||||
 			goto out_free;
 | 
			
		||||
 		}
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_pedit_ops, bind, false);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			goto out_free;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
 | 
			
		||||
index 5d8bfa878477..997c34db1491 100644
 | 
			
		||||
--- a/net/sched/act_police.c
 | 
			
		||||
+++ b/net/sched/act_police.c
 | 
			
		||||
@@ -85,6 +85,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
 | 
			
		||||
 	struct tc_action_net *tn = net_generic(net, police_net_id);
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 	int size;
 | 
			
		||||
 
 | 
			
		||||
 	if (nla == NULL)
 | 
			
		||||
@@ -101,7 +102,8 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_POLICE_TBF]);
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -109,10 +111,10 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, NULL, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, NULL, a,
 | 
			
		||||
 				     &act_police_ops, bind, false);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c
 | 
			
		||||
index c7f5d630d97c..ac37654ca292 100644
 | 
			
		||||
--- a/net/sched/act_sample.c
 | 
			
		||||
+++ b/net/sched/act_sample.c
 | 
			
		||||
@@ -43,7 +43,7 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tc_action_net *tn = net_generic(net, sample_net_id);
 | 
			
		||||
 	struct nlattr *tb[TCA_SAMPLE_MAX + 1];
 | 
			
		||||
 	struct psample_group *psample_group;
 | 
			
		||||
-	u32 psample_group_num, rate;
 | 
			
		||||
+	u32 psample_group_num, rate, index;
 | 
			
		||||
 	struct tc_sample *parm;
 | 
			
		||||
 	struct tcf_sample *s;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
@@ -59,8 +59,8 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_SAMPLE_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -68,10 +68,10 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_sample_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 		ret = ACT_P_CREATED;
 | 
			
		||||
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
 | 
			
		||||
index 52400d49f81f..658efae71a09 100644
 | 
			
		||||
--- a/net/sched/act_simple.c
 | 
			
		||||
+++ b/net/sched/act_simple.c
 | 
			
		||||
@@ -88,6 +88,7 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct tcf_defact *d;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (nla == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -100,7 +101,8 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_DEF_PARMS]);
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -111,15 +113,15 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		if (exists)
 | 
			
		||||
 			tcf_idr_release(*a, bind);
 | 
			
		||||
 		else
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_simp_ops, bind, false);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
 | 
			
		||||
index 86d90fc5e97e..7709710a41f7 100644
 | 
			
		||||
--- a/net/sched/act_skbedit.c
 | 
			
		||||
+++ b/net/sched/act_skbedit.c
 | 
			
		||||
@@ -107,6 +107,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	u16 *queue_mapping = NULL, *ptype = NULL;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (nla == NULL)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -153,8 +154,8 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_SKBEDIT_PARMS]);
 | 
			
		||||
-
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -165,15 +166,15 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		if (exists)
 | 
			
		||||
 			tcf_idr_release(*a, bind);
 | 
			
		||||
 		else
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_skbedit_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
 | 
			
		||||
index 588077fafd6c..3038493d18ca 100644
 | 
			
		||||
--- a/net/sched/act_skbmod.c
 | 
			
		||||
+++ b/net/sched/act_skbmod.c
 | 
			
		||||
@@ -88,12 +88,12 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	struct nlattr *tb[TCA_SKBMOD_MAX + 1];
 | 
			
		||||
 	struct tcf_skbmod_params *p, *p_old;
 | 
			
		||||
 	struct tc_skbmod *parm;
 | 
			
		||||
+	u32 lflags = 0, index;
 | 
			
		||||
 	struct tcf_skbmod *d;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
 	u8 *daddr = NULL;
 | 
			
		||||
 	u8 *saddr = NULL;
 | 
			
		||||
 	u16 eth_type = 0;
 | 
			
		||||
-	u32 lflags = 0;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla)
 | 
			
		||||
@@ -122,10 +122,11 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_SKBMOD_PARMS]);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
 	if (parm->flags & SKBMOD_F_SWAPMAC)
 | 
			
		||||
 		lflags = SKBMOD_F_SWAPMAC;
 | 
			
		||||
 
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -136,15 +137,15 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		if (exists)
 | 
			
		||||
 			tcf_idr_release(*a, bind);
 | 
			
		||||
 		else
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_skbmod_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c
 | 
			
		||||
index 72d9c432e8b4..66bfe57e74ae 100644
 | 
			
		||||
--- a/net/sched/act_tunnel_key.c
 | 
			
		||||
+++ b/net/sched/act_tunnel_key.c
 | 
			
		||||
@@ -224,6 +224,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	__be16 flags;
 | 
			
		||||
 	u8 tos, ttl;
 | 
			
		||||
 	int ret = 0;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla) {
 | 
			
		||||
@@ -244,7 +245,8 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]);
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -338,7 +340,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_tunnel_key_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
 			NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
 | 
			
		||||
@@ -384,7 +386,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	if (exists)
 | 
			
		||||
 		tcf_idr_release(*a, bind);
 | 
			
		||||
 	else
 | 
			
		||||
-		tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+		tcf_idr_cleanup(tn, index);
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
 | 
			
		||||
index 20a7d4dc381c..da993edd2e40 100644
 | 
			
		||||
--- a/net/sched/act_vlan.c
 | 
			
		||||
+++ b/net/sched/act_vlan.c
 | 
			
		||||
@@ -118,6 +118,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	u8 push_prio = 0;
 | 
			
		||||
 	bool exists = false;
 | 
			
		||||
 	int ret = 0, err;
 | 
			
		||||
+	u32 index;
 | 
			
		||||
 
 | 
			
		||||
 	if (!nla)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
@@ -129,7 +130,8 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 	if (!tb[TCA_VLAN_PARMS])
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	parm = nla_data(tb[TCA_VLAN_PARMS]);
 | 
			
		||||
-	err = tcf_idr_check_alloc(tn, &parm->index, a, bind);
 | 
			
		||||
+	index = parm->index;
 | 
			
		||||
+	err = tcf_idr_check_alloc(tn, &index, a, bind);
 | 
			
		||||
 	if (err < 0)
 | 
			
		||||
 		return err;
 | 
			
		||||
 	exists = err;
 | 
			
		||||
@@ -145,7 +147,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 			if (exists)
 | 
			
		||||
 				tcf_idr_release(*a, bind);
 | 
			
		||||
 			else
 | 
			
		||||
-				tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+				tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return -EINVAL;
 | 
			
		||||
 		}
 | 
			
		||||
 		push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]);
 | 
			
		||||
@@ -153,7 +155,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 			if (exists)
 | 
			
		||||
 				tcf_idr_release(*a, bind);
 | 
			
		||||
 			else
 | 
			
		||||
-				tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+				tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return -ERANGE;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
@@ -167,7 +169,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 				if (exists)
 | 
			
		||||
 					tcf_idr_release(*a, bind);
 | 
			
		||||
 				else
 | 
			
		||||
-					tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+					tcf_idr_cleanup(tn, index);
 | 
			
		||||
 				return -EPROTONOSUPPORT;
 | 
			
		||||
 			}
 | 
			
		||||
 		} else {
 | 
			
		||||
@@ -181,16 +183,16 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla,
 | 
			
		||||
 		if (exists)
 | 
			
		||||
 			tcf_idr_release(*a, bind);
 | 
			
		||||
 		else
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 	action = parm->v_action;
 | 
			
		||||
 
 | 
			
		||||
 	if (!exists) {
 | 
			
		||||
-		ret = tcf_idr_create(tn, parm->index, est, a,
 | 
			
		||||
+		ret = tcf_idr_create(tn, index, est, a,
 | 
			
		||||
 				     &act_vlan_ops, bind, true);
 | 
			
		||||
 		if (ret) {
 | 
			
		||||
-			tcf_idr_cleanup(tn, parm->index);
 | 
			
		||||
+			tcf_idr_cleanup(tn, index);
 | 
			
		||||
 			return ret;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,50 +0,0 @@
 | 
			
		|||
From ce58a3655121936ebf353db542315e3531233113 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Ursula Braun <ubraun@linux.ibm.com>
 | 
			
		||||
Date: Fri, 2 Aug 2019 10:16:38 +0200
 | 
			
		||||
Subject: [PATCH 798/826] net/smc: do not schedule tx_work in SMC_CLOSED state
 | 
			
		||||
 | 
			
		||||
[ Upstream commit f9cedf1a9b1cdcfb0c52edb391d01771e43994a4 ]
 | 
			
		||||
 | 
			
		||||
The setsockopts options TCP_NODELAY and TCP_CORK may schedule the
 | 
			
		||||
tx worker. Make sure the socket is not yet moved into SMC_CLOSED
 | 
			
		||||
state (for instance by a shutdown SHUT_RDWR call).
 | 
			
		||||
 | 
			
		||||
Reported-by: syzbot+92209502e7aab127c75f@syzkaller.appspotmail.com
 | 
			
		||||
Reported-by: syzbot+b972214bb803a343f4fe@syzkaller.appspotmail.com
 | 
			
		||||
Fixes: 01d2f7e2cdd31 ("net/smc: sockopts TCP_NODELAY and TCP_CORK")
 | 
			
		||||
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
 | 
			
		||||
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/smc/af_smc.c | 8 ++++++--
 | 
			
		||||
 1 file changed, 6 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
 | 
			
		||||
index 9bbab6ba2dab..26dcd02b2d0c 100644
 | 
			
		||||
--- a/net/smc/af_smc.c
 | 
			
		||||
+++ b/net/smc/af_smc.c
 | 
			
		||||
@@ -1680,14 +1680,18 @@ static int smc_setsockopt(struct socket *sock, int level, int optname,
 | 
			
		||||
 		}
 | 
			
		||||
 		break;
 | 
			
		||||
 	case TCP_NODELAY:
 | 
			
		||||
-		if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) {
 | 
			
		||||
+		if (sk->sk_state != SMC_INIT &&
 | 
			
		||||
+		    sk->sk_state != SMC_LISTEN &&
 | 
			
		||||
+		    sk->sk_state != SMC_CLOSED) {
 | 
			
		||||
 			if (val && !smc->use_fallback)
 | 
			
		||||
 				mod_delayed_work(system_wq, &smc->conn.tx_work,
 | 
			
		||||
 						 0);
 | 
			
		||||
 		}
 | 
			
		||||
 		break;
 | 
			
		||||
 	case TCP_CORK:
 | 
			
		||||
-		if (sk->sk_state != SMC_INIT && sk->sk_state != SMC_LISTEN) {
 | 
			
		||||
+		if (sk->sk_state != SMC_INIT &&
 | 
			
		||||
+		    sk->sk_state != SMC_LISTEN &&
 | 
			
		||||
+		    sk->sk_state != SMC_CLOSED) {
 | 
			
		||||
 			if (!val && !smc->use_fallback)
 | 
			
		||||
 				mod_delayed_work(system_wq, &smc->conn.tx_work,
 | 
			
		||||
 						 0);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,84 +0,0 @@
 | 
			
		|||
From cd7f02fecac188f3363ef1d420b284c2239947e0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Johan Hovold <johan@kernel.org>
 | 
			
		||||
Date: Mon, 5 Aug 2019 12:00:55 +0200
 | 
			
		||||
Subject: [PATCH 799/826] NFC: nfcmrvl: fix gpio-handling regression
 | 
			
		||||
 | 
			
		||||
[ Upstream commit c3953a3c2d3175d2f9f0304c9a1ba89e7743c5e4 ]
 | 
			
		||||
 | 
			
		||||
Fix two reset-gpio sanity checks which were never converted to use
 | 
			
		||||
gpio_is_valid(), and make sure to use -EINVAL to indicate a missing
 | 
			
		||||
reset line also for the UART-driver module parameter and for the USB
 | 
			
		||||
driver.
 | 
			
		||||
 | 
			
		||||
This specifically prevents the UART and USB drivers from incidentally
 | 
			
		||||
trying to request and use gpio 0, and also avoids triggering a WARN() in
 | 
			
		||||
gpio_to_desc() during probe when no valid reset line has been specified.
 | 
			
		||||
 | 
			
		||||
Fixes: e33a3f84f88f ("NFC: nfcmrvl: allow gpio 0 for reset signalling")
 | 
			
		||||
Reported-by: syzbot+cf35b76f35e068a1107f@syzkaller.appspotmail.com
 | 
			
		||||
Tested-by: syzbot+cf35b76f35e068a1107f@syzkaller.appspotmail.com
 | 
			
		||||
Signed-off-by: Johan Hovold <johan@kernel.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nfc/nfcmrvl/main.c | 4 ++--
 | 
			
		||||
 drivers/nfc/nfcmrvl/uart.c | 4 ++--
 | 
			
		||||
 drivers/nfc/nfcmrvl/usb.c  | 1 +
 | 
			
		||||
 3 files changed, 5 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
 | 
			
		||||
index e65d027b91fa..529be35ac178 100644
 | 
			
		||||
--- a/drivers/nfc/nfcmrvl/main.c
 | 
			
		||||
+++ b/drivers/nfc/nfcmrvl/main.c
 | 
			
		||||
@@ -244,7 +244,7 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
 | 
			
		||||
 	/* Reset possible fault of previous session */
 | 
			
		||||
 	clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
 | 
			
		||||
 
 | 
			
		||||
-	if (priv->config.reset_n_io) {
 | 
			
		||||
+	if (gpio_is_valid(priv->config.reset_n_io)) {
 | 
			
		||||
 		nfc_info(priv->dev, "reset the chip\n");
 | 
			
		||||
 		gpio_set_value(priv->config.reset_n_io, 0);
 | 
			
		||||
 		usleep_range(5000, 10000);
 | 
			
		||||
@@ -255,7 +255,7 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
 | 
			
		||||
 
 | 
			
		||||
 void nfcmrvl_chip_halt(struct nfcmrvl_private *priv)
 | 
			
		||||
 {
 | 
			
		||||
-	if (priv->config.reset_n_io)
 | 
			
		||||
+	if (gpio_is_valid(priv->config.reset_n_io))
 | 
			
		||||
 		gpio_set_value(priv->config.reset_n_io, 0);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
 | 
			
		||||
index 9a22056e8d9e..e5a622ce4b95 100644
 | 
			
		||||
--- a/drivers/nfc/nfcmrvl/uart.c
 | 
			
		||||
+++ b/drivers/nfc/nfcmrvl/uart.c
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 static unsigned int hci_muxed;
 | 
			
		||||
 static unsigned int flow_control;
 | 
			
		||||
 static unsigned int break_control;
 | 
			
		||||
-static unsigned int reset_n_io;
 | 
			
		||||
+static int reset_n_io = -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
 ** NFCMRVL NCI OPS
 | 
			
		||||
@@ -231,5 +231,5 @@ MODULE_PARM_DESC(break_control, "Tell if UART driver must drive break signal.");
 | 
			
		||||
 module_param(hci_muxed, uint, 0);
 | 
			
		||||
 MODULE_PARM_DESC(hci_muxed, "Tell if transport is muxed in HCI one.");
 | 
			
		||||
 
 | 
			
		||||
-module_param(reset_n_io, uint, 0);
 | 
			
		||||
+module_param(reset_n_io, int, 0);
 | 
			
		||||
 MODULE_PARM_DESC(reset_n_io, "GPIO that is wired to RESET_N signal.");
 | 
			
		||||
diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c
 | 
			
		||||
index 945cc903d8f1..888e298f610b 100644
 | 
			
		||||
--- a/drivers/nfc/nfcmrvl/usb.c
 | 
			
		||||
+++ b/drivers/nfc/nfcmrvl/usb.c
 | 
			
		||||
@@ -305,6 +305,7 @@ static int nfcmrvl_probe(struct usb_interface *intf,
 | 
			
		||||
 
 | 
			
		||||
 	/* No configuration for USB */
 | 
			
		||||
 	memset(&config, 0, sizeof(config));
 | 
			
		||||
+	config.reset_n_io = -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	nfc_info(&udev->dev, "intf %p id %p\n", intf, id);
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
From eaa34bd4f7b5e505c6c211cb906f6a2ce2242e4c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Claudiu Manoil <claudiu.manoil@nxp.com>
 | 
			
		||||
Date: Thu, 25 Jul 2019 16:33:18 +0300
 | 
			
		||||
Subject: [PATCH 800/826] ocelot: Cancel delayed work before wq destruction
 | 
			
		||||
 | 
			
		||||
[ Upstream commit c5d139697d5d9ecf9c7cd92d7d7838a173508900 ]
 | 
			
		||||
 | 
			
		||||
Make sure the delayed work for stats update is not pending before
 | 
			
		||||
wq destruction.
 | 
			
		||||
This fixes the module unload path.
 | 
			
		||||
The issue is there since day 1.
 | 
			
		||||
 | 
			
		||||
Fixes: a556c76adc05 ("net: mscc: Add initial Ocelot switch support")
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
 | 
			
		||||
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/mscc/ocelot.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
 | 
			
		||||
index 10291198decd..732ba21d3369 100644
 | 
			
		||||
--- a/drivers/net/ethernet/mscc/ocelot.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mscc/ocelot.c
 | 
			
		||||
@@ -1767,6 +1767,7 @@ EXPORT_SYMBOL(ocelot_init);
 | 
			
		||||
 
 | 
			
		||||
 void ocelot_deinit(struct ocelot *ocelot)
 | 
			
		||||
 {
 | 
			
		||||
+	cancel_delayed_work(&ocelot->stats_work);
 | 
			
		||||
 	destroy_workqueue(ocelot->stats_queue);
 | 
			
		||||
 	mutex_destroy(&ocelot->stats_lock);
 | 
			
		||||
 }
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,88 +0,0 @@
 | 
			
		|||
From 5295d651548559e90245a5d744566af98d951df1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Taras Kondratiuk <takondra@cisco.com>
 | 
			
		||||
Date: Mon, 29 Jul 2019 22:15:07 +0000
 | 
			
		||||
Subject: [PATCH 801/826] tipc: compat: allow tipc commands without arguments
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 4da5f0018eef4c0de31675b670c80e82e13e99d1 ]
 | 
			
		||||
 | 
			
		||||
Commit 2753ca5d9009 ("tipc: fix uninit-value in tipc_nl_compat_doit")
 | 
			
		||||
broke older tipc tools that use compat interface (e.g. tipc-config from
 | 
			
		||||
tipcutils package):
 | 
			
		||||
 | 
			
		||||
% tipc-config -p
 | 
			
		||||
operation not supported
 | 
			
		||||
 | 
			
		||||
The commit started to reject TIPC netlink compat messages that do not
 | 
			
		||||
have attributes. It is too restrictive because some of such messages are
 | 
			
		||||
valid (they don't need any arguments):
 | 
			
		||||
 | 
			
		||||
% grep 'tx none' include/uapi/linux/tipc_config.h
 | 
			
		||||
#define  TIPC_CMD_NOOP              0x0000    /* tx none, rx none */
 | 
			
		||||
#define  TIPC_CMD_GET_MEDIA_NAMES   0x0002    /* tx none, rx media_name(s) */
 | 
			
		||||
#define  TIPC_CMD_GET_BEARER_NAMES  0x0003    /* tx none, rx bearer_name(s) */
 | 
			
		||||
#define  TIPC_CMD_SHOW_PORTS        0x0006    /* tx none, rx ultra_string */
 | 
			
		||||
#define  TIPC_CMD_GET_REMOTE_MNG    0x4003    /* tx none, rx unsigned */
 | 
			
		||||
#define  TIPC_CMD_GET_MAX_PORTS     0x4004    /* tx none, rx unsigned */
 | 
			
		||||
#define  TIPC_CMD_GET_NETID         0x400B    /* tx none, rx unsigned */
 | 
			
		||||
#define  TIPC_CMD_NOT_NET_ADMIN     0xC001    /* tx none, rx none */
 | 
			
		||||
 | 
			
		||||
This patch relaxes the original fix and rejects messages without
 | 
			
		||||
arguments only if such arguments are expected by a command (reg_type is
 | 
			
		||||
non zero).
 | 
			
		||||
 | 
			
		||||
Fixes: 2753ca5d9009 ("tipc: fix uninit-value in tipc_nl_compat_doit")
 | 
			
		||||
Cc: stable@vger.kernel.org
 | 
			
		||||
Signed-off-by: Taras Kondratiuk <takondra@cisco.com>
 | 
			
		||||
Acked-by: Ying Xue <ying.xue@windriver.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 net/tipc/netlink_compat.c | 11 +++++++----
 | 
			
		||||
 1 file changed, 7 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
 | 
			
		||||
index 85ebb675600c..318c541970ec 100644
 | 
			
		||||
--- a/net/tipc/netlink_compat.c
 | 
			
		||||
+++ b/net/tipc/netlink_compat.c
 | 
			
		||||
@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg {
 | 
			
		||||
 	int rep_type;
 | 
			
		||||
 	int rep_size;
 | 
			
		||||
 	int req_type;
 | 
			
		||||
+	int req_size;
 | 
			
		||||
 	struct net *net;
 | 
			
		||||
 	struct sk_buff *rep;
 | 
			
		||||
 	struct tlv_desc *req;
 | 
			
		||||
@@ -257,7 +258,8 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
 | 
			
		||||
 	int err;
 | 
			
		||||
 	struct sk_buff *arg;
 | 
			
		||||
 
 | 
			
		||||
-	if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
 | 
			
		||||
+	if (msg->req_type && (!msg->req_size ||
 | 
			
		||||
+			      !TLV_CHECK_TYPE(msg->req, msg->req_type)))
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	msg->rep = tipc_tlv_alloc(msg->rep_size);
 | 
			
		||||
@@ -354,7 +356,8 @@ static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
 | 
			
		||||
 {
 | 
			
		||||
 	int err;
 | 
			
		||||
 
 | 
			
		||||
-	if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
 | 
			
		||||
+	if (msg->req_type && (!msg->req_size ||
 | 
			
		||||
+			      !TLV_CHECK_TYPE(msg->req, msg->req_type)))
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 
 | 
			
		||||
 	err = __tipc_nl_compat_doit(cmd, msg);
 | 
			
		||||
@@ -1276,8 +1279,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
 | 
			
		||||
 		goto send;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
 | 
			
		||||
-	if (!len || !TLV_OK(msg.req, len)) {
 | 
			
		||||
+	msg.req_size = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
 | 
			
		||||
+	if (msg.req_size && !TLV_OK(msg.req, msg.req_size)) {
 | 
			
		||||
 		msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
 | 
			
		||||
 		err = -EOPNOTSUPP;
 | 
			
		||||
 		goto send;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,46 +0,0 @@
 | 
			
		|||
From f378724e10ced69c5e55db2e23ad350ede76f174 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Alexis Bauvin <abauvin@scaleway.com>
 | 
			
		||||
Date: Tue, 23 Jul 2019 16:23:01 +0200
 | 
			
		||||
Subject: [PATCH 802/826] tun: mark small packets as owned by the tap sock
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 4b663366246be1d1d4b1b8b01245b2e88ad9e706 ]
 | 
			
		||||
 | 
			
		||||
- v1 -> v2: Move skb_set_owner_w to __tun_build_skb to reduce patch size
 | 
			
		||||
 | 
			
		||||
Small packets going out of a tap device go through an optimized code
 | 
			
		||||
path that uses build_skb() rather than sock_alloc_send_pskb(). The
 | 
			
		||||
latter calls skb_set_owner_w(), but the small packet code path does not.
 | 
			
		||||
 | 
			
		||||
The net effect is that small packets are not owned by the userland
 | 
			
		||||
application's socket (e.g. QEMU), while large packets are.
 | 
			
		||||
This can be seen with a TCP session, where packets are not owned when
 | 
			
		||||
the window size is small enough (around PAGE_SIZE), while they are once
 | 
			
		||||
the window grows (note that this requires the host to support virtio
 | 
			
		||||
tso for the guest to offload segmentation).
 | 
			
		||||
All this leads to inconsistent behaviour in the kernel, especially on
 | 
			
		||||
netfilter modules that uses sk->socket (e.g. xt_owner).
 | 
			
		||||
 | 
			
		||||
Fixes: 66ccbc9c87c2 ("tap: use build_skb() for small packet")
 | 
			
		||||
Signed-off-by: Alexis Bauvin <abauvin@scaleway.com>
 | 
			
		||||
Acked-by: Jason Wang <jasowang@redhat.com>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/tun.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
 | 
			
		||||
index b67fee56ec81..5fa7047ea361 100644
 | 
			
		||||
--- a/drivers/net/tun.c
 | 
			
		||||
+++ b/drivers/net/tun.c
 | 
			
		||||
@@ -1682,6 +1682,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 | 
			
		||||
 
 | 
			
		||||
 	skb_reserve(skb, pad - delta);
 | 
			
		||||
 	skb_put(skb, len);
 | 
			
		||||
+	skb_set_owner_w(skb, tfile->socket.sk);
 | 
			
		||||
 	get_page(alloc_frag->page);
 | 
			
		||||
 	alloc_frag->offset += buflen;
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
From cd84a10792f08d3d0cc1cbeed07634e454fe9abd Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Edward Srouji <edwards@mellanox.com>
 | 
			
		||||
Date: Tue, 23 Jul 2019 10:12:55 +0300
 | 
			
		||||
Subject: [PATCH 803/826] net/mlx5: Fix modify_cq_in alignment
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 7a32f2962c56d9d8a836b4469855caeee8766bd4 ]
 | 
			
		||||
 | 
			
		||||
Fix modify_cq_in alignment to match the device specification.
 | 
			
		||||
After this fix the 'cq_umem_valid' field will be in the right offset.
 | 
			
		||||
 | 
			
		||||
Cc: <stable@vger.kernel.org> # 4.19
 | 
			
		||||
Fixes: bd37197554eb ("net/mlx5: Update mlx5_ifc with DEVX UID bits")
 | 
			
		||||
Signed-off-by: Edward Srouji <edwards@mellanox.com>
 | 
			
		||||
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
 | 
			
		||||
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
 | 
			
		||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 include/linux/mlx5/mlx5_ifc.h | 7 ++++++-
 | 
			
		||||
 1 file changed, 6 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
 | 
			
		||||
index f043d65b9bac..177f11c96187 100644
 | 
			
		||||
--- a/include/linux/mlx5/mlx5_ifc.h
 | 
			
		||||
+++ b/include/linux/mlx5/mlx5_ifc.h
 | 
			
		||||
@@ -5623,7 +5623,12 @@ struct mlx5_ifc_modify_cq_in_bits {
 | 
			
		||||
 
 | 
			
		||||
 	struct mlx5_ifc_cqc_bits cq_context;
 | 
			
		||||
 
 | 
			
		||||
-	u8         reserved_at_280[0x600];
 | 
			
		||||
+	u8         reserved_at_280[0x60];
 | 
			
		||||
+
 | 
			
		||||
+ 	u8         cq_umem_valid[0x1];
 | 
			
		||||
+	u8         reserved_at_2e1[0x1f];
 | 
			
		||||
+
 | 
			
		||||
+	u8         reserved_at_300[0x580];
 | 
			
		||||
 
 | 
			
		||||
 	u8         pas[0][0x40];
 | 
			
		||||
 };
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,106 +0,0 @@
 | 
			
		|||
From 0ccf47265e4cb7fd13d339ee20a84bdbdbd466ef Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Ariel Levkovich <lariel@mellanox.com>
 | 
			
		||||
Date: Sat, 6 Jul 2019 18:06:15 +0300
 | 
			
		||||
Subject: [PATCH 804/826] net/mlx5e: Prevent encap flow counter update async to
 | 
			
		||||
 user query
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 90bb769291161cf25a818d69cf608c181654473e ]
 | 
			
		||||
 | 
			
		||||
This patch prevents a race between user invoked cached counters
 | 
			
		||||
query and a neighbor last usage updater.
 | 
			
		||||
 | 
			
		||||
The cached flow counter stats can be queried by calling
 | 
			
		||||
"mlx5_fc_query_cached" which provides the number of bytes and
 | 
			
		||||
packets that passed via this flow since the last time this counter
 | 
			
		||||
was queried.
 | 
			
		||||
It does so by reducting the last saved stats from the current, cached
 | 
			
		||||
stats and then updating the last saved stats with the cached stats.
 | 
			
		||||
It also provide the lastuse value for that flow.
 | 
			
		||||
 | 
			
		||||
Since "mlx5e_tc_update_neigh_used_value" needs to retrieve the
 | 
			
		||||
last usage time of encapsulation flows, it calls the flow counter
 | 
			
		||||
query method periodically and async to user queries of the flow counter
 | 
			
		||||
using cls_flower.
 | 
			
		||||
This call is causing the driver to update the last reported bytes and
 | 
			
		||||
packets from the cache and therefore, future user queries of the flow
 | 
			
		||||
stats will return lower than expected number for bytes and packets
 | 
			
		||||
since the last saved stats in the driver was updated async to the last
 | 
			
		||||
saved stats in cls_flower.
 | 
			
		||||
 | 
			
		||||
This causes wrong stats presentation of encapsulation flows to user.
 | 
			
		||||
 | 
			
		||||
Since the neighbor usage updater only needs the lastuse stats from the
 | 
			
		||||
cached counter, the fix is to use a dedicated lastuse query call that
 | 
			
		||||
returns the lastuse value without synching between the cached stats and
 | 
			
		||||
the last saved stats.
 | 
			
		||||
 | 
			
		||||
Fixes: f6dfb4c3f216 ("net/mlx5e: Update neighbour 'used' state using HW flow rules counters")
 | 
			
		||||
Signed-off-by: Ariel Levkovich <lariel@mellanox.com>
 | 
			
		||||
Reviewed-by: Roi Dayan <roid@mellanox.com>
 | 
			
		||||
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c       | 4 ++--
 | 
			
		||||
 drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c | 5 +++++
 | 
			
		||||
 include/linux/mlx5/fs.h                               | 1 +
 | 
			
		||||
 3 files changed, 8 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
 | 
			
		||||
index 9f7f8425f676..c8928ce69185 100644
 | 
			
		||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
 | 
			
		||||
@@ -992,13 +992,13 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
 | 
			
		||||
 void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
 | 
			
		||||
 {
 | 
			
		||||
 	struct mlx5e_neigh *m_neigh = &nhe->m_neigh;
 | 
			
		||||
-	u64 bytes, packets, lastuse = 0;
 | 
			
		||||
 	struct mlx5e_tc_flow *flow;
 | 
			
		||||
 	struct mlx5e_encap_entry *e;
 | 
			
		||||
 	struct mlx5_fc *counter;
 | 
			
		||||
 	struct neigh_table *tbl;
 | 
			
		||||
 	bool neigh_used = false;
 | 
			
		||||
 	struct neighbour *n;
 | 
			
		||||
+	u64 lastuse;
 | 
			
		||||
 
 | 
			
		||||
 	if (m_neigh->family == AF_INET)
 | 
			
		||||
 		tbl = &arp_tbl;
 | 
			
		||||
@@ -1015,7 +1015,7 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
 | 
			
		||||
 		list_for_each_entry(flow, &e->flows, encap) {
 | 
			
		||||
 			if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
 | 
			
		||||
 				counter = mlx5_flow_rule_counter(flow->rule[0]);
 | 
			
		||||
-				mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
 | 
			
		||||
+				lastuse = mlx5_fc_query_lastuse(counter);
 | 
			
		||||
 				if (time_after((unsigned long)lastuse, nhe->reported_lastuse)) {
 | 
			
		||||
 					neigh_used = true;
 | 
			
		||||
 					break;
 | 
			
		||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
 | 
			
		||||
index 58af6be13dfa..808ddd732e04 100644
 | 
			
		||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
 | 
			
		||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c
 | 
			
		||||
@@ -321,6 +321,11 @@ int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter,
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(mlx5_fc_query);
 | 
			
		||||
 
 | 
			
		||||
+u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter)
 | 
			
		||||
+{
 | 
			
		||||
+	return counter->cache.lastuse;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 void mlx5_fc_query_cached(struct mlx5_fc *counter,
 | 
			
		||||
 			  u64 *bytes, u64 *packets, u64 *lastuse)
 | 
			
		||||
 {
 | 
			
		||||
diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h
 | 
			
		||||
index 804516e4f483..3386399feadc 100644
 | 
			
		||||
--- a/include/linux/mlx5/fs.h
 | 
			
		||||
+++ b/include/linux/mlx5/fs.h
 | 
			
		||||
@@ -188,6 +188,7 @@ int mlx5_modify_rule_destination(struct mlx5_flow_handle *handler,
 | 
			
		||||
 struct mlx5_fc *mlx5_flow_rule_counter(struct mlx5_flow_handle *handler);
 | 
			
		||||
 struct mlx5_fc *mlx5_fc_create(struct mlx5_core_dev *dev, bool aging);
 | 
			
		||||
 void mlx5_fc_destroy(struct mlx5_core_dev *dev, struct mlx5_fc *counter);
 | 
			
		||||
+u64 mlx5_fc_query_lastuse(struct mlx5_fc *counter);
 | 
			
		||||
 void mlx5_fc_query_cached(struct mlx5_fc *counter,
 | 
			
		||||
 			  u64 *bytes, u64 *packets, u64 *lastuse);
 | 
			
		||||
 int mlx5_fc_query(struct mlx5_core_dev *dev, struct mlx5_fc *counter,
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,55 +0,0 @@
 | 
			
		|||
From 473430ed61174498db9fcac8bbfee122657d3933 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Date: Sat, 27 Jul 2019 12:45:10 +0200
 | 
			
		||||
Subject: [PATCH 805/826] r8169: don't use MSI before RTL8168d
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 003bd5b4a7b4a94b501e3a1e2e7c9df6b2a94ed4 ]
 | 
			
		||||
 | 
			
		||||
It was reported that after resuming from suspend network fails with
 | 
			
		||||
error "do_IRQ: 3.38 No irq handler for vector", see [0]. Enabling WoL
 | 
			
		||||
can work around the issue, but the only actual fix is to disable MSI.
 | 
			
		||||
So let's mimic the behavior of the vendor driver and disable MSI on
 | 
			
		||||
all chip versions before RTL8168d.
 | 
			
		||||
 | 
			
		||||
[0] https://bugzilla.kernel.org/show_bug.cgi?id=204079
 | 
			
		||||
 | 
			
		||||
Fixes: 6c6aa15fdea5 ("r8169: improve interrupt handling")
 | 
			
		||||
Reported-by: Dušan Dragić <dragic.dusan@gmail.com>
 | 
			
		||||
Tested-by: Dušan Dragić <dragic.dusan@gmail.com>
 | 
			
		||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/realtek/r8169.c | 9 +++++++--
 | 
			
		||||
 1 file changed, 7 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
 | 
			
		||||
index a6992c4c7313..0c8b7146637e 100644
 | 
			
		||||
--- a/drivers/net/ethernet/realtek/r8169.c
 | 
			
		||||
+++ b/drivers/net/ethernet/realtek/r8169.c
 | 
			
		||||
@@ -7239,13 +7239,18 @@ static int rtl_alloc_irq(struct rtl8169_private *tp)
 | 
			
		||||
 {
 | 
			
		||||
 	unsigned int flags;
 | 
			
		||||
 
 | 
			
		||||
-	if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
 | 
			
		||||
+	switch (tp->mac_version) {
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06:
 | 
			
		||||
 		RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
 | 
			
		||||
 		RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable);
 | 
			
		||||
 		RTL_W8(tp, Cfg9346, Cfg9346_Lock);
 | 
			
		||||
+		/* fall through */
 | 
			
		||||
+	case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_24:
 | 
			
		||||
 		flags = PCI_IRQ_LEGACY;
 | 
			
		||||
-	} else {
 | 
			
		||||
+		break;
 | 
			
		||||
+	default:
 | 
			
		||||
 		flags = PCI_IRQ_ALL_TYPES;
 | 
			
		||||
+		break;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return pci_alloc_irq_vectors(tp->pci_dev, 1, 1, flags);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,145 +0,0 @@
 | 
			
		|||
From e6e9bcef12ca2e2119f999d38dbca5147b06bc14 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Arnd Bergmann <arnd@arndb.de>
 | 
			
		||||
Date: Tue, 30 Jul 2019 21:25:20 +0200
 | 
			
		||||
Subject: [PATCH 806/826] compat_ioctl: pppoe: fix PPPOEIOCSFWD handling
 | 
			
		||||
 | 
			
		||||
[ Upstream commit 055d88242a6046a1ceac3167290f054c72571cd9 ]
 | 
			
		||||
 | 
			
		||||
Support for handling the PPPOEIOCSFWD ioctl in compat mode was added in
 | 
			
		||||
linux-2.5.69 along with hundreds of other commands, but was always broken
 | 
			
		||||
sincen only the structure is compatible, but the command number is not,
 | 
			
		||||
due to the size being sizeof(size_t), or at first sizeof(sizeof((struct
 | 
			
		||||
sockaddr_pppox)), which is different on 64-bit architectures.
 | 
			
		||||
 | 
			
		||||
Guillaume Nault adds:
 | 
			
		||||
 | 
			
		||||
  And the implementation was broken until 2016 (see 29e73269aa4d ("pppoe:
 | 
			
		||||
  fix reference counting in PPPoE proxy")), and nobody ever noticed. I
 | 
			
		||||
  should probably have removed this ioctl entirely instead of fixing it.
 | 
			
		||||
  Clearly, it has never been used.
 | 
			
		||||
 | 
			
		||||
Fix it by adding a compat_ioctl handler for all pppoe variants that
 | 
			
		||||
translates the command number and then calls the regular ioctl function.
 | 
			
		||||
 | 
			
		||||
All other ioctl commands handled by pppoe are compatible between 32-bit
 | 
			
		||||
and 64-bit, and require compat_ptr() conversion.
 | 
			
		||||
 | 
			
		||||
This should apply to all stable kernels.
 | 
			
		||||
 | 
			
		||||
Acked-by: Guillaume Nault <g.nault@alphalink.fr>
 | 
			
		||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
 | 
			
		||||
Signed-off-by: David S. Miller <davem@davemloft.net>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ppp/pppoe.c  |  3 +++
 | 
			
		||||
 drivers/net/ppp/pppox.c  | 13 +++++++++++++
 | 
			
		||||
 drivers/net/ppp/pptp.c   |  3 +++
 | 
			
		||||
 fs/compat_ioctl.c        |  3 ---
 | 
			
		||||
 include/linux/if_pppox.h |  3 +++
 | 
			
		||||
 net/l2tp/l2tp_ppp.c      |  3 +++
 | 
			
		||||
 6 files changed, 25 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
 | 
			
		||||
index f22639f0116a..c04f3dc17d76 100644
 | 
			
		||||
--- a/drivers/net/ppp/pppoe.c
 | 
			
		||||
+++ b/drivers/net/ppp/pppoe.c
 | 
			
		||||
@@ -1120,6 +1120,9 @@ static const struct proto_ops pppoe_ops = {
 | 
			
		||||
 	.recvmsg	= pppoe_recvmsg,
 | 
			
		||||
 	.mmap		= sock_no_mmap,
 | 
			
		||||
 	.ioctl		= pppox_ioctl,
 | 
			
		||||
+#ifdef CONFIG_COMPAT
 | 
			
		||||
+	.compat_ioctl	= pppox_compat_ioctl,
 | 
			
		||||
+#endif
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct pppox_proto pppoe_proto = {
 | 
			
		||||
diff --git a/drivers/net/ppp/pppox.c b/drivers/net/ppp/pppox.c
 | 
			
		||||
index c0599b3b23c0..9128e42e33e7 100644
 | 
			
		||||
--- a/drivers/net/ppp/pppox.c
 | 
			
		||||
+++ b/drivers/net/ppp/pppox.c
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
 #include <linux/string.h>
 | 
			
		||||
 #include <linux/module.h>
 | 
			
		||||
 #include <linux/kernel.h>
 | 
			
		||||
+#include <linux/compat.h>
 | 
			
		||||
 #include <linux/errno.h>
 | 
			
		||||
 #include <linux/netdevice.h>
 | 
			
		||||
 #include <linux/net.h>
 | 
			
		||||
@@ -103,6 +104,18 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 | 
			
		||||
 
 | 
			
		||||
 EXPORT_SYMBOL(pppox_ioctl);
 | 
			
		||||
 
 | 
			
		||||
+#ifdef CONFIG_COMPAT
 | 
			
		||||
+int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 | 
			
		||||
+{
 | 
			
		||||
+	if (cmd == PPPOEIOCSFWD32)
 | 
			
		||||
+		cmd = PPPOEIOCSFWD;
 | 
			
		||||
+
 | 
			
		||||
+	return pppox_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+EXPORT_SYMBOL(pppox_compat_ioctl);
 | 
			
		||||
+#endif
 | 
			
		||||
+
 | 
			
		||||
 static int pppox_create(struct net *net, struct socket *sock, int protocol,
 | 
			
		||||
 			int kern)
 | 
			
		||||
 {
 | 
			
		||||
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
 | 
			
		||||
index 7321a4eca235..9ad3ff40a563 100644
 | 
			
		||||
--- a/drivers/net/ppp/pptp.c
 | 
			
		||||
+++ b/drivers/net/ppp/pptp.c
 | 
			
		||||
@@ -633,6 +633,9 @@ static const struct proto_ops pptp_ops = {
 | 
			
		||||
 	.recvmsg    = sock_no_recvmsg,
 | 
			
		||||
 	.mmap       = sock_no_mmap,
 | 
			
		||||
 	.ioctl      = pppox_ioctl,
 | 
			
		||||
+#ifdef CONFIG_COMPAT
 | 
			
		||||
+	.compat_ioctl = pppox_compat_ioctl,
 | 
			
		||||
+#endif
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct pppox_proto pppox_pptp_proto = {
 | 
			
		||||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
 | 
			
		||||
index a9b00942e87d..8f08095ee54e 100644
 | 
			
		||||
--- a/fs/compat_ioctl.c
 | 
			
		||||
+++ b/fs/compat_ioctl.c
 | 
			
		||||
@@ -894,9 +894,6 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN)
 | 
			
		||||
 COMPATIBLE_IOCTL(PPPIOCATTCHAN)
 | 
			
		||||
 COMPATIBLE_IOCTL(PPPIOCGCHAN)
 | 
			
		||||
 COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)
 | 
			
		||||
-/* PPPOX */
 | 
			
		||||
-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
 | 
			
		||||
-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
 | 
			
		||||
 /* Big A */
 | 
			
		||||
 /* sparc only */
 | 
			
		||||
 /* Big Q for sound/OSS */
 | 
			
		||||
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
 | 
			
		||||
index ba7a9b0c7c57..24e9b360da65 100644
 | 
			
		||||
--- a/include/linux/if_pppox.h
 | 
			
		||||
+++ b/include/linux/if_pppox.h
 | 
			
		||||
@@ -84,6 +84,9 @@ extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp);
 | 
			
		||||
 extern void unregister_pppox_proto(int proto_num);
 | 
			
		||||
 extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
 | 
			
		||||
 extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 | 
			
		||||
+extern int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 | 
			
		||||
+
 | 
			
		||||
+#define PPPOEIOCSFWD32    _IOW(0xB1 ,0, compat_size_t)
 | 
			
		||||
 
 | 
			
		||||
 /* PPPoX socket states */
 | 
			
		||||
 enum {
 | 
			
		||||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
 | 
			
		||||
index 04d9946dcdba..c0956781665e 100644
 | 
			
		||||
--- a/net/l2tp/l2tp_ppp.c
 | 
			
		||||
+++ b/net/l2tp/l2tp_ppp.c
 | 
			
		||||
@@ -1686,6 +1686,9 @@ static const struct proto_ops pppol2tp_ops = {
 | 
			
		||||
 	.recvmsg	= pppol2tp_recvmsg,
 | 
			
		||||
 	.mmap		= sock_no_mmap,
 | 
			
		||||
 	.ioctl		= pppox_ioctl,
 | 
			
		||||
+#ifdef CONFIG_COMPAT
 | 
			
		||||
+	.compat_ioctl = pppox_compat_ioctl,
 | 
			
		||||
+#endif
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct pppox_proto pppol2tp_proto = {
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,44 +0,0 @@
 | 
			
		|||
From 7528e95b7519d24027a4362e2a05a12d4747586f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Date: Fri, 31 May 2019 10:38:57 -0700
 | 
			
		||||
Subject: [PATCH 807/826] cgroup: Call cgroup_release() before __exit_signal()
 | 
			
		||||
 | 
			
		||||
commit 6b115bf58e6f013ca75e7115aabcbd56c20ff31d upstream.
 | 
			
		||||
 | 
			
		||||
cgroup_release() calls cgroup_subsys->release() which is used by the
 | 
			
		||||
pids controller to uncharge its pid.  We want to use it to manage
 | 
			
		||||
iteration of dying tasks which requires putting it before
 | 
			
		||||
__unhash_process().  Move cgroup_release() above __exit_signal().
 | 
			
		||||
While this makes it uncharge before the pid is freed, pid is RCU freed
 | 
			
		||||
anyway and the window is very narrow.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Cc: Oleg Nesterov <oleg@redhat.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 kernel/exit.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/kernel/exit.c b/kernel/exit.c
 | 
			
		||||
index 5c0964dc805a..e10de9836dd7 100644
 | 
			
		||||
--- a/kernel/exit.c
 | 
			
		||||
+++ b/kernel/exit.c
 | 
			
		||||
@@ -194,6 +194,7 @@ void release_task(struct task_struct *p)
 | 
			
		||||
 	rcu_read_unlock();
 | 
			
		||||
 
 | 
			
		||||
 	proc_flush_task(p);
 | 
			
		||||
+	cgroup_release(p);
 | 
			
		||||
 
 | 
			
		||||
 	write_lock_irq(&tasklist_lock);
 | 
			
		||||
 	ptrace_release_task(p);
 | 
			
		||||
@@ -219,7 +220,6 @@ void release_task(struct task_struct *p)
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	write_unlock_irq(&tasklist_lock);
 | 
			
		||||
-	cgroup_release(p);
 | 
			
		||||
 	release_thread(p);
 | 
			
		||||
 	call_rcu(&p->rcu, delayed_put_task_struct);
 | 
			
		||||
 
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,154 +0,0 @@
 | 
			
		|||
From 370b9e6399da09fe10005fe455878b356de7b85f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Date: Fri, 31 May 2019 10:38:58 -0700
 | 
			
		||||
Subject: [PATCH 808/826] cgroup: Implement css_task_iter_skip()
 | 
			
		||||
 | 
			
		||||
commit b636fd38dc40113f853337a7d2a6885ad23b8811 upstream.
 | 
			
		||||
 | 
			
		||||
When a task is moved out of a cset, task iterators pointing to the
 | 
			
		||||
task are advanced using the normal css_task_iter_advance() call.  This
 | 
			
		||||
is fine but we'll be tracking dying tasks on csets and thus moving
 | 
			
		||||
tasks from cset->tasks to (to be added) cset->dying_tasks.  When we
 | 
			
		||||
remove a task from cset->tasks, if we advance the iterators, they may
 | 
			
		||||
move over to the next cset before we had the chance to add the task
 | 
			
		||||
back on the dying list, which can allow the task to escape iteration.
 | 
			
		||||
 | 
			
		||||
This patch separates out skipping from advancing.  Skipping only moves
 | 
			
		||||
the affected iterators to the next pointer rather than fully advancing
 | 
			
		||||
it and the following advancing will recognize that the cursor has
 | 
			
		||||
already been moved forward and do the rest of advancing.  This ensures
 | 
			
		||||
that when a task moves from one list to another in its cset, as long
 | 
			
		||||
as it moves in the right direction, it's always visible to iteration.
 | 
			
		||||
 | 
			
		||||
This doesn't cause any visible behavior changes.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Cc: Oleg Nesterov <oleg@redhat.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 include/linux/cgroup.h |  3 +++
 | 
			
		||||
 kernel/cgroup/cgroup.c | 60 +++++++++++++++++++++++++-----------------
 | 
			
		||||
 2 files changed, 39 insertions(+), 24 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
 | 
			
		||||
index 8937d48a5389..f85e65b248b7 100644
 | 
			
		||||
--- a/include/linux/cgroup.h
 | 
			
		||||
+++ b/include/linux/cgroup.h
 | 
			
		||||
@@ -43,6 +43,9 @@
 | 
			
		||||
 /* walk all threaded css_sets in the domain */
 | 
			
		||||
 #define CSS_TASK_ITER_THREADED		(1U << 1)
 | 
			
		||||
 
 | 
			
		||||
+/* internal flags */
 | 
			
		||||
+#define CSS_TASK_ITER_SKIPPED		(1U << 16)
 | 
			
		||||
+
 | 
			
		||||
 /* a css_task_iter should be treated as an opaque object */
 | 
			
		||||
 struct css_task_iter {
 | 
			
		||||
 	struct cgroup_subsys		*ss;
 | 
			
		||||
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
 | 
			
		||||
index 81441117f611..c093e187f6a6 100644
 | 
			
		||||
--- a/kernel/cgroup/cgroup.c
 | 
			
		||||
+++ b/kernel/cgroup/cgroup.c
 | 
			
		||||
@@ -212,7 +212,8 @@ static struct cftype cgroup_base_files[];
 | 
			
		||||
 
 | 
			
		||||
 static int cgroup_apply_control(struct cgroup *cgrp);
 | 
			
		||||
 static void cgroup_finalize_control(struct cgroup *cgrp, int ret);
 | 
			
		||||
-static void css_task_iter_advance(struct css_task_iter *it);
 | 
			
		||||
+static void css_task_iter_skip(struct css_task_iter *it,
 | 
			
		||||
+			       struct task_struct *task);
 | 
			
		||||
 static int cgroup_destroy_locked(struct cgroup *cgrp);
 | 
			
		||||
 static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
 | 
			
		||||
 					      struct cgroup_subsys *ss);
 | 
			
		||||
@@ -775,6 +776,21 @@ static void css_set_update_populated(struct css_set *cset, bool populated)
 | 
			
		||||
 		cgroup_update_populated(link->cgrp, populated);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+/*
 | 
			
		||||
+ * @task is leaving, advance task iterators which are pointing to it so
 | 
			
		||||
+ * that they can resume at the next position.  Advancing an iterator might
 | 
			
		||||
+ * remove it from the list, use safe walk.  See css_task_iter_skip() for
 | 
			
		||||
+ * details.
 | 
			
		||||
+ */
 | 
			
		||||
+static void css_set_skip_task_iters(struct css_set *cset,
 | 
			
		||||
+				    struct task_struct *task)
 | 
			
		||||
+{
 | 
			
		||||
+	struct css_task_iter *it, *pos;
 | 
			
		||||
+
 | 
			
		||||
+	list_for_each_entry_safe(it, pos, &cset->task_iters, iters_node)
 | 
			
		||||
+		css_task_iter_skip(it, task);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * css_set_move_task - move a task from one css_set to another
 | 
			
		||||
  * @task: task being moved
 | 
			
		||||
@@ -800,22 +816,9 @@ static void css_set_move_task(struct task_struct *task,
 | 
			
		||||
 		css_set_update_populated(to_cset, true);
 | 
			
		||||
 
 | 
			
		||||
 	if (from_cset) {
 | 
			
		||||
-		struct css_task_iter *it, *pos;
 | 
			
		||||
-
 | 
			
		||||
 		WARN_ON_ONCE(list_empty(&task->cg_list));
 | 
			
		||||
 
 | 
			
		||||
-		/*
 | 
			
		||||
-		 * @task is leaving, advance task iterators which are
 | 
			
		||||
-		 * pointing to it so that they can resume at the next
 | 
			
		||||
-		 * position.  Advancing an iterator might remove it from
 | 
			
		||||
-		 * the list, use safe walk.  See css_task_iter_advance*()
 | 
			
		||||
-		 * for details.
 | 
			
		||||
-		 */
 | 
			
		||||
-		list_for_each_entry_safe(it, pos, &from_cset->task_iters,
 | 
			
		||||
-					 iters_node)
 | 
			
		||||
-			if (it->task_pos == &task->cg_list)
 | 
			
		||||
-				css_task_iter_advance(it);
 | 
			
		||||
-
 | 
			
		||||
+		css_set_skip_task_iters(from_cset, task);
 | 
			
		||||
 		list_del_init(&task->cg_list);
 | 
			
		||||
 		if (!css_set_populated(from_cset))
 | 
			
		||||
 			css_set_update_populated(from_cset, false);
 | 
			
		||||
@@ -4183,10 +4186,19 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it)
 | 
			
		||||
 	list_add(&it->iters_node, &cset->task_iters);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void css_task_iter_advance(struct css_task_iter *it)
 | 
			
		||||
+static void css_task_iter_skip(struct css_task_iter *it,
 | 
			
		||||
+			       struct task_struct *task)
 | 
			
		||||
 {
 | 
			
		||||
-	struct list_head *next;
 | 
			
		||||
+	lockdep_assert_held(&css_set_lock);
 | 
			
		||||
+
 | 
			
		||||
+	if (it->task_pos == &task->cg_list) {
 | 
			
		||||
+		it->task_pos = it->task_pos->next;
 | 
			
		||||
+		it->flags |= CSS_TASK_ITER_SKIPPED;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
 
 | 
			
		||||
+static void css_task_iter_advance(struct css_task_iter *it)
 | 
			
		||||
+{
 | 
			
		||||
 	lockdep_assert_held(&css_set_lock);
 | 
			
		||||
 repeat:
 | 
			
		||||
 	if (it->task_pos) {
 | 
			
		||||
@@ -4195,15 +4207,15 @@ static void css_task_iter_advance(struct css_task_iter *it)
 | 
			
		||||
 		 * consumed first and then ->mg_tasks.  After ->mg_tasks,
 | 
			
		||||
 		 * we move onto the next cset.
 | 
			
		||||
 		 */
 | 
			
		||||
-		next = it->task_pos->next;
 | 
			
		||||
-
 | 
			
		||||
-		if (next == it->tasks_head)
 | 
			
		||||
-			next = it->mg_tasks_head->next;
 | 
			
		||||
+		if (it->flags & CSS_TASK_ITER_SKIPPED)
 | 
			
		||||
+			it->flags &= ~CSS_TASK_ITER_SKIPPED;
 | 
			
		||||
+		else
 | 
			
		||||
+			it->task_pos = it->task_pos->next;
 | 
			
		||||
 
 | 
			
		||||
-		if (next == it->mg_tasks_head)
 | 
			
		||||
+		if (it->task_pos == it->tasks_head)
 | 
			
		||||
+			it->task_pos = it->mg_tasks_head->next;
 | 
			
		||||
+		if (it->task_pos == it->mg_tasks_head)
 | 
			
		||||
 			css_task_iter_advance_css_set(it);
 | 
			
		||||
-		else
 | 
			
		||||
-			it->task_pos = next;
 | 
			
		||||
 	} else {
 | 
			
		||||
 		/* called from start, proceed to the first cset */
 | 
			
		||||
 		css_task_iter_advance_css_set(it);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,163 +0,0 @@
 | 
			
		|||
From 4340d175b89896d069c1e875f5b98c80a408f680 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Date: Fri, 31 May 2019 10:38:58 -0700
 | 
			
		||||
Subject: [PATCH 809/826] cgroup: Include dying leaders with live threads in
 | 
			
		||||
 PROCS iterations
 | 
			
		||||
 | 
			
		||||
commit c03cd7738a83b13739f00546166969342c8ff014 upstream.
 | 
			
		||||
 | 
			
		||||
CSS_TASK_ITER_PROCS currently iterates live group leaders; however,
 | 
			
		||||
this means that a process with dying leader and live threads will be
 | 
			
		||||
skipped.  IOW, cgroup.procs might be empty while cgroup.threads isn't,
 | 
			
		||||
which is confusing to say the least.
 | 
			
		||||
 | 
			
		||||
Fix it by making cset track dying tasks and include dying leaders with
 | 
			
		||||
live threads in PROCS iteration.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Reported-and-tested-by: Topi Miettinen <toiwoton@gmail.com>
 | 
			
		||||
Cc: Oleg Nesterov <oleg@redhat.com>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 include/linux/cgroup-defs.h |  1 +
 | 
			
		||||
 include/linux/cgroup.h      |  1 +
 | 
			
		||||
 kernel/cgroup/cgroup.c      | 44 +++++++++++++++++++++++++++++++------
 | 
			
		||||
 3 files changed, 39 insertions(+), 7 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
 | 
			
		||||
index a6090154b2ab..a01ebb630abc 100644
 | 
			
		||||
--- a/include/linux/cgroup-defs.h
 | 
			
		||||
+++ b/include/linux/cgroup-defs.h
 | 
			
		||||
@@ -207,6 +207,7 @@ struct css_set {
 | 
			
		||||
 	 */
 | 
			
		||||
 	struct list_head tasks;
 | 
			
		||||
 	struct list_head mg_tasks;
 | 
			
		||||
+	struct list_head dying_tasks;
 | 
			
		||||
 
 | 
			
		||||
 	/* all css_task_iters currently walking this cset */
 | 
			
		||||
 	struct list_head task_iters;
 | 
			
		||||
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
 | 
			
		||||
index f85e65b248b7..b4854b48a4f3 100644
 | 
			
		||||
--- a/include/linux/cgroup.h
 | 
			
		||||
+++ b/include/linux/cgroup.h
 | 
			
		||||
@@ -60,6 +60,7 @@ struct css_task_iter {
 | 
			
		||||
 	struct list_head		*task_pos;
 | 
			
		||||
 	struct list_head		*tasks_head;
 | 
			
		||||
 	struct list_head		*mg_tasks_head;
 | 
			
		||||
+	struct list_head		*dying_tasks_head;
 | 
			
		||||
 
 | 
			
		||||
 	struct css_set			*cur_cset;
 | 
			
		||||
 	struct css_set			*cur_dcset;
 | 
			
		||||
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
 | 
			
		||||
index c093e187f6a6..89dd464f6862 100644
 | 
			
		||||
--- a/kernel/cgroup/cgroup.c
 | 
			
		||||
+++ b/kernel/cgroup/cgroup.c
 | 
			
		||||
@@ -673,6 +673,7 @@ struct css_set init_css_set = {
 | 
			
		||||
 	.dom_cset		= &init_css_set,
 | 
			
		||||
 	.tasks			= LIST_HEAD_INIT(init_css_set.tasks),
 | 
			
		||||
 	.mg_tasks		= LIST_HEAD_INIT(init_css_set.mg_tasks),
 | 
			
		||||
+	.dying_tasks		= LIST_HEAD_INIT(init_css_set.dying_tasks),
 | 
			
		||||
 	.task_iters		= LIST_HEAD_INIT(init_css_set.task_iters),
 | 
			
		||||
 	.threaded_csets		= LIST_HEAD_INIT(init_css_set.threaded_csets),
 | 
			
		||||
 	.cgrp_links		= LIST_HEAD_INIT(init_css_set.cgrp_links),
 | 
			
		||||
@@ -1145,6 +1146,7 @@ static struct css_set *find_css_set(struct css_set *old_cset,
 | 
			
		||||
 	cset->dom_cset = cset;
 | 
			
		||||
 	INIT_LIST_HEAD(&cset->tasks);
 | 
			
		||||
 	INIT_LIST_HEAD(&cset->mg_tasks);
 | 
			
		||||
+	INIT_LIST_HEAD(&cset->dying_tasks);
 | 
			
		||||
 	INIT_LIST_HEAD(&cset->task_iters);
 | 
			
		||||
 	INIT_LIST_HEAD(&cset->threaded_csets);
 | 
			
		||||
 	INIT_HLIST_NODE(&cset->hlist);
 | 
			
		||||
@@ -4152,15 +4154,18 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it)
 | 
			
		||||
 			it->task_pos = NULL;
 | 
			
		||||
 			return;
 | 
			
		||||
 		}
 | 
			
		||||
-	} while (!css_set_populated(cset));
 | 
			
		||||
+	} while (!css_set_populated(cset) && !list_empty(&cset->dying_tasks));
 | 
			
		||||
 
 | 
			
		||||
 	if (!list_empty(&cset->tasks))
 | 
			
		||||
 		it->task_pos = cset->tasks.next;
 | 
			
		||||
-	else
 | 
			
		||||
+	else if (!list_empty(&cset->mg_tasks))
 | 
			
		||||
 		it->task_pos = cset->mg_tasks.next;
 | 
			
		||||
+	else
 | 
			
		||||
+		it->task_pos = cset->dying_tasks.next;
 | 
			
		||||
 
 | 
			
		||||
 	it->tasks_head = &cset->tasks;
 | 
			
		||||
 	it->mg_tasks_head = &cset->mg_tasks;
 | 
			
		||||
+	it->dying_tasks_head = &cset->dying_tasks;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * We don't keep css_sets locked across iteration steps and thus
 | 
			
		||||
@@ -4199,6 +4204,8 @@ static void css_task_iter_skip(struct css_task_iter *it,
 | 
			
		||||
 
 | 
			
		||||
 static void css_task_iter_advance(struct css_task_iter *it)
 | 
			
		||||
 {
 | 
			
		||||
+	struct task_struct *task;
 | 
			
		||||
+
 | 
			
		||||
 	lockdep_assert_held(&css_set_lock);
 | 
			
		||||
 repeat:
 | 
			
		||||
 	if (it->task_pos) {
 | 
			
		||||
@@ -4215,17 +4222,32 @@ static void css_task_iter_advance(struct css_task_iter *it)
 | 
			
		||||
 		if (it->task_pos == it->tasks_head)
 | 
			
		||||
 			it->task_pos = it->mg_tasks_head->next;
 | 
			
		||||
 		if (it->task_pos == it->mg_tasks_head)
 | 
			
		||||
+			it->task_pos = it->dying_tasks_head->next;
 | 
			
		||||
+		if (it->task_pos == it->dying_tasks_head)
 | 
			
		||||
 			css_task_iter_advance_css_set(it);
 | 
			
		||||
 	} else {
 | 
			
		||||
 		/* called from start, proceed to the first cset */
 | 
			
		||||
 		css_task_iter_advance_css_set(it);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	/* if PROCS, skip over tasks which aren't group leaders */
 | 
			
		||||
-	if ((it->flags & CSS_TASK_ITER_PROCS) && it->task_pos &&
 | 
			
		||||
-	    !thread_group_leader(list_entry(it->task_pos, struct task_struct,
 | 
			
		||||
-					    cg_list)))
 | 
			
		||||
-		goto repeat;
 | 
			
		||||
+	if (!it->task_pos)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	task = list_entry(it->task_pos, struct task_struct, cg_list);
 | 
			
		||||
+
 | 
			
		||||
+	if (it->flags & CSS_TASK_ITER_PROCS) {
 | 
			
		||||
+		/* if PROCS, skip over tasks which aren't group leaders */
 | 
			
		||||
+		if (!thread_group_leader(task))
 | 
			
		||||
+			goto repeat;
 | 
			
		||||
+
 | 
			
		||||
+		/* and dying leaders w/o live member threads */
 | 
			
		||||
+		if (!atomic_read(&task->signal->live))
 | 
			
		||||
+			goto repeat;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		/* skip all dying ones */
 | 
			
		||||
+		if (task->flags & PF_EXITING)
 | 
			
		||||
+			goto repeat;
 | 
			
		||||
+	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
@@ -5682,6 +5704,7 @@ void cgroup_exit(struct task_struct *tsk)
 | 
			
		||||
 	if (!list_empty(&tsk->cg_list)) {
 | 
			
		||||
 		spin_lock_irq(&css_set_lock);
 | 
			
		||||
 		css_set_move_task(tsk, cset, NULL, false);
 | 
			
		||||
+		list_add_tail(&tsk->cg_list, &cset->dying_tasks);
 | 
			
		||||
 		cset->nr_tasks--;
 | 
			
		||||
 		spin_unlock_irq(&css_set_lock);
 | 
			
		||||
 	} else {
 | 
			
		||||
@@ -5702,6 +5725,13 @@ void cgroup_release(struct task_struct *task)
 | 
			
		||||
 	do_each_subsys_mask(ss, ssid, have_release_callback) {
 | 
			
		||||
 		ss->release(task);
 | 
			
		||||
 	} while_each_subsys_mask();
 | 
			
		||||
+
 | 
			
		||||
+	if (use_task_css_set_links) {
 | 
			
		||||
+		spin_lock_irq(&css_set_lock);
 | 
			
		||||
+		css_set_skip_task_iters(task_css_set(task), task);
 | 
			
		||||
+		list_del_init(&task->cg_list);
 | 
			
		||||
+		spin_unlock_irq(&css_set_lock);
 | 
			
		||||
+	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 void cgroup_free(struct task_struct *task)
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,45 +0,0 @@
 | 
			
		|||
From 0a9abd277819058b6beafa40bfe0a56f19edec38 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Date: Wed, 5 Jun 2019 09:54:34 -0700
 | 
			
		||||
Subject: [PATCH 810/826] cgroup: css_task_iter_skip()'d iterators must be
 | 
			
		||||
 advanced before accessed
 | 
			
		||||
 | 
			
		||||
commit cee0c33c546a93957a52ae9ab6bebadbee765ec5 upstream.
 | 
			
		||||
 | 
			
		||||
b636fd38dc40 ("cgroup: Implement css_task_iter_skip()") introduced
 | 
			
		||||
css_task_iter_skip() which is used to fix task iterations skipping
 | 
			
		||||
dying threadgroup leaders with live threads.  Skipping is implemented
 | 
			
		||||
as a subportion of full advancing but css_task_iter_next() forgot to
 | 
			
		||||
fully advance a skipped iterator before determining the next task to
 | 
			
		||||
visit causing it to return invalid task pointers.
 | 
			
		||||
 | 
			
		||||
Fix it by making css_task_iter_next() fully advance the iterator if it
 | 
			
		||||
has been skipped since the previous iteration.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Reported-by: syzbot
 | 
			
		||||
Link: http://lkml.kernel.org/r/00000000000097025d058a7fd785@google.com
 | 
			
		||||
Fixes: b636fd38dc40 ("cgroup: Implement css_task_iter_skip()")
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 kernel/cgroup/cgroup.c | 4 ++++
 | 
			
		||||
 1 file changed, 4 insertions(+)
 | 
			
		||||
 | 
			
		||||
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
 | 
			
		||||
index 89dd464f6862..ddde75bae7af 100644
 | 
			
		||||
--- a/kernel/cgroup/cgroup.c
 | 
			
		||||
+++ b/kernel/cgroup/cgroup.c
 | 
			
		||||
@@ -4303,6 +4303,10 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it)
 | 
			
		||||
 
 | 
			
		||||
 	spin_lock_irq(&css_set_lock);
 | 
			
		||||
 
 | 
			
		||||
+	/* @it may be half-advanced by skips, finish advancing */
 | 
			
		||||
+	if (it->flags & CSS_TASK_ITER_SKIPPED)
 | 
			
		||||
+		css_task_iter_advance(it);
 | 
			
		||||
+
 | 
			
		||||
 	if (it->task_pos) {
 | 
			
		||||
 		it->cur_task = list_entry(it->task_pos, struct task_struct,
 | 
			
		||||
 					  cg_list);
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,39 +0,0 @@
 | 
			
		|||
From ebda41dd170fd160e44f97d7a2a215ae9d0009b1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Date: Mon, 10 Jun 2019 09:08:27 -0700
 | 
			
		||||
Subject: [PATCH 811/826] cgroup: Fix css_task_iter_advance_css_set() cset skip
 | 
			
		||||
 condition
 | 
			
		||||
 | 
			
		||||
commit c596687a008b579c503afb7a64fcacc7270fae9e upstream.
 | 
			
		||||
 | 
			
		||||
While adding handling for dying task group leaders c03cd7738a83
 | 
			
		||||
("cgroup: Include dying leaders with live threads in PROCS
 | 
			
		||||
iterations") added an inverted cset skip condition to
 | 
			
		||||
css_task_iter_advance_css_set().  It should skip cset if it's
 | 
			
		||||
completely empty but was incorrectly testing for the inverse condition
 | 
			
		||||
for the dying_tasks list.  Fix it.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tejun Heo <tj@kernel.org>
 | 
			
		||||
Fixes: c03cd7738a83 ("cgroup: Include dying leaders with live threads in PROCS iterations")
 | 
			
		||||
Reported-by: syzbot+d4bba5ccd4f9a2a68681@syzkaller.appspotmail.com
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 kernel/cgroup/cgroup.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
 | 
			
		||||
index ddde75bae7af..78ef274b036e 100644
 | 
			
		||||
--- a/kernel/cgroup/cgroup.c
 | 
			
		||||
+++ b/kernel/cgroup/cgroup.c
 | 
			
		||||
@@ -4154,7 +4154,7 @@ static void css_task_iter_advance_css_set(struct css_task_iter *it)
 | 
			
		||||
 			it->task_pos = NULL;
 | 
			
		||||
 			return;
 | 
			
		||||
 		}
 | 
			
		||||
-	} while (!css_set_populated(cset) && !list_empty(&cset->dying_tasks));
 | 
			
		||||
+	} while (!css_set_populated(cset) && list_empty(&cset->dying_tasks));
 | 
			
		||||
 
 | 
			
		||||
 	if (!list_empty(&cset->tasks))
 | 
			
		||||
 		it->task_pos = cset->tasks.next;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,56 +0,0 @@
 | 
			
		|||
From 48fcdaba7b0d31e59f01ce96b4f53e8149787d1a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Lukas Wunner <lukas@wunner.de>
 | 
			
		||||
Date: Wed, 3 Jul 2019 12:29:31 +0200
 | 
			
		||||
Subject: [PATCH 812/826] spi: bcm2835: Fix 3-wire mode if DMA is enabled
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
commit 8d8bef50365847134b51c1ec46786bc2873e4e47 upstream.
 | 
			
		||||
 | 
			
		||||
Commit 6935224da248 ("spi: bcm2835: enable support of 3-wire mode")
 | 
			
		||||
added 3-wire support to the BCM2835 SPI driver by setting the REN bit
 | 
			
		||||
(Read Enable) in the CS register when receiving data.  The REN bit puts
 | 
			
		||||
the transmitter in high-impedance state.  The driver recognizes that
 | 
			
		||||
data is to be received by checking whether the rx_buf of a transfer is
 | 
			
		||||
non-NULL.
 | 
			
		||||
 | 
			
		||||
Commit 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers
 | 
			
		||||
meeting certain conditions") subsequently broke 3-wire support because
 | 
			
		||||
it set the SPI_MASTER_MUST_RX flag which causes spi_map_msg() to replace
 | 
			
		||||
rx_buf with a dummy buffer if it is NULL.  As a result, rx_buf is
 | 
			
		||||
*always* non-NULL if DMA is enabled.
 | 
			
		||||
 | 
			
		||||
Reinstate 3-wire support by not only checking whether rx_buf is non-NULL,
 | 
			
		||||
but also checking that it is not the dummy buffer.
 | 
			
		||||
 | 
			
		||||
Fixes: 3ecd37edaa2a ("spi: bcm2835: enable dma modes for transfers meeting certain conditions")
 | 
			
		||||
Reported-by: Nuno Sá <nuno.sa@analog.com>
 | 
			
		||||
Signed-off-by: Lukas Wunner <lukas@wunner.de>
 | 
			
		||||
Cc: stable@vger.kernel.org # v4.2+
 | 
			
		||||
Cc: Martin Sperl <kernel@martin.sperl.org>
 | 
			
		||||
Acked-by: Stefan Wahren <wahrenst@gmx.net>
 | 
			
		||||
Link: https://lore.kernel.org/r/328318841455e505370ef8ecad97b646c033dc8a.1562148527.git.lukas@wunner.de
 | 
			
		||||
Signed-off-by: Mark Brown <broonie@kernel.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/spi/spi-bcm2835.c | 3 ++-
 | 
			
		||||
 1 file changed, 2 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
 | 
			
		||||
index 25abf2d1732a..eab27d41ba83 100644
 | 
			
		||||
--- a/drivers/spi/spi-bcm2835.c
 | 
			
		||||
+++ b/drivers/spi/spi-bcm2835.c
 | 
			
		||||
@@ -554,7 +554,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
 | 
			
		||||
 	bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);
 | 
			
		||||
 
 | 
			
		||||
 	/* handle all the 3-wire mode */
 | 
			
		||||
-	if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf))
 | 
			
		||||
+	if (spi->mode & SPI_3WIRE && tfr->rx_buf &&
 | 
			
		||||
+	    tfr->rx_buf != master->dummy_rx)
 | 
			
		||||
 		cs |= BCM2835_SPI_CS_REN;
 | 
			
		||||
 	else
 | 
			
		||||
 		cs &= ~BCM2835_SPI_CS_REN;
 | 
			
		||||
-- 
 | 
			
		||||
2.22.0
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue