Skip to content

Commit

Permalink
add kernel v6.4 support
Browse files Browse the repository at this point in the history
These are the same patches as v6.3.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
  • Loading branch information
smuellerDD committed Jul 3, 2023
1 parent 4bf1f6a commit 5c95067
Show file tree
Hide file tree
Showing 26 changed files with 14,467 additions and 0 deletions.
422 changes: 422 additions & 0 deletions kernel_patches/v6.4/v50-0000-cover-letter.patch

Large diffs are not rendered by default.

4,374 changes: 4,374 additions & 0 deletions kernel_patches/v6.4/v50-0001-LRNG-Entropy-Source-and-DRNG-Manager.patch

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
From 00c96821779bc3ca240de75fcaba7f3219fb3101 Mon Sep 17 00:00:00 2001
From: Stephan Mueller <smueller@chronox.de>
Date: Sun, 15 May 2022 15:40:46 +0200
Subject: [PATCH v50 02/25] LRNG - allocate one DRNG instance per NUMA node

In order to improve NUMA-locality when serving getrandom(2) requests,
allocate one DRNG instance per node.

The DRNG instance that is present right from the start of the kernel is
reused as the first per-NUMA-node DRNG. For all remaining online NUMA
nodes a new DRNG instance is allocated.

During boot time, the multiple DRNG instances are seeded sequentially.
With this, the first DRNG instance (referenced as the initial DRNG
in the code) is completely seeded with 256 bits of entropy before the
next DRNG instance is completely seeded.

When random numbers are requested, the NUMA-node-local DRNG is checked
whether it has been already fully seeded. If this is not the case, the
initial DRNG is used to serve the request.

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
drivers/char/lrng/Makefile | 2 +
drivers/char/lrng/lrng_numa.c | 124 ++++++++++++++++++++++++++++++++++
drivers/char/lrng/lrng_numa.h | 4 ++
drivers/char/lrng/lrng_proc.h | 11 +++
4 files changed, 141 insertions(+)
create mode 100644 drivers/char/lrng/lrng_numa.c
create mode 100644 drivers/char/lrng/lrng_proc.h

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 809e1911d370..60effabb1372 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -8,4 +8,6 @@ obj-y += lrng_es_mgr.o lrng_drng_mgr.o \
obj-$(CONFIG_LRNG_SHA256) += lrng_sha256.o
obj-$(CONFIG_LRNG_SHA1) += lrng_sha1.o

+obj-$(CONFIG_NUMA) += lrng_numa.o
+
obj-$(CONFIG_LRNG_DRNG_CHACHA20) += lrng_drng_chacha20.o
diff --git a/drivers/char/lrng/lrng_numa.c b/drivers/char/lrng/lrng_numa.c
new file mode 100644
index 000000000000..d74dd8df2843
--- /dev/null
+++ b/drivers/char/lrng/lrng_numa.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG NUMA support
+ *
+ * Copyright (C) 2022, Stephan Mueller <smueller@chronox.de>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/lrng.h>
+#include <linux/slab.h>
+
+#include "lrng_drng_mgr.h"
+#include "lrng_es_irq.h"
+#include "lrng_es_mgr.h"
+#include "lrng_numa.h"
+#include "lrng_proc.h"
+
+static struct lrng_drng **lrng_drng __read_mostly = NULL;
+
+struct lrng_drng **lrng_drng_instances(void)
+{
+ /* counterpart to cmpxchg_release in _lrng_drngs_numa_alloc */
+ return READ_ONCE(lrng_drng);
+}
+
+/* Allocate the data structures for the per-NUMA node DRNGs */
+static void _lrng_drngs_numa_alloc(struct work_struct *work)
+{
+ struct lrng_drng **drngs;
+ struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+ u32 node;
+ bool init_drng_used = false;
+
+ mutex_lock(&lrng_crypto_cb_update);
+
+ /* per-NUMA-node DRNGs are already present */
+ if (lrng_drng)
+ goto unlock;
+
+ /* Make sure the initial DRNG is initialized and its drng_cb is set */
+ if (lrng_drng_initalize())
+ goto err;
+
+ drngs = kcalloc(nr_node_ids, sizeof(void *), GFP_KERNEL|__GFP_NOFAIL);
+ for_each_online_node(node) {
+ struct lrng_drng *drng;
+
+ if (!init_drng_used) {
+ drngs[node] = lrng_drng_init;
+ init_drng_used = true;
+ continue;
+ }
+
+ drng = kmalloc_node(sizeof(struct lrng_drng),
+ GFP_KERNEL|__GFP_NOFAIL, node);
+ memset(drng, 0, sizeof(lrng_drng));
+
+ if (lrng_drng_alloc_common(drng, lrng_drng_init->drng_cb)) {
+ kfree(drng);
+ goto err;
+ }
+
+ drng->hash_cb = lrng_drng_init->hash_cb;
+ drng->hash = lrng_drng_init->hash_cb->hash_alloc();
+ if (IS_ERR(drng->hash)) {
+ lrng_drng_init->drng_cb->drng_dealloc(drng->drng);
+ kfree(drng);
+ goto err;
+ }
+
+ mutex_init(&drng->lock);
+ rwlock_init(&drng->hash_lock);
+
+ /*
+ * No reseeding of NUMA DRNGs from previous DRNGs as this
+ * would complicate the code. Let it simply reseed.
+ */
+ drngs[node] = drng;
+
+ lrng_pool_inc_numa_node();
+ pr_info("DRNG and entropy pool read hash for NUMA node %d allocated\n",
+ node);
+ }
+
+ /* counterpart to READ_ONCE in lrng_drng_instances */
+ if (!cmpxchg_release(&lrng_drng, NULL, drngs)) {
+ lrng_pool_all_numa_nodes_seeded(false);
+ goto unlock;
+ }
+
+err:
+ for_each_online_node(node) {
+ struct lrng_drng *drng = drngs[node];
+
+ if (drng == lrng_drng_init)
+ continue;
+
+ if (drng) {
+ drng->hash_cb->hash_dealloc(drng->hash);
+ drng->drng_cb->drng_dealloc(drng->drng);
+ kfree(drng);
+ }
+ }
+ kfree(drngs);
+
+unlock:
+ mutex_unlock(&lrng_crypto_cb_update);
+}
+
+static DECLARE_WORK(lrng_drngs_numa_alloc_work, _lrng_drngs_numa_alloc);
+
+static void lrng_drngs_numa_alloc(void)
+{
+ schedule_work(&lrng_drngs_numa_alloc_work);
+}
+
+static int __init lrng_numa_init(void)
+{
+ lrng_drngs_numa_alloc();
+ return 0;
+}
+
+late_initcall(lrng_numa_init);
diff --git a/drivers/char/lrng/lrng_numa.h b/drivers/char/lrng/lrng_numa.h
index bfbb9a489031..dc8dff9816ee 100644
--- a/drivers/char/lrng/lrng_numa.h
+++ b/drivers/char/lrng/lrng_numa.h
@@ -6,6 +6,10 @@
#ifndef _LRNG_NUMA_H
#define _LRNG_NUMA_H

+#ifdef CONFIG_NUMA
+struct lrng_drng **lrng_drng_instances(void);
+#else /* CONFIG_NUMA */
static inline struct lrng_drng **lrng_drng_instances(void) { return NULL; }
+#endif /* CONFIG_NUMA */

#endif /* _LRNG_NUMA_H */
diff --git a/drivers/char/lrng/lrng_proc.h b/drivers/char/lrng/lrng_proc.h
new file mode 100644
index 000000000000..e8097abe7fbd
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+/*
+ * Copyright (C) 2022, Stephan Mueller <smueller@chronox.de>
+ */
+
+#ifndef _LRNG_PROC_H
+#define _LRNG_PROC_H
+
+static inline void lrng_pool_inc_numa_node(void) { }
+
+#endif /* _LRNG_PROC_H */
--
2.40.0

145 changes: 145 additions & 0 deletions kernel_patches/v6.4/v50-0003-LRNG-proc-interface.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
From 7f992ffb0e7c02390c0eaf056a8a1f422b6ffa4e Mon Sep 17 00:00:00 2001
From: Stephan Mueller <smueller@chronox.de>
Date: Sun, 18 Dec 2022 21:12:42 +0100
Subject: [PATCH v50 03/25] LRNG - /proc interface

The patch adds the file lrng_type which provides details about
the LRNG:

- the name of the DRNG that produces the random numbers for /dev/random,
/dev/urandom, getrandom(2)

- the hash used to produce random numbers from the entropy pool

- the number of secondary DRNG instances

- indicator whether the LRNG operates SP800-90B compliant

- indicator whether a high-resolution timer is identified - only with a
high-resolution timer the interrupt noise source will deliver sufficient
entropy

- indicator whether the LRNG has been minimally seeded (i.e. is the
secondary DRNG seeded with at least 128 bits of entropy)

- indicator whether the LRNG has been fully seeded (i.e. is the
secondary DRNG seeded with at least 256 bits of entropy)

Signed-off-by: Stephan Mueller <smueller@chronox.de>
---
drivers/char/lrng/Makefile | 1 +
drivers/char/lrng/lrng_proc.c | 74 +++++++++++++++++++++++++++++++++++
drivers/char/lrng/lrng_proc.h | 4 ++
3 files changed, 79 insertions(+)
create mode 100644 drivers/char/lrng/lrng_proc.c

diff --git a/drivers/char/lrng/Makefile b/drivers/char/lrng/Makefile
index 60effabb1372..dafa6299972d 100644
--- a/drivers/char/lrng/Makefile
+++ b/drivers/char/lrng/Makefile
@@ -8,6 +8,7 @@ obj-y += lrng_es_mgr.o lrng_drng_mgr.o \
obj-$(CONFIG_LRNG_SHA256) += lrng_sha256.o
obj-$(CONFIG_LRNG_SHA1) += lrng_sha1.o

+obj-$(CONFIG_SYSCTL) += lrng_proc.o
obj-$(CONFIG_NUMA) += lrng_numa.o

obj-$(CONFIG_LRNG_DRNG_CHACHA20) += lrng_drng_chacha20.o
diff --git a/drivers/char/lrng/lrng_proc.c b/drivers/char/lrng/lrng_proc.c
new file mode 100644
index 000000000000..a9c8d90c7d56
--- /dev/null
+++ b/drivers/char/lrng/lrng_proc.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+/*
+ * LRNG proc interfaces
+ *
+ * Copyright (C) 2022, Stephan Mueller <smueller@chronox.de>
+ */
+
+#include <linux/lrng.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+#include "lrng_drng_mgr.h"
+#include "lrng_es_aux.h"
+#include "lrng_es_mgr.h"
+#include "lrng_proc.h"
+
+/* Number of online DRNGs */
+static u32 numa_drngs = 1;
+
+void lrng_pool_inc_numa_node(void)
+{
+ numa_drngs++;
+}
+
+static int lrng_proc_type_show(struct seq_file *m, void *v)
+{
+ struct lrng_drng *lrng_drng_init = lrng_drng_init_instance();
+ unsigned char buf[270];
+ u32 i;
+
+ mutex_lock(&lrng_drng_init->lock);
+ snprintf(buf, sizeof(buf),
+ "DRNG name: %s\n"
+ "LRNG security strength in bits: %d\n"
+ "Number of DRNG instances: %u\n"
+ "Standards compliance: %sNTG.1 (2011%s)\n"
+ "LRNG minimally seeded: %s\n"
+ "LRNG fully seeded: %s\n"
+ "LRNG entropy level: %u\n",
+ lrng_drng_init->drng_cb->drng_name(),
+ lrng_security_strength(),
+ numa_drngs,
+ lrng_sp80090c_compliant() ? "SP800-90C, " : "",
+ lrng_ntg1_2022_compliant() ? " / 2022" : "",
+ lrng_state_min_seeded() ? "true" : "false",
+ lrng_state_fully_seeded() ? "true" : "false",
+ lrng_avail_entropy());
+ seq_write(m, buf, strlen(buf));
+
+ for_each_lrng_es(i) {
+ snprintf(buf, sizeof(buf),
+ "Entropy Source %u properties:\n"
+ " Name: %s\n",
+ i, lrng_es[i]->name);
+ seq_write(m, buf, strlen(buf));
+
+ buf[0] = '\0';
+ lrng_es[i]->state(buf, sizeof(buf));
+ seq_write(m, buf, strlen(buf));
+ }
+
+ mutex_unlock(&lrng_drng_init->lock);
+
+ return 0;
+}
+
+static int __init lrng_proc_type_init(void)
+{
+ proc_create_single("lrng_type", 0444, NULL, &lrng_proc_type_show);
+ return 0;
+}
+
+module_init(lrng_proc_type_init);
diff --git a/drivers/char/lrng/lrng_proc.h b/drivers/char/lrng/lrng_proc.h
index e8097abe7fbd..c653274f1954 100644
--- a/drivers/char/lrng/lrng_proc.h
+++ b/drivers/char/lrng/lrng_proc.h
@@ -6,6 +6,10 @@
#ifndef _LRNG_PROC_H
#define _LRNG_PROC_H

+#ifdef CONFIG_SYSCTL
+void lrng_pool_inc_numa_node(void);
+#else
static inline void lrng_pool_inc_numa_node(void) { }
+#endif

#endif /* _LRNG_PROC_H */
--
2.40.0

Loading

0 comments on commit 5c95067

Please sign in to comment.