aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Kartikeya Dwivedi <memxor@gmail.com>2021-07-02 16:48:22 +0530
committerAlexei Starovoitov <ast@kernel.org>2021-07-07 20:01:45 -0700
commitcb0f80039fb7ec9981a74d22019daaa85ff51a3d (patch)
tree4a723ac4dfa94fb5af8474bb084e9f997559d805
parentnet: core: Split out code to run generic XDP prog (diff)
downloadlinux-cb0f80039fb7ec9981a74d22019daaa85ff51a3d.tar.gz
linux-cb0f80039fb7ec9981a74d22019daaa85ff51a3d.zip
bitops: Add non-atomic bitops for pointers
cpumap needs to set, clear, and test the lowest bit in skb pointer in various places. To make these checks less noisy, add pointer friendly bitop macros that also do some typechecking to sanitize the argument. These wrap the non-atomic bitops __set_bit, __clear_bit, and test_bit but for pointer arguments. Pointer's address has to be passed in and it is treated as an unsigned long *, since width and representation of pointer and unsigned long match on targets Linux supports. They are prefixed with double underscore to indicate lack of atomicity. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com> Link: https://lore.kernel.org/bpf/20210702111825.491065-3-memxor@gmail.com
-rw-r--r--include/linux/bitops.h50
-rw-r--r--include/linux/typecheck.h9
2 files changed, 59 insertions, 0 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 26bf15e6cd35..5e62e2383b7f 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -4,6 +4,7 @@
#include <asm/types.h>
#include <linux/bits.h>
+#include <linux/typecheck.h>
#include <uapi/linux/kernel.h>
@@ -253,6 +254,55 @@ static __always_inline void __assign_bit(long nr, volatile unsigned long *addr,
__clear_bit(nr, addr);
}
+/**
+ * __ptr_set_bit - Set bit in a pointer's value
+ * @nr: the bit to set
+ * @addr: the address of the pointer variable
+ *
+ * Example:
+ * void *p = foo();
+ * __ptr_set_bit(bit, &p);
+ */
+#define __ptr_set_bit(nr, addr) \
+ ({ \
+ typecheck_pointer(*(addr)); \
+ __set_bit(nr, (unsigned long *)(addr)); \
+ })
+
+/**
+ * __ptr_clear_bit - Clear bit in a pointer's value
+ * @nr: the bit to clear
+ * @addr: the address of the pointer variable
+ *
+ * Example:
+ * void *p = foo();
+ * __ptr_clear_bit(bit, &p);
+ */
+#define __ptr_clear_bit(nr, addr) \
+ ({ \
+ typecheck_pointer(*(addr)); \
+ __clear_bit(nr, (unsigned long *)(addr)); \
+ })
+
+/**
+ * __ptr_test_bit - Test bit in a pointer's value
+ * @nr: the bit to test
+ * @addr: the address of the pointer variable
+ *
+ * Example:
+ * void *p = foo();
+ * if (__ptr_test_bit(bit, &p)) {
+ * ...
+ * } else {
+ * ...
+ * }
+ */
+#define __ptr_test_bit(nr, addr) \
+ ({ \
+ typecheck_pointer(*(addr)); \
+ test_bit(nr, (unsigned long *)(addr)); \
+ })
+
#ifdef __KERNEL__
#ifndef set_mask_bits
diff --git a/include/linux/typecheck.h b/include/linux/typecheck.h
index 20d310331eb5..46b15e2aaefb 100644
--- a/include/linux/typecheck.h
+++ b/include/linux/typecheck.h
@@ -22,4 +22,13 @@
(void)__tmp; \
})
+/*
+ * Check at compile time that something is a pointer type.
+ */
+#define typecheck_pointer(x) \
+({ typeof(x) __dummy; \
+ (void)sizeof(*__dummy); \
+ 1; \
+})
+
#endif /* TYPECHECK_H_INCLUDED */
rge.txt: fix reference to synopsisMichael Lohmann1-10/+10 2023-12-20trailer: use offsets for trailer_start/trailer_endLinus Arver3-21/+20 2023-12-20trailer: find the end of the log messageLinus Arver1-23/+40 2023-12-20The third batchJunio C Hamano1-0/+33 2023-12-20rebase: use strvec_pushf() for format-patch revisionsRené Scharfe1-11/+6 2023-12-19completion: support pseudoref existence checks for reftablesStan Hu1-0/+23 2023-12-19completion: refactor existence checks for pseudorefsStan Hu1-5/+15 2023-12-19remote.h: retire CAS_OPT_NAMEJunio C Hamano3-5/+3 2023-12-18The second batchJunio C Hamano1-0/+29 2023-12-18pkt-line: do not chomp newlines for sideband messagesJiang Xin3-3/+31 2023-12-18pkt-line: memorize sideband fragment in readerJiang Xin3-4/+6 2023-12-18test-pkt-line: add option parser for unpack-sidebandJiang Xin2-5/+112 2023-12-18doc: format.notes specify a ref under refs/notes/ hierarchyJunio C Hamano1-1/+1 2023-12-18test-lib-functions.sh: fix test_grep fail message wordingShreyansh Paliwal1-1/+1 2023-12-18git-compat-util: convert skip_{prefix,suffix}{,_mem} to boolRené Scharfe1-20/+22 2023-12-18fetch: no redundant error message for atomic fetchJiang Xin2-6/+10 2023-12-18t5574: test porcelain output of atomic fetchJiang Xin1-39/+50 2023-12-15docs: MERGE_AUTOSTASH is not that specialJunio C Hamano1-1/+1 2023-12-15docs: AUTO_MERGE is not that specialJunio C Hamano3-3/+3 2023-12-15refs.h: HEAD is not that specialJunio C Hamano1-1/+1 2023-12-15git-bisect.txt: BISECT_HEAD is not that specialJunio C Hamano1-1/+1 2023-12-15git.txt: HEAD is not that specialJunio C Hamano1-3/+4 2023-12-15git-add.txt: add missing short option -A to synopsisEric Sunshine1-1/+1 2023-12-15tests: adjust whitespace in chainlint expectationsPatrick Steinhardt27-74/+90