2 * Linux interface for guest-context code injection
4 * (c) Kyle C. Hale 2011
9 #include <linux/uaccess.h>
10 #include <linux/vmalloc.h>
12 #include <linux/module.h>
14 #include <interfaces/vmm_host_hypercall.h>
18 #include "linux-exts.h"
19 #include "iface-host-hypercall.h"
21 static int host_hypercall_nop(palacios_core_t core,
22 unsigned int hcall_id,
23 struct guest_accessors *acc,
25 printk("palacios: host_hypercall_nop dummy handler invoked\n");
26 printk(" rip=%p\n rsp=%p\n rbp=%p\n rflags=%p\n",
27 (void*)(acc->get_rip(core)),
28 (void*)(acc->get_rsp(core)),
29 (void*)(acc->get_rbp(core)),
30 (void*)(acc->get_rflags(core)));
32 printk(" rax=%p\n rbx=%p\n rcx=%p\n rdx=%p\n rsi=%p\n rdi=%p\n",
33 (void*)(acc->get_rax(core)),
34 (void*)(acc->get_rbx(core)),
35 (void*)(acc->get_rcx(core)),
36 (void*)(acc->get_rdx(core)),
37 (void*)(acc->get_rsi(core)),
38 (void*)(acc->get_rdi(core)));
39 printk(" r8=%p\n r9=%p\n r10=%p\n r11=%p\n r12=%p\n r13=%p\n r14=%p\n r15=%p\n",
40 (void*)(acc->get_r8(core)),
41 (void*)(acc->get_r9(core)),
42 (void*)(acc->get_r10(core)),
43 (void*)(acc->get_r11(core)),
44 (void*)(acc->get_r12(core)),
45 (void*)(acc->get_r13(core)),
46 (void*)(acc->get_r14(core)),
47 (void*)(acc->get_r15(core)));
48 printk(" cr0=%p\n cr2=%p\n cr3=%p\n cr4=%p\n cr8=%p\n efer=%p\n",
49 (void*)(acc->get_cr0(core)),
50 (void*)(acc->get_cr2(core)),
51 (void*)(acc->get_cr3(core)),
52 (void*)(acc->get_cr4(core)),
53 (void*)(acc->get_cr8(core)),
54 (void*)(acc->get_efer(core)));
59 static int vm_hypercall_add (struct v3_guest *guest,
64 struct hcall_data hdata;
67 if (copy_from_user(&hdata,(void __user *) arg, sizeof(struct hcall_data))) {
68 printk("palacios: copy from user in getting input for hypercall add\n");
72 if (0==strcmp(hdata.fn,"")) {
73 printk("palacios: no hypercall function supplied, using default\n");
74 func = (void*) host_hypercall_nop;
76 func = __symbol_get(hdata.fn);
80 printk("palacios: cannot find function '%s' for hypercall addition - perhaps your module hasn't been loaded yet?\n",hdata.fn);
84 if (v3_register_host_hypercall(guest->v3_ctx,
88 printk("palacios: cannot register hypercall 0x%x for function %s (%p)\n",
89 hdata.hcall_nr, hdata.fn, func);
93 printk("palacios: hypercall %d (0x%x) registered for function %s (%p)\n",
94 hdata.hcall_nr,hdata.hcall_nr,hdata.fn,func);
98 static int vm_hypercall_remove (struct v3_guest *guest,
103 struct hcall_data hdata;
105 if (copy_from_user(&hdata,(void __user *) arg, sizeof(struct hcall_data))) {
106 printk("palacios: copy from user in getting input for hypercall remove\n");
109 if (v3_unregister_host_hypercall(guest->v3_ctx,
111 printk("palacios: cannot unregister hypercall 0x%x\n", hdata.hcall_nr);
115 printk("palacios: hypercall %d (0x%x) unregistered\n",
116 hdata.hcall_nr,hdata.hcall_nr);
121 static int init_host_hypercall (void) {
126 static int deinit_host_hypercall (void) {
130 static int guest_init_host_hypercall (struct v3_guest * guest, void ** vm_data) {
131 add_guest_ctrl(guest, V3_VM_HYPERCALL_ADD, vm_hypercall_add, NULL);
132 add_guest_ctrl(guest, V3_VM_HYPERCALL_REMOVE, vm_hypercall_remove, NULL);
137 static int guest_deinit_host_hypercall (struct v3_guest * guest, void * vm_data) {
142 static struct linux_ext host_hypercall_ext = {
143 .name = "HOST_HYPERCALL",
144 .init = init_host_hypercall,
145 .deinit = deinit_host_hypercall,
146 .guest_init = guest_init_host_hypercall,
147 .guest_deinit = guest_deinit_host_hypercall
150 register_extension(&host_hypercall_ext);