[Skiboot] [PATCH 13/13] add nx-842 self test
Dan Streetman
ddstreet at ieee.org
Tue Mar 17 08:24:09 AEDT 2015
Add selftest module for NX-842 hardware driver.
Signed-off-by: Dan Streetman <ddstreet at ieee.org>
---
drivers/crypto/nx/Kconfig | 10 +-
drivers/crypto/nx/Makefile | 2 +
drivers/crypto/nx/nx-842-test.c | 728 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 739 insertions(+), 1 deletion(-)
create mode 100644 drivers/crypto/nx/nx-842-test.c
diff --git a/drivers/crypto/nx/Kconfig b/drivers/crypto/nx/Kconfig
index 894aa6c..e5b7f2d 100644
--- a/drivers/crypto/nx/Kconfig
+++ b/drivers/crypto/nx/Kconfig
@@ -1,5 +1,5 @@
config CRYPTO_DEV_NX_ENCRYPT
- tristate "Encryption acceleration support on pSeries platforms"
+ tristate "Encryption acceleration support on pSeries platform"
depends on IBMVIO && !CPU_LITTLE_ENDIAN
default y
select CRYPTO_AES
@@ -45,3 +45,11 @@ config CRYPTO_DEV_NX_POWERNV_COMPRESS
module supports acceleration for compressing memory with the 842
algorithm. This supports NX hardware on the PowerNV platform.
If you choose 'M' here, this module will be called nx_compress_powernv.
+
+config CRYPTO_DEV_NX_SELFTEST
+ tristate "Compression acceleration self-test"
+ depends on CRYPTO_DEV_NX_COMPRESS
+ default n
+ help
+ Provides debugfs interface to run self-tests to verify driver and hw
+ functionality.
diff --git a/drivers/crypto/nx/Makefile b/drivers/crypto/nx/Makefile
index 82221f2..f27cf35 100644
--- a/drivers/crypto/nx/Makefile
+++ b/drivers/crypto/nx/Makefile
@@ -13,6 +13,8 @@ nx-crypto-objs := nx.o \
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o
obj-$(CONFIG_CRYPTO_DEV_NX_PSERIES_COMPRESS) += nx-compress-pseries.o
obj-$(CONFIG_CRYPTO_DEV_NX_POWERNV_COMPRESS) += nx-compress-powernv.o
+obj-$(CONFIG_CRYPTO_DEV_NX_SELFTEST) += nx-compress-test.o
nx-compress-objs := nx-842.o
nx-compress-pseries-objs := nx-842-pseries.o
nx-compress-powernv-objs := nx-842-powernv.o
+nx-compress-test-objs := nx-842-test.o
diff --git a/drivers/crypto/nx/nx-842-test.c b/drivers/crypto/nx/nx-842-test.c
new file mode 100644
index 0000000..4775c42
--- /dev/null
+++ b/drivers/crypto/nx/nx-842-test.c
@@ -0,0 +1,728 @@
+/*
+ * Self-test for IBM 842 compression accelerator
+ *
+ * Copyright (C) 2015 Dan Streetman, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kthread.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/crypto.h>
+#include <linux/nx842.h>
+#include <linux/sw842.h>
+
+#include "nx-842.h"
+
+#define MODULE_NAME "nx842-compress-test"
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dan Streetman <ddstreet at ieee.org>");
+MODULE_DESCRIPTION("842 H/W Compression driver self-tests");
+
+#define TEST_BUF_ORDER (2)
+#define TEST_BUF_SIZE (PAGE_SIZE * (1 << TEST_BUF_ORDER))
+
+/* these combined must be < TEST_BUF_SIZE */
+#define MAX_TEST_START (PAGE_SIZE)
+#define MAX_TEST_LEN (PAGE_SIZE * 3)
+
+#define DBG_BUF_LINE_SIZE (0x10)
+#define DBG_BUF_LINES_MAX (0x40)
+#define DBG_BUF_LEN_MAX (DBG_BUF_LINE_SIZE * DBG_BUF_LINES_MAX)
+
+struct test_arg_param {
+ struct crypto_comp *tfm;
+ void *wmem;
+};
+
+struct test_selftest_param {
+ char *name;
+ int (*constraints)(struct nx842_constraints *constraints);
+ struct semaphore lock;
+ struct task_struct *kthread;
+ unsigned char *a, *b, *c;
+ unsigned int astart, bstart, cstart;
+ unsigned int alen, blen, clen;
+ struct test_arg_param arg;
+ unsigned long comp_bps, decomp_bps, sw_bps;
+ int (*comp)(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len,
+ struct test_arg_param *p);
+ int (*decomp)(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len,
+ struct test_arg_param *p);
+ int (*sw_decomp)(const unsigned char *in, int in_len,
+ unsigned char *out, int *out_len);
+};
+
+static struct test_selftest_param test_selftest_param,
+ test_crypto842_selftest_param;
+
+static int test_crypto842_comp(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len, struct test_arg_param *p)
+{
+ return crypto_comp_compress(p->tfm, in, in_len, out, out_len);
+}
+static int test_crypto842_decomp(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len, struct test_arg_param *p)
+{
+ return crypto_comp_decompress(p->tfm, in, in_len, out, out_len);
+}
+static int test_nx842_comp(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len, struct test_arg_param *p)
+{
+ return nx842_compress(in, in_len, out, out_len, p->wmem);
+}
+static int test_nx842_decomp(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len, struct test_arg_param *p)
+{
+ return nx842_decompress(in, in_len, out, out_len, p->wmem);
+}
+
+static void debug_buffer(char *msg, unsigned char *buf, unsigned int len)
+{
+ pr_debug("%s\n", msg);
+
+ print_hex_dump_debug("", DUMP_PREFIX_OFFSET, 16, 1, buf,
+ min_t(unsigned int, len, DBG_BUF_LEN_MAX), 0);
+}
+
+#define params_pr(t, msg, s, al, bl, cl, c) pr_##t( \
+ "%s start 0x%x alen 0x%x blen 0x%x clen 0x%x " \
+ " align 0x%x mult 0x%x min 0x%x max 0x%x\n", \
+ (msg), (s), (al), (bl), (cl), \
+ (c)->alignment, (c)->multiple, (c)->minimum, (c)->maximum);
+#define params_debug(msg, s, al, bl, cl, c) params_pr(debug, \
+ msg, s, al, bl, cl, c)
+#define params_err(msg, s, al, bl, cl, c) params_pr(err, \
+ msg, s, al, bl, cl, c)
+
+static unsigned long calc_bps(u64 bps, u64 bytes, u64 start)
+{
+ u64 bpus = (bps + bytes) * 1000000;
+ u64 us = 1000000 + (get_tb() - start) / tb_ticks_per_usec;
+
+ return bpus / us;
+}
+
+static int expected_fail(bool condition, char* testname, char *condname,
+ int ret, int start, unsigned int alen,
+ unsigned int blen, unsigned int clen,
+ struct nx842_constraints *constraints)
+{
+ if (condition) {
+ char *fmt = "%s self test (%s) expected to fail, but didn't.";
+ char msg[256];
+
+ if (ret)
+ return 1;
+
+ snprintf(msg, 256, fmt, testname, condname);
+
+ params_debug(msg, start, alen, blen, clen, constraints);
+ }
+
+ return 0;
+}
+
+static int test_check_expected_fail(char *testname,
+ int ret, int start, unsigned int alen,
+ unsigned int blen, unsigned int clen,
+ struct nx842_constraints *constraints)
+{
+ unsigned int lens[3] = { alen, blen, clen, };
+ char *names[3] = { "a", "b", "c", };
+ int i;
+
+ if (expected_fail(start % constraints->alignment, testname,
+ "invalid align", ret, start, alen, blen, clen, constraints))
+ return -1;
+
+ for (i = 0; i < 3; i++) {
+ unsigned int l = lens[i];
+ char *n = names[i];
+ char reason[256];
+
+ if (!l)
+ continue;
+
+ snprintf(reason, 256, "%s len invalid", n);
+ if (expected_fail(l % constraints->multiple, testname,
+ reason, ret, start, alen, blen, clen, constraints))
+ return -1;
+
+ snprintf(reason, 256, "%s len under min", n);
+ if (expected_fail(l < constraints->minimum, testname,
+ reason, ret, start, alen, blen, clen, constraints))
+ return -1;
+
+ snprintf(reason, 256, "%s len over max", n);
+ if (expected_fail(l > constraints->maximum, testname,
+ reason, ret, start, alen, blen, clen, constraints))
+ return -1;
+ }
+
+ return 0;
+}
+
+static int test_check_valid_data(char *testname,
+ unsigned char *a, int start, unsigned int alen,
+ unsigned char *b, unsigned int blen,
+ unsigned char *c, unsigned int clen,
+ struct nx842_constraints *constraints)
+{
+ if (alen != clen) {
+ char *fmt = "%s self test length mismatch.";
+ char msg[256];
+
+ snprintf(msg, 256, fmt, testname);
+ params_err(msg, start, alen, blen, clen, constraints);
+ return -1;
+ }
+
+ if (memcmp(&a[start], c, alen)) {
+ char *fmt = "%s self test data mismatch.";
+ char msg[256];
+
+ snprintf(msg, 256, fmt, testname);
+ params_err(msg, start, alen, blen, clen, constraints);
+
+ debug_buffer("original data", &a[start], alen);
+ debug_buffer("compressed data", b, blen);
+ debug_buffer("decompressed data", c, clen);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int test_sw_decomp(struct test_selftest_param *p)
+{
+ struct nx842_constraints nc = { 0, 0, 0, 0, };
+ unsigned long start;
+ int ret;
+
+ /* can't sw decomp with crypto/842.c
+ * (it does sw decomp internally if needed)
+ */
+ if (!p->sw_decomp)
+ return 0;
+
+ p->clen = TEST_BUF_SIZE;
+
+ memset(p->c, 0, p->clen);
+
+ start = get_tb();
+
+ ret = p->sw_decomp(p->b, p->blen, p->c, &p->clen);
+
+ if (ret) {
+ params_err("sw decompress self test failed.",
+ p->astart, p->alen, p->blen, p->clen, &nc);
+ debug_buffer("compressed data", p->b, p->blen);
+ return -1;
+ }
+
+ if (test_check_valid_data("sw decompress",
+ p->a, p->astart, p->alen,
+ p->b, p->blen, p->c, p->clen, &nc))
+ return -1;
+
+ p->sw_bps = calc_bps(p->sw_bps, p->clen, start);
+
+ return 0;
+}
+
+static int test_decomp(struct test_selftest_param *p)
+{
+ struct nx842_constraints constraints;
+ unsigned long start;
+ int ret;
+
+ if ((ret = p->constraints(&constraints))) {
+ pr_err("error getting nx842 constraints : %d\n", ret);
+ return ret;
+ }
+
+ p->clen = min_t(int, constraints.maximum, TEST_BUF_SIZE);
+ p->clen = round_down(p->clen, constraints.multiple);
+
+ memset(p->c, 0, p->clen);
+
+ start = get_tb();
+
+ ret = p->decomp(p->b, p->blen, p->c, &p->clen, &p->arg);
+
+ // TODO - add decomp tests with invalid align and len
+ if (test_check_expected_fail("decompression", ret,
+ p->astart, p->alen, p->blen, p->clen, &constraints))
+ return 0;
+
+ if (ret) {
+ params_err("decompression self test failed.",
+ p->astart, p->alen, p->blen, p->clen, &constraints);
+ debug_buffer("compressed data", p->b, p->blen);
+ return -1;
+ }
+
+ if (test_check_valid_data("decompress",
+ p->a, p->astart, p->alen,
+ p->b, p->blen, p->c, p->clen, &constraints))
+ return -1;
+
+ p->decomp_bps = calc_bps(p->decomp_bps, p->clen, start);
+
+ return test_sw_decomp(p);
+}
+
+static int test_comp(struct test_selftest_param *p)
+{
+ struct nx842_constraints constraints;
+ unsigned long start;
+ int ret;
+
+ if ((ret = p->constraints(&constraints))) {
+ pr_err("error getting nx842 constraints : %d\n", ret);
+ return ret;
+ }
+
+ p->blen = min_t(int, constraints.maximum, TEST_BUF_SIZE);
+ p->blen = round_down(p->blen, constraints.multiple);
+
+ memset(p->b, 0, p->blen);
+
+ start = get_tb();
+
+ ret = p->comp(&p->a[p->astart], p->alen, p->b, &p->blen, &p->arg);
+
+ if (test_check_expected_fail("compression", ret,
+ p->astart, p->alen, p->blen, 0, &constraints))
+ return 0;
+
+ if (ret) {
+ params_err("compression self test failed.",
+ p->astart, p->alen, p->blen, 0, &constraints);
+ debug_buffer("original data", p->a, p->alen);
+ return -1;
+ }
+
+ p->comp_bps = calc_bps(p->comp_bps, p->alen, start);
+
+ return test_decomp(p);
+}
+
+static int test_crypto842_constraints(struct nx842_constraints *constraints)
+{
+ constraints->alignment = 1;
+ constraints->multiple = 1;
+ constraints->minimum = 1;
+ constraints->maximum = PAGE_SIZE * 4; /* arbitrary */
+
+ return 0;
+}
+
+static int test_run(void *data)
+{
+ struct test_selftest_param *p = data;
+ int i, ret = 0, pct = 0, test_n = 0, test_total;
+
+ for (i = 0; i*16+15 < TEST_BUF_SIZE; i++)
+ memset(&p->a[i*16], i%0xff, 16);
+
+ pr_info("%s starting.\n", p->name);
+
+ BUILD_BUG_ON(MAX_TEST_START + MAX_TEST_LEN > TEST_BUF_SIZE);
+
+ /* p->alen should have been set to > 0 by file write arg */
+ test_total = MAX_TEST_LEN - p->alen;
+ for (; p->alen <= MAX_TEST_LEN; p->alen++) {
+ for (p->astart = 0; p->astart < MAX_TEST_START; p->astart++) {
+ if ((ret = test_comp(p)) || kthread_should_stop())
+ goto end;
+ if (!(p->astart % 0x1000))
+ schedule(); /* don't lock up the cpu */
+ }
+ if (((test_n++)*100)/test_total >= pct) {
+ pr_info("self test %d%% complete.\n", pct);
+ pct += 1;
+ }
+ }
+
+end:
+ if (kthread_should_stop())
+ pr_info("self test interrupted\n");
+
+ pr_info("self test completed.\n");
+
+ p->kthread = NULL;
+ module_put(THIS_MODULE);
+
+ return ret;
+}
+
+/* Self-test */
+
+static ssize_t __test_selftest_read(struct file *file,
+ char __user *buf, size_t len, loff_t *off,
+ struct test_selftest_param *p)
+{
+ int ret = 0;
+ char tmp[128];
+
+ if (*off > 0)
+ return 0;
+
+ if (down_interruptible(&p->lock))
+ return -EBUSY;
+
+ if (p->kthread) {
+ schedule_timeout_interruptible(10); /* slow down the updates */
+ snprintf(tmp, 128, "astart %x/%lx alen %x/%lx "
+ "MBps: %ld comp %ld decomp %ld sw decomp"
+ " \r",
+ p->astart, MAX_TEST_START, p->alen, MAX_TEST_LEN,
+ p->comp_bps / 1000000,
+ p->decomp_bps / 1000000,
+ p->sw_bps / 1000000);
+ } else {
+ snprintf(tmp, 128,
+ "\nself test not running\n");
+ *off = strlen(tmp);
+ }
+
+ len = min(len, strlen(tmp));
+
+ if (copy_to_user(buf, tmp, len))
+ ret = -EFAULT;
+
+ up(&p->lock);
+
+ return ret ? ret : len;
+}
+
+static ssize_t __test_selftest_write(struct file *file,
+ const char __user *buf, size_t len, loff_t *off,
+ struct test_selftest_param *p)
+{
+ int ret = 0, arg;
+
+ if (*off > 0 || len < 1)
+ return -EINVAL;
+
+ if ((ret = kstrtoint_from_user(buf, len, 0, &arg)))
+ return ret;
+
+ if (down_interruptible(&p->lock))
+ return -EBUSY;
+
+ if (arg > 0) {
+ if (!p->kthread) {
+ __module_get(THIS_MODULE);
+ p->alen = arg;
+ p->kthread = kthread_run(test_run, p, p->name);
+ if (IS_ERR(p->kthread)) {
+ ret = PTR_ERR(p->kthread);
+ p->kthread = NULL;
+ module_put(THIS_MODULE);
+ }
+ }
+ } else if (!arg) {
+ if (p->kthread)
+ ret = kthread_stop(p->kthread);
+ } else {
+ ret = -EINVAL;
+ }
+
+ if (!ret)
+ *off = 1;
+
+ up(&p->lock);
+
+ return ret ? ret : len;
+}
+
+#define TEST_FUNC(name) \
+static ssize_t test_##name##_read(struct file *file, \
+ char __user *buf, size_t len, loff_t *off) \
+{ \
+ return __test_selftest_read(file, buf, len, off, \
+ &test_##name##_param); \
+} \
+static ssize_t test_##name##_write(struct file *file, \
+ const char __user *buf, size_t len, loff_t *off) \
+{ \
+ return __test_selftest_write(file, buf, len, off, \
+ &test_##name##_param); \
+}
+
+TEST_FUNC(selftest);
+TEST_FUNC(crypto842_selftest);
+
+/************************************/
+/* Provided buffer comp/decomp test */
+
+struct test_buffer_param {
+ struct semaphore lock;
+ unsigned char *buffer;
+ unsigned int len;
+ struct test_arg_param arg;
+ int (*op)(const unsigned char *in, unsigned int in_len,
+ unsigned char *out, unsigned int *out_len,
+ struct test_arg_param *p);
+};
+
+static struct test_buffer_param test_comp_param, test_decomp_param,
+ test_crypto842_comp_param, test_crypto842_decomp_param;
+
+static ssize_t test_buffer_read(struct file *file, char __user *buf, size_t len,
+ loff_t *off, struct test_buffer_param *p)
+{
+ ssize_t ret;
+
+ pr_debug("buffer read f_pos %d off %d len %d\n",
+ (int)file->f_pos, (int)*off, (int)len);
+
+ if (file->f_pos > 0 || *off > 0)
+ return 0;
+
+ if (down_interruptible(&p->lock))
+ return -EBUSY;
+
+ pr_debug("buffer read p->len %d\n", p->len);
+
+ if (!p->len) {
+ ret = 0;
+ } else if (len < p->len) {
+ ret = -ENOSPC;
+ } else if (copy_to_user(buf, p->buffer, p->len)) {
+ ret = -EFAULT;
+ } else {
+ *off = ret = p->len;
+ p->len = 0;
+ }
+
+ up(&p->lock);
+
+ return ret;
+}
+
+static ssize_t test_buffer_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *off, struct test_buffer_param *p)
+{
+ int ret;
+ unsigned char *in;
+
+ pr_debug("buffer write f_pos %d off %d len %d\n",
+ (int)file->f_pos, (int)*off, (int)len);
+
+ if (file->f_pos > 0 || *off > 0 || len < 1)
+ return -EINVAL;
+ else if (len > (PAGE_SIZE * 4))
+ return -ENOSPC;
+
+ if (down_interruptible(&p->lock))
+ return -EBUSY;
+
+ pr_debug("buffer write was p->len %d\n", p->len);
+
+ p->len = TEST_BUF_SIZE;
+
+ if (!(in = (unsigned char*)__get_free_page(GFP_KERNEL)))
+ ret = -ENOMEM;
+ else if (copy_from_user(in, buf, len))
+ ret = -EFAULT;
+ else if (!(ret = p->op(in, len,
+ p->buffer, &p->len, &p->arg)))
+ *off = ret = len;
+
+ free_page((unsigned long)in);
+
+ up(&p->lock);
+
+ return ret;
+}
+
+#define TEST_BUFFER_FUNC(name) \
+static ssize_t test_##name##_read(struct file *file, \
+ char __user *buf, size_t len, loff_t *off) \
+{ \
+ return test_buffer_read(file, buf, len, off, \
+ &test_##name##_param); \
+} \
+static ssize_t test_##name##_write(struct file *file, \
+ const char __user *buf, size_t len, loff_t *off) \
+{ \
+ return test_buffer_write(file, buf, len, off, \
+ &test_##name##_param); \
+}
+
+TEST_BUFFER_FUNC(comp);
+TEST_BUFFER_FUNC(decomp);
+TEST_BUFFER_FUNC(crypto842_comp);
+TEST_BUFFER_FUNC(crypto842_decomp);
+
+#define TEST_FOPS(name) \
+ static struct file_operations test_##name##_ops = { \
+ .owner = THIS_MODULE, \
+ .read = test_##name##_read, \
+ .write = test_##name##_write, \
+ };
+
+TEST_FOPS(selftest);
+TEST_FOPS(comp);
+TEST_FOPS(decomp);
+TEST_FOPS(crypto842_selftest);
+TEST_FOPS(crypto842_comp);
+TEST_FOPS(crypto842_decomp);
+
+static struct dentry *test_root = NULL;
+
+static void test_exit(void)
+{
+ struct test_selftest_param *selftest_params[] = {
+ &test_selftest_param, &test_crypto842_selftest_param, };
+ struct test_buffer_param *buffer_params[] = {
+ &test_comp_param, &test_decomp_param,
+ &test_crypto842_comp_param, &test_crypto842_decomp_param, };
+ int i;
+
+ debugfs_remove_recursive(test_root);
+
+ for (i = 0; i < ARRAY_SIZE(selftest_params); i++) {
+ struct test_selftest_param *p = selftest_params[i];
+
+ if (p->arg.tfm)
+ crypto_free_comp(p->arg.tfm);
+ kfree(p->arg.wmem);
+ free_pages((unsigned long)p->a, TEST_BUF_ORDER);
+ free_pages((unsigned long)p->b, TEST_BUF_ORDER);
+ free_pages((unsigned long)p->c, TEST_BUF_ORDER);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(buffer_params); i++) {
+ struct test_buffer_param *p = buffer_params[i];
+
+ if (p->arg.tfm)
+ crypto_free_comp(p->arg.tfm);
+ kfree(p->arg.wmem);
+ free_pages((unsigned long)p->buffer, TEST_BUF_ORDER);
+ }
+}
+module_exit(test_exit);
+
+static int __init test_init(void)
+{
+ struct dentry *crypto_842_root;
+ struct test_selftest_param *selftest_params[] = {
+ &test_selftest_param, &test_crypto842_selftest_param, };
+ struct test_buffer_param *buffer_params[] = {
+ &test_comp_param, &test_decomp_param,
+ &test_crypto842_comp_param, &test_crypto842_decomp_param, };
+ int i, ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(selftest_params); i++) {
+ struct test_selftest_param *p = selftest_params[i];
+
+ sema_init(&p->lock, 1);
+
+ p->arg.tfm = crypto_alloc_comp("842", 0, 0);
+ p->arg.wmem = kmalloc(NX842_MEM_COMPRESS, GFP_KERNEL);
+ p->a = (unsigned char*)__get_free_pages(GFP_KERNEL,
+ TEST_BUF_ORDER);
+ p->b = (unsigned char*)__get_free_pages(GFP_KERNEL,
+ TEST_BUF_ORDER);
+ p->c = (unsigned char*)__get_free_pages(GFP_KERNEL,
+ TEST_BUF_ORDER);
+ if (IS_ERR(p->arg.tfm)) {
+ p->arg.tfm = NULL;
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (!p->arg.wmem || !p->a || !p->b || !p->c) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(buffer_params); i++) {
+ struct test_buffer_param *p = buffer_params[i];
+
+ sema_init(&p->lock, 1);
+ p->len = 0;
+
+ p->arg.tfm = crypto_alloc_comp("842", 0, 0);
+ p->arg.wmem = kmalloc(NX842_MEM_COMPRESS, GFP_KERNEL);
+ p->buffer = (unsigned char *)__get_free_pages(GFP_KERNEL,
+ TEST_BUF_ORDER);
+ if (IS_ERR(p->arg.tfm)) {
+ p->arg.tfm = NULL;
+ ret = -EINVAL;
+ goto fail;
+ }
+ if (!p->buffer || !p->arg.wmem) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ test_comp_param.op = test_nx842_comp;
+ test_decomp_param.op = test_nx842_decomp;
+ test_crypto842_comp_param.op = test_crypto842_comp;
+ test_crypto842_decomp_param.op = test_crypto842_decomp;
+
+ test_selftest_param.name = "nx842 selftest";
+ test_selftest_param.constraints = nx842_constraints;
+ test_selftest_param.comp = test_nx842_comp;
+ test_selftest_param.decomp = test_nx842_decomp;
+ test_selftest_param.sw_decomp = sw842_decompress;
+ test_crypto842_selftest_param.name = "crypto 842 selftest";
+ test_crypto842_selftest_param.constraints =
+ test_crypto842_constraints;
+ test_crypto842_selftest_param.comp = test_crypto842_comp;
+ test_crypto842_selftest_param.decomp = test_crypto842_decomp;
+ test_crypto842_selftest_param.sw_decomp = NULL;
+
+ if (!debugfs_initialized()) {
+ ret = -ENODEV;
+ } else if (!(test_root =
+ debugfs_create_dir("nx_compress_test", NULL))) {
+ ret = -ENOMEM;
+ } else if (!(crypto_842_root =
+ debugfs_create_dir("crypto_842", test_root))) {
+ ret = -ENOMEM;
+ } else {
+ debugfs_create_file("selftest", S_IRUGO | S_IWUSR,
+ test_root, NULL, &test_selftest_ops);
+ debugfs_create_file("compress", S_IRUGO | S_IWUSR,
+ test_root, NULL, &test_comp_ops);
+ debugfs_create_file("decompress", S_IRUGO | S_IWUSR,
+ test_root, NULL, &test_decomp_ops);
+
+ debugfs_create_file("selftest", S_IRUGO | S_IWUSR,
+ crypto_842_root, NULL, &test_crypto842_selftest_ops);
+ debugfs_create_file("compress", S_IRUGO | S_IWUSR,
+ crypto_842_root, NULL, &test_crypto842_comp_ops);
+ debugfs_create_file("decompress", S_IRUGO | S_IWUSR,
+ crypto_842_root, NULL, &test_crypto842_decomp_ops);
+ }
+
+fail:
+ if (ret)
+ test_exit();
+
+ return ret;
+}
+module_init(test_init);
--
2.1.0
More information about the Skiboot
mailing list