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 &&