Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


bug fix to check for illegal memory ranges
[palacios.git] / palacios / src / palacios / vmm_multitree.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20
21 #include <palacios/vmm_multitree.h>
22 #include <palacios/vmm_string.h>
23
24 #include <palacios/vmm_rbtree.h>
25
26 static inline 
27 struct v3_mtree * __insert_mtree_node(struct v3_mtree * root, struct v3_mtree * node) {
28     struct rb_node ** p = &(root->child.rb_node);
29     struct rb_node * parent = NULL;
30     struct v3_mtree * tmp_node;
31
32     while (*p) {
33         int ret = 0;
34         parent = *p;
35         tmp_node = rb_entry(parent, struct v3_mtree, tree_node);
36
37         ret = strcmp(node->name, tmp_node->name);
38
39         if (ret < 0) {
40             p = &(*p)->rb_left;
41         } else if (ret > 0) {
42             p = &(*p)->rb_right;
43         } else {
44             return tmp_node;
45         }
46     }
47
48     rb_link_node(&(node->tree_node), parent, p);
49   
50     return NULL;
51 }
52
53
54
55 struct v3_mtree * v3_mtree_create_node(struct v3_mtree * root, char * name) {
56     struct v3_mtree * node = (struct v3_mtree *)V3_Malloc(sizeof(struct v3_mtree));
57     struct v3_mtree * ret = NULL;
58
59
60     PrintDebug("Creating Node %s\n", name);
61
62     memset(node, 0, sizeof(struct v3_mtree));
63     strncpy(node->name, name, 50);
64
65     if ((ret = __insert_mtree_node(root, node))) {
66         PrintError("Insertion failure\n");
67         V3_Free(node);
68         return NULL;
69     }
70
71     PrintDebug("Node (%s)=%p, root=%p, root->child=%p\n", node->name, node, root, root->child.rb_node);
72
73     v3_rb_insert_color(&(node->tree_node), &(root->child));
74
75     PrintDebug("balanced\n");
76
77     return node;
78 }
79
80
81 struct v3_mtree * v3_mtree_create_subtree(struct v3_mtree * root, char * name) {
82     struct v3_mtree * node = NULL;
83
84     PrintDebug("Creating Subtree %s\n", name);
85     node = v3_mtree_create_node(root, name);
86
87     if (node == NULL) {
88         return NULL;
89     }
90
91     node->subtree = 1;
92
93     return node;
94 }
95
96
97 struct v3_mtree * v3_mtree_create_value(struct v3_mtree * root, char * name, 
98                                         uint64_t size, void * value) {
99     struct v3_mtree * node  = NULL;
100
101     PrintDebug("Creating value %s\n", name);    
102     node = v3_mtree_create_node(root, name);
103
104     if (node == NULL) {
105         return NULL;
106     }
107
108     node->size = size;
109     node->value = value;
110
111     return node;
112 }
113
114
115
116 struct v3_mtree * v3_mtree_find_node(struct v3_mtree * root, char * name) {
117     struct rb_node * n = root->child.rb_node;
118     struct v3_mtree * tmp_node = NULL;
119
120     if (root->subtree == 0) {
121         PrintError("Searching for node on a non-root mtree (search=%s), root=%s\n", name, root->name);
122         return NULL;
123     }
124    
125     while (n) {
126         int ret = 0;
127         tmp_node = rb_entry(n, struct v3_mtree, tree_node);
128         ret = strcmp(tmp_node->name, name);
129
130         if (ret < 0) {
131             n = n->rb_left;
132         } else if (ret > 0) {
133             n = n->rb_right;
134         } else {
135             return tmp_node;
136         }       
137     }
138
139     return NULL;
140 }
141
142
143 struct v3_mtree * v3_mtree_find_subtree(struct v3_mtree * root, char * name) {
144     struct v3_mtree * node = v3_mtree_find_node(root, name);
145     
146     if (node->subtree == 0) {
147         return NULL;
148     }
149
150     return node;
151 }
152
153
154 struct v3_mtree * v3_mtree_find_value(struct v3_mtree * root, char * name) {
155     struct v3_mtree * node= v3_mtree_find_node(root, name);
156     
157     if (node->subtree == 1) {
158         return NULL;
159     }
160
161     return node;
162 }
163
164
165 struct v3_mtree * v3_mtree_first_child(struct v3_mtree * root) {
166     struct rb_node * node = v3_rb_first(&(root->child));
167
168     if (node == NULL) {
169         return NULL;
170     }
171
172     return rb_entry(node, struct v3_mtree, tree_node);
173 }
174
175
176 struct v3_mtree * v3_mtree_next_node(struct v3_mtree * node) {
177     struct rb_node * next_node = v3_rb_next(&(node->tree_node));
178
179     if (next_node == NULL) {
180         return NULL;
181     }
182     return rb_entry(next_node, struct v3_mtree, tree_node);
183 }