9f0562d
From patchwork Mon Apr  9 15:45:50 2018
9f0562d
Content-Type: text/plain; charset="utf-8"
9f0562d
MIME-Version: 1.0
9f0562d
Content-Transfer-Encoding: 7bit
9f0562d
Subject: [v2,1/5] crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK
9f0562d
From: Jan Glauber <jglauber@cavium.com>
9f0562d
X-Patchwork-Id: 10331719
9f0562d
Message-Id: <20180409154554.7578-2-jglauber@cavium.com>
9f0562d
To: Herbert Xu <herbert@gondor.apana.org.au>
9f0562d
Cc: "David S . Miller" <davem@davemloft.net>,
9f0562d
 linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
9f0562d
 Mahipal Challa <Mahipal.Challa@cavium.com>,
9f0562d
 Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>,
9f0562d
 stable <stable@vger.kernel.org>
9f0562d
Date: Mon,  9 Apr 2018 17:45:50 +0200
9f0562d
9f0562d
Enabling virtual mapped kernel stacks breaks the thunderx_zip
9f0562d
driver. On compression or decompression the executing CPU hangs
9f0562d
in an endless loop. The reason for this is the usage of __pa
9f0562d
by the driver which does no longer work for an address that is
9f0562d
not part of the 1:1 mapping.
9f0562d
9f0562d
The zip driver allocates a result struct on the stack and needs
9f0562d
to tell the hardware the physical address within this struct
9f0562d
that is used to signal the completion of the request.
9f0562d
9f0562d
As the hardware gets the wrong address after the broken __pa
9f0562d
conversion it writes to an arbitrary address. The zip driver then
9f0562d
waits forever for the completion byte to contain a non-zero value.
9f0562d
9f0562d
Allocating the result struct from 1:1 mapped memory resolves this
9f0562d
bug.
9f0562d
9f0562d
Signed-off-by: Jan Glauber <jglauber@cavium.com>
9f0562d
Reviewed-by: Robert Richter <rrichter@cavium.com>
9f0562d
Cc: stable <stable@vger.kernel.org> # 4.14
9f0562d
---
9f0562d
 drivers/crypto/cavium/zip/zip_crypto.c | 22 ++++++++++++++--------
9f0562d
 1 file changed, 14 insertions(+), 8 deletions(-)
9f0562d
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_crypto.c b/drivers/crypto/cavium/zip/zip_crypto.c
9f0562d
index 8df4d26cf9d4..b92b6e7e100f 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_crypto.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_crypto.c
9f0562d
@@ -124,7 +124,7 @@ int zip_compress(const u8 *src, unsigned int slen,
9f0562d
 		 struct zip_kernel_ctx *zip_ctx)
9f0562d
 {
9f0562d
 	struct zip_operation  *zip_ops   = NULL;
9f0562d
-	struct zip_state      zip_state;
9f0562d
+	struct zip_state      *zip_state;
9f0562d
 	struct zip_device     *zip = NULL;
9f0562d
 	int ret;
9f0562d
 
9f0562d
@@ -135,20 +135,23 @@ int zip_compress(const u8 *src, unsigned int slen,
9f0562d
 	if (!zip)
9f0562d
 		return -ENODEV;
9f0562d
 
9f0562d
-	memset(&zip_state, 0, sizeof(struct zip_state));
9f0562d
+	zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC);
9f0562d
+	if (!zip_state)
9f0562d
+		return -ENOMEM;
9f0562d
+
9f0562d
 	zip_ops = &zip_ctx->zip_comp;
9f0562d
 
9f0562d
 	zip_ops->input_len  = slen;
9f0562d
 	zip_ops->output_len = *dlen;
9f0562d
 	memcpy(zip_ops->input, src, slen);
9f0562d
 
9f0562d
-	ret = zip_deflate(zip_ops, &zip_state, zip);
9f0562d
+	ret = zip_deflate(zip_ops, zip_state, zip);
9f0562d
 
9f0562d
 	if (!ret) {
9f0562d
 		*dlen = zip_ops->output_len;
9f0562d
 		memcpy(dst, zip_ops->output, *dlen);
9f0562d
 	}
9f0562d
-
9f0562d
+	kfree(zip_state);
9f0562d
 	return ret;
9f0562d
 }
9f0562d
 
9f0562d
@@ -157,7 +160,7 @@ int zip_decompress(const u8 *src, unsigned int slen,
9f0562d
 		   struct zip_kernel_ctx *zip_ctx)
9f0562d
 {
9f0562d
 	struct zip_operation  *zip_ops   = NULL;
9f0562d
-	struct zip_state      zip_state;
9f0562d
+	struct zip_state      *zip_state;
9f0562d
 	struct zip_device     *zip = NULL;
9f0562d
 	int ret;
9f0562d
 
9f0562d
@@ -168,7 +171,10 @@ int zip_decompress(const u8 *src, unsigned int slen,
9f0562d
 	if (!zip)
9f0562d
 		return -ENODEV;
9f0562d
 
9f0562d
-	memset(&zip_state, 0, sizeof(struct zip_state));
9f0562d
+	zip_state = kzalloc(sizeof(*zip_state), GFP_ATOMIC);
9f0562d
+	if (!zip_state)
9f0562d
+		return -ENOMEM;
9f0562d
+
9f0562d
 	zip_ops = &zip_ctx->zip_decomp;
9f0562d
 	memcpy(zip_ops->input, src, slen);
9f0562d
 
9f0562d
@@ -179,13 +185,13 @@ int zip_decompress(const u8 *src, unsigned int slen,
9f0562d
 	zip_ops->input_len  = slen;
9f0562d
 	zip_ops->output_len = *dlen;
9f0562d
 
9f0562d
-	ret = zip_inflate(zip_ops, &zip_state, zip);
9f0562d
+	ret = zip_inflate(zip_ops, zip_state, zip);
9f0562d
 
9f0562d
 	if (!ret) {
9f0562d
 		*dlen = zip_ops->output_len;
9f0562d
 		memcpy(dst, zip_ops->output, *dlen);
9f0562d
 	}
9f0562d
-
9f0562d
+	kfree(zip_state);
9f0562d
 	return ret;
9f0562d
 }
9f0562d
 
9f0562d
From patchwork Mon Apr  9 15:45:51 2018
9f0562d
Content-Type: text/plain; charset="utf-8"
9f0562d
MIME-Version: 1.0
9f0562d
Content-Transfer-Encoding: 7bit
9f0562d
Subject: [v2,2/5] crypto: thunderx_zip: Limit result reading attempts
9f0562d
From: Jan Glauber <jglauber@cavium.com>
9f0562d
X-Patchwork-Id: 10331705
9f0562d
Message-Id: <20180409154554.7578-3-jglauber@cavium.com>
9f0562d
To: Herbert Xu <herbert@gondor.apana.org.au>
9f0562d
Cc: "David S . Miller" <davem@davemloft.net>,
9f0562d
 linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
9f0562d
 Mahipal Challa <Mahipal.Challa@cavium.com>,
9f0562d
 Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>,
9f0562d
 stable <stable@vger.kernel.org>
9f0562d
Date: Mon,  9 Apr 2018 17:45:51 +0200
9f0562d
9f0562d
After issuing a request an endless loop was used to read the
9f0562d
completion state from memory which is asynchronously updated
9f0562d
by the ZIP coprocessor.
9f0562d
9f0562d
Add an upper bound to the retry attempts to prevent a CPU getting stuck
9f0562d
forever in case of an error. Additionally, add a read memory barrier
9f0562d
and a small delay between the reading attempts.
9f0562d
9f0562d
Signed-off-by: Jan Glauber <jglauber@cavium.com>
9f0562d
Reviewed-by: Robert Richter <rrichter@cavium.com>
9f0562d
Cc: stable <stable@vger.kernel.org> # 4.14
9f0562d
---
9f0562d
 drivers/crypto/cavium/zip/common.h      | 21 +++++++++++++++++++++
9f0562d
 drivers/crypto/cavium/zip/zip_deflate.c |  4 ++--
9f0562d
 drivers/crypto/cavium/zip/zip_inflate.c |  4 ++--
9f0562d
 3 files changed, 25 insertions(+), 4 deletions(-)
9f0562d
9f0562d
diff --git a/drivers/crypto/cavium/zip/common.h b/drivers/crypto/cavium/zip/common.h
9f0562d
index dc451e0a43c5..58fb3ed6e644 100644
9f0562d
--- a/drivers/crypto/cavium/zip/common.h
9f0562d
+++ b/drivers/crypto/cavium/zip/common.h
9f0562d
@@ -46,8 +46,10 @@
9f0562d
 #ifndef __COMMON_H__
9f0562d
 #define __COMMON_H__
9f0562d
 
9f0562d
+#include <linux/delay.h>
9f0562d
 #include <linux/init.h>
9f0562d
 #include <linux/interrupt.h>
9f0562d
+#include <linux/io.h>
9f0562d
 #include <linux/kernel.h>
9f0562d
 #include <linux/module.h>
9f0562d
 #include <linux/pci.h>
9f0562d
@@ -149,6 +151,25 @@ struct zip_operation {
9f0562d
 	u32   sizeofzops;
9f0562d
 };
9f0562d
 
9f0562d
+static inline int zip_poll_result(union zip_zres_s *result)
9f0562d
+{
9f0562d
+	int retries = 1000;
9f0562d
+
9f0562d
+	while (!result->s.compcode) {
9f0562d
+		if (!--retries) {
9f0562d
+			pr_err("ZIP ERR: request timed out");
9f0562d
+			return -ETIMEDOUT;
9f0562d
+		}
9f0562d
+		udelay(10);
9f0562d
+		/*
9f0562d
+		 * Force re-reading of compcode which is updated
9f0562d
+		 * by the ZIP coprocessor.
9f0562d
+		 */
9f0562d
+		rmb();
9f0562d
+	}
9f0562d
+	return 0;
9f0562d
+}
9f0562d
+
9f0562d
 /* error messages */
9f0562d
 #define zip_err(fmt, args...) pr_err("ZIP ERR:%s():%d: " \
9f0562d
 			      fmt "\n", __func__, __LINE__, ## args)
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_deflate.c b/drivers/crypto/cavium/zip/zip_deflate.c
9f0562d
index 9a944b8c1e29..d7133f857d67 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_deflate.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_deflate.c
9f0562d
@@ -129,8 +129,8 @@ int zip_deflate(struct zip_operation *zip_ops, struct zip_state *s,
9f0562d
 	/* Stats update for compression requests submitted */
9f0562d
 	atomic64_inc(&zip_dev->stats.comp_req_submit);
9f0562d
 
9f0562d
-	while (!result_ptr->s.compcode)
9f0562d
-		continue;
9f0562d
+	/* Wait for completion or error */
9f0562d
+	zip_poll_result(result_ptr);
9f0562d
 
9f0562d
 	/* Stats update for compression requests completed */
9f0562d
 	atomic64_inc(&zip_dev->stats.comp_req_complete);
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_inflate.c b/drivers/crypto/cavium/zip/zip_inflate.c
9f0562d
index 50cbdd83dbf2..7e0d73e2f89e 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_inflate.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_inflate.c
9f0562d
@@ -143,8 +143,8 @@ int zip_inflate(struct zip_operation *zip_ops, struct zip_state *s,
9f0562d
 	/* Decompression requests submitted stats update */
9f0562d
 	atomic64_inc(&zip_dev->stats.decomp_req_submit);
9f0562d
 
9f0562d
-	while (!result_ptr->s.compcode)
9f0562d
-		continue;
9f0562d
+	/* Wait for completion or error */
9f0562d
+	zip_poll_result(result_ptr);
9f0562d
 
9f0562d
 	/* Decompression requests completed stats update */
9f0562d
 	atomic64_inc(&zip_dev->stats.decomp_req_complete);
9f0562d
From patchwork Mon Apr  9 15:45:52 2018
9f0562d
Content-Type: text/plain; charset="utf-8"
9f0562d
MIME-Version: 1.0
9f0562d
Content-Transfer-Encoding: 7bit
9f0562d
Subject: [v2,3/5] crypto: thunderx_zip: Prevent division by zero
9f0562d
From: Jan Glauber <jglauber@cavium.com>
9f0562d
X-Patchwork-Id: 10331709
9f0562d
Message-Id: <20180409154554.7578-4-jglauber@cavium.com>
9f0562d
To: Herbert Xu <herbert@gondor.apana.org.au>
9f0562d
Cc: "David S . Miller" <davem@davemloft.net>,
9f0562d
 linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
9f0562d
 Mahipal Challa <Mahipal.Challa@cavium.com>,
9f0562d
 Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>
9f0562d
Date: Mon,  9 Apr 2018 17:45:52 +0200
9f0562d
9f0562d
Avoid two potential divisions by zero when calculating average
9f0562d
values for the zip statistics.
9f0562d
9f0562d
Signed-off-by: Jan Glauber <jglauber@cavium.com>
9f0562d
Reviewed-by: Robert Richter <rrichter@cavium.com>
9f0562d
---
9f0562d
 drivers/crypto/cavium/zip/zip_main.c | 9 +++++----
9f0562d
 1 file changed, 5 insertions(+), 4 deletions(-)
9f0562d
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
9f0562d
index 1cd8aa488185..79b449e0f955 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_main.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_main.c
9f0562d
@@ -482,10 +482,11 @@ static int zip_show_stats(struct seq_file *s, void *unused)
9f0562d
 				atomic64_add(val, &st->pending_req);
9f0562d
 			}
9f0562d
 
9f0562d
-			avg_chunk = (atomic64_read(&st->comp_in_bytes) /
9f0562d
-				     atomic64_read(&st->comp_req_complete));
9f0562d
-			avg_cr = (atomic64_read(&st->comp_in_bytes) /
9f0562d
-				  atomic64_read(&st->comp_out_bytes));
9f0562d
+			val = atomic64_read(&st->comp_req_complete);
9f0562d
+			avg_chunk = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0;
9f0562d
+
9f0562d
+			val = atomic64_read(&st->comp_out_bytes);
9f0562d
+			avg_cr = (val) ? atomic64_read(&st->comp_in_bytes) / val : 0;
9f0562d
 			seq_printf(s, "        ZIP Device %d Stats\n"
9f0562d
 				      "-----------------------------------\n"
9f0562d
 				      "Comp Req Submitted        : \t%lld\n"
9f0562d
From patchwork Mon Apr  9 15:45:53 2018
9f0562d
Content-Type: text/plain; charset="utf-8"
9f0562d
MIME-Version: 1.0
9f0562d
Content-Transfer-Encoding: 7bit
9f0562d
Subject: [v2,4/5] crypto: thunderx_zip: Fix statistics pending request value
9f0562d
From: Jan Glauber <jglauber@cavium.com>
9f0562d
X-Patchwork-Id: 10331711
9f0562d
Message-Id: <20180409154554.7578-5-jglauber@cavium.com>
9f0562d
To: Herbert Xu <herbert@gondor.apana.org.au>
9f0562d
Cc: "David S . Miller" <davem@davemloft.net>,
9f0562d
 linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
9f0562d
 Mahipal Challa <Mahipal.Challa@cavium.com>,
9f0562d
 Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>
9f0562d
Date: Mon,  9 Apr 2018 17:45:53 +0200
9f0562d
9f0562d
The pending request counter was read from the wrong register. While
9f0562d
at it, there is no need to use an atomic for it as it is only read
9f0562d
localy in a loop.
9f0562d
9f0562d
Signed-off-by: Jan Glauber <jglauber@cavium.com>
9f0562d
Reviewed-by: Robert Richter <rrichter@cavium.com>
9f0562d
---
9f0562d
 drivers/crypto/cavium/zip/zip_main.c | 13 +++++--------
9f0562d
 drivers/crypto/cavium/zip/zip_main.h |  1 -
9f0562d
 2 files changed, 5 insertions(+), 9 deletions(-)
9f0562d
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
9f0562d
index 79b449e0f955..ae5b20c695ca 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_main.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_main.c
9f0562d
@@ -469,6 +469,8 @@ static int zip_show_stats(struct seq_file *s, void *unused)
9f0562d
 	struct zip_stats  *st;
9f0562d
 
9f0562d
 	for (index = 0; index < MAX_ZIP_DEVICES; index++) {
9f0562d
+		u64 pending = 0;
9f0562d
+
9f0562d
 		if (zip_dev[index]) {
9f0562d
 			zip = zip_dev[index];
9f0562d
 			st  = &zip->stats;
9f0562d
@@ -476,10 +478,8 @@ static int zip_show_stats(struct seq_file *s, void *unused)
9f0562d
 			/* Get all the pending requests */
9f0562d
 			for (q = 0; q < ZIP_NUM_QUEUES; q++) {
9f0562d
 				val = zip_reg_read((zip->reg_base +
9f0562d
-						    ZIP_DBG_COREX_STA(q)));
9f0562d
-				val = (val >> 32);
9f0562d
-				val = val & 0xffffff;
9f0562d
-				atomic64_add(val, &st->pending_req);
9f0562d
+						    ZIP_DBG_QUEX_STA(q)));
9f0562d
+				pending += val >> 32 & 0xffffff;
9f0562d
 			}
9f0562d
 
9f0562d
 			val = atomic64_read(&st->comp_req_complete);
9f0562d
@@ -514,10 +514,7 @@ static int zip_show_stats(struct seq_file *s, void *unused)
9f0562d
 				       (u64)atomic64_read(&st->decomp_in_bytes),
9f0562d
 				       (u64)atomic64_read(&st->decomp_out_bytes),
9f0562d
 				       (u64)atomic64_read(&st->decomp_bad_reqs),
9f0562d
-				       (u64)atomic64_read(&st->pending_req));
9f0562d
-
9f0562d
-			/* Reset pending requests  count */
9f0562d
-			atomic64_set(&st->pending_req, 0);
9f0562d
+				       pending);
9f0562d
 		}
9f0562d
 	}
9f0562d
 	return 0;
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_main.h b/drivers/crypto/cavium/zip/zip_main.h
9f0562d
index 64e051f60784..e1e4fa92ce80 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_main.h
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_main.h
9f0562d
@@ -74,7 +74,6 @@ struct zip_stats {
9f0562d
 	atomic64_t    comp_req_complete;
9f0562d
 	atomic64_t    decomp_req_submit;
9f0562d
 	atomic64_t    decomp_req_complete;
9f0562d
-	atomic64_t    pending_req;
9f0562d
 	atomic64_t    comp_in_bytes;
9f0562d
 	atomic64_t    comp_out_bytes;
9f0562d
 	atomic64_t    decomp_in_bytes;
9f0562d
From patchwork Mon Apr  9 15:45:54 2018
9f0562d
Content-Type: text/plain; charset="utf-8"
9f0562d
MIME-Version: 1.0
9f0562d
Content-Transfer-Encoding: 7bit
9f0562d
Subject: [v2,5/5] crypto: thunderx_zip: Fix smp_processor_id() warnings
9f0562d
From: Jan Glauber <jglauber@cavium.com>
9f0562d
X-Patchwork-Id: 10331715
9f0562d
Message-Id: <20180409154554.7578-6-jglauber@cavium.com>
9f0562d
To: Herbert Xu <herbert@gondor.apana.org.au>
9f0562d
Cc: "David S . Miller" <davem@davemloft.net>,
9f0562d
 linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
9f0562d
 Mahipal Challa <Mahipal.Challa@cavium.com>,
9f0562d
 Robert Richter <rrichter@cavium.com>, Jan Glauber <jglauber@cavium.com>
9f0562d
Date: Mon,  9 Apr 2018 17:45:54 +0200
9f0562d
9f0562d
Switch to raw_smp_processor_id() to prevent a number of
9f0562d
warnings from kernel debugging. We do not care about
9f0562d
preemption here, as the CPU number is only used as a
9f0562d
poor mans load balancing or device selection. If preemption
9f0562d
happens during a compress/decompress operation a small performance
9f0562d
hit will occur but everything will continue to work, so just
9f0562d
ignore it.
9f0562d
9f0562d
Signed-off-by: Jan Glauber <jglauber@cavium.com>
9f0562d
Reviewed-by: Robert Richter <rrichter@cavium.com>
9f0562d
---
9f0562d
 drivers/crypto/cavium/zip/zip_device.c | 4 ++--
9f0562d
 drivers/crypto/cavium/zip/zip_main.c   | 2 +-
9f0562d
 2 files changed, 3 insertions(+), 3 deletions(-)
9f0562d
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_device.c b/drivers/crypto/cavium/zip/zip_device.c
9f0562d
index ccf21fb91513..f174ec29ed69 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_device.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_device.c
9f0562d
@@ -87,12 +87,12 @@ u32 zip_load_instr(union zip_inst_s *instr,
9f0562d
 	 * Distribute the instructions between the enabled queues based on
9f0562d
 	 * the CPU id.
9f0562d
 	 */
9f0562d
-	if (smp_processor_id() % 2 == 0)
9f0562d
+	if (raw_smp_processor_id() % 2 == 0)
9f0562d
 		queue = 0;
9f0562d
 	else
9f0562d
 		queue = 1;
9f0562d
 
9f0562d
-	zip_dbg("CPU Core: %d Queue number:%d", smp_processor_id(), queue);
9f0562d
+	zip_dbg("CPU Core: %d Queue number:%d", raw_smp_processor_id(), queue);
9f0562d
 
9f0562d
 	/* Take cmd buffer lock */
9f0562d
 	spin_lock(&zip_dev->iq[queue].lock);
9f0562d
diff --git a/drivers/crypto/cavium/zip/zip_main.c b/drivers/crypto/cavium/zip/zip_main.c
9f0562d
index ae5b20c695ca..be055b9547f6 100644
9f0562d
--- a/drivers/crypto/cavium/zip/zip_main.c
9f0562d
+++ b/drivers/crypto/cavium/zip/zip_main.c
9f0562d
@@ -113,7 +113,7 @@ struct zip_device *zip_get_device(int node)
9f0562d
  */
9f0562d
 int zip_get_node_id(void)
9f0562d
 {
9f0562d
-	return cpu_to_node(smp_processor_id());
9f0562d
+	return cpu_to_node(raw_smp_processor_id());
9f0562d
 }
9f0562d
 
9f0562d
 /* Initializes the ZIP h/w sub-system */