xref: /linux/drivers/gpu/drm/i915/i915_ptr_util.h (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
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 
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