1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2023 Huawei Device Co., Ltd.
4 */
5
6 #include <linux/list.h>
7 #include "jit_space_list.h"
8
init_jit_space_node(unsigned long begin,unsigned long end)9 inline struct jit_space_node *init_jit_space_node(unsigned long begin, unsigned long end)
10 {
11 struct jit_space_node *new = kmalloc(sizeof(struct jit_space_node), GFP_KERNEL);
12 if (new == NULL) {
13 jit_memory_log_error("malloc for jit_space_node failed");
14 return NULL;
15 }
16 new->begin = begin;
17 new->end = end;
18 return new;
19 }
20
find_jit_space(struct list_head * head,unsigned long begin,unsigned long size,int * err)21 const void find_jit_space(struct list_head *head, unsigned long begin, unsigned long size, int *err)
22 {
23 unsigned long end = begin + size;
24 struct jit_space_node *node;
25 struct list_head *cur;
26
27 list_for_each(cur, head)
28 {
29 node = list_entry(cur, struct jit_space_node, head);
30 if (node->begin <= begin && node->end >= end) {
31 *err = 0;
32 return;
33 }
34 }
35 *err = -EACCES;
36 }
37
update_jit_space(struct list_head * head,unsigned long begin,unsigned long size)38 void update_jit_space(struct list_head *head, unsigned long begin, unsigned long size)
39 {
40 unsigned long end = begin + size;
41
42 struct jit_space_node *new = init_jit_space_node(begin, end);
43 if (new == NULL)
44 return;
45 list_add(&(new->head), head);
46
47 struct jit_space_node *now = list_entry(head->next, struct jit_space_node, head);
48 }
49
delete_jit_space(struct list_head * head,unsigned long begin,unsigned long size,int * err)50 void delete_jit_space(struct list_head *head, unsigned long begin, unsigned long size, int *err)
51 {
52 unsigned long end = begin + size;
53 struct jit_space_node *node;
54 struct list_head *cur;
55
56 list_for_each(cur, head) {
57 node = list_entry(cur, struct jit_space_node, head);
58
59 if (begin >= node->begin && end <= node->end) {
60 if (begin == node->begin && end == node->end) { // [| cut&node |]
61 list_del(cur);
62 kfree(node);
63 } else if (begin != node->begin && end != node->end) { // [ node | cut | node ]
64 struct jit_space_node *new = init_jit_space_node(end, node->end);
65 if (new == NULL) {
66 *err = -ENOMEM;
67 return;
68 }
69 node->end = begin;
70 list_add(&(new->head), cur);
71 } else if (begin != node->begin) { // [ node | cut |]
72 node->end == begin;
73 } else if (end != node->end) { // [| cut | node ]
74 node->begin = end;
75 }
76 return;
77 }
78 }
79 }
80
exit_jit_space(struct list_head * head)81 void exit_jit_space(struct list_head *head)
82 {
83 struct list_head *cur, *next;
84 struct jit_space_node *node;
85
86 list_for_each_safe(cur, next, head) {
87 node = list_entry(cur, struct jit_space_node, head);
88 list_del(cur);
89 kfree(node);
90 }
91 }