Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cddl/dev/kinst/kinst.h
48254 views
1
/*
2
* SPDX-License-Identifier: CDDL 1.0
3
*
4
* Copyright (c) 2022 Christos Margiolis <[email protected]>
5
* Copyright (c) 2023 The FreeBSD Foundation
6
*
7
* Portions of this software were developed by Christos Margiolis
8
* <[email protected]> under sponsorship from the FreeBSD Foundation.
9
*/
10
11
#ifndef _KINST_H_
12
#define _KINST_H_
13
14
#include <sys/dtrace.h>
15
16
typedef struct {
17
char kpd_func[DTRACE_FUNCNAMELEN];
18
char kpd_mod[DTRACE_MODNAMELEN];
19
int kpd_off;
20
} dtrace_kinst_probedesc_t;
21
22
#define KINSTIOC_MAKEPROBE _IOW('k', 1, dtrace_kinst_probedesc_t)
23
24
#ifdef _KERNEL
25
26
#include <sys/queue.h>
27
28
#include "kinst_isa.h"
29
30
struct kinst_probe {
31
LIST_ENTRY(kinst_probe) kp_hashnext;
32
const char *kp_func;
33
char kp_name[16];
34
dtrace_id_t kp_id;
35
kinst_patchval_t kp_patchval;
36
kinst_patchval_t kp_savedval;
37
kinst_patchval_t *kp_patchpoint;
38
uint8_t *kp_tramp;
39
40
struct kinst_probe_md kp_md;
41
};
42
43
struct kinst_cpu_state {
44
/*
45
* kinst uses a breakpoint to return from the trampoline and resume
46
* execution. To do this safely, kinst implements a per-CPU state
47
* machine; the state is set to KINST_PROBE_FIRED for the duration of
48
* the trampoline execution (i.e from the time we transfer execution to
49
* it, until we return). Upon return, the state is set to
50
* KINST_PROBE_ARMED to indicate that a probe is not currently firing.
51
* All CPUs have their state initialized to KINST_PROBE_ARMED when
52
* kinst is loaded.
53
*/
54
enum {
55
KINST_PROBE_ARMED,
56
KINST_PROBE_FIRED,
57
} state;
58
/*
59
* Points to the probe whose trampoline we're currently executing.
60
*/
61
const struct kinst_probe *kp;
62
/*
63
* Because we execute trampolines with interrupts disabled, we have to
64
* cache the CPU's status in order to restore it when we return from
65
* the trampoline.
66
*/
67
uint64_t status;
68
};
69
70
LIST_HEAD(kinst_probe_list, kinst_probe);
71
72
extern struct kinst_probe_list *kinst_probetab;
73
74
#define KINST_PROBETAB_MAX 0x8000 /* 32k */
75
#define KINST_ADDR2NDX(addr) (((uintptr_t)(addr)) & (KINST_PROBETAB_MAX - 1))
76
#define KINST_GETPROBE(i) (&kinst_probetab[KINST_ADDR2NDX(i)])
77
78
struct linker_file;
79
struct linker_symval;
80
81
/* kinst.c */
82
volatile void *kinst_memcpy(volatile void *, volatile const void *, size_t);
83
bool kinst_excluded(const char *);
84
void kinst_probe_create(struct kinst_probe *, struct linker_file *);
85
86
/* arch/kinst_isa.c */
87
int kinst_invop(uintptr_t, struct trapframe *, uintptr_t);
88
void kinst_patch_tracepoint(struct kinst_probe *, kinst_patchval_t);
89
int kinst_make_probe(struct linker_file *, int, struct linker_symval *,
90
void *);
91
int kinst_md_init(void);
92
void kinst_md_deinit(void);
93
bool kinst_md_excluded(const char *);
94
95
/* trampoline.c */
96
int kinst_trampoline_init(void);
97
int kinst_trampoline_deinit(void);
98
uint8_t *kinst_trampoline_alloc(int);
99
void kinst_trampoline_dealloc(uint8_t *);
100
101
#ifdef MALLOC_DECLARE
102
MALLOC_DECLARE(M_KINST);
103
#endif /* MALLOC_DECLARE */
104
105
#define KINST_LOG_HELPER(fmt, ...) \
106
printf("%s:%d: " fmt "%s\n", __func__, __LINE__, __VA_ARGS__)
107
#define KINST_LOG(...) \
108
KINST_LOG_HELPER(__VA_ARGS__, "")
109
110
#endif /* _KERNEL */
111
112
#endif /* _KINST_H_ */
113
114