--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2012, Kyle C. Hale <kh@u.northwestern.edu>
+ * Copyright (c) 2012, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Authors: Kyle C. Hale <kh@u.northwestern.edu>
+ * Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __VMM_HOST_HYPERCALL_H__
+#define __VMM_HOST_HYPERCALL_H__
+
+#include <palacios/vmm.h>
+
+/* palacios v3_vm_info struct is opaque to the host */
+typedef void * host_vm_info_t;
+
+typedef void * palacios_core_t;
+
+
+// Notice that host implementation is itself
+// palacios-specific at this point. It must be
+// include the palacios-headers needed to understand
+// a guest_info, etc.
+//
+// The idea here is to make it possible to create something
+// like a linux kernel module, that is compiled against
+// palacios itself, but inserted after palacios.
+// The module then make full use of palacios functions
+// to manipulate guest state, as if it were a part of
+// palacios
+//
+
+#define GET_SET_REG_DECL(R) \
+ uint64_t (*get_##R)(palacios_core_t core); \
+ void (*set_##R)(palacios_core_t core, uint64_t val);
+
+
+
+struct guest_accessors {
+ // You can read/write the GPRs
+ GET_SET_REG_DECL(rax)
+ GET_SET_REG_DECL(rbx)
+ GET_SET_REG_DECL(rcx)
+ GET_SET_REG_DECL(rdx)
+ GET_SET_REG_DECL(rsi)
+ GET_SET_REG_DECL(rdi)
+ GET_SET_REG_DECL(rbp)
+ GET_SET_REG_DECL(rsp)
+ GET_SET_REG_DECL(r8)
+ GET_SET_REG_DECL(r9)
+ GET_SET_REG_DECL(r10)
+ GET_SET_REG_DECL(r11)
+ GET_SET_REG_DECL(r12)
+ GET_SET_REG_DECL(r13)
+ GET_SET_REG_DECL(r14)
+ GET_SET_REG_DECL(r15)
+
+ GET_SET_REG_DECL(rip);
+ GET_SET_REG_DECL(rflags)
+ GET_SET_REG_DECL(cr0)
+ GET_SET_REG_DECL(cr2)
+ GET_SET_REG_DECL(cr3)
+ GET_SET_REG_DECL(cr4)
+ GET_SET_REG_DECL(cr8)
+ GET_SET_REG_DECL(efer)
+
+ int (*gva_to_hva)(palacios_core_t core, uint64_t gva, uint64_t *hva);
+ int (*gva_to_gpa)(palacios_core_t core, uint64_t gva, uint64_t *gpa);
+ int (*gpa_to_hva)(palacios_core_t core, uint64_t gpa, uint64_t *hva);
+
+ int (*read_gva)(palacios_core_t core, uint64_t addr,
+ int n, void *dest);
+ int (*read_gpa)(palacios_core_t core, uint64_t addr,
+ int n, void *dest);
+
+ int (*write_gva)(palacios_core_t core, uint64_t addr,
+ int n, void *src);
+ int (*write_gpa)(palacios_core_t core, uint64_t addr,
+ int n, void *src);
+};
+
+
+
+int v3_register_host_hypercall(host_vm_info_t * vm,
+ unsigned int hypercall_id,
+ int (*hypercall)(palacios_core_t core,
+ unsigned int hcall_id,
+ struct guest_accessors *accessors,
+ void *priv_data),
+ void *priv_data);
+
+int v3_unregister_host_hypercall(host_vm_info_t *vm,
+ unsigned int hypercall_id);
+
+#ifdef __V3VEE__
+
+#endif /* !__V3VEE__ */
+#endif
+
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2012, Kyle C. Hale <kh@u.northwestern.edu>
+ * Copyright (c) 2012, Peter Dinda <pdinda@northwestern.edu>
+ * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Authors: Kyle C. Hale <kh@u.northwestern.edu>
+ * Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vm_guest_mem.h>
+#include <palacios/vmm_hypercall.h>
+#include <palacios/vmm_types.h>
+
+#include <interfaces/vmm_host_hypercall.h>
+
+
+#define GET_SET_GPR_IMPL(R) \
+ static uint64_t get_##R(palacios_core_t core) { return ((struct guest_info *)core)->vm_regs.R;} \
+ static void set_##R(palacios_core_t core, uint64_t val) { ((struct guest_info *)core)->vm_regs.R = val; }
+
+#define GET_SET_CR_IMPL(R) \
+ static uint64_t get_##R(palacios_core_t core) { return ((struct guest_info *)core)->ctrl_regs.R;} \
+ static void set_##R(palacios_core_t core, uint64_t val) { ((struct guest_info *)core)->ctrl_regs.R = val; }
+
+#define DECL_IT(R) .get_##R = get_##R, .set_##R = set_##R,
+
+GET_SET_GPR_IMPL(rax)
+GET_SET_GPR_IMPL(rbx)
+GET_SET_GPR_IMPL(rcx)
+GET_SET_GPR_IMPL(rdx)
+GET_SET_GPR_IMPL(rsi)
+GET_SET_GPR_IMPL(rdi)
+GET_SET_GPR_IMPL(rbp)
+GET_SET_GPR_IMPL(rsp)
+GET_SET_GPR_IMPL(r8)
+GET_SET_GPR_IMPL(r9)
+GET_SET_GPR_IMPL(r10)
+GET_SET_GPR_IMPL(r11)
+GET_SET_GPR_IMPL(r12)
+GET_SET_GPR_IMPL(r13)
+GET_SET_GPR_IMPL(r14)
+GET_SET_GPR_IMPL(r15)
+
+static uint64_t get_rip(palacios_core_t core) { return ((struct guest_info *)core)->rip;}
+
+static void set_rip(palacios_core_t core, uint64_t val) { ((struct guest_info *)core)->rip = val; }
+
+
+GET_SET_CR_IMPL(cr0)
+GET_SET_CR_IMPL(cr2)
+GET_SET_CR_IMPL(cr3)
+GET_SET_CR_IMPL(cr4)
+GET_SET_CR_IMPL(cr8)
+GET_SET_CR_IMPL(efer)
+GET_SET_CR_IMPL(rflags)
+
+
+
+static struct guest_accessors guest_acc = {
+DECL_IT(rax)
+DECL_IT(rbx)
+DECL_IT(rcx)
+DECL_IT(rdx)
+DECL_IT(rsi)
+DECL_IT(rdi)
+DECL_IT(rbp)
+DECL_IT(rsp)
+DECL_IT(r8)
+DECL_IT(r9)
+DECL_IT(r10)
+DECL_IT(r11)
+DECL_IT(r12)
+DECL_IT(r13)
+DECL_IT(r14)
+DECL_IT(r15)
+
+DECL_IT(rip)
+DECL_IT(cr0)
+DECL_IT(cr2)
+DECL_IT(cr3)
+DECL_IT(cr4)
+DECL_IT(cr8)
+DECL_IT(efer)
+DECL_IT(rflags)
+
+.gva_to_hva = (int (*)(palacios_core_t, uint64_t, uint64_t *)) v3_gva_to_hva,
+.gpa_to_hva = (int (*)(palacios_core_t, uint64_t, uint64_t *)) v3_gpa_to_hva,
+.gva_to_gpa = (int (*)(palacios_core_t, uint64_t, uint64_t *)) v3_gva_to_gpa,
+.read_gva = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_read_gva_memory,
+.read_gpa = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_read_gpa_memory,
+.write_gva = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_write_gva_memory,
+.write_gpa = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_write_gpa_memory,
+
+ } ;
+
+
+
+
+
+
+struct bounce_data {
+ int (*hypercall)(palacios_core_t core,
+ unsigned int hcall_id,
+ struct guest_accessors *accessors,
+ void *priv_data);
+ void *priv_data;
+};
+
+static int bounce(struct guest_info *core,
+ unsigned int hcall_id,
+ void *priv_data)
+{
+ struct bounce_data *b = (struct bounce_data *) priv_data;
+
+ return b->hypercall(core,hcall_id,&guest_acc,b->priv_data);
+}
+
+
+
+int v3_register_host_hypercall(host_vm_info_t * vm,
+ unsigned int hypercall_id,
+ int (*hypercall)(palacios_core_t core,
+ uint_t hcall_id,
+ struct guest_accessors *acc,
+ void * priv_data),
+ void * priv_data) {
+
+ struct bounce_data *b = V3_Malloc(sizeof(struct bounce_data));
+
+ if (!b) {
+ return -1;
+ }
+
+ b->hypercall=hypercall;
+ b->priv_data=priv_data;
+
+ if (v3_register_hypercall((struct v3_vm_info*) vm,
+ hypercall_id,
+ bounce,
+ b) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+int v3_unregister_host_hypercall(host_vm_info_t * vm,
+ unsigned int hypercall_id)
+{
+ return v3_remove_hypercall((struct v3_vm_info*)vm, hypercall_id);
+}
+