Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


check for out-of-bounds index when freeing a VM
[palacios.git] / linux_module / iface-host-hypercall.c
1 /* 
2  * Linux interface for guest-context code injection
3  *
4  * (c) Kyle C. Hale 2011
5  *
6  */
7
8 #include <linux/elf.h>
9 #include <linux/uaccess.h>
10 #include <linux/vmalloc.h>
11
12 #include <linux/module.h>
13
14 #include <interfaces/vmm_host_hypercall.h>
15
16 #include "palacios.h"
17 #include "vm.h"
18 #include "linux-exts.h"
19 #include "iface-host-hypercall.h"
20
21 static int host_hypercall_nop(palacios_core_t core,
22                               unsigned int hcall_id, 
23                               struct guest_accessors *acc,
24                               void *priv_data) {
25   DEBUG("palacios: host_hypercall_nop dummy handler invoked\n");
26   DEBUG(" 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)));
31
32   DEBUG(" 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   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",
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   DEBUG(" cr0=%p\n cr2=%p\n cr3=%p\n cr4=%p\n apic_tpr=%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_apic_tpr(core)),
54          (void*)(acc->get_efer(core)));
55   return 0;
56 }
57
58
59 static int vm_hypercall_add (struct v3_guest *guest, 
60                              unsigned int cmd, 
61                              unsigned long arg, 
62                              void *priv_data) {
63
64   struct hcall_data hdata;
65   void *func;
66
67   if (copy_from_user(&hdata,(void __user *) arg, sizeof(struct hcall_data))) { 
68     ERROR("palacios: copy from user in getting input for hypercall add\n");
69     return -EFAULT;
70   }
71
72   if (0==strcmp(hdata.fn,"")) { 
73     WARNING("palacios: no hypercall function supplied, using default\n");
74     func = (void*) host_hypercall_nop;
75   } else {
76     func = __symbol_get(hdata.fn);
77   }
78
79   if (func == NULL) { 
80     ERROR("palacios: cannot find function '%s' for hypercall addition - perhaps your module hasn't been loaded yet?\n",hdata.fn);
81     return -EFAULT;
82   }
83
84   if (v3_register_host_hypercall(guest->v3_ctx, 
85                                  hdata.hcall_nr,
86                                  func,
87                                  NULL)) { 
88     ERROR("palacios: cannot register hypercall 0x%x for function %s (%p)\n",
89            hdata.hcall_nr, hdata.fn, func);
90     return -EFAULT;
91   } 
92
93   INFO("palacios: hypercall %d (0x%x) registered for function %s (%p)\n", 
94          hdata.hcall_nr,hdata.hcall_nr,hdata.fn,func);
95   return 0;
96 }
97
98 static int vm_hypercall_remove (struct v3_guest *guest, 
99                                 unsigned int cmd, 
100                                 unsigned long arg, 
101                                 void *priv_data) {
102
103   struct hcall_data hdata;
104
105   if (copy_from_user(&hdata,(void __user *) arg, sizeof(struct hcall_data))) { 
106     ERROR("palacios: copy from user in getting input for hypercall remove\n");
107     return -EFAULT;
108   }
109   if (v3_unregister_host_hypercall(guest->v3_ctx, 
110                                    hdata.hcall_nr)) {
111     ERROR("palacios: cannot unregister hypercall 0x%x\n", hdata.hcall_nr);
112     return -EFAULT;
113   } 
114
115   INFO("palacios: hypercall %d (0x%x) unregistered\n", 
116          hdata.hcall_nr,hdata.hcall_nr);
117
118   return 0;
119 }
120
121 static int init_host_hypercall (void) {
122     return 0;
123 }
124
125
126 static int deinit_host_hypercall (void) {
127     return 0;
128 }
129
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);
133     return 0;
134 }
135
136
137 static int guest_deinit_host_hypercall (struct v3_guest * guest, void * vm_data) {
138     return 0;
139 }
140
141
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 
148 };
149
150 register_extension(&host_hypercall_ext);