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