Commit b1f578b8 authored by Corentin Labbe's avatar Corentin Labbe Committed by Herbert Xu
Browse files

crypto: sun4i-ss - enabled stats via debugfs



This patch enable to access usage stats for each algorithm.

Signed-off-by: default avatarCorentin Labbe <clabbe@baylibre.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 9bc3dd24
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -32,6 +32,15 @@ config CRYPTO_DEV_SUN4I_SS_PRNG
	  Select this option if you want to provide kernel-side support for
	  the Pseudo-Random Number Generator found in the Security System.

config CRYPTO_DEV_SUN4I_SS_DEBUG
	bool "Enable sun4i-ss stats"
	depends on CRYPTO_DEV_SUN4I_SS
	depends on DEBUG_FS
	help
	  Say y to enable sun4i-ss debug stats.
	  This will create /sys/kernel/debug/sun4i-ss/stats for displaying
	  the number of requests per algorithm.

config CRYPTO_DEV_SUN8I_CE
	tristate "Support for Allwinner Crypto Engine cryptographic offloader"
	select CRYPTO_SKCIPHER
+20 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
	struct sg_mapping_iter mi, mo;
	unsigned int oi, oo; /* offset for in and out */
	unsigned long flags;
	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
	struct sun4i_ss_alg_template *algt;

	if (!areq->cryptlen)
		return 0;
@@ -52,6 +54,12 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
		scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
	}

	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
		algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);
		algt->stat_opti++;
		algt->stat_bytes += areq->cryptlen;
	}

	spin_lock_irqsave(&ss->slock, flags);

	for (i = 0; i < op->keylen / 4; i++)
@@ -147,6 +155,13 @@ static int noinline_for_stack sun4i_ss_cipher_poll_fallback(struct skcipher_requ
	struct sun4i_tfm_ctx *op = crypto_skcipher_ctx(tfm);
	struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
	int err;
	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
	struct sun4i_ss_alg_template *algt;

	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
		algt = container_of(alg, struct sun4i_ss_alg_template, alg.crypto);
		algt->stat_fb++;
	}

	skcipher_request_set_tfm(&ctx->fallback_req, op->fallback_tfm);
	skcipher_request_set_callback(&ctx->fallback_req, areq->base.flags,
@@ -236,6 +251,11 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
		scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
	}

	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
		algt->stat_req++;
		algt->stat_bytes += areq->cryptlen;
	}

	spin_lock_irqsave(&ss->slock, flags);

	for (i = 0; i < op->keylen / 4; i++)
+52 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
 */
#include <linux/clk.h>
#include <linux/crypto.h>
#include <linux/debugfs.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -234,6 +235,51 @@ static struct sun4i_ss_alg_template ss_algs[] = {
#endif
};

static int sun4i_ss_dbgfs_read(struct seq_file *seq, void *v)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
		if (!ss_algs[i].ss)
			continue;
		switch (ss_algs[i].type) {
		case CRYPTO_ALG_TYPE_SKCIPHER:
			seq_printf(seq, "%s %s reqs=%lu opti=%lu fallback=%lu tsize=%lu\n",
				   ss_algs[i].alg.crypto.base.cra_driver_name,
				   ss_algs[i].alg.crypto.base.cra_name,
				   ss_algs[i].stat_req, ss_algs[i].stat_opti, ss_algs[i].stat_fb,
				   ss_algs[i].stat_bytes);
			break;
		case CRYPTO_ALG_TYPE_RNG:
			seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n",
				   ss_algs[i].alg.rng.base.cra_driver_name,
				   ss_algs[i].alg.rng.base.cra_name,
				   ss_algs[i].stat_req, ss_algs[i].stat_bytes);
			break;
		case CRYPTO_ALG_TYPE_AHASH:
			seq_printf(seq, "%s %s reqs=%lu\n",
				   ss_algs[i].alg.hash.halg.base.cra_driver_name,
				   ss_algs[i].alg.hash.halg.base.cra_name,
				   ss_algs[i].stat_req);
			break;
		}
	}
	return 0;
}

static int sun4i_ss_dbgfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, sun4i_ss_dbgfs_read, inode->i_private);
}

static const struct file_operations sun4i_ss_debugfs_fops = {
	.owner = THIS_MODULE,
	.open = sun4i_ss_dbgfs_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
};

/*
 * Power management strategy: The device is suspended unless a TFM exists for
 * one of the algorithms proposed by this driver.
@@ -454,6 +500,12 @@ static int sun4i_ss_probe(struct platform_device *pdev)
			break;
		}
	}

	/* Ignore error of debugfs */
	ss->dbgfs_dir = debugfs_create_dir("sun4i-ss", NULL);
	ss->dbgfs_stats = debugfs_create_file("stats", 0444, ss->dbgfs_dir, ss,
					      &sun4i_ss_debugfs_fops);

	return 0;
error_alg:
	i--;
+6 −0
Original line number Diff line number Diff line
@@ -191,8 +191,10 @@ static int sun4i_hash(struct ahash_request *areq)
	u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32] = {0}, v, ivmode = 0;
	struct sun4i_req_ctx *op = ahash_request_ctx(areq);
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
	struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
	struct sun4i_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm);
	struct sun4i_ss_ctx *ss = tfmctx->ss;
	struct sun4i_ss_alg_template *algt;
	struct scatterlist *in_sg = areq->src;
	struct sg_mapping_iter mi;
	int in_r, err = 0;
@@ -398,6 +400,10 @@ static int sun4i_hash(struct ahash_request *areq)
 */

hash_final:
	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
		algt = container_of(alg, struct sun4i_ss_alg_template, alg.hash);
		algt->stat_req++;
	}

	/* write the remaining words of the wait buffer */
	if (op->len) {
+5 −0
Original line number Diff line number Diff line
@@ -32,6 +32,11 @@ int sun4i_ss_prng_generate(struct crypto_rng *tfm, const u8 *src,
	if (err < 0)
		return err;

	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
		algt->stat_req++;
		algt->stat_bytes += todo;
	}

	spin_lock_bh(&ss->slock);

	writel(mode, ss->base + SS_CTL);
Loading