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