git: ecca3180855a - main - kinst: replace KINST_TRAMP_INIT
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 23 May 2023 13:59:11 UTC
The branch main has been updated by christos:
URL: https://cgit.FreeBSD.org/src/commit/?id=ecca3180855a2aa7eb394706c7ae69d9c67b87b5
commit ecca3180855a2aa7eb394706c7ae69d9c67b87b5
Author: Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2023-05-23 13:58:36 +0000
Commit: Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2023-05-23 13:58:36 +0000
kinst: replace KINST_TRAMP_INIT
The current implementation of KINST_TRAMP_INIT is working only on amd64,
where the breakpoint instruction is one byte long, which might not be
the case for other architectures (e.g in RISC-V it's either 2 or 4
bytes). This patch introduces two machine-dependent constants,
KINST_TRAMP_FILL_PATTERN and KINST_TRAMP_FILL_SIZE, which hold the fill
instruction and the size of that instruction in bytes respectively.
Reviewed by: markj
Approved by: markj (mentor)
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D39504
---
sys/cddl/dev/kinst/amd64/kinst_isa.h | 12 ++++--------
sys/cddl/dev/kinst/trampoline.c | 22 +++++++++++++++++-----
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/sys/cddl/dev/kinst/amd64/kinst_isa.h b/sys/cddl/dev/kinst/amd64/kinst_isa.h
index 4c6387b8cb50..eb4f79c4c726 100644
--- a/sys/cddl/dev/kinst/amd64/kinst_isa.h
+++ b/sys/cddl/dev/kinst/amd64/kinst_isa.h
@@ -17,14 +17,10 @@
* have 2 instructions stored in the trampoline, and each of them can take up
* to 16 bytes, 32 bytes is enough to cover even the worst case scenario.
*/
-#define KINST_TRAMP_SIZE 32
-#define KINST_TRAMPCHUNK_SIZE PAGE_SIZE
-
-/*
- * Fill the trampolines with breakpoint instructions so that the kernel will
- * crash cleanly if things somehow go wrong.
- */
-#define KINST_TRAMP_INIT(t, s) memset((t), KINST_PATCHVAL, (s))
+#define KINST_TRAMP_SIZE 32
+#define KINST_TRAMPCHUNK_SIZE PAGE_SIZE
+#define KINST_TRAMP_FILL_PATTERN ((uint8_t []){KINST_PATCHVAL})
+#define KINST_TRAMP_FILL_SIZE sizeof(uint8_t)
typedef uint8_t kinst_patchval_t;
diff --git a/sys/cddl/dev/kinst/trampoline.c b/sys/cddl/dev/kinst/trampoline.c
index 6614a6ed9302..5575503f60fb 100644
--- a/sys/cddl/dev/kinst/trampoline.c
+++ b/sys/cddl/dev/kinst/trampoline.c
@@ -28,9 +28,6 @@
#include "kinst.h"
#include "kinst_isa.h"
-/*
- * We can have 4KB/32B = 128 trampolines per chunk.
- */
#define KINST_TRAMPS_PER_CHUNK (KINST_TRAMPCHUNK_SIZE / KINST_TRAMP_SIZE)
struct trampchunk {
@@ -47,6 +44,21 @@ SX_SYSINIT(kinst_tramp_sx, &kinst_tramp_sx, "kinst tramp");
static eventhandler_tag kinst_thread_ctor_handler;
static eventhandler_tag kinst_thread_dtor_handler;
+/*
+ * Fill the trampolines with KINST_TRAMP_FILL_PATTERN so that the kernel will
+ * crash cleanly if things somehow go wrong.
+ */
+static void
+kinst_trampoline_fill(uint8_t *addr, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i += KINST_TRAMP_FILL_SIZE) {
+ memcpy(&addr[i], KINST_TRAMP_FILL_PATTERN,
+ KINST_TRAMP_FILL_SIZE);
+ }
+}
+
static struct trampchunk *
kinst_trampchunk_alloc(void)
{
@@ -77,7 +89,7 @@ kinst_trampchunk_alloc(void)
M_WAITOK | M_EXEC);
KASSERT(error == KERN_SUCCESS, ("kmem_back failed: %d", error));
- KINST_TRAMP_INIT((void *)trampaddr, KINST_TRAMPCHUNK_SIZE);
+ kinst_trampoline_fill((uint8_t *)trampaddr, KINST_TRAMPCHUNK_SIZE);
/* Allocate a tracker for this chunk. */
chunk = malloc(sizeof(*chunk), M_KINST, M_WAITOK);
@@ -171,7 +183,7 @@ kinst_trampoline_dealloc_locked(uint8_t *tramp, bool freechunks)
TAILQ_FOREACH(chunk, &kinst_trampchunks, next) {
for (off = 0; off < KINST_TRAMPS_PER_CHUNK; off++) {
if (chunk->addr + off * KINST_TRAMP_SIZE == tramp) {
- KINST_TRAMP_INIT(tramp, KINST_TRAMP_SIZE);
+ kinst_trampoline_fill(tramp, KINST_TRAMP_SIZE);
BIT_SET(KINST_TRAMPS_PER_CHUNK, off,
&chunk->free);
if (freechunks &&