]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/if_wg/include/sys/support.h
service(8): use an environment more consistent with init(8)
[FreeBSD/FreeBSD.git] / sys / dev / if_wg / include / sys / support.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2019-2020 Rubicon Communications, LLC (Netgate)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *   2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29
30 #ifndef SYS_SUPPORT_H_
31 #define SYS_SUPPORT_H_
32 #ifdef __LOCORE
33 #include <machine/asm.h>
34 #define SYM_FUNC_START ENTRY
35 #define SYM_FUNC_END END
36
37 #else
38 #include <sys/types.h>
39 #include <sys/limits.h>
40 #include <sys/endian.h>
41 #include <sys/libkern.h>
42 #include <sys/malloc.h>
43 #include <sys/proc.h>
44 #include <sys/lock.h>
45 #include <vm/uma.h>
46
47 #if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
48 #include <machine/fpu.h>
49 #endif
50 #include <crypto/siphash/siphash.h>
51
52
53 #define COMPAT_ZINC_IS_A_MODULE
54 MALLOC_DECLARE(M_WG);
55
56 #define BUILD_BUG_ON(x)                 CTASSERT(!(x))
57
58 #define BIT(nr)                 (1UL << (nr))
59 #define BIT_ULL(nr)             (1ULL << (nr))
60 #ifdef __LP64__
61 #define BITS_PER_LONG           64
62 #else
63 #define BITS_PER_LONG           32
64 #endif
65
66 #define rw_enter_write rw_wlock
67 #define rw_exit_write rw_wunlock
68 #define rw_enter_read rw_rlock
69 #define rw_exit_read rw_runlock
70 #define rw_exit rw_unlock
71
72 #define ASSERT(x) MPASS(x)
73
74 #define ___PASTE(a,b) a##b
75 #define __PASTE(a,b) ___PASTE(a,b)
76 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
77
78 #define typeof(x) __typeof__(x)
79
80
81 #define min_t(t, a, b) ({ t __a = (a); t __b = (b); __a > __b ? __b : __a; })
82
83 typedef uint8_t u8;
84 typedef uint16_t u16;
85 typedef uint32_t u32;
86 typedef uint32_t __le32;
87 typedef uint64_t  u64;
88 typedef uint64_t  __le64;
89
90 #define __must_check            __attribute__((__warn_unused_result__))
91 #define asmlinkage
92 #define __ro_after_init __read_mostly
93
94 #define get_unaligned_le32(x) le32dec(x)
95 #define get_unaligned_le64(x) le64dec(x)
96
97 #define cpu_to_le64(x) htole64(x)
98 #define cpu_to_le32(x) htole32(x)
99 #define letoh64(x) le64toh(x)
100
101 #define need_resched() \
102         ((curthread->td_flags & (TDF_NEEDRESCHED|TDF_ASTPENDING)) || \
103          curthread->td_owepreempt)
104
105  
106 #define CONTAINER_OF(a, b, c) __containerof((a), b, c)
107
108 typedef struct {
109         uint64_t        k0;
110         uint64_t        k1;
111 } SIPHASH_KEY;
112
113 static inline uint64_t
114 siphash24(const SIPHASH_KEY *key, const void *src, size_t len)
115 {
116         SIPHASH_CTX ctx;
117
118         return (SipHashX(&ctx, 2, 4, (const uint8_t *)key, src, len));
119 }
120
121 static inline void
122 put_unaligned_le32(u32 val, void *p)
123 {
124         *((__le32 *)p) = cpu_to_le32(val);
125 }
126
127
128 #define rol32(i32, n) ((i32) << (n) | (i32) >> (32 - (n)))
129
130 #define memzero_explicit(p, s) explicit_bzero(p, s)
131
132 #define EXPORT_SYMBOL(x)
133
134 #define U32_MAX         ((u32)~0U)
135 #if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
136 #define kfpu_begin(ctx) {                                                       \
137                 if (ctx->sc_fpu_ctx == NULL)     {                       \
138                         ctx->sc_fpu_ctx = fpu_kern_alloc_ctx(0); \
139                 }                                                                                                                \
140                 critical_enter();                                                                                \
141         fpu_kern_enter(curthread, ctx->sc_fpu_ctx, FPU_KERN_NORMAL); \
142 }
143
144 #define kfpu_end(ctx)    {                                               \
145                 MPASS(ctx->sc_fpu_ctx != NULL);                  \
146                 fpu_kern_leave(curthread, ctx->sc_fpu_ctx);     \
147                 critical_exit();                             \
148 }
149 #else
150 #define kfpu_begin(ctx)
151 #define kfpu_end(ctx)
152 #define fpu_kern_free_ctx(p)
153 #endif
154
155 typedef enum {
156         HAVE_NO_SIMD = 1 << 0,
157         HAVE_FULL_SIMD = 1 << 1,
158         HAVE_SIMD_IN_USE = 1 << 31
159 } simd_context_state_t;
160
161 typedef struct {
162         simd_context_state_t sc_state;
163         struct fpu_kern_ctx *sc_fpu_ctx;
164 } simd_context_t;
165
166
167 #define DONT_USE_SIMD NULL
168
169 static __must_check inline bool
170 may_use_simd(void)
171 {
172 #if defined(__amd64__)
173         return true;
174 #else
175         return false;
176 #endif
177 }
178
179 static inline void
180 simd_get(simd_context_t *ctx)
181 {
182         ctx->sc_state = may_use_simd() ? HAVE_FULL_SIMD : HAVE_NO_SIMD;
183 }
184
185 static inline void
186 simd_put(simd_context_t *ctx)
187 {
188 #if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
189         if (is_fpu_kern_thread(0))
190                 return;
191 #endif
192         if (ctx->sc_state & HAVE_SIMD_IN_USE)
193                 kfpu_end(ctx);
194         ctx->sc_state = HAVE_NO_SIMD;
195 }
196
197 static __must_check inline bool
198 simd_use(simd_context_t *ctx)
199 {
200 #if defined(__aarch64__) || defined(__amd64__) || defined(__i386__)
201         if (is_fpu_kern_thread(0))
202                 return true;
203 #else
204         return false;
205 #endif
206         if (ctx == NULL)
207                 return false;
208         if (!(ctx->sc_state & HAVE_FULL_SIMD))
209                 return false;
210         if (ctx->sc_state & HAVE_SIMD_IN_USE)
211                 return true;
212         kfpu_begin(ctx);
213         ctx->sc_state |= HAVE_SIMD_IN_USE;
214         return true;
215 }
216
217 static inline bool
218 simd_relax(simd_context_t *ctx)
219 {
220         if ((ctx->sc_state & HAVE_SIMD_IN_USE) && need_resched()) {
221                 simd_put(ctx);
222                 simd_get(ctx);
223                 return simd_use(ctx);
224         }
225         return false;
226 }
227
228 #define unlikely(x) __predict_false(x)
229 #define likely(x) __predict_true(x)
230 /* Generic path for arbitrary size */
231
232
233 static inline unsigned long
234 __crypto_memneq_generic(const void *a, const void *b, size_t size)
235 {
236         unsigned long neq = 0;
237
238         while (size >= sizeof(unsigned long)) {
239                 neq |= *(const unsigned long *)a ^ *(const unsigned long *)b;
240                 __compiler_membar();
241                 a  = ((const char *)a + sizeof(unsigned long));
242                 b = ((const char *)b + sizeof(unsigned long));
243                 size -= sizeof(unsigned long);
244         }
245         while (size > 0) {
246                 neq |= *(const unsigned char *)a ^ *(const unsigned char *)b;
247                 __compiler_membar();
248                 a  = (const char *)a + 1;
249                 b = (const char *)b + 1;
250                 size -= 1;
251         }
252         return neq;
253 }
254
255 #define crypto_memneq(a, b, c) __crypto_memneq_generic((a), (b), (c))
256
257 static inline void
258 __cpu_to_le32s(uint32_t *buf)
259 {
260         *buf = htole32(*buf);
261 }
262
263 static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
264 {
265         while (words--) {
266                 __cpu_to_le32s(buf);
267                 buf++;
268         }
269 }
270
271 #define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1
272 void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len);
273
274 static inline void crypto_xor_cpy(u8 *dst, const u8 *src1, const u8 *src2,
275                                   unsigned int size)
276 {
277         if (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS &&
278             __builtin_constant_p(size) &&
279             (size % sizeof(unsigned long)) == 0) {
280                 unsigned long *d = (unsigned long *)dst;
281                 const unsigned long *s1 = (const unsigned long *)src1;
282                 const unsigned long *s2 = (const unsigned long *)src2;
283
284                 while (size > 0) {
285                         *d++ = *s1++ ^ *s2++;
286                         size -= sizeof(unsigned long);
287                 }
288         } else {
289                 __crypto_xor(dst, src1, src2, size);
290         }
291 }
292 #include <sys/kernel.h>
293 #define module_init(fn)                                                 \
294 static void \
295 wrap_ ## fn(void *dummy __unused) \
296 {                                                                \
297         fn();                                            \
298 }                                                                                                                                               \
299 SYSINIT(if_wg_ ## fn, SI_SUB_LAST, SI_ORDER_FIRST, wrap_ ## fn, NULL)
300
301
302 #define module_exit(fn)                                                         \
303 static void \
304 wrap_ ## fn(void *dummy __unused) \
305 {                                                                \
306         fn();                                            \
307 }                                                                                                                                               \
308 SYSUNINIT(if_wg_ ## fn, SI_SUB_LAST, SI_ORDER_FIRST, wrap_ ## fn, NULL)
309
310 #define module_param(a, b, c)
311 #define MODULE_LICENSE(x)
312 #define MODULE_DESCRIPTION(x)
313 #define MODULE_AUTHOR(x)
314
315 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
316
317 #define __initconst
318 #define __initdata
319 #define __init
320 #define __exit
321 #define BUG() panic("%s:%d bug hit!\n", __FILE__, __LINE__)
322
323 #define WARN_ON(cond) ({                                        \
324       bool __ret = (cond);                                      \
325       if (__ret) {                                              \
326                 printf("WARNING %s failed at %s:%d\n",          \
327                     __stringify(cond), __FILE__, __LINE__);     \
328       }                                                         \
329       unlikely(__ret);                                          \
330 })
331
332 #define pr_err printf
333 #define pr_info printf
334 #define IS_ENABLED(x) 0
335 #define ___stringify(...)               #__VA_ARGS__
336 #define __stringify(...)                ___stringify(__VA_ARGS__)
337 #define kmalloc(size, flag) malloc((size), M_WG, M_WAITOK)
338 #define kfree(p) free(p, M_WG)
339 #define vzalloc(size) malloc((size), M_WG, M_WAITOK|M_ZERO)
340 #define vfree(p) free(p, M_WG)
341 #endif
342 #endif