[1/2] hwrng: add driver for MediaTek TRNG SMC

Message ID 89865515728cb937b6591160ad9c30b4bcc8dd41.1676467500.git.daniel@makrotopia.org
State New
Headers
Series [1/2] hwrng: add driver for MediaTek TRNG SMC |

Commit Message

Daniel Golle Feb. 15, 2023, 1:27 p.m. UTC
  Add driver providing kernel-side support for the Random Number
Generator hardware found on Mediatek SoCs which have a driver in ARM
TrustedFirmware-A allowing Linux to read random numbers using a
non-standard vendor-defined Secure Monitor Call.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                         |  1 +
 drivers/char/hw_random/Kconfig      | 16 +++++++
 drivers/char/hw_random/Makefile     |  1 +
 drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++
 4 files changed, 92 insertions(+)
 create mode 100644 drivers/char/hw_random/mtk-rng-v2.c


base-commit: 9d9019bcea1aac7eed64a1a4966282b6b7b141c8
  

Comments

AngeloGioacchino Del Regno Feb. 16, 2023, 10:03 a.m. UTC | #1
Il 15/02/23 14:27, Daniel Golle ha scritto:
> Add driver providing kernel-side support for the Random Number
> Generator hardware found on Mediatek SoCs which have a driver in ARM
> TrustedFirmware-A allowing Linux to read random numbers using a
> non-standard vendor-defined Secure Monitor Call.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>

Hello Daniel,

incidentally, I've also done some research on this one some months ago, when
I was deep in adding support for the Helio X10 SoC (MT6795) on Xperia M5.

The rng-v2 is simply the same rng but hypervised by the TF-A... and the only
difference is, well, as you're also pointing out, that we're using secure
monitor calls instead of direct MMIO handling.

There's also not much more than what you've implemented here and the only kind
of addition that we will ever see on this one will be about changing the SIP
command (as some older SoCs use a different one)... so...

...I don't think that adding an entirely new driver is worth the noise, hence
I propose to simply add handling for the Secure RNG to mtk-rng.c instead: it's
shorter and we would only need to address one if branch on that probe function
to set a different callback.

The clock should then be optional for *some* of those "v2 handling" devices,
as if I recall correctly, some do need the clock to be handled from Linux
anyway... otherwise this v2 driver will be "soon" looking bloody similar to
the "v1", adding a bit of code duplication around.

What do you think?

Regards,
Angelo

> ---
>   MAINTAINERS                         |  1 +
>   drivers/char/hw_random/Kconfig      | 16 +++++++
>   drivers/char/hw_random/Makefile     |  1 +
>   drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++
>   4 files changed, 92 insertions(+)
>   create mode 100644 drivers/char/hw_random/mtk-rng-v2.c
>
  
Matthias Brugger Feb. 16, 2023, 11:32 a.m. UTC | #2
On 16/02/2023 11:03, AngeloGioacchino Del Regno wrote:
> Il 15/02/23 14:27, Daniel Golle ha scritto:
>> Add driver providing kernel-side support for the Random Number
>> Generator hardware found on Mediatek SoCs which have a driver in ARM
>> TrustedFirmware-A allowing Linux to read random numbers using a
>> non-standard vendor-defined Secure Monitor Call.
>>
>> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> 
> Hello Daniel,
> 
> incidentally, I've also done some research on this one some months ago, when
> I was deep in adding support for the Helio X10 SoC (MT6795) on Xperia M5.
> 
> The rng-v2 is simply the same rng but hypervised by the TF-A... and the only
> difference is, well, as you're also pointing out, that we're using secure
> monitor calls instead of direct MMIO handling.
> 
> There's also not much more than what you've implemented here and the only kind
> of addition that we will ever see on this one will be about changing the SIP
> command (as some older SoCs use a different one)... so...
> 
> ...I don't think that adding an entirely new driver is worth the noise, hence
> I propose to simply add handling for the Secure RNG to mtk-rng.c instead: it's
> shorter and we would only need to address one if branch on that probe function
> to set a different callback.
> 
> The clock should then be optional for *some* of those "v2 handling" devices,
> as if I recall correctly, some do need the clock to be handled from Linux
> anyway... otherwise this v2 driver will be "soon" looking bloody similar to
> the "v1", adding a bit of code duplication around.
> 
> What do you think?
> 

That was exactly what I was thinking as well when I had a look at the driver. I 
propose to add it to mtk-rng.c. I don't see any value having a second driver for 
this.

Regards,
Matthias

> Regards,
> Angelo
> 
>> ---
>>   MAINTAINERS                         |  1 +
>>   drivers/char/hw_random/Kconfig      | 16 +++++++
>>   drivers/char/hw_random/Makefile     |  1 +
>>   drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++
>>   4 files changed, 92 insertions(+)
>>   create mode 100644 drivers/char/hw_random/mtk-rng-v2.c
>>
>
  
Rob Herring Feb. 20, 2023, 11:58 p.m. UTC | #3
On Thu, Feb 16, 2023 at 12:32:10PM +0100, Matthias Brugger wrote:
> 
> 
> On 16/02/2023 11:03, AngeloGioacchino Del Regno wrote:
> > Il 15/02/23 14:27, Daniel Golle ha scritto:
> > > Add driver providing kernel-side support for the Random Number
> > > Generator hardware found on Mediatek SoCs which have a driver in ARM
> > > TrustedFirmware-A allowing Linux to read random numbers using a
> > > non-standard vendor-defined Secure Monitor Call.
> > > 
> > > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > 
> > Hello Daniel,
> > 
> > incidentally, I've also done some research on this one some months ago, when
> > I was deep in adding support for the Helio X10 SoC (MT6795) on Xperia M5.
> > 
> > The rng-v2 is simply the same rng but hypervised by the TF-A... and the only
> > difference is, well, as you're also pointing out, that we're using secure
> > monitor calls instead of direct MMIO handling.
> > 
> > There's also not much more than what you've implemented here and the only kind
> > of addition that we will ever see on this one will be about changing the SIP
> > command (as some older SoCs use a different one)... so...
> > 
> > ...I don't think that adding an entirely new driver is worth the noise, hence
> > I propose to simply add handling for the Secure RNG to mtk-rng.c instead: it's
> > shorter and we would only need to address one if branch on that probe function
> > to set a different callback.
> > 
> > The clock should then be optional for *some* of those "v2 handling" devices,
> > as if I recall correctly, some do need the clock to be handled from Linux
> > anyway... otherwise this v2 driver will be "soon" looking bloody similar to
> > the "v1", adding a bit of code duplication around.
> > 
> > What do you think?
> > 
> 
> That was exactly what I was thinking as well when I had a look at the
> driver. I propose to add it to mtk-rng.c. I don't see any value having a
> second driver for this.

Or fix the firmware to use the already defined SMC TRNG interface...

In any case, like the SMC TRNG, you don't need a DT binding. The 
firmware interface is discoverable. Try the SMC call and if it succeeds, 
you have a TRNG.

Rob

> 
> Regards,
> Matthias
> 
> > Regards,
> > Angelo
> > 
> > > ---
> > >   MAINTAINERS                         |  1 +
> > >   drivers/char/hw_random/Kconfig      | 16 +++++++
> > >   drivers/char/hw_random/Makefile     |  1 +
> > >   drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++
> > >   4 files changed, 92 insertions(+)
> > >   create mode 100644 drivers/char/hw_random/mtk-rng-v2.c
> > > 
> >
  
Daniel Golle Feb. 21, 2023, 12:14 a.m. UTC | #4
On Mon, Feb 20, 2023 at 05:58:11PM -0600, Rob Herring wrote:
> On Thu, Feb 16, 2023 at 12:32:10PM +0100, Matthias Brugger wrote:
> > 
> > 
> > On 16/02/2023 11:03, AngeloGioacchino Del Regno wrote:
> > > Il 15/02/23 14:27, Daniel Golle ha scritto:
> > > > Add driver providing kernel-side support for the Random Number
> > > > Generator hardware found on Mediatek SoCs which have a driver in ARM
> > > > TrustedFirmware-A allowing Linux to read random numbers using a
> > > > non-standard vendor-defined Secure Monitor Call.
> > > > 
> > > > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > > 
> > > Hello Daniel,
> > > 
> > > incidentally, I've also done some research on this one some months ago, when
> > > I was deep in adding support for the Helio X10 SoC (MT6795) on Xperia M5.
> > > 
> > > The rng-v2 is simply the same rng but hypervised by the TF-A... and the only
> > > difference is, well, as you're also pointing out, that we're using secure
> > > monitor calls instead of direct MMIO handling.
> > > 
> > > There's also not much more than what you've implemented here and the only kind
> > > of addition that we will ever see on this one will be about changing the SIP
> > > command (as some older SoCs use a different one)... so...
> > > 
> > > ...I don't think that adding an entirely new driver is worth the noise, hence
> > > I propose to simply add handling for the Secure RNG to mtk-rng.c instead: it's
> > > shorter and we would only need to address one if branch on that probe function
> > > to set a different callback.
> > > 
> > > The clock should then be optional for *some* of those "v2 handling" devices,
> > > as if I recall correctly, some do need the clock to be handled from Linux
> > > anyway... otherwise this v2 driver will be "soon" looking bloody similar to
> > > the "v1", adding a bit of code duplication around.
> > > 
> > > What do you think?
> > > 
> > 
> > That was exactly what I was thinking as well when I had a look at the
> > driver. I propose to add it to mtk-rng.c. I don't see any value having a
> > second driver for this.
> 
> Or fix the firmware to use the already defined SMC TRNG interface...

I agree that this would obviously be the best solution of all, and it's
also not completely impossible as TF-A for this platform can quite easily
be built from source. However, for devices already out there it may still
not be an option.

> 
> In any case, like the SMC TRNG, you don't need a DT binding. The 
> firmware interface is discoverable. Try the SMC call and if it succeeds, 
> you have a TRNG.

I'll try that and let you know how it goes ;)


Cheers


Daniel

> 
> Rob
> 
> > 
> > Regards,
> > Matthias
> > 
> > > Regards,
> > > Angelo
> > > 
> > > > ---
> > > >   MAINTAINERS                         |  1 +
> > > >   drivers/char/hw_random/Kconfig      | 16 +++++++
> > > >   drivers/char/hw_random/Makefile     |  1 +
> > > >   drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++
> > > >   4 files changed, 92 insertions(+)
> > > >   create mode 100644 drivers/char/hw_random/mtk-rng-v2.c
> > > > 
> > >
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index be167c695c64..90d82aba6d73 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13148,6 +13148,7 @@  F:	drivers/leds/leds-mt6323.c
 MEDIATEK RANDOM NUMBER GENERATOR SUPPORT
 M:	Sean Wang <sean.wang@mediatek.com>
 S:	Maintained
+F:	drivers/char/hw_random/mtk-rng-v2.c
 F:	drivers/char/hw_random/mtk-rng.c
 
 MEDIATEK SMI DRIVER
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 4fdf07ae3c54..7c900185486d 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -439,6 +439,22 @@  config HW_RANDOM_MTK
 
 	  If unsure, say Y.
 
+config HW_RANDOM_MTK_V2
+	tristate "Mediatek Random Number Generator support (v2/SMC)"
+	depends on HW_RANDOM
+	depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST
+	default y
+	help
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on Mediatek SoCs which have a driver
+	  in ARM TrustedFirmware-A allowing Linux to read using a non-
+	  standard vendor-defined Secure Monitor Call.
+
+	  To compile this driver as a module, choose M here. the
+	  module will be called mtk-rng-v2.
+
+	  If unsure, say Y.
+
 config HW_RANDOM_S390
 	tristate "S390 True Random Number Generator support"
 	depends on S390
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 09bde4a0f971..ba319c509e86 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -38,6 +38,7 @@  obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
 obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
 obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o
 obj-$(CONFIG_HW_RANDOM_MTK)	+= mtk-rng.o
+obj-$(CONFIG_HW_RANDOM_MTK_V2)	+= mtk-rng-v2.o
 obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
 obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
 obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
diff --git a/drivers/char/hw_random/mtk-rng-v2.c b/drivers/char/hw_random/mtk-rng-v2.c
new file mode 100644
index 000000000000..6e61f4361d9e
--- /dev/null
+++ b/drivers/char/hw_random/mtk-rng-v2.c
@@ -0,0 +1,74 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for Mediatek Hardware Random Number Generator (v2/SMCC)
+ *
+ * Copyright (C) 2023 Daniel Golle <daniel@makrotopia.org>
+ * based on patch from Mingming Su <Mingming.Su@mediatek.com>
+ */
+#define MTK_RNG_DEV KBUILD_MODNAME
+
+#include <linux/arm-smccc.h>
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk_sip_svc.h>
+
+#define MTK_SIP_KERNEL_GET_RND		MTK_SIP_SMC_CMD(0x550)
+
+static int mtk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+	struct arm_smccc_res res;
+	int retval = 0;
+
+	while (max >= sizeof(u32)) {
+		arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0,
+			      &res);
+		if (res.a0)
+			break;
+
+		*(u32 *)buf = res.a1;
+		retval += sizeof(u32);
+		buf += sizeof(u32);
+		max -= sizeof(u32);
+	}
+
+	return retval || !wait ? retval : -EIO;
+}
+
+static int mtk_rng_v2_probe(struct platform_device *pdev)
+{
+	struct hwrng *trng;
+
+	trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
+	if (!trng)
+		return -ENOMEM;
+
+	trng->name = pdev->name;
+	trng->read = mtk_rng_v2_read;
+	trng->quality = 900;
+
+	return devm_hwrng_register(&pdev->dev, trng);
+}
+
+static const struct of_device_id mtk_rng_v2_match[] = {
+	{ .compatible = "mediatek,mt7981-rng" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_rng_v2_match);
+
+static struct platform_driver mtk_rng_v2_driver = {
+	.probe          = mtk_rng_v2_probe,
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.of_match_table = mtk_rng_v2_match,
+	},
+};
+module_platform_driver(mtk_rng_v2_driver);
+
+MODULE_DESCRIPTION("Mediatek Random Number Generator Driver (v2/SMC)");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+MODULE_LICENSE("GPL");