From 9f0562dcf9fafc0d2416ff46aebf1b9041bdc8d8 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Mon, 9 Apr 2018 18:37:40 +0100 Subject: [PATCH] Fixes for Cavium ThunderX ZIP driver stability --- arm64-thunderx-crypto-zip-fixes.patch | 403 ++++++++++++++++++++++++++ kernel.spec | 6 + 2 files changed, 409 insertions(+) create mode 100644 arm64-thunderx-crypto-zip-fixes.patch 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 +X-Patchwork-Id: 10331719 +Message-Id: <20180409154554.7578-2-jglauber@cavium.com> +To: Herbert Xu +Cc: "David S . Miller" , + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa , + Robert Richter , Jan Glauber , + stable +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 +Reviewed-by: Robert Richter +Cc: stable # 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 +X-Patchwork-Id: 10331705 +Message-Id: <20180409154554.7578-3-jglauber@cavium.com> +To: Herbert Xu +Cc: "David S . Miller" , + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa , + Robert Richter , Jan Glauber , + stable +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 +Reviewed-by: Robert Richter +Cc: stable # 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 + #include + #include ++#include + #include + #include + #include +@@ -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 +X-Patchwork-Id: 10331709 +Message-Id: <20180409154554.7578-4-jglauber@cavium.com> +To: Herbert Xu +Cc: "David S . Miller" , + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa , + Robert Richter , Jan Glauber +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 +Reviewed-by: Robert Richter +--- + 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 +X-Patchwork-Id: 10331711 +Message-Id: <20180409154554.7578-5-jglauber@cavium.com> +To: Herbert Xu +Cc: "David S . Miller" , + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa , + Robert Richter , Jan Glauber +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 +Reviewed-by: Robert Richter +--- + 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 +X-Patchwork-Id: 10331715 +Message-Id: <20180409154554.7578-6-jglauber@cavium.com> +To: Herbert Xu +Cc: "David S . Miller" , + linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, + Mahipal Challa , + Robert Richter , Jan Glauber +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 +Reviewed-by: Robert Richter +--- + 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 +- Fixes for Cavium ThunderX ZIP driver stability + * Mon Apr 09 2018 Justin M. Forbes - 4.17.0-0.rc0.git5.1 - Linux v4.16-10608-gf8cf2f16a7c9