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.


unified and simplified the control register handlers to operate in all CPU modes
[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->ctrl_regs.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
60 static const uchar_t REAL_STR[] = "Real";
61 static const uchar_t PROTECTED_STR[] = "Protected";
62 static const uchar_t PROTECTED_PAE_STR[] = "Protected+PAE";
63 static const uchar_t LONG_STR[] = "Long";
64 static const uchar_t LONG_32_COMPAT_STR[] = "32bit Compat";
65 static const uchar_t LONG_16_COMPAT_STR[] = "16bit Compat";
66
67 const uchar_t * v3_cpu_mode_to_str(v3_vm_cpu_mode_t mode) {
68   switch (mode) {
69   case REAL:
70     return REAL_STR;
71   case PROTECTED:
72     return PROTECTED_STR;
73   case PROTECTED_PAE:
74     return PROTECTED_PAE_STR;
75   case LONG:
76     return LONG_STR;
77   case LONG_32_COMPAT:
78     return LONG_32_COMPAT_STR;
79   case LONG_16_COMPAT:
80     return LONG_16_COMPAT_STR;
81   default:
82     return NULL;
83   }
84 }
85
86 v3_vm_mem_mode_t v3_get_mem_mode(struct guest_info * info) {
87   struct cr0_32 * cr0;
88
89   if (info->shdw_pg_mode == SHADOW_PAGING) {
90     cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
91   } else if (info->shdw_pg_mode == NESTED_PAGING) {
92     cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
93   } else {
94     PrintError("Invalid Paging Mode...\n");
95     V3_ASSERT(0);
96     return -1;
97   }
98
99   if (cr0->pg == 0) {
100     return PHYSICAL_MEM;
101   } else {
102     return VIRTUAL_MEM;
103   }
104 }
105
106 static const uchar_t PHYS_MEM_STR[] = "Physical Memory";
107 static const uchar_t VIRT_MEM_STR[] = "Virtual Memory";
108
109 const uchar_t * v3_mem_mode_to_str(v3_vm_mem_mode_t mode) {
110   switch (mode) {
111   case PHYSICAL_MEM:
112     return PHYS_MEM_STR;
113   case VIRTUAL_MEM:
114     return VIRT_MEM_STR;
115   default:
116     return NULL;
117   }
118 }
119
120
121 void v3_print_segments(struct guest_info * info) {
122   struct v3_segments * segs = &(info->segments);
123   int i = 0;
124   struct v3_segment * seg_ptr;
125
126   seg_ptr=(struct v3_segment *)segs;
127   
128   char *seg_names[] = {"CS", "DS" , "ES", "FS", "GS", "SS" , "LDTR", "GDTR", "IDTR", "TR", NULL};
129   PrintDebug("Segments\n");
130
131   for (i = 0; seg_names[i] != NULL; i++) {
132
133     PrintDebug("\t%s: Sel=%x, base=%p, limit=%x\n", seg_names[i], seg_ptr[i].selector, 
134                (void *)(addr_t)seg_ptr[i].base, seg_ptr[i].limit);
135
136   }
137
138 }
139
140
141 void v3_print_ctrl_regs(struct guest_info * info) {
142   struct v3_ctrl_regs * regs = &(info->ctrl_regs);
143   int i = 0;
144   v3_reg_t * reg_ptr;
145   char * reg_names[] = {"CR0", "CR2", "CR3", "CR4", "CR8", "FLAGS", NULL};
146   vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA(info->vmm_data);
147
148   reg_ptr= (v3_reg_t *)regs;
149
150   PrintDebug("32 bit Ctrl Regs:\n");
151
152   for (i = 0; reg_names[i] != NULL; i++) {
153     PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
154   }
155
156   PrintDebug("\tEFER=0x%p\n", (void*)(addr_t)(guest_state->efer));
157
158 }
159
160
161 void v3_print_GPRs(struct guest_info * info) {
162   struct v3_gprs * regs = &(info->vm_regs);
163   int i = 0;
164   v3_reg_t * reg_ptr;
165   char * reg_names[] = { "RDI", "RSI", "RBP", "RSP", "RBX", "RDX", "RCX", "RAX", NULL};
166
167   reg_ptr= (v3_reg_t *)regs;
168
169   PrintDebug("32 bit GPRs:\n");
170
171   for (i = 0; reg_names[i] != NULL; i++) {
172     PrintDebug("\t%s=0x%p\n", reg_names[i], (void *)(addr_t)reg_ptr[i]);  
173   }
174 }