Commit b9705796 authored by Jan Glauber's avatar Jan Glauber Committed by Greg Kroah-Hartman

crypto: cavium - Limit result reading attempts

commit c782a8c4 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: default avatarJan Glauber <jglauber@cavium.com>
Reviewed-by: default avatarRobert Richter <rrichter@cavium.com>
Cc: stable <stable@vger.kernel.org> # 4.14
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 072e8b1f
...@@ -46,8 +46,10 @@ ...@@ -46,8 +46,10 @@
#ifndef __COMMON_H__ #ifndef __COMMON_H__
#define __COMMON_H__ #define __COMMON_H__
#include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -149,6 +151,25 @@ struct zip_operation { ...@@ -149,6 +151,25 @@ struct zip_operation {
u32 sizeofzops; 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 */ /* error messages */
#define zip_err(fmt, args...) pr_err("ZIP ERR:%s():%d: " \ #define zip_err(fmt, args...) pr_err("ZIP ERR:%s():%d: " \
fmt "\n", __func__, __LINE__, ## args) fmt "\n", __func__, __LINE__, ## args)
......
...@@ -129,8 +129,8 @@ int zip_deflate(struct zip_operation *zip_ops, struct zip_state *s, ...@@ -129,8 +129,8 @@ int zip_deflate(struct zip_operation *zip_ops, struct zip_state *s,
/* Stats update for compression requests submitted */ /* Stats update for compression requests submitted */
atomic64_inc(&zip_dev->stats.comp_req_submit); atomic64_inc(&zip_dev->stats.comp_req_submit);
while (!result_ptr->s.compcode) /* Wait for completion or error */
continue; zip_poll_result(result_ptr);
/* Stats update for compression requests completed */ /* Stats update for compression requests completed */
atomic64_inc(&zip_dev->stats.comp_req_complete); atomic64_inc(&zip_dev->stats.comp_req_complete);
......
...@@ -143,8 +143,8 @@ int zip_inflate(struct zip_operation *zip_ops, struct zip_state *s, ...@@ -143,8 +143,8 @@ int zip_inflate(struct zip_operation *zip_ops, struct zip_state *s,
/* Decompression requests submitted stats update */ /* Decompression requests submitted stats update */
atomic64_inc(&zip_dev->stats.decomp_req_submit); atomic64_inc(&zip_dev->stats.decomp_req_submit);
while (!result_ptr->s.compcode) /* Wait for completion or error */
continue; zip_poll_result(result_ptr);
/* Decompression requests completed stats update */ /* Decompression requests completed stats update */
atomic64_inc(&zip_dev->stats.decomp_req_complete); atomic64_inc(&zip_dev->stats.decomp_req_complete);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment