#include <palacios/vmm_hypercall.h>
#include <palacios/vmm.h>
+#include <palacios/vm_guest.h>
-void v3_init_hypercall_map(struct guest_info * info) {
- info->hcall_map.rb_node = NULL;
+static int hcall_test(struct guest_info * info, hcall_id_t hcall_id, void * private_data) {
+ info->vm_regs.rbx = 0x1111;
+ info->vm_regs.rcx = 0x2222;
+ info->vm_regs.rdx = 0x3333;
+ info->vm_regs.rsi = 0x4444;
+ info->vm_regs.rdi = 0x5555;
+ return 0;
+}
+
+
+
+void v3_init_hypercall_map(struct v3_vm_info * vm) {
+ vm->hcall_map.rb_node = NULL;
+
+ v3_register_hypercall(vm, TEST_HCALL, hcall_test, NULL);
}
struct hypercall {
uint_t id;
- int (*hcall_fn)(struct guest_info * info, uint_t hcall_id, void * priv_data);
+ int (*hcall_fn)(struct guest_info * info, hcall_id_t hcall_id, void * priv_data);
void * priv_data;
struct rb_node tree_node;
-static inline struct hypercall * __insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
- struct rb_node ** p = &(info->hcall_map.rb_node);
+static inline struct hypercall * __insert_hypercall(struct v3_vm_info * vm, struct hypercall * hcall) {
+ struct rb_node ** p = &(vm->hcall_map.rb_node);
struct rb_node * parent = NULL;
struct hypercall * tmp_hcall = NULL;
}
-static inline struct hypercall * insert_hypercall(struct guest_info * info, struct hypercall * hcall) {
+static inline struct hypercall * insert_hypercall(struct v3_vm_info * vm, struct hypercall * hcall) {
struct hypercall * ret;
- if ((ret = __insert_hypercall(info, hcall))) {
+ if ((ret = __insert_hypercall(vm, hcall))) {
return ret;
}
- v3_rb_insert_color(&(hcall->tree_node), &(info->hcall_map));
+ v3_rb_insert_color(&(hcall->tree_node), &(vm->hcall_map));
return NULL;
}
-static struct hypercall * get_hypercall(struct guest_info * info, uint_t id) {
- struct rb_node * n = info->hcall_map.rb_node;
+static struct hypercall * get_hypercall(struct v3_vm_info * vm, hcall_id_t id) {
+ struct rb_node * n = vm->hcall_map.rb_node;
struct hypercall * hcall = NULL;
while (n) {
}
-int v3_register_hypercall(struct guest_info * info, uint_t hypercall_id,
- int (*hypercall)(struct guest_info * info, uint_t hcall_id, void * priv_data),
+int v3_register_hypercall(struct v3_vm_info * vm, hcall_id_t hypercall_id,
+ int (*hypercall)(struct guest_info * info, hcall_id_t hcall_id, void * priv_data),
void * priv_data) {
struct hypercall * hcall = (struct hypercall *)V3_Malloc(sizeof(struct hypercall));
hcall->priv_data = priv_data;
hcall->hcall_fn = hypercall;
- if (insert_hypercall(info, hcall)) {
+ if (insert_hypercall(vm, hcall)) {
V3_Free(hcall);
return -1;
}
int v3_handle_hypercall(struct guest_info * info) {
- uint_t hypercall_id = *(uint_t *)&info->vm_regs.rax;
-
- struct hypercall * hcall = get_hypercall(info, hypercall_id);
+ hcall_id_t hypercall_id = *(uint_t *)&info->vm_regs.rax;
+ struct hypercall * hcall = get_hypercall(info->vm_info, hypercall_id);
if (!hcall) {
PrintError("Invalid Hypercall (%d(0x%x) not registered)\n",
return -1;
}
- return hcall->hcall_fn(info, hypercall_id, hcall->priv_data);
+ if (hcall->hcall_fn(info, hypercall_id, hcall->priv_data) == 0) {
+ info->vm_regs.rax = 0;
+ } else {
+ info->vm_regs.rax = -1;
+ }
+
+ return 0;
}
+