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.


reformatting of the source files
[palacios.git] / palacios / src / palacios / vm_guest.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
21
22
23 #include <palacios/vm_guest.h>
24 #include <palacios/vmm_ctrl_regs.h>
25 #include <palacios/vmm.h>
26 #include <palacios/vmcb.h>
27
28
29 v3_vm_cpu_mode_t v3_get_cpu_mode(struct guest_info * info) {
30     struct cr0_32 * cr0;
31     struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
32     struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
33     struct v3_segment * cs = &(info->segments.cs);
34
35     if (info->shdw_pg_mode == SHADOW_PAGING) {
36         cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
37     } else if (info->shdw_pg_mode == NESTED_PAGING) {
38         cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
39     } else {
40         PrintError("Invalid Paging Mode...\n");
41         V3_ASSERT(0);
42         return -1;
43     }
44
45     if (cr0->pe == 0) {
46         return REAL;
47     } else if ((cr4->pae == 0) && (efer->lme == 0)) {
48         return PROTECTED;
49     } else if (efer->lme == 0) {
50         return PROTECTED_PAE;
51     } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
52         return LONG;
53     } else {
54         // What about LONG_16_COMPAT???
55         return LONG_32_COMPAT;
56     }
57 }
58
59 // Get address width in bytes
60 uint_t v3_get_addr_width(struct guest_info * info) {
61     struct cr0_32 * cr0;
62     struct cr4_32 * cr4 = (struct cr4_32 *)&(info->ctrl_regs.cr4);
63     struct efer_64 * efer = (struct efer_64 *)&(info->guest_efer);
64     struct v3_segment * cs = &(info->segments.cs);
65
66     if (info->shdw_pg_mode == SHADOW_PAGING) {
67         cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
68     } else if (info->shdw_pg_mode == NESTED_PAGING) {
69         cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
70     } else {
71         PrintError("Invalid Paging Mode...\n");
72         V3_ASSERT(0);
73         return -1;
74     }
75
76     if (cr0->pe == 0) {
77         return 2;
78     } else if ((cr4->pae == 0) && (efer->lme == 0)) {
79         return 4;
80     } else if (efer->lme == 0) {
81         return 4;
82     } else if ((efer->lme == 1) && (cs->long_mode == 1)) {
83         return 8;
84     } else {
85         // What about LONG_16_COMPAT???
86         return 4;
87     }
88 }
89
90
91 static const uchar_t REAL_STR[] = "Real";
92 static const uchar_t PROTECTED_STR[] = "Protected";
93 static const uchar_t PROTECTED_PAE_STR[] = "Protected+PAE";
94 static const uchar_t LONG_STR[] = "Long";
95 static const uchar_t LONG_32_COMPAT_STR[] = "32bit Compat";
96 static const uchar_t LONG_16_COMPAT_STR[] = "16bit Compat";
97
98 const uchar_t * v3_cpu_mode_to_str(v3_vm_cpu_mode_t mode) {
99     switch (mode) {
100         case REAL:
101             return REAL_STR;
102         case PROTECTED:
103             return PROTECTED_STR;
104         case PROTECTED_PAE:
105             return PROTECTED_PAE_STR;
106         case LONG:
107             return LONG_STR;
108         case LONG_32_COMPAT:
109             return LONG_32_COMPAT_STR;
110         case LONG_16_COMPAT:
111             return LONG_16_COMPAT_STR;
112         default:
113             return NULL;
114     }
115 }
116
117 v3_vm_mem_mode_t v3_get_mem_mode(struct guest_info * info) {
118     struct cr0_32 * cr0;
119
120     if (info->shdw_pg_mode == SHADOW_PAGING) {
121         cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
122     } else if (info->shdw_pg_mode == NESTED_PAGING) {
123         cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
124     } else {
125         PrintError("Invalid Paging Mode...\n");
126         V3_ASSERT(0);
127         return -1;
128     }
129
130     if (cr0->pg == 0) {
131         return PHYSICAL_MEM;
132     } else {
133         return VIRTUAL_MEM;
134     }
135 }
136
137 static const uchar_t PHYS_MEM_STR[] = "Physical Memory";
138 static const uchar_t VIRT_MEM_STR[] = "Virtual Memory";
139
140 const uchar_t * v3_mem_mode_to_str(v3_vm_mem_mode_t mode) {
141     switch (mode) {
142         case PHYSICAL_MEM:
143             return PHYS_MEM_STR;
144         case VIRTUAL_MEM:
145             return VIRT_MEM_STR;
146         default:
147             return NULL;
148     }
149 }
150
151
152 void v3_print_segments(struct guest_info * info) {
153     struct v3_segments * segs = &(info->segments);
154     int i = 0;
155     struct v3_segment * seg_ptr;
156
157     seg_ptr=(struct v3_segment *)segs;
158   
159     char *seg_names[] = {"CS", "DS" , "ES", "FS", "GS", "SS" , "LDTR", "GDTR", "IDTR", "TR", NULL};
160     PrintDebug("Segments\n");
161
162     for (i = 0; seg_names[i] != NULL; i++) {
163
164         PrintDebug("\t%s: Sel=%x, base=%p, limit=%x (long_mode=%d, db=%d)\n", seg_names[i], seg_ptr[i].selector, 
165                    (void *)(addr_t)seg_ptr[i].base, seg_ptr[i].limit,
166                    seg_ptr[i].long_mode, seg_ptr[i].db);
167
168     }
169
170 }
171
172
173 void v3_print_ctrl_regs(struct guest_info * info) {
174     struct v3_ctrl_regs * regs = &(info->ctrl_regs);
175     int i = 0;
176     v3_reg_t * reg_ptr;
177     char * reg_names[] = {"CR0", "CR2", "CR3", "CR4", "CR8", "FLAGS", NULL};
178     vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(info->vmm_data);
179
180     reg_ptr= (v3_reg_t *)regs;
181
182     PrintDebug("32 bit Ctrl Regs:\n");
183
184     for (i = 0; reg_names[i] != NULL; i++) {
185         PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
186     }
187
188     PrintDebug("\tEFER=0x%p\n", (void*)(addr_t)(guest_state->efer));
189
190 }
191
192
193 #ifdef __V3_32BIT__
194 void v3_print_GPRs(struct guest_info * info) {
195     struct v3_gprs * regs = &(info->vm_regs);
196     int i = 0;
197     v3_reg_t * reg_ptr;
198     char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", NULL};
199
200     reg_ptr= (v3_reg_t *)regs;
201
202     PrintDebug("32 bit GPRs:\n");
203
204     for (i = 0; reg_names[i] != NULL; i++) {
205         PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
206     }
207 }
208 #elif __V3_64BIT__
209 void v3_print_GPRs(struct guest_info * info) {
210     struct v3_gprs * regs = &(info->vm_regs);
211     int i = 0;
212     v3_reg_t * reg_ptr;
213     char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", \
214                            "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", NULL};
215
216     reg_ptr= (v3_reg_t *)regs;
217
218     PrintDebug("64 bit GPRs:\n");
219
220     for (i = 0; reg_names[i] != NULL; i++) {
221         PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
222     }
223 }
224
225
226
227 #endif