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