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.


bug fix to check for illegal memory ranges
[palacios.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("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("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("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("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("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     state->sym_page = (struct v3_symspy_global_page *)V3_VAddr((void *)state->global_page_pa);
122     memset(state->sym_page, 0, PAGE_SIZE_4KB);
123
124     memcpy(&(state->sym_page->magic), "V3V", 3);
125
126     v3_hook_msr(vm, SYMSPY_LOCAL_MSR, symspy_msr_read, symspy_msr_write, NULL);
127     v3_hook_msr(vm, SYMSPY_GLOBAL_MSR, symspy_msr_read, symspy_msr_write, NULL);
128     
129     return 0;
130 }
131
132
133
134 int v3_init_symspy_core(struct guest_info * core, struct v3_symspy_local_state * state) {
135     state->local_page_pa = (addr_t)V3_AllocPages(1);
136     state->local_page = (struct v3_symspy_local_page *)V3_VAddr((void *)state->local_page_pa);
137     memset(state->local_page, 0, PAGE_SIZE_4KB);
138
139     snprintf((uint8_t *)&(state->local_page->magic), 8, "V3V.%d", core->vcpu_id);
140
141     return 0;
142 }
143
144
145
146 int v3_sym_map_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn) {
147     struct v3_symspy_global_state * global_state = &(vm->sym_vm_state.symspy_state);
148     uint_t dev_index = (bus << 8) + (dev << 3) + fn;
149     uint_t major = dev_index / 8;
150     uint_t minor = dev_index % 8;
151
152     if (bus > 3) {
153         PrintError("Invalid PCI bus %d\n", bus);
154         return -1;
155     }
156
157     PrintDebug("Setting passthrough pci map for index=%d\n", dev_index);
158
159     global_state->sym_page->pci_pt_map[major] |= 0x1 << minor;
160
161     PrintDebug("pt_map entry=%x\n",   global_state->sym_page->pci_pt_map[major]);
162
163     PrintDebug("pt map vmm addr=%p\n", global_state->sym_page->pci_pt_map);
164
165     return 0;
166 }
167
168 int v3_sym_unmap_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, uint_t fn) {
169     struct v3_symspy_global_state * global_state = &(vm->sym_vm_state.symspy_state);
170     uint_t dev_index = (bus << 8) + (dev << 3) + fn;
171     uint_t major = dev_index / 8;
172     uint_t minor = dev_index % 8;
173
174     if (bus > 3) {
175         PrintError("Invalid PCI bus %d\n", bus);
176         return -1;
177     }
178
179     global_state->sym_page->pci_pt_map[major] &= ~(0x1 << minor);
180
181     return 0;
182 }
183
184
185 struct v3_symspy_global_page * v3_sym_get_symspy_vm(struct v3_vm_info * vm) {
186     return vm->sym_vm_state.symspy_state.sym_page;
187 }
188
189 struct v3_symspy_local_page * v3_sym_get_symspy_core(struct guest_info * core) {
190     return core->sym_core_state.symspy_state.local_page;
191 }