Page MenuHomeFreeBSD

D35411.diff
No OneTemporary

D35411.diff

diff --git a/sys/arm64/conf/std.dev b/sys/arm64/conf/std.dev
--- a/sys/arm64/conf/std.dev
+++ b/sys/arm64/conf/std.dev
@@ -53,6 +53,7 @@
# Pseudo devices.
device crypto # core crypto support
+device armv8_rng # Armv8.5 rndr RNG
device loop # Network loopback
device ether # Ethernet support
device vlan # 802.1Q VLAN support
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -379,6 +379,8 @@
dev/psci/smccc_arm64.S standard
dev/psci/smccc.c standard
+dev/random/armv8rng.c optional armv8_rng !random_loadable
+
dev/safexcel/safexcel.c optional safexcel fdt
dev/sdhci/sdhci_xenon.c optional sdhci_xenon sdhci
diff --git a/sys/dev/random/armv8rng.c b/sys/dev/random/armv8rng.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/random/armv8rng.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2022 The FreeBSD Foundation
+ *
+ * This software was developed by Andrew Turner under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/random.h>
+
+#include <machine/armreg.h>
+
+#include <dev/random/randomdev.h>
+
+static u_int random_rndr_read(void *, u_int);
+
+static bool has_rndr;
+static struct random_source random_armv8_rndr = {
+ .rs_ident = "Armv8 rndr RNG",
+ .rs_source = RANDOM_PURE_ARMV8,
+ .rs_read = random_rndr_read,
+};
+
+static inline int
+random_rndr_read_one(u_long *buf)
+{
+ u_long val;
+ int loop, ret;
+
+ loop = 10;
+ do {
+ __asm __volatile(
+ ".arch_extension rng \n"
+ "mrs %0, rndrrs \n" /* Read the random number */
+ "cset %w1, ne \n" /* 1 on success, 0 on failure */
+ ".arch_extension norng \n"
+ : "=&r" (val), "=&r"(ret) :: "cc");
+ } while (ret != 0 && --loop > 0);
+
+ if (ret != 0)
+ *buf = val;
+
+ return (ret);
+}
+
+static u_int
+random_rndr_read(void *buf, u_int c)
+{
+ u_long *b;
+ u_int count;
+
+ b = buf;
+ for (count = 0; count < c; count += sizeof(*b)) {
+ if (!random_rndr_read_one(b))
+ break;
+
+ b++;
+ }
+
+ return (count);
+}
+
+static int
+rndr_modevent(module_t mod, int type, void *unused)
+{
+ uint64_t reg;
+ int error = 0;
+
+ switch (type) {
+ case MOD_LOAD:
+ has_rndr = false;
+ if (get_kernel_reg(ID_AA64ISAR0_EL1, &reg) &&
+ ID_AA64ISAR0_RNDR_VAL(reg) != ID_AA64ISAR0_RNDR_NONE) {
+ has_rndr = true;
+ random_source_register(&random_armv8_rndr);
+ printf("random: fast provider: \"%s\"\n",
+ random_armv8_rndr.rs_ident);
+ }
+ break;
+
+ case MOD_UNLOAD:
+ if (has_rndr)
+ random_source_deregister(&random_armv8_rndr);
+ break;
+
+ case MOD_SHUTDOWN:
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+
+ }
+
+ return (error);
+}
+
+static moduledata_t rndr_mod = {
+ "rndr",
+ rndr_modevent,
+ 0
+};
+
+DECLARE_MODULE(rndr, rndr_mod, SI_SUB_RANDOM, SI_ORDER_FOURTH);
+MODULE_VERSION(rndr, 1);
+MODULE_DEPEND(rndr, random_harvestq, 1, 1, 1);
diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -385,6 +385,7 @@
[RANDOM_PURE_TPM] = "PURE_TPM",
[RANDOM_PURE_VMGENID] = "PURE_VMGENID",
[RANDOM_PURE_QUALCOMM] = "PURE_QUALCOMM",
+ [RANDOM_PURE_ARMV8] = "PURE_ARMV8",
/* "ENTROPYSOURCE" */
};
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -41,6 +41,7 @@
${_arcmsr} \
${_allwinner} \
${_armv8crypto} \
+ ${_armv8_rng} \
${_asmc} \
ata \
ath \
@@ -674,6 +675,7 @@
.if ${MACHINE_CPUARCH} == "aarch64"
_armv8crypto= armv8crypto
+_armv8_rng= armv8_rng
_dpaa2= dpaa2
_sff= sff
_em= em
diff --git a/sys/modules/armv8_rng/Makefile b/sys/modules/armv8_rng/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/armv8_rng/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/random
+
+KMOD= armv8_rng
+SRCS= armv8rng.c
+SRCS+= bus_if.h device_if.h
+
+CFLAGS+= -I${SRCTOP}/sys
+
+.include <bsd.kmod.mk>
diff --git a/sys/sys/random.h b/sys/sys/random.h
--- a/sys/sys/random.h
+++ b/sys/sys/random.h
@@ -102,6 +102,7 @@
RANDOM_PURE_TPM,
RANDOM_PURE_VMGENID,
RANDOM_PURE_QUALCOMM,
+ RANDOM_PURE_ARMV8,
ENTROPYSOURCE
};
_Static_assert(ENTROPYSOURCE <= 32,

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 11, 11:07 PM (18 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15758738
Default Alt Text
D35411.diff (5 KB)

Event Timeline