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.


minor cleanup to vmxassist context code
[palacios.git] / palacios / src / palacios / vmx_assist.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, Andy Gocke <agocke@gmail.com>
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Andy Gocke <agocke@gmail.com>
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/vmx_assist.h>
21 #include <palacios/vmx_lowlevel.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <palacios/vmx.h>
24
25 static int vmx_save_world_ctx(struct guest_info * info, struct vmx_assist_context * ctx);
26 static int vmx_restore_world_ctx(struct guest_info * info, struct vmx_assist_context * ctx);
27
28 int v3_vmxassist_ctx_switch(struct guest_info * info) {
29     struct vmx_assist_context * old_ctx = NULL;
30     struct vmx_assist_context * new_ctx = NULL;
31     struct vmx_assist_header * hdr = NULL;
32     vmx_state_t state = ((struct vmx_data *)info->vmm_data)->state;
33
34
35     if (guest_pa_to_host_va(info, VMXASSIST_BASE, (addr_t *)&hdr) == -1) {
36         PrintError("Could not translate address for vmxassist header\n");
37         return -1;
38     }
39
40     if (hdr->magic != VMXASSIST_MAGIC) {
41         PrintError("VMXASSIT_MAGIC field is invalid\n");
42         return -1;
43     }
44
45
46     if (guest_pa_to_host_va(info, (addr_t)(hdr->old_ctx_gpa), (addr_t *)&(old_ctx)) == -1) {
47         PrintError("Could not translate address for VMXASSIST old context\n");
48         return -1;
49     }
50
51     if (guest_pa_to_host_va(info, (addr_t)(hdr->new_ctx_gpa), (addr_t *)&(new_ctx)) == -1) {
52         PrintError("Could not translate address for VMXASSIST new context\n");
53         return -1;
54     }
55
56
57     if (state == VMXASSIST_DISABLED) {
58
59         /* Save the old Context */
60         if (vmx_save_world_ctx(info, old_ctx) != 0) {
61             PrintError("Could not save VMXASSIST world context\n");
62             return -1;
63         }
64
65         /* restore new context, vmxassist should launch the bios the first time */
66         if (vmx_restore_world_ctx(info, new_ctx) != 0) {
67             PrintError("VMXASSIST could not restore new context\n");
68             return -1;
69         }
70
71     } else if (state == VMXASSIST_ENABLED) {
72         /* restore old context */
73         if (vmx_restore_world_ctx(info, old_ctx) != 0) {
74             PrintError("VMXASSIST could not restore old context\n");
75             return -1;
76         }
77     }
78
79     return 0;
80 }
81
82         
83 int vmx_save_world_ctx(struct guest_info * info, struct vmx_assist_context * ctx) {
84     int error = 0;
85
86     PrintDebug("Writing from RIP: 0x%p\n", (void *)info->rip);
87
88     error |= vmcs_read(VMCS_GUEST_RIP, &(ctx->eip));
89     error |= vmcs_read(VMCS_GUEST_RSP, &(ctx->esp));
90     error |= vmcs_read(VMCS_GUEST_RFLAGS, &(ctx->eflags));
91
92     error |= vmcs_read(VMCS_CR0_READ_SHDW, &(ctx->cr0));
93     ctx->cr3 = info->shdw_pg_state.guest_cr3;
94     error |= vmcs_read(VMCS_CR4_READ_SHDW, &(ctx->cr4));
95
96     error |= vmcs_read(VMCS_GUEST_IDTR_LIMIT, &(ctx->idtr_limit));
97     error |= vmcs_read(VMCS_GUEST_IDTR_BASE, &(ctx->idtr_base));
98
99     error |= vmcs_read(VMCS_GUEST_GDTR_LIMIT, &(ctx->gdtr_limit));
100     error |= vmcs_read(VMCS_GUEST_GDTR_BASE, &(ctx->gdtr_base));
101
102     error |= vmcs_read(VMCS_GUEST_CS_SELECTOR, &(ctx->cs_sel));
103     error |= vmcs_read(VMCS_GUEST_CS_LIMIT, &(ctx->cs_limit));
104     error |= vmcs_read(VMCS_GUEST_CS_BASE, &(ctx->cs_base));
105     error |= vmcs_read(VMCS_GUEST_CS_ACCESS, &(ctx->cs_arbytes.bytes));
106
107     error |= vmcs_read(VMCS_GUEST_DS_SELECTOR, &(ctx->ds_sel));
108     error |= vmcs_read(VMCS_GUEST_DS_LIMIT, &(ctx->ds_limit));
109     error |= vmcs_read(VMCS_GUEST_DS_BASE, &(ctx->ds_base));
110     error |= vmcs_read(VMCS_GUEST_DS_ACCESS, &(ctx->ds_arbytes.bytes));
111
112     error |= vmcs_read(VMCS_GUEST_ES_SELECTOR, &(ctx->es_sel));
113     error |= vmcs_read(VMCS_GUEST_ES_LIMIT, &(ctx->es_limit));
114     error |= vmcs_read(VMCS_GUEST_ES_BASE, &(ctx->es_base));
115     error |= vmcs_read(VMCS_GUEST_ES_ACCESS, &(ctx->es_arbytes.bytes));
116
117     error |= vmcs_read(VMCS_GUEST_SS_SELECTOR, &(ctx->ss_sel));
118     error |= vmcs_read(VMCS_GUEST_SS_LIMIT, &(ctx->ss_limit));
119     error |= vmcs_read(VMCS_GUEST_SS_BASE, &(ctx->ss_base));
120     error |= vmcs_read(VMCS_GUEST_SS_ACCESS, &(ctx->ss_arbytes.bytes));
121
122     error |= vmcs_read(VMCS_GUEST_FS_SELECTOR, &(ctx->fs_sel));
123     error |= vmcs_read(VMCS_GUEST_FS_LIMIT, &(ctx->fs_limit));
124     error |= vmcs_read(VMCS_GUEST_FS_BASE, &(ctx->fs_base));
125     error |= vmcs_read(VMCS_GUEST_FS_ACCESS, &(ctx->fs_arbytes.bytes));
126
127     error |= vmcs_read(VMCS_GUEST_GS_SELECTOR, &(ctx->gs_sel));
128     error |= vmcs_read(VMCS_GUEST_GS_LIMIT, &(ctx->gs_limit));
129     error |= vmcs_read(VMCS_GUEST_GS_BASE, &(ctx->gs_base));
130     error |= vmcs_read(VMCS_GUEST_GS_ACCESS, &(ctx->gs_arbytes.bytes));
131
132     error |= vmcs_read(VMCS_GUEST_TR_SELECTOR, &(ctx->tr_sel));
133     error |= vmcs_read(VMCS_GUEST_TR_LIMIT, &(ctx->tr_limit));
134     error |= vmcs_read(VMCS_GUEST_TR_BASE, &(ctx->tr_base));
135     error |= vmcs_read(VMCS_GUEST_TR_ACCESS, &(ctx->tr_arbytes.bytes));
136
137     error |= vmcs_read(VMCS_GUEST_LDTR_SELECTOR, &(ctx->ldtr_sel));
138     error |= vmcs_read(VMCS_GUEST_LDTR_LIMIT, &(ctx->ldtr_limit));
139     error |= vmcs_read(VMCS_GUEST_LDTR_BASE, &(ctx->ldtr_base));
140     error |= vmcs_read(VMCS_GUEST_LDTR_ACCESS, &(ctx->ldtr_arbytes.bytes));
141
142     return error;
143 }
144
145 int vmx_restore_world_ctx(struct guest_info * info, struct vmx_assist_context * ctx) {
146     int error = 0;
147
148     PrintDebug("ctx rip: %p\n", (void *)(addr_t)ctx->eip);
149
150     error |= vmcs_write(VMCS_GUEST_RIP, ctx->eip);
151     error |= vmcs_write(VMCS_GUEST_RSP, ctx->esp);
152     error |= vmcs_write(VMCS_GUEST_RFLAGS, ctx->eflags);
153
154     error |= vmcs_write(VMCS_CR0_READ_SHDW, ctx->cr0);
155     info->shdw_pg_state.guest_cr3 = ctx->cr3;
156     error |= vmcs_write(VMCS_CR4_READ_SHDW, ctx->cr4);
157
158     error |= vmcs_write(VMCS_GUEST_IDTR_LIMIT, ctx->idtr_limit);
159     error |= vmcs_write(VMCS_GUEST_IDTR_BASE, ctx->idtr_base);
160
161     error |= vmcs_write(VMCS_GUEST_GDTR_LIMIT, ctx->gdtr_limit);
162     error |= vmcs_write(VMCS_GUEST_GDTR_BASE, ctx->gdtr_base);
163
164     error |= vmcs_write(VMCS_GUEST_CS_SELECTOR, ctx->cs_sel);
165     error |= vmcs_write(VMCS_GUEST_CS_LIMIT, ctx->cs_limit);
166     error |= vmcs_write(VMCS_GUEST_CS_BASE, ctx->cs_base);
167     error |= vmcs_write(VMCS_GUEST_CS_ACCESS, ctx->cs_arbytes.bytes);
168
169     error |= vmcs_write(VMCS_GUEST_DS_SELECTOR, ctx->ds_sel);
170     error |= vmcs_write(VMCS_GUEST_DS_LIMIT, ctx->ds_limit);
171     error |= vmcs_write(VMCS_GUEST_DS_BASE, ctx->ds_base);
172     error |= vmcs_write(VMCS_GUEST_DS_ACCESS, ctx->ds_arbytes.bytes);
173
174     error |= vmcs_write(VMCS_GUEST_ES_SELECTOR, ctx->es_sel);
175     error |= vmcs_write(VMCS_GUEST_ES_LIMIT, ctx->es_limit);
176     error |= vmcs_write(VMCS_GUEST_ES_BASE, ctx->es_base);
177     error |= vmcs_write(VMCS_GUEST_ES_ACCESS, ctx->es_arbytes.bytes);
178
179     error |= vmcs_write(VMCS_GUEST_SS_SELECTOR, ctx->ss_sel);
180     error |= vmcs_write(VMCS_GUEST_SS_LIMIT, ctx->ss_limit);
181     error |= vmcs_write(VMCS_GUEST_SS_BASE, ctx->ss_base);
182     error |= vmcs_write(VMCS_GUEST_SS_ACCESS, ctx->ss_arbytes.bytes);
183
184     error |= vmcs_write(VMCS_GUEST_FS_SELECTOR, ctx->fs_sel);
185     error |= vmcs_write(VMCS_GUEST_FS_LIMIT, ctx->fs_limit);
186     error |= vmcs_write(VMCS_GUEST_FS_BASE, ctx->fs_base);
187     error |= vmcs_write(VMCS_GUEST_FS_ACCESS, ctx->fs_arbytes.bytes);
188
189     error |= vmcs_write(VMCS_GUEST_GS_SELECTOR, ctx->gs_sel);
190     error |= vmcs_write(VMCS_GUEST_GS_LIMIT, ctx->gs_limit);
191     error |= vmcs_write(VMCS_GUEST_GS_BASE, ctx->gs_base);
192     error |= vmcs_write(VMCS_GUEST_GS_ACCESS, ctx->gs_arbytes.bytes);
193
194     error |= vmcs_write(VMCS_GUEST_TR_SELECTOR, ctx->tr_sel);
195     error |= vmcs_write(VMCS_GUEST_TR_LIMIT, ctx->tr_limit);
196     error |= vmcs_write(VMCS_GUEST_TR_BASE, ctx->tr_base);
197     error |= vmcs_write(VMCS_GUEST_TR_ACCESS, ctx->tr_arbytes.bytes);
198
199     error |= vmcs_write(VMCS_GUEST_LDTR_SELECTOR, ctx->ldtr_sel);
200     error |= vmcs_write(VMCS_GUEST_LDTR_LIMIT, ctx->ldtr_limit);
201     error |= vmcs_write(VMCS_GUEST_LDTR_BASE, ctx->ldtr_base);
202     error |= vmcs_write(VMCS_GUEST_LDTR_ACCESS, ctx->ldtr_arbytes.bytes);
203
204     return error;
205 }
206
207