| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: compat_stub.h,v 1.1.2.24 2018/09/18 01:15:58 pgoyette Exp $ */ | | 1 | /* $NetBSD: compat_stub.h,v 1.1.2.25 2018/09/18 03:32:35 pgoyette Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2018 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Paul Goyette | | 8 | * by Paul Goyette |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -22,177 +22,27 @@ | | | @@ -22,177 +22,27 @@ |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #ifndef _SYS_COMPAT_STUB_H | | 32 | #ifndef _SYS_COMPAT_STUB_H |
33 | #define _SYS_COMPAT_STUB_H | | 33 | #define _SYS_COMPAT_STUB_H |
34 | | | 34 | |
35 | #include <sys/param.h> /* for COHERENCY_UNIT, for __cacheline_aligned */ | | 35 | #include <sys/compat_hook.h> |
36 | #include <sys/mutex.h> | | | |
37 | #include <sys/localcount.h> | | | |
38 | #include <sys/condvar.h> | | | |
39 | #include <sys/pserialize.h> | | | |
40 | #include <sys/atomic.h> | | | |
41 | | | | |
42 | /* | | | |
43 | * Macros for creating MP-safe vectored function calls, where | | | |
44 | * the function implementations are in modules which could be | | | |
45 | * unloaded. | | | |
46 | */ | | | |
47 | | | | |
48 | #define COMPAT_HOOK(hook,args) \ | | | |
49 | extern struct hook ## _t { \ | | | |
50 | kmutex_t mtx; \ | | | |
51 | kcondvar_t cv; \ | | | |
52 | struct localcount lc; \ | | | |
53 | pserialize_t psz; \ | | | |
54 | bool hooked; \ | | | |
55 | int (*f)args; \ | | | |
56 | } hook __cacheline_aligned; | | | |
57 | | | | |
58 | #define COMPAT_HOOK2(hook,args1,args2) \ | | | |
59 | extern struct hook ## _t { \ | | | |
60 | kmutex_t mtx; \ | | | |
61 | kcondvar_t cv; \ | | | |
62 | struct localcount lc; \ | | | |
63 | pserialize_t psz; \ | | | |
64 | bool hooked; \ | | | |
65 | int (*f1)args1; \ | | | |
66 | int (*f2)args2; \ | | | |
67 | } hook __cacheline_aligned; | | | |
68 | | | | |
69 | #define COMPAT_SET_HOOK(hook, waitchan, func) \ | | | |
70 | static void hook ## _set(void); \ | | | |
71 | static void hook ## _set(void) \ | | | |
72 | { \ | | | |
73 | \ | | | |
74 | KASSERT(!hook.hooked); \ | | | |
75 | \ | | | |
76 | hook.psz = pserialize_create(); \ | | | |
77 | mutex_init(&hook.mtx, MUTEX_DEFAULT, IPL_NONE); \ | | | |
78 | cv_init(&hook.cv, waitchan); \ | | | |
79 | localcount_init(&hook.lc); \ | | | |
80 | hook.f = func; \ | | | |
81 | \ | | | |
82 | /* Make sure it's initialized before anyone uses it */ \ | | | |
83 | membar_producer(); \ | | | |
84 | \ | | | |
85 | /* Let them use it */ \ | | | |
86 | hook.hooked = true; \ | | | |
87 | } | | | |
88 | | | | |
89 | #define COMPAT_SET_HOOK2(hook, waitchan, func1, func2) \ | | | |
90 | static void hook ## _set(void); \ | | | |
91 | static void hook ## _set(void) \ | | | |
92 | { \ | | | |
93 | \ | | | |
94 | KASSERT(!hook.hooked); \ | | | |
95 | \ | | | |
96 | hook.psz = pserialize_create(); \ | | | |
97 | mutex_init(&hook.mtx, MUTEX_DEFAULT, IPL_NONE); \ | | | |
98 | cv_init(&hook.cv, waitchan); \ | | | |
99 | localcount_init(&hook.lc); \ | | | |
100 | hook.f1 = func1; \ | | | |
101 | hook.f2 = func2; \ | | | |
102 | \ | | | |
103 | /* Make sure it's initialized before anyone uses it */ \ | | | |
104 | membar_producer(); \ | | | |
105 | \ | | | |
106 | /* Let them use it */ \ | | | |
107 | hook.hooked = true; \ | | | |
108 | } | | | |
109 | | | | |
110 | #define COMPAT_UNSET_HOOK(hook) \ | | | |
111 | static void (hook ## _unset)(void); \ | | | |
112 | static void (hook ## _unset)(void) \ | | | |
113 | { \ | | | |
114 | \ | | | |
115 | KASSERT(kernconfig_is_held()); \ | | | |
116 | KASSERT(hook.hooked); \ | | | |
117 | KASSERT(hook.f); \ | | | |
118 | \ | | | |
119 | /* Prevent new localcount_acquire calls. */ \ | | | |
120 | hook.hooked = false; \ | | | |
121 | \ | | | |
122 | /* Wait for existing localcount_acquire calls to drain. */ \ | | | |
123 | pserialize_perform(hook.psz); \ | | | |
124 | \ | | | |
125 | /* Wait for existing localcount references to drain. */\ | | | |
126 | localcount_drain(&hook.lc, &hook.cv, &hook.mtx); \ | | | |
127 | \ | | | |
128 | localcount_fini(&hook.lc); \ | | | |
129 | cv_destroy(&hook.cv); \ | | | |
130 | mutex_destroy(&hook.mtx); \ | | | |
131 | pserialize_destroy(hook.psz); \ | | | |
132 | } | | | |
133 | | | | |
134 | #define COMPAT_UNSET_HOOK2(hook) \ | | | |
135 | static void (hook ## _unset)(void); \ | | | |
136 | static void (hook ## _unset)(void) \ | | | |
137 | { \ | | | |
138 | \ | | | |
139 | KASSERT(kernconfig_is_held()); \ | | | |
140 | KASSERT(hook.hooked); \ | | | |
141 | KASSERT(hook.f1); \ | | | |
142 | KASSERT(hook.f2); \ | | | |
143 | \ | | | |
144 | /* Prevent new localcount_acquire calls. */ \ | | | |
145 | hook.hooked = false; \ | | | |
146 | \ | | | |
147 | /* Wait for existing localcount_acquire calls to drain. */ \ | | | |
148 | pserialize_perform(hook.psz); \ | | | |
149 | \ | | | |
150 | /* Wait for existing localcount references to drain. */\ | | | |
151 | localcount_drain(&hook.lc, &hook.cv, &hook.mtx); \ | | | |
152 | \ | | | |
153 | localcount_fini(&hook.lc); \ | | | |
154 | cv_destroy(&hook.cv); \ | | | |
155 | mutex_destroy(&hook.mtx); \ | | | |
156 | pserialize_destroy(hook.psz); \ | | | |
157 | } | | | |
158 | | | | |
159 | #define COMPAT_CALL_HOOK_DECL(hook, which, decl, args, default) \ | | | |
160 | int \ | | | |
161 | hook ## _ ## which ## _call decl; | | | |
162 | #define COMPAT_CALL_HOOK(hook, which, decl, args, default) \ | | | |
163 | int \ | | | |
164 | hook ## _ ## which ## _call decl \ | | | |
165 | { \ | | | |
166 | bool hooked; \ | | | |
167 | int error, s; \ | | | |
168 | \ | | | |
169 | s = pserialize_read_enter(); \ | | | |
170 | hooked = hook.hooked; \ | | | |
171 | if (hooked) { \ | | | |
172 | membar_consumer(); \ | | | |
173 | localcount_acquire(&hook.lc); \ | | | |
174 | } \ | | | |
175 | pserialize_read_exit(s); \ | | | |
176 | \ | | | |
177 | if (hooked) { \ | | | |
178 | error = (*hook.which)args; \ | | | |
179 | localcount_release(&hook.lc, &hook.cv, \ | | | |
180 | &hook.mtx); \ | | | |
181 | } else { \ | | | |
182 | error = default; \ | | | |
183 | } \ | | | |
184 | return error; \ | | | |
185 | } | | | |
186 | | | 36 | |
187 | /* | | 37 | /* |
188 | * Routine hooks for compat_50___sys_ntp_gettime | | 38 | * Routine hooks for compat_50___sys_ntp_gettime |
189 | * | | 39 | * |
190 | * MP-hooks not needed since the NTP code is not modular | | 40 | * MP-hooks not needed since the NTP code is not modular |
191 | */ | | 41 | */ |
192 | | | 42 | |
193 | struct ntptimeval; | | 43 | struct ntptimeval; |
194 | | | 44 | |
195 | extern void (*vec_ntp_gettime)(struct ntptimeval *); | | 45 | extern void (*vec_ntp_gettime)(struct ntptimeval *); |
196 | extern int (*vec_ntp_timestatus)(void); | | 46 | extern int (*vec_ntp_timestatus)(void); |
197 | | | 47 | |
198 | COMPAT_HOOK2(ntp_gettime_hooks, (struct ntptimeval *), (void)) | | 48 | COMPAT_HOOK2(ntp_gettime_hooks, (struct ntptimeval *), (void)) |