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) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.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_hypercall.h>
21 #include <palacios/vmm.h>
24 void v3_init_hypercall_map(struct guest_info * info) {
25 info->hcall_map.rb_node = NULL;
32 int (*hcall_fn)(struct guest_info * info, uint_t hcall_id, void * priv_data);
35 struct rb_node tree_node;
40 static inline struct hypercall * __insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
41 struct rb_node ** p = &(info->hcall_map.rb_node);
42 struct rb_node * parent = NULL;
43 struct hypercall * tmp_hcall = NULL;
47 tmp_hcall = rb_entry(parent, struct hypercall, tree_node);
49 if (hcall->id < tmp_hcall->id) {
51 } else if (hcall->id > tmp_hcall->id) {
58 rb_link_node(&(hcall->tree_node), parent, p);
64 static inline struct hypercall * insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
65 struct hypercall * ret;
67 if ((ret = __insert_hypercall(info, hcall))) {
71 v3_rb_insert_color(&(hcall->tree_node), &(info->hcall_map));
77 static struct hypercall * get_hypercall(struct guest_info * info, uint_t id) {
78 struct rb_node * n = info->hcall_map.rb_node;
79 struct hypercall * hcall = NULL;
82 hcall = rb_entry(n, struct hypercall, tree_node);
86 } else if (id > hcall->id) {
97 int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id,
98 int (*hypercall)(struct guest_info * info, uint_t hcall_id, void * priv_data),
101 struct hypercall * hcall = (struct hypercall *)V3_Malloc(sizeof(struct hypercall));
103 hcall->id = hypercall_id;
104 hcall->priv_data = priv_data;
105 hcall->hcall_fn = hypercall;
107 if (insert_hypercall(info, hcall)) {
116 int v3_handle_hypercall(struct guest_info * info) {
117 uint_t hypercall_id = *(uint_t *)&info->vm_regs.rax;
119 struct hypercall * hcall = get_hypercall(info, hypercall_id);
122 PrintError("Invalid Hypercall (%d not registered)\n", hypercall_id);
126 return hcall->hcall_fn(info, hypercall_id, hcall->priv_data);