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.


2330f6d667eb8a2c0e88df6d82123548aa89560a
[palacios.git] / palacios / src / palacios / vmm_shdw_pg_swapbypass.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_shadow_paging.h>
21 #include <palacios/vmm_ctrl_regs.h>
22
23 #include <palacios/vm_guest.h>
24 #include <palacios/vm_guest_mem.h>
25
26 struct shadow_page_data {
27     v3_reg_t cr3;
28     addr_t page_pa;
29   
30     struct list_head page_list_node;
31 };
32
33
34 struct swapbypass_local_state {
35  
36     struct list_head page_list;
37
38 };
39
40
41 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core);
42
43
44 #include "vmm_shdw_pg_swapbypass_32.h"
45 #include "vmm_shdw_pg_swapbypass_32pae.h"
46 #include "vmm_shdw_pg_swapbypass_64.h"
47
48
49 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core) {
50     struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
51     struct swapbypass_local_state * impl_state = (struct swapbypass_local_state *)(state->local_impl_data);
52     v3_reg_t cur_cr3 = core->ctrl_regs.cr3;
53     struct shadow_page_data * page_tail = NULL;
54     addr_t shdw_page = 0;
55
56     if (!list_empty(&(impl_state->page_list))) {
57         page_tail = list_tail_entry(&(impl_state->page_list), struct shadow_page_data, page_list_node);
58
59
60         if (page_tail->cr3 != cur_cr3) {
61             PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
62                        (void *)(addr_t)page_tail->page_pa, 
63                        (void *)(addr_t)cur_cr3, 
64                        (void *)(addr_t)(page_tail->cr3));
65
66             list_move(&(page_tail->page_list_node), &(impl_state->page_list));
67
68             memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB);
69
70
71             return page_tail;
72         }
73     }
74
75     // else  
76
77     page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data));
78     page_tail->page_pa = (addr_t)V3_AllocPages(1);
79
80     PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n", 
81                (void *)(addr_t)page_tail->page_pa, 
82                (void *)(addr_t)cur_cr3);
83
84     page_tail->cr3 = cur_cr3;
85     list_add(&(page_tail->page_list_node), &(impl_state->page_list));
86
87     shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa));
88     memset((void *)shdw_page, 0, PAGE_SIZE_4KB);
89
90     return page_tail;
91 }
92
93
94
95 static int sb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
96
97     V3_Print("SWAPBYPASS initialization\n");
98     return 0;
99 }
100
101 static int sb_deinit(struct v3_vm_info * vm) {
102     return -1;
103 }
104
105 static int sb_local_init(struct guest_info * core) {
106     struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
107     struct swapbypass_local_state * swapbypass_state = NULL;
108
109     V3_Print("SWAPBYPASS local initialization\n");
110
111
112     swapbypass_state = (struct swapbypass_local_state *)V3_Malloc(sizeof(struct swapbypass_local_state));
113
114     INIT_LIST_HEAD(&(swapbypass_state->page_list));
115
116     state->local_impl_data = swapbypass_state;
117
118     return 0;
119 }
120
121
122 static int sb_activate_shdw_pt(struct guest_info * core) {
123     switch (v3_get_vm_cpu_mode(core)) {
124
125         case PROTECTED:
126             return activate_shadow_pt_32(core);
127         case PROTECTED_PAE:
128             return activate_shadow_pt_32pae(core);
129         case LONG:
130         case LONG_32_COMPAT:
131         case LONG_16_COMPAT:
132             return activate_shadow_pt_64(core);
133         default:
134             PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
135             return -1;
136     }
137
138     return 0;
139 }
140
141 static int sb_invalidate_shdw_pt(struct guest_info * core) {
142     return sb_activate_shdw_pt(core);
143 }
144
145
146 static int sb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t error_code) {
147
148         switch (v3_get_vm_cpu_mode(core)) {
149             case PROTECTED:
150                 return handle_shadow_pagefault_32(core, fault_addr, error_code);
151                 break;
152             case PROTECTED_PAE:
153                 return handle_shadow_pagefault_32pae(core, fault_addr, error_code);
154             case LONG:
155             case LONG_32_COMPAT:
156             case LONG_16_COMPAT:
157                 return handle_shadow_pagefault_64(core, fault_addr, error_code);
158                 break;
159             default:
160                 PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
161                 return -1;
162         }
163 }
164
165
166 static int sb_handle_invlpg(struct guest_info * core, addr_t vaddr) {
167
168     switch (v3_get_vm_cpu_mode(core)) {
169         case PROTECTED:
170             return handle_shadow_invlpg_32(core, vaddr);
171         case PROTECTED_PAE:
172             return handle_shadow_invlpg_32pae(core, vaddr);
173         case LONG:
174         case LONG_32_COMPAT:
175         case LONG_16_COMPAT:
176             return handle_shadow_invlpg_64(core, vaddr);
177         default:
178             PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
179             return -1;
180     }
181 }
182
183 static struct v3_shdw_pg_impl sb_impl =  {
184     .name = "SWAPBYPASS",
185     .init = sb_init,
186     .deinit = sb_deinit,
187     .local_init = sb_local_init,
188     .handle_pagefault = sb_handle_pf,
189     .handle_invlpg = sb_handle_invlpg,
190     .activate_shdw_pt = sb_activate_shdw_pt,
191     .invalidate_shdw_pt = sb_invalidate_shdw_pt
192 };
193
194
195
196
197
198 register_shdw_pg_impl(&sb_impl);