All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/6] Drivers for Loongson security engine
@ 2025-02-26  3:03 Qunqin Zhao
  2025-02-26  3:03 ` [PATCH v4 1/6] mfd: Add support for Loongson Security Module Qunqin Zhao
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Qunqin Zhao @ 2025-02-26  3:03 UTC (permalink / raw)
  To: lee, herbert, davem, peterhuewe, jarkko
  Cc: linux-kernel, loongarch, linux-crypto, jgg, linux-integrity,
	pmenzel, Qunqin Zhao

Loongson security engine supports random number generation, hash,
symmetric encryption and asymmetric encryption. Based on these
encryption functions, TPM2 have been implemented in it.

mfd is the baser driver, crypto and tpm are users.

v4: Please look at changelog in tpm and MAINTAINERS. No changes to tpm
    and crypto. 
v3: Put the updates to the MAINTAINERS in a separate patch.
v2: Removed misc driver. Added tpm driver.

Qunqin Zhao (6):
  mfd: Add support for Loongson Security Module
  MAINTAINERS: Add entry for Loongson Security Module driver
  crypto: loongson - add Loongson RNG driver support
  MAINTAINERS: Add entry for Loongson RNG driver
  tpm: Add a driver for Loongson TPM device
  MAINTAINERS: Add tpm_lsse.c to LOONGSON CRYPTO DRIVER entry

 MAINTAINERS                            |  14 +
 drivers/char/tpm/Kconfig               |   9 +
 drivers/char/tpm/Makefile              |   1 +
 drivers/char/tpm/tpm_lsse.c            | 103 +++++++
 drivers/crypto/Kconfig                 |   1 +
 drivers/crypto/Makefile                |   1 +
 drivers/crypto/loongson/Kconfig        |   6 +
 drivers/crypto/loongson/Makefile       |   2 +
 drivers/crypto/loongson/ls6000se-rng.c | 190 +++++++++++++
 drivers/mfd/Kconfig                    |  10 +
 drivers/mfd/Makefile                   |   2 +
 drivers/mfd/ls6000se.c                 | 374 +++++++++++++++++++++++++
 include/linux/mfd/ls6000se.h           |  75 +++++
 13 files changed, 788 insertions(+)
 create mode 100644 drivers/char/tpm/tpm_lsse.c
 create mode 100644 drivers/crypto/loongson/Kconfig
 create mode 100644 drivers/crypto/loongson/Makefile
 create mode 100644 drivers/crypto/loongson/ls6000se-rng.c
 create mode 100644 drivers/mfd/ls6000se.c
 create mode 100644 include/linux/mfd/ls6000se.h


base-commit: bd315242821784e9384abae911a70d5fda9a3298
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v4 1/6] mfd: Add support for Loongson Security Module
  2025-02-26  3:03 [PATCH v4 0/6] Drivers for Loongson security engine Qunqin Zhao
@ 2025-02-26  3:03 ` Qunqin Zhao
  2025-03-12  8:08   ` Lee Jones
  2025-02-26  3:03 ` [PATCH v4 2/6] MAINTAINERS: Add entry for Loongson Security Module driver Qunqin Zhao
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Qunqin Zhao @ 2025-02-26  3:03 UTC (permalink / raw)
  To: lee, herbert, davem, peterhuewe, jarkko
  Cc: linux-kernel, loongarch, linux-crypto, jgg, linux-integrity,
	pmenzel, Qunqin Zhao, Yinggang Gu

This driver supports Loongson Security Module, which provides the control
for it's hardware encryption acceleration child devices.

Co-developed-by: Yinggang Gu <guyinggang@loongson.cn>
Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
---
v3-v4: None

v2: Removed "ls6000se-sdf" device, added "ls6000se-tpm" device.
    Passed dmamem size to SE firmware in se_init_hw() function.

 drivers/mfd/Kconfig          |  10 +
 drivers/mfd/Makefile         |   2 +
 drivers/mfd/ls6000se.c       | 374 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/ls6000se.h |  75 +++++++
 4 files changed, 461 insertions(+)
 create mode 100644 drivers/mfd/ls6000se.c
 create mode 100644 include/linux/mfd/ls6000se.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d44c69bb3d..318fb113c1 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -2439,5 +2439,15 @@ config MFD_UPBOARD_FPGA
 	  To compile this driver as a module, choose M here: the module will be
 	  called upboard-fpga.
 
+config MFD_LS6000SE
+	tristate "Loongson Security Module Interface"
+	depends on LOONGARCH && ACPI
+	select MFD_CORE
+	help
+	  The Loongson security module provides the control for hardware
+	  encryption acceleration devices. Each device uses at least one
+	  channel to interact with security module, and each channel may
+	  have its own buffer provided by security module.
+
 endmenu
 endif
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 9220eaf7cf..9556de7715 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -294,3 +294,5 @@ obj-$(CONFIG_MFD_RSMU_I2C)	+= rsmu_i2c.o rsmu_core.o
 obj-$(CONFIG_MFD_RSMU_SPI)	+= rsmu_spi.o rsmu_core.o
 
 obj-$(CONFIG_MFD_UPBOARD_FPGA)	+= upboard-fpga.o
+
+obj-$(CONFIG_MFD_LS6000SE)	+= ls6000se.o
diff --git a/drivers/mfd/ls6000se.c b/drivers/mfd/ls6000se.c
new file mode 100644
index 0000000000..24d76c2ffc
--- /dev/null
+++ b/drivers/mfd/ls6000se.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2025 Loongson Technology Corporation Limited */
+
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ls6000se.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+/*
+ * The Loongson Security Module provides the control for hardware
+ * encryption acceleration child devices. The SE framework is
+ * shown as follows:
+ *
+ *                   +------------+
+ *                   |    CPU     |
+ *                   +------------+
+ *			^	^
+ *	            DMA |	| IRQ
+ *			v	v
+ *        +-----------------------------------+
+ *        |     Loongson Security Module      |
+ *        +-----------------------------------+
+ *             ^                ^
+ *    channel1 |       channel2 |
+ *             v                v
+ *        +-----------+    +----------+
+ *        | sub-dev1  |    | sub-dev2 |  ..... Max sub-dev31
+ *        +-----------+    +----------+
+ *
+ * The CPU cannot directly communicate with SE's sub devices,
+ * but sends commands to SE, which processes the commands and
+ * sends them to the corresponding sub devices.
+ */
+
+struct loongson_se {
+	void __iomem *base;
+	u32 version;
+	spinlock_t dev_lock;
+	struct completion cmd_completion;
+
+	/* dma memory */
+	void *mem_base;
+	int mem_map_pages;
+	unsigned long *mem_map;
+
+	/* channel */
+	struct mutex ch_init_lock;
+	struct lsse_ch chs[SE_CH_MAX];
+};
+
+union se_request {
+	u32 info[8];
+	struct se_cmd {
+		u32 cmd;
+		u32 info[7];
+	} req;
+	struct se_res {
+		u32 cmd;
+		u32 cmd_ret;
+		u32 info[6];
+	} res;
+};
+
+static inline u32 se_readl(struct loongson_se *se, u32 off)
+{
+	return readl(se->base + off);
+}
+
+static inline void se_writel(struct loongson_se *se, u32 val, u32 off)
+{
+	writel(val, se->base + off);
+}
+
+static void se_enable_int_locked(struct loongson_se *se, u32 int_bit)
+{
+	u32 tmp;
+
+	tmp = se_readl(se, SE_S2LINT_EN);
+	tmp |= int_bit;
+	se_writel(se, tmp, SE_S2LINT_EN);
+}
+
+static void se_disable_int(struct loongson_se *se, u32 int_bit)
+{
+	unsigned long flag;
+	u32 tmp;
+
+	spin_lock_irqsave(&se->dev_lock, flag);
+
+	tmp = se_readl(se, SE_S2LINT_EN);
+	tmp &= ~(int_bit);
+	se_writel(se, tmp, SE_S2LINT_EN);
+
+	spin_unlock_irqrestore(&se->dev_lock, flag);
+}
+
+static int se_poll(struct loongson_se *se, u32 int_bit)
+{
+	u32 status;
+	int err;
+
+	spin_lock_irq(&se->dev_lock);
+
+	se_enable_int_locked(se, int_bit);
+	se_writel(se, int_bit, SE_L2SINT_SET);
+	err = readl_relaxed_poll_timeout_atomic(se->base + SE_L2SINT_STAT, status,
+						!(status & int_bit), 1, 10000);
+
+	spin_unlock_irq(&se->dev_lock);
+
+	return err;
+}
+
+static int se_send_requeset(struct loongson_se *se, union se_request *req)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(req->info); i++)
+		se_writel(se, req->info[i], SE_DATA_S + i * 4);
+
+	return se_poll(se, SE_INT_SETUP);
+}
+
+/*
+ * Called by SE's child device driver.
+ * Send a request to the corresponding device.
+ */
+int se_send_ch_requeset(struct lsse_ch *ch)
+{
+	return se_poll(ch->se, ch->int_bit);
+}
+EXPORT_SYMBOL_GPL(se_send_ch_requeset);
+
+static int se_get_res(struct loongson_se *se, u32 cmd, union se_request *res)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(res->info); i++)
+		res->info[i] = se_readl(se, SE_DATA_L + i * 4);
+
+	if (res->res.cmd != cmd)
+		return -EFAULT;
+
+	return 0;
+}
+
+static int se_send_genl_cmd(struct loongson_se *se, union se_request *req)
+{
+	int err;
+
+	err = se_send_requeset(se, req);
+	if (err)
+		return err;
+
+	if (!wait_for_completion_timeout(&se->cmd_completion, HZ))
+		return -ETIME;
+
+	return se_get_res(se, req->req.cmd, req);
+}
+
+static int se_set_msg(struct lsse_ch *ch)
+{
+	struct loongson_se *se = ch->se;
+	union se_request req;
+
+	req.req.cmd = SE_CMD_SETMSG;
+	req.req.info[0] = ch->id;
+	req.req.info[1] = ch->smsg - se->mem_base;
+	req.req.info[2] = ch->msg_size;
+
+	return se_send_genl_cmd(se, &req);
+}
+
+static irqreturn_t se_irq(int irq, void *dev_id)
+{
+	struct loongson_se *se = (struct loongson_se *)dev_id;
+	struct lsse_ch *ch;
+	u32 int_status;
+	int id;
+
+	int_status = se_readl(se, SE_S2LINT_STAT);
+	se_disable_int(se, int_status);
+	if (int_status & SE_INT_SETUP) {
+		complete(&se->cmd_completion);
+		int_status &= ~SE_INT_SETUP;
+		se_writel(se, SE_INT_SETUP, SE_S2LINT_CL);
+	}
+
+	while (int_status) {
+		id = __ffs(int_status);
+
+		ch = &se->chs[id];
+		if (ch->complete)
+			ch->complete(ch);
+		int_status &= ~BIT(id);
+		se_writel(se, BIT(id), SE_S2LINT_CL);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int se_init_hw(struct loongson_se *se, dma_addr_t addr, int size)
+{
+	union se_request req;
+	int err;
+
+	/* Start engine */
+	req.req.cmd = SE_CMD_START;
+	err = se_send_genl_cmd(se, &req);
+	if (err)
+		return err;
+
+	/* Get Version */
+	req.req.cmd = SE_CMD_GETVER;
+	err = se_send_genl_cmd(se, &req);
+	if (err)
+		return err;
+	se->version = req.res.info[0];
+
+	/* Setup dma memory */
+	req.req.cmd = SE_CMD_SETBUF;
+	req.req.info[0] = addr & 0xffffffff;
+	req.req.info[1] = addr >> 32;
+	req.req.info[2] = size;
+
+	return se_send_genl_cmd(se, &req);
+}
+
+/*
+ * se_init_ch() - Init the channel used by child device.
+ *
+ * Allocate dma memory as agreed upon with SE on SE probe,
+ * and register the callback function when the data processing
+ * in this channel is completed.
+ */
+struct lsse_ch *se_init_ch(struct device *dev, int id, int data_size, int msg_size,
+			   void *priv, void (*complete)(struct lsse_ch *se_ch))
+{
+	struct loongson_se *se = dev_get_drvdata(dev);
+	struct lsse_ch *ch;
+	int data_first, data_nr;
+	int msg_first, msg_nr;
+
+	mutex_lock(&se->ch_init_lock);
+
+	ch = &se->chs[id];
+	ch->se = se;
+	ch->id = id;
+	ch->int_bit = BIT(id);
+
+	data_nr = round_up(data_size, PAGE_SIZE) / PAGE_SIZE;
+	data_first = bitmap_find_next_zero_area(se->mem_map, se->mem_map_pages,
+						0, data_nr, 0);
+	if (data_first >= se->mem_map_pages) {
+		ch = NULL;
+		goto out_unlock;
+	}
+
+	bitmap_set(se->mem_map, data_first, data_nr);
+	ch->off = data_first * PAGE_SIZE;
+	ch->data_buffer = se->mem_base + ch->off;
+	ch->data_size = data_size;
+
+	msg_nr = round_up(msg_size, PAGE_SIZE) / PAGE_SIZE;
+	msg_first = bitmap_find_next_zero_area(se->mem_map, se->mem_map_pages,
+					       0, msg_nr, 0);
+	if (msg_first >= se->mem_map_pages) {
+		ch = NULL;
+		goto out_unlock;
+	}
+
+	bitmap_set(se->mem_map, msg_first, msg_nr);
+	ch->smsg = se->mem_base + msg_first * PAGE_SIZE;
+	ch->rmsg = ch->smsg + msg_size / 2;
+	ch->msg_size = msg_size;
+	ch->complete = complete;
+	ch->priv = priv;
+	ch->version = se->version;
+
+	if (se_set_msg(ch))
+		ch = NULL;
+
+out_unlock:
+	mutex_unlock(&se->ch_init_lock);
+
+	return ch;
+}
+EXPORT_SYMBOL_GPL(se_init_ch);
+
+static const struct mfd_cell se_devs[] = {
+	{ .name = "ls6000se-sdf" },
+	{ .name = "ls6000se-tpm" },
+};
+
+static int loongson_se_probe(struct platform_device *pdev)
+{
+	struct loongson_se *se;
+	struct device *dev = &pdev->dev;
+	int nr_irq, irq, err, size;
+	dma_addr_t paddr;
+
+	se = devm_kmalloc(dev, sizeof(*se), GFP_KERNEL);
+	if (!se)
+		return -ENOMEM;
+	dev_set_drvdata(dev, se);
+	init_completion(&se->cmd_completion);
+	spin_lock_init(&se->dev_lock);
+	mutex_init(&se->ch_init_lock);
+	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+	if (device_property_read_u32(dev, "dmam_size", &size))
+		return -ENODEV;
+	size = roundup_pow_of_two(size);
+	se->mem_base = dmam_alloc_coherent(dev, size, &paddr, GFP_KERNEL);
+	if (!se->mem_base)
+		return -ENOMEM;
+	se->mem_map_pages = size / PAGE_SIZE;
+	se->mem_map = devm_bitmap_zalloc(dev, se->mem_map_pages, GFP_KERNEL);
+	if (!se->mem_map)
+		return -ENOMEM;
+
+	se->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(se->base))
+		return PTR_ERR(se->base);
+
+	nr_irq = platform_irq_count(pdev);
+	if (nr_irq <= 0)
+		return -ENODEV;
+	while (nr_irq) {
+		irq = platform_get_irq(pdev, --nr_irq);
+		/* Use the same interrupt handler address.
+		 * Determine which irq it is accroding
+		 * SE_S2LINT_STAT register.
+		 */
+		err = devm_request_irq(dev, irq, se_irq, 0, "ls6000se", se);
+		if (err)
+			dev_err(dev, "failed to request irq: %d\n", irq);
+	}
+
+	err = se_init_hw(se, paddr, size);
+	if (err)
+		return err;
+
+	return devm_mfd_add_devices(dev, 0, se_devs, ARRAY_SIZE(se_devs),
+				    NULL, 0, NULL);
+}
+
+static const struct acpi_device_id loongson_se_acpi_match[] = {
+	{"LOON0011", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, loongson_se_acpi_match);
+
+static struct platform_driver loongson_se_driver = {
+	.probe   = loongson_se_probe,
+	.driver  = {
+		.name  = "ls6000se",
+		.acpi_match_table = loongson_se_acpi_match,
+	},
+};
+module_platform_driver(loongson_se_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yinggang Gu <guyinggang@loongson.cn>");
+MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@loongson.cn>");
+MODULE_DESCRIPTION("Loongson Security Module driver");
diff --git a/include/linux/mfd/ls6000se.h b/include/linux/mfd/ls6000se.h
new file mode 100644
index 0000000000..f70e9f196a
--- /dev/null
+++ b/include/linux/mfd/ls6000se.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Copyright (C) 2025 Loongson Technology Corporation Limited */
+
+#ifndef __LOONGSON_SE_H__
+#define __LOONGSON_SE_H__
+
+#define SE_DATA_S			0x0
+#define SE_DATA_L			0x20
+#define SE_S2LINT_STAT			0x88
+#define SE_S2LINT_EN			0x8c
+#define SE_S2LINT_SET			0x90
+#define SE_S2LINT_CL			0x94
+#define SE_L2SINT_STAT			0x98
+#define SE_L2SINT_EN			0x9c
+#define SE_L2SINT_SET			0xa0
+#define SE_L2SINT_CL			0xa4
+
+/* INT bit definition */
+#define SE_INT_SETUP			BIT(0)
+#define SE_INT_TPM			BIT(5)
+
+#define SE_CMD_START			0x0
+#define SE_CMD_STOP			0x1
+#define SE_CMD_GETVER			0x2
+#define SE_CMD_SETBUF			0x3
+#define SE_CMD_SETMSG			0x4
+
+#define SE_CMD_RNG			0x100
+#define SE_CMD_SM2_SIGN			0x200
+#define SE_CMD_SM2_VSIGN		0x201
+#define SE_CMD_SM3_DIGEST		0x300
+#define SE_CMD_SM3_UPDATE		0x301
+#define SE_CMD_SM3_FINISH		0x302
+#define SE_CMD_SM4_ECB_ENCRY		0x400
+#define SE_CMD_SM4_ECB_DECRY		0x401
+#define SE_CMD_SM4_CBC_ENCRY		0x402
+#define SE_CMD_SM4_CBC_DECRY		0x403
+#define SE_CMD_SM4_CTR			0x404
+#define SE_CMD_TPM			0x500
+#define SE_CMD_ZUC_INIT_READ		0x600
+#define SE_CMD_ZUC_READ			0x601
+#define SE_CMD_SDF			0x700
+
+#define SE_CH_MAX			32
+#define SE_CH_RNG			1
+#define SE_CH_SM2			2
+#define SE_CH_SM3			3
+#define SE_CH_SM4			4
+#define SE_CH_TPM			5
+#define SE_CH_ZUC			6
+#define SE_CH_SDF			7
+
+struct lsse_ch {
+	struct loongson_se *se;
+	void *priv;
+	u32 version;
+	u32 id;
+	u32 int_bit;
+
+	void *smsg;
+	void *rmsg;
+	int msg_size;
+
+	void *data_buffer;
+	int data_size;
+	u32 off;
+
+	void (*complete)(struct lsse_ch *se_ch);
+};
+
+struct lsse_ch *se_init_ch(struct device *dev, int id, int data_size, int msg_size,
+			   void *priv, void (*complete)(struct lsse_ch *se_ch));
+int se_send_ch_requeset(struct lsse_ch *ch);
+
+#endif
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 2/6] MAINTAINERS: Add entry for Loongson Security Module driver
  2025-02-26  3:03 [PATCH v4 0/6] Drivers for Loongson security engine Qunqin Zhao
  2025-02-26  3:03 ` [PATCH v4 1/6] mfd: Add support for Loongson Security Module Qunqin Zhao
@ 2025-02-26  3:03 ` Qunqin Zhao
  2025-02-26  3:03 ` [PATCH v4 3/6] crypto: loongson - add Loongson RNG driver support Qunqin Zhao
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Qunqin Zhao @ 2025-02-26  3:03 UTC (permalink / raw)
  To: lee, herbert, davem, peterhuewe, jarkko
  Cc: linux-kernel, loongarch, linux-crypto, jgg, linux-integrity,
	pmenzel, Qunqin Zhao

This patch adds an entry for Loongson Security Module driver in the list
of maintainers.

Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
---
v4: Changed tile to "Add entry for ....".
    Lowcased "Maintainers" in commit message.

 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 896a307fa0..1b741b20f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13616,6 +13616,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
 F:	drivers/i2c/busses/i2c-ls2x.c
 
+LOONGSON SECURITY MODULE DRIVER
+M:	Qunqin Zhao <zhaoqunqin@loongson.cn>
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/mfd/ls6000se.c
+F:	include/linux/mfd/ls6000se.h
+
 LOONGSON-2 SOC SERIES CLOCK DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	linux-clk@vger.kernel.org
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 3/6] crypto: loongson - add Loongson RNG driver support
  2025-02-26  3:03 [PATCH v4 0/6] Drivers for Loongson security engine Qunqin Zhao
  2025-02-26  3:03 ` [PATCH v4 1/6] mfd: Add support for Loongson Security Module Qunqin Zhao
  2025-02-26  3:03 ` [PATCH v4 2/6] MAINTAINERS: Add entry for Loongson Security Module driver Qunqin Zhao
@ 2025-02-26  3:03 ` Qunqin Zhao
  2025-02-26  3:03 ` [PATCH v4 4/6] MAINTAINERS: Add entry for Loongson RNG driver Qunqin Zhao
  2025-02-28 14:13 ` [PATCH v4 0/6] Drivers for Loongson security engine Huacai Chen
  4 siblings, 0 replies; 8+ messages in thread
From: Qunqin Zhao @ 2025-02-26  3:03 UTC (permalink / raw)
  To: lee, herbert, davem, peterhuewe, jarkko
  Cc: linux-kernel, loongarch, linux-crypto, jgg, linux-integrity,
	pmenzel, Qunqin Zhao, Yinggang Gu

Loongson's Random Number Generator is found inside Loongson 6000SE.

Co-developed-by: Yinggang Gu <guyinggang@loongson.cn>
Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
---
v2-v4: None

 drivers/crypto/Kconfig                 |   1 +
 drivers/crypto/Makefile                |   1 +
 drivers/crypto/loongson/Kconfig        |   6 +
 drivers/crypto/loongson/Makefile       |   2 +
 drivers/crypto/loongson/ls6000se-rng.c | 190 +++++++++++++++++++++++++
 5 files changed, 200 insertions(+)
 create mode 100644 drivers/crypto/loongson/Kconfig
 create mode 100644 drivers/crypto/loongson/Makefile
 create mode 100644 drivers/crypto/loongson/ls6000se-rng.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 19ab145f91..567ed81b0d 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -855,5 +855,6 @@ config CRYPTO_DEV_SA2UL
 
 source "drivers/crypto/aspeed/Kconfig"
 source "drivers/crypto/starfive/Kconfig"
+source "drivers/crypto/loongson/Kconfig"
 
 endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index fef18ffdb1..643c3710b3 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -50,3 +50,4 @@ obj-y += hisilicon/
 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
 obj-y += intel/
 obj-y += starfive/
+obj-y += loongson/
diff --git a/drivers/crypto/loongson/Kconfig b/drivers/crypto/loongson/Kconfig
new file mode 100644
index 0000000000..2b0b8b3241
--- /dev/null
+++ b/drivers/crypto/loongson/Kconfig
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+config CRYPTO_DEV_LS6000SE_RNG
+        tristate "Support for Loongson 6000SE RNG Driver"
+        depends on MFD_LS6000SE
+        help
+          Support for Loongson 6000SE RNG Driver.
diff --git a/drivers/crypto/loongson/Makefile b/drivers/crypto/loongson/Makefile
new file mode 100644
index 0000000000..17b0fa89e9
--- /dev/null
+++ b/drivers/crypto/loongson/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CRYPTO_DEV_LS6000SE_RNG)	+= ls6000se-rng.o
diff --git a/drivers/crypto/loongson/ls6000se-rng.c b/drivers/crypto/loongson/ls6000se-rng.c
new file mode 100644
index 0000000000..b366475782
--- /dev/null
+++ b/drivers/crypto/loongson/ls6000se-rng.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 HiSilicon Limited. */
+/* Copyright (c) 2025 Loongson Technology Corporation Limited. */
+
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mfd/ls6000se.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <crypto/internal/rng.h>
+
+struct lsrng_list {
+	struct mutex lock;
+	struct list_head list;
+	int is_init;
+};
+
+struct lsrng {
+	bool is_used;
+	struct lsse_ch *se_ch;
+	struct list_head list;
+	struct completion rng_completion;
+};
+
+struct lsrng_ctx {
+	struct lsrng *rng;
+};
+
+struct rng_msg {
+	u32 cmd;
+	union {
+		u32 len;
+		u32 ret;
+	} u;
+	u32 resved;
+	u32 out_off;
+	u32 pad[4];
+};
+
+static atomic_t rng_active_devs;
+static struct lsrng_list rng_devices;
+
+static void lsrng_complete(struct lsse_ch *ch)
+{
+	struct lsrng *rng = (struct lsrng *)ch->priv;
+
+	complete(&rng->rng_completion);
+}
+
+static int lsrng_generate(struct crypto_rng *tfm, const u8 *src,
+			  unsigned int slen, u8 *dstn, unsigned int dlen)
+{
+	struct lsrng_ctx *ctx = crypto_rng_ctx(tfm);
+	struct lsrng *rng = ctx->rng;
+	struct rng_msg *msg;
+	int err, len;
+
+	do {
+		len = min(dlen, PAGE_SIZE);
+		msg = rng->se_ch->smsg;
+		msg->u.len = len;
+		err = se_send_ch_requeset(rng->se_ch);
+		if (err)
+			return err;
+
+		wait_for_completion_interruptible(&rng->rng_completion);
+
+		msg = rng->se_ch->rmsg;
+		if (msg->u.ret)
+			return -EFAULT;
+
+		memcpy(dstn, rng->se_ch->data_buffer, len);
+		dlen -= len;
+		dstn += len;
+	} while (dlen > 0);
+
+	return 0;
+}
+
+static int lsrng_init(struct crypto_tfm *tfm)
+{
+	struct lsrng_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct lsrng *rng;
+	int ret = -EBUSY;
+
+	mutex_lock(&rng_devices.lock);
+	list_for_each_entry(rng, &rng_devices.list, list) {
+		if (!rng->is_used) {
+			rng->is_used = true;
+			ctx->rng = rng;
+			ret = 0;
+			break;
+		}
+	}
+	mutex_unlock(&rng_devices.lock);
+
+	return ret;
+}
+
+static void lsrng_exit(struct crypto_tfm *tfm)
+{
+	struct lsrng_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	mutex_lock(&rng_devices.lock);
+	ctx->rng->is_used = false;
+	mutex_unlock(&rng_devices.lock);
+}
+
+static int no_seed(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
+{
+	return 0;
+}
+
+static struct rng_alg lsrng_alg = {
+	.generate = lsrng_generate,
+	.seed =	no_seed,
+	.base = {
+		.cra_name = "stdrng",
+		.cra_driver_name = "loongson_stdrng",
+		.cra_priority = 300,
+		.cra_ctxsize = sizeof(struct lsrng_ctx),
+		.cra_module = THIS_MODULE,
+		.cra_init = lsrng_init,
+		.cra_exit = lsrng_exit,
+	},
+};
+
+static void lsrng_add_to_list(struct lsrng *rng)
+{
+	mutex_lock(&rng_devices.lock);
+	list_add_tail(&rng->list, &rng_devices.list);
+	mutex_unlock(&rng_devices.lock);
+}
+
+static int lsrng_probe(struct platform_device *pdev)
+{
+	struct rng_msg *msg;
+	struct lsrng *rng;
+	int ret;
+
+	rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+	if (!rng)
+		return -ENOMEM;
+
+	init_completion(&rng->rng_completion);
+	rng->se_ch = se_init_ch(pdev->dev.parent, SE_CH_RNG, PAGE_SIZE,
+				sizeof(struct rng_msg) * 2, rng, lsrng_complete);
+	if (!rng->se_ch)
+		return -ENODEV;
+	msg = rng->se_ch->smsg;
+	msg->cmd = SE_CMD_RNG;
+	msg->out_off = rng->se_ch->off;
+
+	if (!rng_devices.is_init) {
+		ret = crypto_register_rng(&lsrng_alg);
+		if (ret) {
+			dev_err(&pdev->dev, "failed to register crypto(%d)\n", ret);
+			return ret;
+		}
+		INIT_LIST_HEAD(&rng_devices.list);
+		mutex_init(&rng_devices.lock);
+		rng_devices.is_init = true;
+	}
+
+	lsrng_add_to_list(rng);
+	atomic_inc(&rng_active_devs);
+
+	return 0;
+}
+
+static struct platform_driver lsrng_driver = {
+	.probe		= lsrng_probe,
+	.driver		= {
+		.name	= "ls6000se-rng",
+	},
+};
+module_platform_driver(lsrng_driver);
+
+MODULE_ALIAS("platform:ls6000se-rng");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yinggang Gu <guyinggang@loongson.cn>");
+MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@loongson.cn>");
+MODULE_DESCRIPTION("Loongson random number generator driver");
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v4 4/6] MAINTAINERS: Add entry for Loongson RNG driver
  2025-02-26  3:03 [PATCH v4 0/6] Drivers for Loongson security engine Qunqin Zhao
                   ` (2 preceding siblings ...)
  2025-02-26  3:03 ` [PATCH v4 3/6] crypto: loongson - add Loongson RNG driver support Qunqin Zhao
@ 2025-02-26  3:03 ` Qunqin Zhao
  2025-02-28 14:13 ` [PATCH v4 0/6] Drivers for Loongson security engine Huacai Chen
  4 siblings, 0 replies; 8+ messages in thread
From: Qunqin Zhao @ 2025-02-26  3:03 UTC (permalink / raw)
  To: lee, herbert, davem, peterhuewe, jarkko
  Cc: linux-kernel, loongarch, linux-crypto, jgg, linux-integrity,
	pmenzel, Qunqin Zhao

This patch adds an entry for Loongson RNG driver in the list of
maintainers.

Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
---
v4: Changed tile to "Add entry for ...".
    Lowcased "Maintainers" in commit message.

 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1b741b20f8..3f04f43ffe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13602,6 +13602,12 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
 F:	drivers/gpio/gpio-loongson-64bit.c
 
+LOONGSON CRYPTO DRIVER
+M:	Qunqin Zhao <zhaoqunqin@loongson.com>
+L:	linux-crypto@vger.kernel.org
+S:	Maintained
+F:	drivers/crypto/loongson/
+
 LOONGSON-2 APB DMA DRIVER
 M:	Binbin Zhou <zhoubinbin@loongson.cn>
 L:	dmaengine@vger.kernel.org
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 0/6] Drivers for Loongson security engine
  2025-02-26  3:03 [PATCH v4 0/6] Drivers for Loongson security engine Qunqin Zhao
                   ` (3 preceding siblings ...)
  2025-02-26  3:03 ` [PATCH v4 4/6] MAINTAINERS: Add entry for Loongson RNG driver Qunqin Zhao
@ 2025-02-28 14:13 ` Huacai Chen
  4 siblings, 0 replies; 8+ messages in thread
From: Huacai Chen @ 2025-02-28 14:13 UTC (permalink / raw)
  To: Qunqin Zhao
  Cc: lee, herbert, davem, peterhuewe, jarkko, linux-kernel, loongarch,
	linux-crypto, jgg, linux-integrity, pmenzel

Hi, Qunqin,

On Wed, Feb 26, 2025 at 11:04 AM Qunqin Zhao <zhaoqunqin@loongson.cn> wrote:
>
> Loongson security engine supports random number generation, hash,
> symmetric encryption and asymmetric encryption. Based on these
> encryption functions, TPM2 have been implemented in it.
>
> mfd is the baser driver, crypto and tpm are users.
Loongson SE should not strongly bound to LS6000, so the naming can be improved:

MFD_LS6000SE -> MFD_LOONGSON_SE,  ls6000se.c -> loongson-se.c
CRYPTO_DEV_LS6000SE_RNG -> CRYPTO_DEV_LOONGSON_RNG,  ls6000se-rng.c ->
loongson-rng.c
TCG_LSSE -> TCG_LOONGSON, tpm_lsse.c ->tpm_loongson.c


Huacai

>
> v4: Please look at changelog in tpm and MAINTAINERS. No changes to tpm
>     and crypto.
> v3: Put the updates to the MAINTAINERS in a separate patch.
> v2: Removed misc driver. Added tpm driver.
>
> Qunqin Zhao (6):
>   mfd: Add support for Loongson Security Module
>   MAINTAINERS: Add entry for Loongson Security Module driver
>   crypto: loongson - add Loongson RNG driver support
>   MAINTAINERS: Add entry for Loongson RNG driver
>   tpm: Add a driver for Loongson TPM device
>   MAINTAINERS: Add tpm_lsse.c to LOONGSON CRYPTO DRIVER entry
>
>  MAINTAINERS                            |  14 +
>  drivers/char/tpm/Kconfig               |   9 +
>  drivers/char/tpm/Makefile              |   1 +
>  drivers/char/tpm/tpm_lsse.c            | 103 +++++++
>  drivers/crypto/Kconfig                 |   1 +
>  drivers/crypto/Makefile                |   1 +
>  drivers/crypto/loongson/Kconfig        |   6 +
>  drivers/crypto/loongson/Makefile       |   2 +
>  drivers/crypto/loongson/ls6000se-rng.c | 190 +++++++++++++
>  drivers/mfd/Kconfig                    |  10 +
>  drivers/mfd/Makefile                   |   2 +
>  drivers/mfd/ls6000se.c                 | 374 +++++++++++++++++++++++++
>  include/linux/mfd/ls6000se.h           |  75 +++++
>  13 files changed, 788 insertions(+)
>  create mode 100644 drivers/char/tpm/tpm_lsse.c
>  create mode 100644 drivers/crypto/loongson/Kconfig
>  create mode 100644 drivers/crypto/loongson/Makefile
>  create mode 100644 drivers/crypto/loongson/ls6000se-rng.c
>  create mode 100644 drivers/mfd/ls6000se.c
>  create mode 100644 include/linux/mfd/ls6000se.h
>
>
> base-commit: bd315242821784e9384abae911a70d5fda9a3298
> --
> 2.43.0
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 1/6] mfd: Add support for Loongson Security Module
  2025-02-26  3:03 ` [PATCH v4 1/6] mfd: Add support for Loongson Security Module Qunqin Zhao
@ 2025-03-12  8:08   ` Lee Jones
  2025-03-12  8:38     ` Qunqin Zhao
  0 siblings, 1 reply; 8+ messages in thread
From: Lee Jones @ 2025-03-12  8:08 UTC (permalink / raw)
  To: Qunqin Zhao
  Cc: herbert, davem, peterhuewe, jarkko, linux-kernel, loongarch,
	linux-crypto, jgg, linux-integrity, pmenzel, Yinggang Gu

On Wed, 26 Feb 2025, Qunqin Zhao wrote:

> This driver supports Loongson Security Module, which provides the control
> for it's hardware encryption acceleration child devices.
> 
> Co-developed-by: Yinggang Gu <guyinggang@loongson.cn>
> Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
> Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
> ---
> v3-v4: None
> 
> v2: Removed "ls6000se-sdf" device, added "ls6000se-tpm" device.
>     Passed dmamem size to SE firmware in se_init_hw() function.
> 
>  drivers/mfd/Kconfig          |  10 +
>  drivers/mfd/Makefile         |   2 +
>  drivers/mfd/ls6000se.c       | 374 +++++++++++++++++++++++++++++++++++
>  include/linux/mfd/ls6000se.h |  75 +++++++
>  4 files changed, 461 insertions(+)
>  create mode 100644 drivers/mfd/ls6000se.c
>  create mode 100644 include/linux/mfd/ls6000se.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index d44c69bb3d..318fb113c1 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -2439,5 +2439,15 @@ config MFD_UPBOARD_FPGA
>  	  To compile this driver as a module, choose M here: the module will be
>  	  called upboard-fpga.
>  
> +config MFD_LS6000SE
> +	tristate "Loongson Security Module Interface"
> +	depends on LOONGARCH && ACPI
> +	select MFD_CORE
> +	help
> +	  The Loongson security module provides the control for hardware
> +	  encryption acceleration devices. Each device uses at least one
> +	  channel to interact with security module, and each channel may
> +	  have its own buffer provided by security module.
> +
>  endmenu
>  endif
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 9220eaf7cf..9556de7715 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -294,3 +294,5 @@ obj-$(CONFIG_MFD_RSMU_I2C)	+= rsmu_i2c.o rsmu_core.o
>  obj-$(CONFIG_MFD_RSMU_SPI)	+= rsmu_spi.o rsmu_core.o
>  
>  obj-$(CONFIG_MFD_UPBOARD_FPGA)	+= upboard-fpga.o
> +
> +obj-$(CONFIG_MFD_LS6000SE)	+= ls6000se.o
> diff --git a/drivers/mfd/ls6000se.c b/drivers/mfd/ls6000se.c
> new file mode 100644
> index 0000000000..24d76c2ffc
> --- /dev/null
> +++ b/drivers/mfd/ls6000se.c

[...]

> +static const struct mfd_cell se_devs[] = {
> +	{ .name = "ls6000se-sdf" },
> +	{ .name = "ls6000se-tpm" },
> +};

Where are the drivers for these devices?  I don't see them anywhere.

I do see ls6000se-rng.  How is that registered?

-- 
Lee Jones [李琼斯]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v4 1/6] mfd: Add support for Loongson Security Module
  2025-03-12  8:08   ` Lee Jones
@ 2025-03-12  8:38     ` Qunqin Zhao
  0 siblings, 0 replies; 8+ messages in thread
From: Qunqin Zhao @ 2025-03-12  8:38 UTC (permalink / raw)
  To: Lee Jones
  Cc: herbert, davem, peterhuewe, jarkko, linux-kernel, loongarch,
	linux-crypto, jgg, linux-integrity, pmenzel, Yinggang Gu


在 2025/3/12 下午4:08, Lee Jones 写道:
> On Wed, 26 Feb 2025, Qunqin Zhao wrote:
>
>> This driver supports Loongson Security Module, which provides the control
>> for it's hardware encryption acceleration child devices.
>>
>> Co-developed-by: Yinggang Gu <guyinggang@loongson.cn>
>> Signed-off-by: Yinggang Gu <guyinggang@loongson.cn>
>> Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
>> ---
>> v3-v4: None
>>
>> v2: Removed "ls6000se-sdf" device, added "ls6000se-tpm" device.
>>      Passed dmamem size to SE firmware in se_init_hw() function.
>>
>>   drivers/mfd/Kconfig          |  10 +
>>   drivers/mfd/Makefile         |   2 +
>>   drivers/mfd/ls6000se.c       | 374 +++++++++++++++++++++++++++++++++++
>>   include/linux/mfd/ls6000se.h |  75 +++++++
>>   4 files changed, 461 insertions(+)
>>   create mode 100644 drivers/mfd/ls6000se.c
>>   create mode 100644 include/linux/mfd/ls6000se.h
>>
>> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
>> index d44c69bb3d..318fb113c1 100644
>> --- a/drivers/mfd/Kconfig
>> +++ b/drivers/mfd/Kconfig
>> @@ -2439,5 +2439,15 @@ config MFD_UPBOARD_FPGA
>>   	  To compile this driver as a module, choose M here: the module will be
>>   	  called upboard-fpga.
>>   
>> +config MFD_LS6000SE
>> +	tristate "Loongson Security Module Interface"
>> +	depends on LOONGARCH && ACPI
>> +	select MFD_CORE
>> +	help
>> +	  The Loongson security module provides the control for hardware
>> +	  encryption acceleration devices. Each device uses at least one
>> +	  channel to interact with security module, and each channel may
>> +	  have its own buffer provided by security module.
>> +
>>   endmenu
>>   endif
>> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
>> index 9220eaf7cf..9556de7715 100644
>> --- a/drivers/mfd/Makefile
>> +++ b/drivers/mfd/Makefile
>> @@ -294,3 +294,5 @@ obj-$(CONFIG_MFD_RSMU_I2C)	+= rsmu_i2c.o rsmu_core.o
>>   obj-$(CONFIG_MFD_RSMU_SPI)	+= rsmu_spi.o rsmu_core.o
>>   
>>   obj-$(CONFIG_MFD_UPBOARD_FPGA)	+= upboard-fpga.o
>> +
>> +obj-$(CONFIG_MFD_LS6000SE)	+= ls6000se.o
>> diff --git a/drivers/mfd/ls6000se.c b/drivers/mfd/ls6000se.c
>> new file mode 100644
>> index 0000000000..24d76c2ffc
>> --- /dev/null
>> +++ b/drivers/mfd/ls6000se.c
> [...]
>
>> +static const struct mfd_cell se_devs[] = {
>> +	{ .name = "ls6000se-sdf" },
>> +	{ .name = "ls6000se-tpm" },
>> +};
> Where are the drivers for these devices?  I don't see them anywhere.
>
> I do see ls6000se-rng.  How is that registered?

Oh.... I made a slip of the pen and wrote that  "ls6000se-sdf" not  
"ls6000se-rng".  Will fix it in next version.

Driver for "ls6000se-tpm" is [PATCH v4 5/6].

Thanks for your comments.

BR, Qunqin.

>


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-03-12  8:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-26  3:03 [PATCH v4 0/6] Drivers for Loongson security engine Qunqin Zhao
2025-02-26  3:03 ` [PATCH v4 1/6] mfd: Add support for Loongson Security Module Qunqin Zhao
2025-03-12  8:08   ` Lee Jones
2025-03-12  8:38     ` Qunqin Zhao
2025-02-26  3:03 ` [PATCH v4 2/6] MAINTAINERS: Add entry for Loongson Security Module driver Qunqin Zhao
2025-02-26  3:03 ` [PATCH v4 3/6] crypto: loongson - add Loongson RNG driver support Qunqin Zhao
2025-02-26  3:03 ` [PATCH v4 4/6] MAINTAINERS: Add entry for Loongson RNG driver Qunqin Zhao
2025-02-28 14:13 ` [PATCH v4 0/6] Drivers for Loongson security engine Huacai Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.