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.


97504bccaeebe0ccbda29ecad4808b06464d21bf
[palacios.git] / palacios / src / palacios / vmm_exits.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) 2012, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2012, 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.h>
22 #include <palacios/vmm_exits.h>
23 #include <palacios/vm_guest.h>
24
25
26 int v3_init_exit_hooks(struct v3_vm_info * vm) {
27     struct v3_exit_map * map = &(vm->exit_map);
28     
29     map->exits = V3_Malloc(sizeof(struct v3_exit_hook) * V3_EXIT_INVALID);
30
31     if (map->exits == NULL) {
32         PrintError("Error allocating exit map\n");
33         return -1;
34     }
35     
36     memset(map->exits, 0, sizeof(struct v3_exit_hook) * V3_EXIT_INVALID);
37
38
39     return 0;
40 }
41
42 int v3_deinit_exit_hooks(struct v3_vm_info * vm) {
43     struct v3_exit_map * map = &(vm->exit_map);
44
45     V3_Free(map->exits);
46
47     return 0;
48 }
49
50
51
52
53 int v3_init_exit_hooks_core(struct guest_info * core) {
54     struct v3_vm_info * vm = core->vm_info;
55     struct v3_exit_map * map = &(vm->exit_map);  
56     struct v3_exit_hook * hook = NULL;
57     int i = 0;
58
59     for (i = 0; i < V3_EXIT_INVALID; i++) {
60         hook = &(map->exits[i]);
61
62         if (hook->hooked) {
63             if (hook->enable(core, i) != 0) {
64                 PrintError("Error could not enable exit hook %d on core %d\n", i, core->vcpu_id);
65                 return -1;
66             }
67         }
68     }
69
70     return 0;
71 }
72
73 int v3_deinit_exit_hooks_core(struct guest_info * core) {
74
75     return 0;
76 }
77
78
79
80 int v3_dispatch_exit_hook(struct guest_info * core, v3_exit_type_t exit_type, void * exit_data) {
81     struct v3_exit_map * map = &(core->vm_info->exit_map);       
82     struct v3_exit_hook * hook = NULL;
83
84     if (exit_type >= V3_EXIT_INVALID) {
85         PrintError("Error: Tried to dispatch invalid exit type (%d)\n", exit_type);
86         return -1;
87     }
88   
89     hook = &(map->exits[exit_type]);
90
91     if (hook->hooked == 0) {
92         PrintError("Tried to dispatch an unhooked exit (%d)\n", exit_type);
93         return -1;
94     }
95
96     return hook->handler(core, exit_type, hook->priv_data, exit_data);
97    
98 }
99
100
101 int v3_register_exit(struct v3_vm_info * vm, v3_exit_type_t exit_type,
102                      int (*enable)(struct guest_info * core, v3_exit_type_t exit_type),
103                      int (*disable)(struct guest_info * core, v3_exit_type_t exit_type)) {
104     struct v3_exit_map * map = &(vm->exit_map);  
105     struct v3_exit_hook * hook = NULL;
106
107     if (exit_type >= V3_EXIT_INVALID) {
108         PrintError("Error: Tried to register invalid exit type (%d)\n", exit_type);
109         return -1;
110     }
111   
112     hook = &(map->exits[exit_type]);
113
114     if (hook->registered == 1) {
115         PrintError("Tried to reregister an exit (%d)\n", exit_type);
116         return -1;
117     }
118
119     hook->registered = 1;
120     hook->enable = enable;
121     hook->disable = disable;
122     
123
124     return 0;
125 }
126
127
128 int v3_hook_exit(struct v3_vm_info * vm, v3_exit_type_t exit_type,
129                  int (*handler)(struct guest_info * core, v3_exit_type_t exit_type, 
130                              void * priv_data, void * exit_data),
131                  void * priv_data, 
132                  struct guest_info * current_core) {
133     struct v3_exit_map * map = &(vm->exit_map);  
134     struct v3_exit_hook * hook = NULL;
135     
136     
137     if (exit_type >= V3_EXIT_INVALID) {
138         PrintError("Error: Tried to hook invalid exit type (%d)\n", exit_type);
139         return -1;
140     }
141   
142     hook = &(map->exits[exit_type]);
143
144     if (hook->registered == 0) {
145         PrintError("Tried to hook unregistered exit (%d)\n", exit_type);
146         return -1;
147     } 
148
149     if (hook->hooked != 0) {
150         PrintError("Tried to rehook exit (%d)\n", exit_type);
151         return -1;
152     }
153
154
155     hook->hooked = 1;
156     hook->handler = handler;
157     hook->priv_data = priv_data;
158
159     if (vm->run_state != VM_INVALID) {
160         int i = 0;
161
162         while (v3_raise_barrier(vm, current_core) == -1);
163         
164         for (i = 0; i < vm->num_cores; i++) {
165             
166             if (hook->enable(&(vm->cores[i]), exit_type) != 0) {
167                 PrintError("Error could not enable exit hook %d on core %d\n", exit_type, i);
168                 v3_lower_barrier(vm);
169                 return -1;
170             }   
171         }
172
173         v3_lower_barrier(vm);
174     }
175     
176     return 0;
177 }
178
179
180
181 int v3_unhook_exit(struct v3_vm_info * vm, v3_exit_type_t exit_type, struct guest_info * current_core) {
182     struct v3_exit_map * map = &(vm->exit_map);  
183     struct v3_exit_hook * hook = NULL;
184     
185     
186     if (exit_type >= V3_EXIT_INVALID) {
187         PrintError("Error: Tried to unhook invalid exit type (%d)\n", exit_type);
188         return -1;
189     }
190   
191     hook = &(map->exits[exit_type]);
192
193     if (hook->registered == 0) {
194         PrintError("Tried to unhook an unregistered exit (%d)\n", exit_type);
195         return -1;
196     } 
197
198     if (hook->hooked == 0) {
199         PrintError("Tried to unhook and unhooked exit (%d)\n", exit_type);
200         return -1;
201     }
202
203
204     hook->hooked = 0;
205     hook->handler = NULL;
206     hook->priv_data = NULL;
207
208     
209     if (vm->run_state != VM_INVALID) {
210         int i = 0;
211
212         while (v3_raise_barrier(vm, current_core) == -1);
213         
214         for (i = 0; i < vm->num_cores; i++) {
215             
216             if (hook->disable(&(vm->cores[i]), exit_type) != 0) {
217                 PrintError("Error could not enable exit hook %d on core %d\n", exit_type, i);
218                 v3_lower_barrier(vm);
219                 return -1;
220             }   
221         }
222
223         v3_lower_barrier(vm);
224     }
225     
226     return 0;
227 }