1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
/*
* Oracle Linux DTrace.
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
#ifndef BPF_LIB_H
#define BPF_LIB_H
/*
* Explicit inline assembler to implement a dynamic upper bound check:
*
* if (var > bnd)
* var = bnd;
*
* The BPF GCC compiler does not guarantee that the bound (expected to be a
* variable that holds a constant value) will be encoded in the source register
* while the BPF verifier does require that (for now).
*/
#define set_upper_bound(var, bnd) \
asm ("jle %0, %1, 1f\n\t" \
"mov %0, %1\n\t" \
"1:" \
: "+r" (var) \
: "r" (bnd) \
: /* no clobbers */ \
);
/*
* Explicit inline assembler to implement a dynamic lower bound check:
*
* if (var < bnd)
* var = bnd;
*
* The BPF GCC compiler does not guarantee that the bound (expected to be a
* variable that holds a constant value) will be encoded in the source register
* while the BPF verifier does require that (for now).
*/
#define set_lower_bound(var, bnd) \
asm ("jge %0, %1, 1f\n\t" \
"mov %0, %1\n\t" \
"1:" \
: "+r" (var) \
: "r" (bnd) \
: /* no clobbers */ \
);
/*
* Explicit inline assembler to implement a non-negative bound check:
*
* if (var < 0)
* var = 0;
*/
#define set_not_neg_bound(var) \
asm ("jsge %0, 0, 1f\n\t" \
"mov %0, 0\n\t" \
"1:" \
: "+r" (var) \
: /* no inputs */ \
: /* no clobbers */ \
);
/*
* Explicit inline assembler to implement atomic add:
*
* *ptr += val;
*/
#define atomic_add(valp, val) \
do { \
register uint64_t *ptr asm("%r0") = (valp); \
register uint64_t tmp asm("%r1") = (val); \
asm (".byte 0xdb, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" \
: /* no outputs */ \
: "r" (ptr), "r" (tmp) \
: "memory" \
); \
} while (0)
#define atomic_add32(valp, val) \
do { \
register uint32_t *ptr asm("%r0") = (valp); \
register uint32_t tmp asm("%r1") = (val); \
asm (".byte 0xc3, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" \
: /* no outputs */ \
: "r" (ptr), "r" (tmp) \
: "memory" \
); \
} while (0)
#endif /* BPF_LIB_H */
|