1 /* SPDX-License-Identifier: MIT */
2 /* Copyright © 2025 Intel Corporation */
3
4 #ifndef __I915_PTR_UTIL_H__
5 #define __I915_PTR_UTIL_H__
6
7 #include <linux/types.h>
8
9 #define ptr_mask_bits(ptr, n) ({ \
10 unsigned long __v = (unsigned long)(ptr); \
11 (typeof(ptr))(__v & -BIT(n)); \
12 })
13
14 #define ptr_unmask_bits(ptr, n) ((unsigned long)(ptr) & (BIT(n) - 1))
15
16 #define ptr_unpack_bits(ptr, bits, n) ({ \
17 unsigned long __v = (unsigned long)(ptr); \
18 *(bits) = __v & (BIT(n) - 1); \
19 (typeof(ptr))(__v & -BIT(n)); \
20 })
21
22 #define ptr_pack_bits(ptr, bits, n) ({ \
23 unsigned long __bits = (bits); \
24 GEM_BUG_ON(__bits & -BIT(n)); \
25 ((typeof(ptr))((unsigned long)(ptr) | __bits)); \
26 })
27
28 #define ptr_dec(ptr) ({ \
29 unsigned long __v = (unsigned long)(ptr); \
30 (typeof(ptr))(__v - 1); \
31 })
32
33 #define ptr_inc(ptr) ({ \
34 unsigned long __v = (unsigned long)(ptr); \
35 (typeof(ptr))(__v + 1); \
36 })
37
38 #define page_mask_bits(ptr) ptr_mask_bits(ptr, PAGE_SHIFT)
39 #define page_unmask_bits(ptr) ptr_unmask_bits(ptr, PAGE_SHIFT)
40 #define page_pack_bits(ptr, bits) ptr_pack_bits(ptr, bits, PAGE_SHIFT)
41 #define page_unpack_bits(ptr, bits) ptr_unpack_bits(ptr, bits, PAGE_SHIFT)
42
ptrdiff(const void * a,const void * b)43 static __always_inline ptrdiff_t ptrdiff(const void *a, const void *b)
44 {
45 return a - b;
46 }
47
48 #define u64_to_ptr(T, x) ({ \
49 typecheck(u64, x); \
50 (T *)(uintptr_t)(x); \
51 })
52
53 /*
54 * container_of_user: Extract the superclass from a pointer to a member.
55 *
56 * Exactly like container_of() with the exception that it plays nicely
57 * with sparse for __user @ptr.
58 */
59 #define container_of_user(ptr, type, member) ({ \
60 void __user *__mptr = (void __user *)(ptr); \
61 BUILD_BUG_ON_MSG(!__same_type(*(ptr), typeof_member(type, member)) && \
62 !__same_type(*(ptr), void), \
63 "pointer type mismatch in container_of()"); \
64 ((type __user *)(__mptr - offsetof(type, member))); })
65
66 #endif /* __I915_PTR_UTIL_H__ */
67