xref: /kvm-unit-tests/lib/alloc.c (revision 5b70cbdb7bc2ea65096b51565c75815cc95945b8)
1 #include "alloc.h"
2 #include "asm/page.h"
3 
4 void *malloc(size_t size)
5 {
6 	return memalign(sizeof(long), size);
7 }
8 
9 void *calloc(size_t nmemb, size_t size)
10 {
11 	void *ptr = malloc(nmemb * size);
12 	if (ptr)
13 		memset(ptr, 0, nmemb * size);
14 	return ptr;
15 }
16 
17 #define METADATA_EXTRA	(2 * sizeof(uintptr_t))
18 #define OFS_SLACK	(-2 * sizeof(uintptr_t))
19 #define OFS_SIZE	(-sizeof(uintptr_t))
20 
21 static inline void *block_begin(void *mem)
22 {
23 	uintptr_t slack = *(uintptr_t *)(mem + OFS_SLACK);
24 	return mem - slack;
25 }
26 
27 static inline uintptr_t block_size(void *mem)
28 {
29 	return *(uintptr_t *)(mem + OFS_SIZE);
30 }
31 
32 void free(void *ptr)
33 {
34 	if (!alloc_ops->free)
35 		return;
36 
37 	void *base = block_begin(ptr);
38 	uintptr_t sz = block_size(ptr);
39 
40 	alloc_ops->free(base, sz);
41 }
42 
43 void *memalign(size_t alignment, size_t size)
44 {
45 	void *p;
46 	uintptr_t blkalign;
47 	uintptr_t mem;
48 
49 	if (!size)
50 		return NULL;
51 
52 	assert(alignment >= sizeof(void *) && is_power_of_2(alignment));
53 	assert(alloc_ops && alloc_ops->memalign);
54 
55 	size += alignment - 1;
56 	blkalign = MAX(alignment, alloc_ops->align_min);
57 	size = ALIGN(size + METADATA_EXTRA, alloc_ops->align_min);
58 	p = alloc_ops->memalign(blkalign, size);
59 	assert(p);
60 
61 	/* Leave room for metadata before aligning the result.  */
62 	mem = (uintptr_t)p + METADATA_EXTRA;
63 	mem = ALIGN(mem, alignment);
64 
65 	/* Write the metadata */
66 	*(uintptr_t *)(mem + OFS_SLACK) = mem - (uintptr_t)p;
67 	*(uintptr_t *)(mem + OFS_SIZE) = size;
68 	return (void *)mem;
69 }
70