2 * Linux interface for guest-context code injection
4 * (c) Kyle C. Hale 2011
9 #include <linux/uaccess.h>
11 #include <linux/module.h>
13 #include <interfaces/vmm_host_hypercall.h>
17 #include "linux-exts.h"
18 #include "iface-host-hypercall.h"
20 static int host_hypercall_nop(palacios_core_t core,
21 unsigned int hcall_id,
22 struct guest_accessors *acc,
24 DEBUG("palacios: host_hypercall_nop dummy handler invoked\n");
25 DEBUG(" rip=%p\n rsp=%p\n rbp=%p\n rflags=%p\n",
26 (void*)(acc->get_rip(core)),
27 (void*)(acc->get_rsp(core)),
28 (void*)(acc->get_rbp(core)),
29 (void*)(acc->get_rflags(core)));
31 DEBUG(" rax=%p\n rbx=%p\n rcx=%p\n rdx=%p\n rsi=%p\n rdi=%p\n",
32 (void*)(acc->get_rax(core)),
33 (void*)(acc->get_rbx(core)),
34 (void*)(acc->get_rcx(core)),
35 (void*)(acc->get_rdx(core)),
36 (void*)(acc->get_rsi(core)),
37 (void*)(acc->get_rdi(core)));
38 DEBUG(" r8=%p\n r9=%p\n r10=%p\n r11=%p\n r12=%p\n r13=%p\n r14=%p\n r15=%p\n",
39 (void*)(acc->get_r8(core)),
40 (void*)(acc->get_r9(core)),
41 (void*)(acc->get_r10(core)),
42 (void*)(acc->get_r11(core)),
43 (void*)(acc->get_r12(core)),
44 (void*)(acc->get_r13(core)),
45 (void*)(acc->get_r14(core)),
46 (void*)(acc->get_r15(core)));
47 DEBUG(" cr0=%p\n cr2=%p\n cr3=%p\n cr4=%p\n apic_tpr=%p\n efer=%p\n",
48 (void*)(acc->get_cr0(core)),
49 (void*)(acc->get_cr2(core)),
50 (void*)(acc->get_cr3(core)),
51 (void*)(acc->get_cr4(core)),
52 (void*)(acc->get_apic_tpr(core)),
53 (void*)(acc->get_efer(core)));
58 static int vm_hypercall_add (struct v3_guest *guest,
63 struct hcall_data hdata;
66 if (copy_from_user(&hdata,(void __user *) arg, sizeof(struct hcall_data))) {
67 ERROR("palacios: copy from user in getting input for hypercall add\n");
71 if (0==strcmp(hdata.fn,"")) {
72 WARNING("palacios: no hypercall function supplied, using default\n");
73 func = (void*) host_hypercall_nop;
75 func = __symbol_get(hdata.fn);
79 ERROR("palacios: cannot find function '%s' for hypercall addition - perhaps your module hasn't been loaded yet?\n",hdata.fn);
83 if (v3_register_host_hypercall(guest->v3_ctx,
87 ERROR("palacios: cannot register hypercall 0x%x for function %s (%p)\n",
88 hdata.hcall_nr, hdata.fn, func);
92 INFO("palacios: hypercall %d (0x%x) registered for function %s (%p)\n",
93 hdata.hcall_nr,hdata.hcall_nr,hdata.fn,func);
97 static int vm_hypercall_remove (struct v3_guest *guest,
102 struct hcall_data hdata;
104 if (copy_from_user(&hdata,(void __user *) arg, sizeof(struct hcall_data))) {
105 ERROR("palacios: copy from user in getting input for hypercall remove\n");
108 if (v3_unregister_host_hypercall(guest->v3_ctx,
110 ERROR("palacios: cannot unregister hypercall 0x%x\n", hdata.hcall_nr);
114 INFO("palacios: hypercall %d (0x%x) unregistered\n",
115 hdata.hcall_nr,hdata.hcall_nr);
120 static int init_host_hypercall (void) {
125 static int deinit_host_hypercall (void) {
129 static int guest_init_host_hypercall (struct v3_guest * guest, void ** vm_data) {
130 add_guest_ctrl(guest, V3_VM_HYPERCALL_ADD, vm_hypercall_add, NULL);
131 add_guest_ctrl(guest, V3_VM_HYPERCALL_REMOVE, vm_hypercall_remove, NULL);
136 static int guest_deinit_host_hypercall (struct v3_guest * guest, void * vm_data) {
137 remove_guest_ctrl(guest, V3_VM_HYPERCALL_ADD);
138 remove_guest_ctrl(guest, V3_VM_HYPERCALL_REMOVE);
143 static struct linux_ext host_hypercall_ext = {
144 .name = "HOST_HYPERCALL",
145 .init = init_host_hypercall,
146 .deinit = deinit_host_hypercall,
147 .guest_init = guest_init_host_hypercall,
148 .guest_deinit = guest_deinit_host_hypercall
151 register_extension(&host_hypercall_ext);