1 #ifndef XEN__XVMALLOC_H
2 #define XEN__XVMALLOC_H
3
4 #include <xen/types.h>
5
6 /*
7 * Xen malloc/free-style interface, as long as there's no need to have
8 * physically contiguous memory allocated. These should be used in preference
9 * to xmalloc() et al.
10 */
11
12 /* Allocate space for typed object. */
13 #define xvmalloc(_type) ((_type *)_xvmalloc(sizeof(_type), __alignof__(_type)))
14 #define xvzalloc(_type) ((_type *)_xvzalloc(sizeof(_type), __alignof__(_type)))
15
16 /* Allocate space for a typed object and copy an existing instance. */
17 #define xvmemdup(ptr) \
18 ({ \
19 void *p_ = _xvmalloc(sizeof(*(ptr)), __alignof__(*(ptr))); \
20 if ( p_ ) \
21 memcpy(p_, ptr, sizeof(*(ptr))); \
22 (typeof(*(ptr)) *)p_; \
23 })
24
25 #define DIM_MUL1(n) (n)
26 #define DIM_MUL2(n1, n2) ({ \
27 unsigned long res_; \
28 __builtin_umull_overflow(n1, n2, &res_) ? ULONG_MAX : res_; \
29 })
30 #define DIM_MUL_(n, nums...) DIM_MUL##n(nums)
31 #define DIM_MUL(n, nums...) DIM_MUL_(n, ## nums)
32
33 /* Allocate space for array of typed objects. */
34 #define xvmalloc_array(type, num, nums...) \
35 ((type *)_xvmalloc_array(sizeof(type), __alignof__(type), \
36 DIM_MUL(count_args(num, ## nums), num, ## nums)))
37 #define xvzalloc_array(type, num, nums...) \
38 ((type *)_xvzalloc_array(sizeof(type), __alignof__(type), \
39 DIM_MUL(count_args(num, ## nums), num, ## nums)))
40
41 /* Allocate space for a structure with a flexible array of typed objects. */
42 #define xvzalloc_flex_struct(type, field, nr) \
43 ((type *)_xvzalloc(offsetof(type, field[nr]), __alignof__(type)))
44
45 #define xvmalloc_flex_struct(type, field, nr) \
46 ((type *)_xvmalloc(offsetof(type, field[nr]), __alignof__(type)))
47
48 /* Re-allocate space for a structure with a flexible array of typed objects. */
49 #define xvrealloc_flex_struct(ptr, field, nr) \
50 ((typeof(ptr))_xvrealloc(ptr, offsetof(typeof(*(ptr)), field[nr]), \
51 __alignof__(typeof(*(ptr)))))
52
53 #ifdef CONFIG_HAS_VMAP
54
55 /* Free any of the above. */
56 void xvfree(void *va);
57
58 /* Underlying functions */
59 void *_xvmalloc(size_t size, unsigned int align);
60 void *_xvzalloc(size_t size, unsigned int align);
61 void *_xvrealloc(void *va, size_t size, unsigned int align);
62
63 #else /* !CONFIG_HAS_VMAP */
64
65 #define xvfree xfree
66 #define _xvmalloc _xmalloc
67 #define _xvzalloc _xzalloc
68 #define _xvrealloc _xrealloc
69
70 #endif /* CONFIG_HAS_VMAP */
71
72 /* Free an allocation, and zero the pointer to it. */
73 #define XVFREE(p) do { \
74 xvfree(p); \
75 (p) = NULL; \
76 } while ( false )
77
_xvmalloc_array(size_t size,unsigned int align,unsigned long num)78 static inline void *_xvmalloc_array(
79 size_t size, unsigned int align, unsigned long num)
80 {
81 /* Check for overflow. */
82 if ( size && num > UINT_MAX / size )
83 return NULL;
84 return _xvmalloc(size * num, align);
85 }
86
_xvzalloc_array(size_t size,unsigned int align,unsigned long num)87 static inline void *_xvzalloc_array(
88 size_t size, unsigned int align, unsigned long num)
89 {
90 /* Check for overflow. */
91 if ( size && num > UINT_MAX / size )
92 return NULL;
93 return _xvzalloc(size * num, align);
94 }
95
96 #endif /* XEN__XVMALLOC_H */
97