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.


added address width calculations
[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