crypto: cavium - Limit result reading attempts
authorJan Glauber <jglauber@cavium.com>
Mon, 9 Apr 2018 15:45:51 +0000 (17:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 16 Jun 2018 07:45:18 +0000 (09:45 +0200)
commit c782a8c43e94ba6c09e9de2d69b5e3a5840ce61c upstream.

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
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/crypto/cavium/zip/common.h
drivers/crypto/cavium/zip/zip_deflate.c
drivers/crypto/cavium/zip/zip_inflate.c

index dc451e0a43c5158d8658425956e6ba01276192d9..58fb3ed6e64424766ac6907b62f77a934bedcc78 100644 (file)
 #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)
index 9a944b8c1e29808b755baecd4ab526efc89fdf32..d7133f857d67198f551db5f39136e141aec8cd55 100644 (file)
@@ -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);
index 50cbdd83dbf21dd8c036213b3bdc0ea730e98429..7e0d73e2f89e1296ef4e36c5de26609e46a74410 100644 (file)
@@ -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);