Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c782a8c4 authored by Jan Glauber's avatar Jan Glauber Committed by Herbert Xu
Browse files

crypto: cavium - Limit result reading attempts



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>
parent 37ff02ac
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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);