Message ID | 20210702111825.491065-3-memxor@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | BPF |
Headers | show |
Series | Generic XDP improvements | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | warning | 8 maintainers not CCed: yhs@fb.com akpm@linux-foundation.org kpsingh@kernel.org andriy.shevchenko@linux.intel.com geert+renesas@glider.be songliubraving@fb.com richard.weiyang@linux.alibaba.com yury.norov@gmail.com |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 18923 this patch: 18923 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 75 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 18364 this patch: 18364 |
netdev/header_inline | success | Link |
From: Kumar Kartikeya Dwivedi > Sent: 02 July 2021 12:18 > > 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. Would this work? #define BIT_OP(val, op) ((typeof (val))((unsigned long)(val) op)) Should let you do: ptr = BIT_OP(ptr, | 1); ptr = BIT_OP(ptr, & ~1); if (BIT_OPT(ptr, & 1)) ... See https://godbolt.org/z/E57aGK4js David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
On Fri, Jul 02, 2021 at 08:17:47PM IST, David Laight wrote: > From: Kumar Kartikeya Dwivedi > > Sent: 02 July 2021 12:18 > > > > 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. > > Would this work? > #define BIT_OP(val, op) ((typeof (val))((unsigned long)(val) op)) > > Should let you do: > ptr = BIT_OP(ptr, | 1); > ptr = BIT_OP(ptr, & ~1); > if (BIT_OPT(ptr, & 1)) > ... > > See https://godbolt.org/z/E57aGK4js > This certainly works, but my preference for keeping it this way was reusing the existing infrastructure (which also has KASAN/KCSAN instrumentation) and avoids UB while shifting. Ofcourse for this particular case, anything works, but if putting this in bitops, I thought we should keep it as simple wrappers over __set_bit/__clear_bit/test_bit. Also, I compared codegen for both, and it looks pretty much the same to me... See https://godbolt.org/z/s9cjEnYKj Let me know if I'm missing something. > David > > - > Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK > Registration No: 1397386 (Wales) -- Kartikeya
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 */