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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2012, Kyle C. Hale <kh@u.norhtwestern.edu>
11 * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Kyle C. Hale <kh@u.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_string.h>
22 #include <palacios/vmm_hashtable.h>
23 #include <palacios/vmm_extensions.h>
24 #include <palacios/vmm_decoder.h>
25 #include <palacios/vm_guest.h>
26 #include <palacios/vm_guest_mem.h>
28 #include <gears/privilege.h>
30 #ifndef V3_CONFIG_DEBUG_EXT_PRIV
32 #define PrintDebug(fmt, args...)
35 static struct v3_privileges * global_privs;
38 priv_hash_fn (addr_t key)
40 return v3_hash_buffer((uint8_t*)key, strlen((char*)key));
45 priv_eq_fn (addr_t key1, addr_t key2)
47 return (strcmp((char*)key1, (char*)key2) == 0);
52 init_priv (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data)
54 struct v3_privileges * p = V3_Malloc(sizeof(struct v3_privileges));
59 PrintError(VM_NONE, VCORE_NONE,"Priv: Problem allocating privileges\n");
63 INIT_LIST_HEAD(&(p->priv_list));
67 if (!(p->priv_table = v3_create_htable(0, priv_hash_fn, priv_eq_fn))) {
68 PrintError(VM_NONE, VCORE_NONE,"Priv: Problem creating privilege hash table\n");
77 deinit_priv (struct v3_vm_info * vm, void * priv_data)
79 struct v3_privileges * privs = (struct v3_privileges *)priv_data;
80 struct v3_priv * p = NULL;
81 struct v3_priv * tmp = NULL;
83 list_for_each_entry_safe(p, tmp, &(privs->priv_list), priv_node) {
84 list_del(&(p->priv_node));
88 v3_free_htable(privs->priv_table, 0, 0);
95 v3_lookup_priv (struct v3_vm_info * vm, const char * name)
97 struct v3_privileges * p = global_privs;
98 return ((struct v3_priv*)v3_htable_search(p->priv_table, (addr_t)name));
103 deinit_all_privs (struct guest_info * core,
107 struct v3_privileges * p = global_privs;
108 struct v3_priv * priv = NULL;
109 struct v3_priv * tmp = NULL;
111 list_for_each_entry_safe(priv, tmp, &p->priv_list, priv_node) {
112 if (priv->deinit(core, priv->private_data) < 0) {
113 PrintError(VM_NONE, VCORE_NONE,"Problem deiniting privilege on core (%s)\n", priv->name);
122 v3_core_raise_all_privs (struct guest_info * core)
124 struct v3_privileges * p = global_privs;
125 struct v3_priv * priv = NULL;
126 struct v3_priv * tmp = NULL;
128 list_for_each_entry_safe(priv, tmp, &p->priv_list, priv_node) {
130 if (priv->raise(core, priv->private_data) < 0) {
131 PrintError(VM_NONE, VCORE_NONE,"Priv: Problem lowering privilege on core (%s)\n", priv->name);
142 v3_core_lower_all_privs (struct guest_info * core)
144 struct v3_privileges * p = global_privs;
145 struct v3_priv * priv = NULL;
146 struct v3_priv * tmp = NULL;
148 list_for_each_entry_safe(priv, tmp, &p->priv_list, priv_node) {
150 if (priv->lower(core, priv->private_data) < 0) {
151 PrintError(VM_NONE, VCORE_NONE,"Priv: Problem lowering privilege on core (%s)\n", priv->name);
162 v3_bind_privilege (struct guest_info * core,
163 const char * priv_name,
164 int (*init) (struct guest_info * core, void ** private_data),
165 int (*lower) (struct guest_info * core, void * private_data),
166 int (*raise) (struct guest_info * core, void * private_data),
167 int (*deinit) (struct guest_info * core, void * private_data),
170 struct v3_privileges * p = global_privs;
171 struct v3_priv * priv = v3_lookup_priv(core->vm_info, priv_name);
173 PrintError(VM_NONE, VCORE_NONE,"Priv: Privilege (%s) already exists\n", priv_name);
177 priv = (struct v3_priv *)V3_Malloc(sizeof(struct v3_priv));
180 PrintError(VM_NONE, VCORE_NONE,"Priv: Problem allocating privilege\n");
184 PrintDebug(VM_NONE, VCORE_NONE,"Priv: Binding privilege (%s)\n", priv_name);
189 priv->deinit = deinit;
190 priv->private_data = priv_data;
192 if (v3_htable_insert(p->priv_table, (addr_t)priv_name, (addr_t)priv) == 0) {
193 PrintError(VM_NONE, VCORE_NONE,"Priv: Could not register privilege (%s)\n", priv_name);
197 if (priv->init(core, &priv->private_data) < 0) {
198 PrintError(VM_NONE, VCORE_NONE,"Priv: Could not initialize privilege (%s)\n", priv_name);
202 V3_Print(VM_NONE, VCORE_NONE, "Privilege (%s) bound and initialized successfully\n", priv_name);
209 static struct v3_extension_impl priv_impl = {
211 .vm_init = init_priv,
212 .vm_deinit = deinit_priv,
214 .core_deinit = deinit_all_privs,
219 register_extension(&priv_impl);