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.


Multiboot enhancements
[palacios.releases.git] / palacios / src / palacios / vmm_symspy.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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm_symspy.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_msr.h>
23 #include <palacios/vm_guest.h>
24 #include <palacios/vmm_sprintf.h>
25
26 #define SYMSPY_GLOBAL_MSR 0x534
27 #define SYMSPY_LOCAL_MSR 0x535
28
29
30 static int symspy_msr_read(struct guest_info * core, uint_t msr, 
31                     struct v3_msr * dst, void * priv_data) {
32     struct v3_symspy_global_state * global_state = &(core->vm_info->sym_vm_state.symspy_state);
33     struct v3_symspy_local_state * local_state = &(core->sym_core_state.symspy_state);
34
35     switch (msr) {
36         case SYMSPY_GLOBAL_MSR:
37             dst->value = global_state->global_guest_pa;
38             break;
39         case SYMSPY_LOCAL_MSR:
40             dst->value = local_state->local_guest_pa;
41             break;
42         default:
43             return -1;
44     }
45
46     return 0;
47 }
48
49
50 static int symspy_msr_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
51
52     if (msr == SYMSPY_GLOBAL_MSR) {
53         struct v3_symspy_global_state * global_state = &(core->vm_info->sym_vm_state.symspy_state);
54
55         PrintDebug(core->vm_info, core, "Symbiotic Glbal MSR write for page %p\n", (void *)(addr_t)src.value);
56
57         if (global_state->active == 1) {
58             // unmap page
59             struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, 
60                                                                      (addr_t)global_state->global_guest_pa);
61
62             if (old_reg == NULL) {
63                 PrintError(core->vm_info, core, "Could not find previously active symbiotic page (%p)\n", 
64                            (void *)(addr_t)global_state->global_guest_pa);
65                 return -1;
66             }
67
68             v3_delete_mem_region(core->vm_info, old_reg);
69         }
70
71         global_state->global_guest_pa = src.value;
72         global_state->global_guest_pa &= ~0xfffLL;
73
74         global_state->active = 1;
75
76         // map page
77         v3_add_shadow_mem(core->vm_info, V3_MEM_CORE_ANY, (addr_t)global_state->global_guest_pa, 
78                           (addr_t)(global_state->global_guest_pa + PAGE_SIZE_4KB - 1), 
79                           global_state->global_page_pa);
80     } else if (msr == SYMSPY_LOCAL_MSR) {
81         struct v3_symspy_local_state * local_state = &(core->sym_core_state.symspy_state);
82
83         PrintDebug(core->vm_info, core, "Symbiotic Local MSR write for page %p\n", (void *)(addr_t)src.value);
84
85         if (local_state->active == 1) {
86             // unmap page
87             struct v3_mem_region * old_reg = v3_get_mem_region(core->vm_info, core->vcpu_id,
88                                                                      (addr_t)local_state->local_guest_pa);
89
90             if (old_reg == NULL) {
91                 PrintError(core->vm_info, core, "Could not find previously active symbiotic page (%p)\n", 
92                            (void *)(addr_t)local_state->local_guest_pa);
93                 return -1;
94             }
95
96             v3_delete_mem_region(core->vm_info, old_reg);
97         }
98
99         local_state->local_guest_pa = src.value;
100         local_state->local_guest_pa &= ~0xfffLL;
101
102         local_state->active = 1;
103
104         // map page
105         v3_add_shadow_mem(core->vm_info, core->vcpu_id, (addr_t)local_state->local_guest_pa, 
106                           (addr_t)(local_state->local_guest_pa + PAGE_SIZE_4KB - 1), 
107                           local_state->local_page_pa);
108     } else {
109         PrintError(core->vm_info, core, "Invalid Symbiotic MSR write (0x%x)\n", msr);
110         return -1;
111     }
112
113     return 0;
114 }
115
116
117
118 int v3_init_symspy_vm(struct v3_vm_info * vm, struct v3_symspy_global_state * state) {
119
120     state->global_page_pa = (addr_t)V3_AllocPages(1);
121     if (!state->global_page_pa) { 
122         PrintError(vm, VCORE_NONE, "Cannot allocate page\n");
123         return -1;
124     }
125
126     state->sym_page = (struct v3_symspy_global_page *)V3_VAddr((void *)state->global_page_pa);
127     memset(state->sym_page, 0, PAGE_SIZE_4KB);
128
129     memcpy(&(state->sym_page->magic), "V3V", 3);
130
131     v3_hook_msr(vm, SYMSPY_LOCAL_MSR, symspy_msr_read, symspy_msr_write, NULL);
132     v3_hook_msr(vm, SYMSPY_GLOBAL_MSR, symspy_msr_read, symspy_msr_write, NULL);
133     
134     return 0;
135 }
136
137
138
139 int v3_init_symspy_core(struct guest_info * core, struct v3_symspy_local_state * state) {
140     state->local_page_pa = (addr_t)V3_AllocPages(1);
141
142     if (!state->local_page_pa) { 
143         PrintError(core->vm_info, core, "Cannot allocate page\n");
144         return -1;
145     }
146     state->local_page = (struct v3_symspy_local_page *)V3_VAddr((void *)state->local_page_pa);
147     memset(state->local_page, 0, PAGE_SIZE_4KB);
148
149     snprintf((uint8_t *)&(state->local_page->magic), 8, "V3V.%d", core->vcpu_id);
150
151     return 0;
152 }
153
154
155
156 int v3_sym_map_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn) {
157     struct v3_symspy_global_state * global_state = &(vm->sym_vm_state.symspy_state);
158     uint_t dev_index = (bus << 8) + (dev << 3) + fn;
159     uint_t major = dev_index / 8;
160     uint_t minor = dev_index % 8;
161
162     if (bus > 3) {
163         PrintError(vm, VCORE_NONE, "Invalid PCI bus %d\n", bus);
164         return -1;
165     }
166
167     PrintDebug(vm, VCORE_NONE, "Setting passthrough pci map for index=%d\n", dev_index);
168
169     global_state->sym_page->pci_pt_map[major] |= 0x1 << minor;
170
171     PrintDebug(vm, VCORE_NONE, "pt_map entry=%x\n",   global_state->sym_page->pci_pt_map[major]);
172
173     PrintDebug(vm, VCORE_NONE, "pt map vmm addr=%p\n", global_state->sym_page->pci_pt_map);
174
175     return 0;
176 }
177
178 int v3_sym_unmap_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn) {
179     struct v3_symspy_global_state * global_state = &(vm->sym_vm_state.symspy_state);
180     uint_t dev_index = (bus << 8) + (dev << 3) + fn;
181     uint_t major = dev_index / 8;
182     uint_t minor = dev_index % 8;
183
184     if (bus > 3) {
185         PrintError(vm, VCORE_NONE, "Invalid PCI bus %d\n", bus);
186         return -1;
187     }
188
189     global_state->sym_page->pci_pt_map[major] &= ~(0x1 << minor);
190
191     return 0;
192 }
193
194
195 struct v3_symspy_global_page * v3_sym_get_symspy_vm(struct v3_vm_info * vm) {
196     return vm->sym_vm_state.symspy_state.sym_page;
197 }
198
199 struct v3_symspy_local_page * v3_sym_get_symspy_core(struct guest_info * core) {
200     return core->sym_core_state.symspy_state.local_page;
201 }