diff mbox series

[v2] hwrng: add Zhaoxin rng driver base on rep_xstore instruction

Message ID 20231121032939.610048-1-LeoLiu-oc@zhaoxin.com
State New
Headers show
Series [v2] hwrng: add Zhaoxin rng driver base on rep_xstore instruction | expand

Commit Message

LeoLiu-oc Nov. 21, 2023, 3:29 a.m. UTC
From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>

Add support for Zhaoxin hardware random number generator.
This driver base on rep_xstore instruction and uses the same
X86_FEATURE_XSTORE as via-rng driver. Therefore, modify the x86_cpu_id
array in the via-rng driver, so that the corresponding driver can be
correctly loader on respective platforms.

---

v1 -> v2:
1. Fix assembler code errors
2. Remove redundant CPU model check codes

Signed-off-by: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
---
 drivers/char/hw_random/Kconfig       | 13 ++++
 drivers/char/hw_random/Makefile      |  1 +
 drivers/char/hw_random/via-rng.c     | 23 +++----
 drivers/char/hw_random/zhaoxin-rng.c | 95 ++++++++++++++++++++++++++++
 4 files changed, 119 insertions(+), 13 deletions(-)
 create mode 100644 drivers/char/hw_random/zhaoxin-rng.c

Comments

Herbert Xu Dec. 1, 2023, 9:31 a.m. UTC | #1
On Tue, Nov 21, 2023 at 11:29:39AM +0800, LeoLiu-oc wrote:
>
> +config HW_RANDOM_ZHAOXIN
> +	tristate "Zhaoxin HW Random Number Generator support"
> +	depends on X86
> +	default HW_RANDOM

Please remove this default.

> diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c
> index a9a0a3b09c8b..6d1312845802 100644
> --- a/drivers/char/hw_random/via-rng.c
> +++ b/drivers/char/hw_random/via-rng.c
> @@ -35,9 +35,6 @@
>  #include <asm/cpufeature.h>
>  #include <asm/fpu/api.h>
>  
> -
> -
> -

Please don't make unrelated changes in a patch.

>  	pr_info("VIA RNG detected\n");
>  	err = hwrng_register(&via_rng);
>  	if (err) {
> -		pr_err(PFX "RNG registering failed (%d)\n",
> -		       err);
> +		pr_err(PFX "RNG registering failed (%d)\n", err);

Ditto.

> +#include <crypto/padlock.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/hw_random.h>
> +#include <linux/delay.h>
> +#include <linux/io.h>
> +#include <linux/cpufeature.h>
> +#include <asm/cpu_device_id.h>
> +#include <asm/fpu/api.h>

Please sort this alphabetically.

Thanks,
Herbert Xu Dec. 1, 2023, 9:34 a.m. UTC | #2
On Tue, Nov 21, 2023 at 11:29:39AM +0800, LeoLiu-oc wrote:
>
> +static const struct x86_cpu_id via_rng_cpu_ids[] = {
> +	X86_MATCH_VENDOR_FAM_FEATURE(CENTAUR, 6, X86_FEATURE_XSTORE, NULL),
> +	{}
> +};
> +MODULE_DEVICE_TABLE(x86cpu, via_rng_cpu_ids);

Rather than moving the whole thing, just add this near the start
of the file:

static const struct x86_cpu_id via_rng_cpu_ids[];

Cheers,
Herbert Xu Dec. 1, 2023, 9:38 a.m. UTC | #3
On Tue, Nov 21, 2023 at 11:29:39AM +0800, LeoLiu-oc wrote:
> From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
> 
> Add support for Zhaoxin hardware random number generator.
> This driver base on rep_xstore instruction and uses the same
> X86_FEATURE_XSTORE as via-rng driver. Therefore, modify the x86_cpu_id
> array in the via-rng driver, so that the corresponding driver can be
> correctly loader on respective platforms.

The patch cc list is still different from your other patch.  Please
make sure that both patches have the same cc list next time.

Thanks,
LeoLiu-oc Dec. 5, 2023, 3:41 a.m. UTC | #4
在 2023/12/1 17:31, Herbert Xu 写道:
> On Tue, Nov 21, 2023 at 11:29:39AM +0800, LeoLiu-oc wrote:
>>
>> +config HW_RANDOM_ZHAOXIN
>> +	tristate "Zhaoxin HW Random Number Generator support"
>> +	depends on X86
>> +	default HW_RANDOM
> 
> Please remove this default.
> 
Okay, it will be deleted in the next version.

>> diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c
>> index a9a0a3b09c8b..6d1312845802 100644
>> --- a/drivers/char/hw_random/via-rng.c
>> +++ b/drivers/char/hw_random/via-rng.c
>> @@ -35,9 +35,6 @@
>>   #include <asm/cpufeature.h>
>>   #include <asm/fpu/api.h>
>>   
>> -
>> -
>> -
> 
> Please don't make unrelated changes in a patch.
> >>   	pr_info("VIA RNG detected\n");
>>   	err = hwrng_register(&via_rng);
>>   	if (err) {
>> -		pr_err(PFX "RNG registering failed (%d)\n",
>> -		       err);
>> +		pr_err(PFX "RNG registering failed (%d)\n", err);
> 
> Ditto.
> 
Okay, these modifications will be restored in the next version.

>> +#include <crypto/padlock.h>
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/hw_random.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/cpufeature.h>
>> +#include <asm/cpu_device_id.h>
>> +#include <asm/fpu/api.h>
> 
> Please sort this alphabetically.
> 
> Thanks,
Okay, it will be modified in the next version.

Sincerely,
Leoliu-oc
LeoLiu-oc Dec. 5, 2023, 3:47 a.m. UTC | #5
在 2023/12/1 17:34, Herbert Xu 写道:
> On Tue, Nov 21, 2023 at 11:29:39AM +0800, LeoLiu-oc wrote:
>>
>> +static const struct x86_cpu_id via_rng_cpu_ids[] = {
>> +	X86_MATCH_VENDOR_FAM_FEATURE(CENTAUR, 6, X86_FEATURE_XSTORE, NULL),
>> +	{}
>> +};
>> +MODULE_DEVICE_TABLE(x86cpu, via_rng_cpu_ids);
> 
> Rather than moving the whole thing, just add this near the start
> of the file:
> 
> static const struct x86_cpu_id via_rng_cpu_ids[];
> 
> Cheers,

Thank you for your suggestions. Will make modifications in the next 
version as suggested.

Sincerely,
Leoliu-oc
LeoLiu-oc Dec. 5, 2023, 6:56 a.m. UTC | #6
在 2023/12/1 17:38, Herbert Xu 写道:
> On Tue, Nov 21, 2023 at 11:29:39AM +0800, LeoLiu-oc wrote:
>> From: LeoLiuoc <LeoLiu-oc@zhaoxin.com>
>>
>> Add support for Zhaoxin hardware random number generator.
>> This driver base on rep_xstore instruction and uses the same
>> X86_FEATURE_XSTORE as via-rng driver. Therefore, modify the x86_cpu_id
>> array in the via-rng driver, so that the corresponding driver can be
>> correctly loader on respective platforms.
> 
> The patch cc list is still different from your other patch.  Please
> make sure that both patches have the same cc list next time.
> 
> Thanks,

Yes, I see what you mean,and will send the next version combined with 
the cc list of the other zhaoxin rng patch in July.

Sincerely,
Leoliu-oc
diff mbox series

Patch

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 442c40efb200..eb0e3d64a547 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -152,6 +152,19 @@  config HW_RANDOM_VIA
 
 	  If unsure, say Y.
 
+config HW_RANDOM_ZHAOXIN
+	tristate "Zhaoxin HW Random Number Generator support"
+	depends on X86
+	default HW_RANDOM
+	help
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on Zhaoxin based motherboards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called zhaoxin-rng.
+
+	  If unsure, say Y.
+
 config HW_RANDOM_IXP4XX
 	tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
 	depends on ARCH_IXP4XX || COMPILE_TEST
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 32549a1186dc..ef5b3ae0794d 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -14,6 +14,7 @@  obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
 obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
 n2-rng-y := n2-drv.o n2-asm.o
 obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
+obj-$(CONFIG_HW_RANDOM_ZHAOXIN) += zhaoxin-rng.o
 obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-trng.o
 obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c
index a9a0a3b09c8b..6d1312845802 100644
--- a/drivers/char/hw_random/via-rng.c
+++ b/drivers/char/hw_random/via-rng.c
@@ -35,9 +35,6 @@ 
 #include <asm/cpufeature.h>
 #include <asm/fpu/api.h>
 
-
-
-
 enum {
 	VIA_STRFILT_CNT_SHIFT	= 16,
 	VIA_STRFILT_FAIL	= (1 << 15),
@@ -135,7 +132,7 @@  static int via_rng_init(struct hwrng *rng)
 	 * is always enabled if CPUID rng_en is set.  There is no
 	 * RNG configuration like it used to be the case in this
 	 * register */
-	if (((c->x86 == 6) && (c->x86_model >= 0x0f))  || (c->x86 > 6)){
+	if ((c->x86 == 6) && (c->x86_model >= 0x0f)) {
 		if (!boot_cpu_has(X86_FEATURE_XSTORE_EN)) {
 			pr_err(PFX "can't enable hardware RNG "
 				"if XSTORE is not enabled\n");
@@ -191,19 +188,25 @@  static struct hwrng via_rng = {
 	.data_read	= via_rng_data_read,
 };
 
+static const struct x86_cpu_id via_rng_cpu_ids[] = {
+	X86_MATCH_VENDOR_FAM_FEATURE(CENTAUR, 6, X86_FEATURE_XSTORE, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, via_rng_cpu_ids);
 
 static int __init via_rng_mod_init(void)
 {
 	int err;
 
-	if (!boot_cpu_has(X86_FEATURE_XSTORE))
+	if (!x86_match_cpu(via_rng_cpu_ids)) {
+		pr_err(PFX "The CPU isn't support XSTORE.\n");
 		return -ENODEV;
+	}
 
 	pr_info("VIA RNG detected\n");
 	err = hwrng_register(&via_rng);
 	if (err) {
-		pr_err(PFX "RNG registering failed (%d)\n",
-		       err);
+		pr_err(PFX "RNG registering failed (%d)\n", err);
 		goto out;
 	}
 out:
@@ -217,11 +220,5 @@  static void __exit via_rng_mod_exit(void)
 }
 module_exit(via_rng_mod_exit);
 
-static struct x86_cpu_id __maybe_unused via_rng_cpu_id[] = {
-	X86_MATCH_FEATURE(X86_FEATURE_XSTORE, NULL),
-	{}
-};
-MODULE_DEVICE_TABLE(x86cpu, via_rng_cpu_id);
-
 MODULE_DESCRIPTION("H/W RNG driver for VIA CPU with PadLock");
 MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/zhaoxin-rng.c b/drivers/char/hw_random/zhaoxin-rng.c
new file mode 100644
index 000000000000..1bd171eebf71
--- /dev/null
+++ b/drivers/char/hw_random/zhaoxin-rng.c
@@ -0,0 +1,95 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * RNG driver for Zhaoxin RNGs
+ *
+ * Copyright 2023 (c) Zhaoxin Semiconductor Co., Ltd
+ */
+
+#include <crypto/padlock.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hw_random.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/cpufeature.h>
+#include <asm/cpu_device_id.h>
+#include <asm/fpu/api.h>
+
+enum {
+	ZHAOXIN_RNG_CHUNK_8		= 0x00, /* 64 rand bits, 64 stored bits */
+	ZHAOXIN_RNG_CHUNK_4		= 0x01, /* 32 rand bits, 32 stored bits */
+	ZHAOXIN_RNG_CHUNK_2		= 0x02, /* 16 rand bits, 32 stored bits */
+	ZHAOXIN_RNG_CHUNK_1		= 0x03, /*  8 rand bits, 32 stored bits */
+	ZHAOXIN_RNG_MAX_SIZE	= (128 * 1024),
+};
+
+static int zhaoxin_rng_init(struct hwrng *rng)
+{
+	if (!boot_cpu_has(X86_FEATURE_XSTORE_EN)) {
+		pr_err(PFX "can't enable hardware RNG if XSTORE is not enabled\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static inline int rep_xstore(size_t size, size_t factor, void *result)
+{
+	asm(".byte 0xf3, 0x0f, 0xa7, 0xc0"
+		: "=m"(*(size_t *)result), "+c"(size), "+d"(factor), "+D"(result));
+
+	return 0;
+}
+
+static int zhaoxin_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+	if (max > ZHAOXIN_RNG_MAX_SIZE)
+		max = ZHAOXIN_RNG_MAX_SIZE;
+
+	rep_xstore(max, ZHAOXIN_RNG_CHUNK_1, data);
+
+	return max;
+}
+
+static struct hwrng zhaoxin_rng = {
+	.name = "zhaoxin",
+	.init = zhaoxin_rng_init,
+	.read = zhaoxin_rng_read,
+};
+
+static const struct x86_cpu_id zhaoxin_rng_cpu_ids[] = {
+	X86_MATCH_VENDOR_FAM_FEATURE(ZHAOXIN, 6, X86_FEATURE_XSTORE, NULL),
+	X86_MATCH_VENDOR_FAM_FEATURE(ZHAOXIN, 7, X86_FEATURE_XSTORE, NULL),
+	X86_MATCH_VENDOR_FAM_FEATURE(CENTAUR, 7, X86_FEATURE_XSTORE, NULL),
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, zhaoxin_rng_cpu_ids);
+
+static int __init zhaoxin_rng_mod_init(void)
+{
+	int err;
+
+	if (!x86_match_cpu(zhaoxin_rng_cpu_ids)) {
+		pr_err(PFX "The CPU isn't support XSTORE.\n");
+		return -ENODEV;
+	}
+
+	pr_info("Zhaoxin RNG detected\n");
+
+	err = hwrng_register(&zhaoxin_rng);
+	if (err)
+		pr_err(PFX "RNG registering failed (%d)\n", err);
+
+	return err;
+}
+module_init(zhaoxin_rng_mod_init);
+
+static void __exit zhaoxin_rng_mod_exit(void)
+{
+	hwrng_unregister(&zhaoxin_rng);
+}
+module_exit(zhaoxin_rng_mod_exit);
+
+MODULE_DESCRIPTION("H/W RNG driver for Zhaoxin CPUs");
+MODULE_AUTHOR("YunShen@zhaoxin.com");
+MODULE_LICENSE("GPL");