-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
These are the same patches as v6.3. Signed-off-by: Stephan Mueller <smueller@chronox.de>
- Loading branch information
1 parent
4bf1f6a
commit 5c95067
Showing
26 changed files
with
14,467 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
4,374 changes: 4,374 additions & 0 deletions
4,374
kernel_patches/v6.4/v50-0001-LRNG-Entropy-Source-and-DRNG-Manager.patch
Large diffs are not rendered by default.
Oops, something went wrong.
207 changes: 207 additions & 0 deletions
207
kernel_patches/v6.4/v50-0002-LRNG-allocate-one-DRNG-instance-per-NUMA-node.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
Oops, something went wrong.