Page MenuHomeFreeBSD

D40962.id124856.diff
No OneTemporary

D40962.id124856.diff

diff --git a/sys/cddl/dev/kinst/kinst.h b/sys/cddl/dev/kinst/kinst.h
--- a/sys/cddl/dev/kinst/kinst.h
+++ b/sys/cddl/dev/kinst/kinst.h
@@ -35,10 +35,38 @@
kinst_patchval_t kp_patchval;
kinst_patchval_t kp_savedval;
kinst_patchval_t *kp_patchpoint;
+ uint8_t *kp_tramp;
struct kinst_probe_md kp_md;
};
+struct kinst_cpu_state {
+ /*
+ * kinst uses a breakpoint to return from the trampoline and resume
+ * execution. To do this safely, kinst implements a per-CPU state
+ * machine; the state is set to KINST_PROBE_FIRED for the duration of
+ * the trampoline execution (i.e from the time we transfer execution to
+ * it, until we return). Upon return, the state is set to
+ * KINST_PROBE_ARMED to indicate that a probe is not currently firing.
+ * All CPUs have their state initialized to KINST_PROBE_ARMED when
+ * kinst is loaded.
+ */
+ enum {
+ KINST_PROBE_ARMED,
+ KINST_PROBE_FIRED,
+ } state;
+ /*
+ * Points to the probe whose trampoline we're currently executing.
+ */
+ struct kinst_probe *kp;
+ /*
+ * Because we execute trampolines with interrupts disabled, we have to
+ * cache the CPU's status in order to restore it when we return from
+ * the trampoline.
+ */
+ uint64_t status;
+};
+
LIST_HEAD(kinst_probe_list, kinst_probe);
extern struct kinst_probe_list *kinst_probetab;
diff --git a/sys/cddl/dev/kinst/kinst.c b/sys/cddl/dev/kinst/kinst.c
--- a/sys/cddl/dev/kinst/kinst.c
+++ b/sys/cddl/dev/kinst/kinst.c
@@ -228,6 +228,9 @@
struct kinst_probe *kp = parg;
LIST_REMOVE(kp, kp_hashnext);
+#ifndef __amd64__
+ kinst_trampoline_dealloc(kp->kp_tramp);
+#endif
free(kp, M_KINST);
}
diff --git a/sys/cddl/dev/kinst/trampoline.c b/sys/cddl/dev/kinst/trampoline.c
--- a/sys/cddl/dev/kinst/trampoline.c
+++ b/sys/cddl/dev/kinst/trampoline.c
@@ -49,8 +49,10 @@
TAILQ_HEAD_INITIALIZER(kinst_trampchunks);
static struct sx kinst_tramp_sx;
SX_SYSINIT(kinst_tramp_sx, &kinst_tramp_sx, "kinst tramp");
+#ifdef __amd64__
static eventhandler_tag kinst_thread_ctor_handler;
static eventhandler_tag kinst_thread_dtor_handler;
+#endif
/*
* Fill the trampolines with KINST_TRAMP_FILL_PATTERN so that the kernel will
@@ -150,12 +152,14 @@
if ((how & M_NOWAIT) != 0)
return (NULL);
- /*
- * We didn't find any free trampoline in the current list,
- * allocate a new one. If that fails the provider will no
- * longer be reliable, so try to warn the user.
- */
if ((chunk = kinst_trampchunk_alloc()) == NULL) {
+#ifdef __amd64__
+ /*
+ * We didn't find any free trampoline in the current
+ * list, allocate a new one. If that fails the
+ * provider will no longer be reliable, so try to warn
+ * the user.
+ */
static bool once = true;
if (once) {
@@ -164,6 +168,7 @@
"kinst: failed to allocate trampoline, "
"probes may not fire");
}
+#endif
return (NULL);
}
off = 0;
@@ -220,6 +225,7 @@
sx_xunlock(&kinst_tramp_sx);
}
+#ifdef __amd64__
static void
kinst_thread_ctor(void *arg __unused, struct thread *td)
{
@@ -240,10 +246,12 @@
*/
kinst_trampoline_dealloc(tramp);
}
+#endif
int
kinst_trampoline_init(void)
{
+#ifdef __amd64__
struct proc *p;
struct thread *td;
void *tramp;
@@ -296,12 +304,21 @@
out:
sx_xunlock(&kinst_tramp_sx);
sx_sunlock(&allproc_lock);
+#else
+ int error = 0;
+
+ sx_xlock(&kinst_tramp_sx);
+ TAILQ_INIT(&kinst_trampchunks);
+ sx_xunlock(&kinst_tramp_sx);
+#endif
+
return (error);
}
int
kinst_trampoline_deinit(void)
{
+#ifdef __amd64__
struct trampchunk *chunk, *tmp;
struct proc *p;
struct thread *td;
@@ -324,6 +341,14 @@
TAILQ_FOREACH_SAFE(chunk, &kinst_trampchunks, next, tmp)
kinst_trampchunk_free(chunk);
sx_xunlock(&kinst_tramp_sx);
+#else
+ struct trampchunk *chunk, *tmp;
+
+ sx_xlock(&kinst_tramp_sx);
+ TAILQ_FOREACH_SAFE(chunk, &kinst_trampchunks, next, tmp)
+ kinst_trampchunk_free(chunk);
+ sx_xunlock(&kinst_tramp_sx);
+#endif
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 30, 3:25 AM (13 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28093653
Default Alt Text
D40962.id124856.diff (3 KB)

Event Timeline