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.


Avoid strict-aliasing related issues when compiling with optimization
[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
11 #include <linux/module.h>
12
13 #include <interfaces/vmm_host_hypercall.h>
14
15 #include "palacios.h"
16 #include "vm.h"
17 #include "linux-exts.h"
18 #include "iface-host-hypercall.h"
19
20 static int host_hypercall_nop(palacios_core_t core,
21                               unsigned int hcall_id, 
22                               struct guest_accessors *acc,
23                               void *priv_data) {
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)));
30
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)));
54   return 0;
55 }
56
57
58 static int vm_hypercall_add (struct v3_guest *guest, 
59                              unsigned int cmd, 
60                              unsigned long arg, 
61                              void *priv_data) {
62
63   struct hcall_data hdata;
64   void *func;
65
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");
68     return -EFAULT;
69   }
70
71   if (0==strcmp(hdata.fn,"")) { 
72     WARNING("palacios: no hypercall function supplied, using default\n");
73     func = (void*) host_hypercall_nop;
74   } else {
75     func = __symbol_get(hdata.fn);
76   }
77
78   if (func == NULL) { 
79     ERROR("palacios: cannot find function '%s' for hypercall addition - perhaps your module hasn't been loaded yet?\n",hdata.fn);
80     return -EFAULT;
81   }
82
83   if (v3_register_host_hypercall(guest->v3_ctx, 
84                                  hdata.hcall_nr,
85                                  func,
86                                  NULL)) { 
87     ERROR("palacios: cannot register hypercall 0x%x for function %s (%p)\n",
88            hdata.hcall_nr, hdata.fn, func);
89     return -EFAULT;
90   } 
91
92   INFO("palacios: hypercall %d (0x%x) registered for function %s (%p)\n", 
93          hdata.hcall_nr,hdata.hcall_nr,hdata.fn,func);
94   return 0;
95 }
96
97 static int vm_hypercall_remove (struct v3_guest *guest, 
98                                 unsigned int cmd, 
99                                 unsigned long arg, 
100                                 void *priv_data) {
101
102   struct hcall_data hdata;
103
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");
106     return -EFAULT;
107   }
108   if (v3_unregister_host_hypercall(guest->v3_ctx, 
109                                    hdata.hcall_nr)) {
110     ERROR("palacios: cannot unregister hypercall 0x%x\n", hdata.hcall_nr);
111     return -EFAULT;
112   } 
113
114   INFO("palacios: hypercall %d (0x%x) unregistered\n", 
115          hdata.hcall_nr,hdata.hcall_nr);
116
117   return 0;
118 }
119
120 static int init_host_hypercall (void) {
121     return 0;
122 }
123
124
125 static int deinit_host_hypercall (void) {
126     return 0;
127 }
128
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);
132     return 0;
133 }
134
135
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);
139     return 0;
140 }
141
142
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 
149 };
150
151 register_extension(&host_hypercall_ext);