git: ecca3180855a - main - kinst: replace KINST_TRAMP_INIT

From: Christos Margiolis <christos_at_FreeBSD.org>
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 &&