1 /*
2 *
3 * (C) COPYRIGHT 2014, 2017 ARM Limited. All rights reserved.
4 *
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
8 * of such GNU licence.
9 *
10 * A copy of the licence is included with the program, and can also be obtained
11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12 * Boston, MA 02110-1301, USA.
13 *
14 */
15
16
17
18 /* Kernel UTF memory management functions */
19
20 #include <linux/list.h>
21 #include <linux/slab.h>
22 #include <linux/module.h>
23
24 #include <kutf/kutf_mem.h>
25
26
27 /**
28 * struct kutf_alloc_entry - Structure representing an allocation.
29 * @node: List node for use with kutf_mempool.
30 * @data: Data area of the allocation
31 */
32 struct kutf_alloc_entry {
33 struct list_head node;
34 u8 data[0];
35 };
36
kutf_mempool_init(struct kutf_mempool * pool)37 int kutf_mempool_init(struct kutf_mempool *pool)
38 {
39 if (!pool) {
40 pr_err("NULL pointer passed to %s\n", __func__);
41 return -1;
42 }
43
44 INIT_LIST_HEAD(&pool->head);
45
46 return 0;
47 }
48 EXPORT_SYMBOL(kutf_mempool_init);
49
kutf_mempool_destroy(struct kutf_mempool * pool)50 void kutf_mempool_destroy(struct kutf_mempool *pool)
51 {
52 struct list_head *remove;
53 struct list_head *tmp;
54
55 if (!pool) {
56 pr_err("NULL pointer passed to %s\n", __func__);
57 return;
58 }
59
60 list_for_each_safe(remove, tmp, &pool->head) {
61 struct kutf_alloc_entry *remove_alloc;
62
63 remove_alloc = list_entry(remove, struct kutf_alloc_entry, node);
64 list_del(&remove_alloc->node);
65 kfree(remove_alloc);
66 }
67 }
68 EXPORT_SYMBOL(kutf_mempool_destroy);
69
kutf_mempool_alloc(struct kutf_mempool * pool,size_t size)70 void *kutf_mempool_alloc(struct kutf_mempool *pool, size_t size)
71 {
72 struct kutf_alloc_entry *ret;
73
74 if (!pool) {
75 pr_err("NULL pointer passed to %s\n", __func__);
76 goto fail_pool;
77 }
78
79 ret = kmalloc(sizeof(*ret) + size, GFP_KERNEL);
80 if (!ret) {
81 pr_err("Failed to allocate memory\n");
82 goto fail_alloc;
83 }
84
85 INIT_LIST_HEAD(&ret->node);
86 list_add(&ret->node, &pool->head);
87
88 return &ret->data[0];
89
90 fail_alloc:
91 fail_pool:
92 return NULL;
93 }
94 EXPORT_SYMBOL(kutf_mempool_alloc);
95