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.


APIC and CR8 changes for vector priorization vs TPR
[palacios.git] / palacios / src / interfaces / vmm_host_hypercall.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2012, Kyle C. Hale <kh@u.northwestern.edu> 
11  * Copyright (c) 2012, Peter Dinda <pdinda@northwestern.edu>
12  * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org> 
13  * All rights reserved.
14  *
15  * Authors: Kyle C. Hale <kh@u.northwestern.edu>
16  *          Peter Dinda <pdinda@northwestern.edu>
17  *
18  * This is free software.  You are permitted to use,
19  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20  */
21
22 #include <palacios/vmm.h>
23 #include <palacios/vm_guest.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vmm_hypercall.h>
26 #include <palacios/vmm_types.h>
27
28 #include <interfaces/vmm_host_hypercall.h>
29
30
31 #define GET_SET_GPR_IMPL(R) \
32   static uint64_t get_##R(palacios_core_t core) { return ((struct guest_info *)core)->vm_regs.R;} \
33   static void set_##R(palacios_core_t core, uint64_t val) { ((struct guest_info *)core)->vm_regs.R = val; } 
34
35 #define GET_SET_CR_IMPL(R) \
36   static uint64_t get_##R(palacios_core_t core) { return ((struct guest_info *)core)->ctrl_regs.R;} \
37   static void set_##R(palacios_core_t core, uint64_t val) { ((struct guest_info *)core)->ctrl_regs.R = val; } 
38
39 #define DECL_IT(R) .get_##R = get_##R, .set_##R = set_##R, 
40
41 GET_SET_GPR_IMPL(rax)
42 GET_SET_GPR_IMPL(rbx)
43 GET_SET_GPR_IMPL(rcx)
44 GET_SET_GPR_IMPL(rdx)
45 GET_SET_GPR_IMPL(rsi)
46 GET_SET_GPR_IMPL(rdi)
47 GET_SET_GPR_IMPL(rbp)
48 GET_SET_GPR_IMPL(rsp)
49 GET_SET_GPR_IMPL(r8)
50 GET_SET_GPR_IMPL(r9)
51 GET_SET_GPR_IMPL(r10)
52 GET_SET_GPR_IMPL(r11)
53 GET_SET_GPR_IMPL(r12)
54 GET_SET_GPR_IMPL(r13)
55 GET_SET_GPR_IMPL(r14)
56 GET_SET_GPR_IMPL(r15)
57
58 static uint64_t get_rip(palacios_core_t core) { return ((struct guest_info *)core)->rip;} 
59
60 static void set_rip(palacios_core_t core, uint64_t val) { ((struct guest_info *)core)->rip = val; } 
61
62
63 GET_SET_CR_IMPL(cr0)
64 GET_SET_CR_IMPL(cr2)
65 GET_SET_CR_IMPL(cr3)
66 GET_SET_CR_IMPL(cr4)
67 GET_SET_CR_IMPL(apic_tpr)
68 GET_SET_CR_IMPL(efer)
69 GET_SET_CR_IMPL(rflags)
70
71
72
73 static struct guest_accessors guest_acc = {
74 DECL_IT(rax)
75 DECL_IT(rbx)
76 DECL_IT(rcx)
77 DECL_IT(rdx)
78 DECL_IT(rsi)
79 DECL_IT(rdi)
80 DECL_IT(rbp)
81 DECL_IT(rsp)
82 DECL_IT(r8)
83 DECL_IT(r9)
84 DECL_IT(r10)
85 DECL_IT(r11)
86 DECL_IT(r12)
87 DECL_IT(r13)
88 DECL_IT(r14)
89 DECL_IT(r15)
90
91 DECL_IT(rip)
92 DECL_IT(cr0)
93 DECL_IT(cr2)
94 DECL_IT(cr3)
95 DECL_IT(cr4)
96 DECL_IT(apic_tpr)
97 DECL_IT(efer)
98 DECL_IT(rflags)
99
100 .gva_to_hva = (int (*)(palacios_core_t, uint64_t, uint64_t *)) v3_gva_to_hva,
101 .gpa_to_hva = (int (*)(palacios_core_t, uint64_t, uint64_t *)) v3_gpa_to_hva,
102 .gva_to_gpa = (int (*)(palacios_core_t, uint64_t, uint64_t *)) v3_gva_to_gpa,
103 .read_gva = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_read_gva_memory,
104 .read_gpa = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_read_gpa_memory,
105 .write_gva = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_write_gva_memory,
106 .write_gpa = (int (*)(palacios_core_t, uint64_t, int, void *)) v3_write_gpa_memory,
107
108               }  ;
109               
110
111
112
113
114
115 struct bounce_data {
116   int (*hypercall)(palacios_core_t core,
117                    unsigned int hcall_id,
118                    struct guest_accessors *accessors,
119                    void *priv_data);
120   void *priv_data;
121 };
122
123 static int bounce(struct guest_info *core,
124                   unsigned int hcall_id,
125                   void *priv_data)
126 {
127   struct bounce_data *b = (struct bounce_data *) priv_data;
128
129   return b->hypercall(core,hcall_id,&guest_acc,b->priv_data);
130 }
131
132
133
134 int v3_register_host_hypercall(host_vm_info_t * vm, 
135                                unsigned int hypercall_id,
136                                int (*hypercall)(palacios_core_t core, 
137                                                 uint_t hcall_id, 
138                                                 struct guest_accessors *acc,
139                                                 void * priv_data),
140                                void * priv_data) {
141
142     struct bounce_data *b = V3_Malloc(sizeof(struct bounce_data));
143
144     if (!b) { 
145         PrintError("Unable to allocate in registering host hypercall\n");
146         return -1;
147     }
148     
149     b->hypercall=hypercall;
150     b->priv_data=priv_data;
151     
152     if (v3_register_hypercall((struct v3_vm_info*) vm, 
153                               hypercall_id, 
154                               bounce,
155                               b) < 0) {
156         PrintError("Cannot register host hypercall\n");
157         V3_Free(b);
158         return -1;
159     }
160     
161     return 0;
162 }
163
164 int v3_unregister_host_hypercall(host_vm_info_t * vm, 
165                                  unsigned int hypercall_id)
166 {
167   return v3_remove_hypercall((struct v3_vm_info*)vm, hypercall_id);
168 }
169