• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }