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.


44777863e113e434ab360c4054e0e1b0bb92326e
[palacios.git] / palacios / src / palacios / vmm_shdw_pg_tlb.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 vtlb_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_tlb_32.h"
45 #include "vmm_shdw_pg_tlb_32pae.h"
46 #include "vmm_shdw_pg_tlb_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 vtlb_local_state * impl_state = (struct vtlb_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 vtlb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
96
97     V3_Print("VTLB initialization\n");
98     return 0;
99 }
100
101 static int vtlb_deinit(struct v3_vm_info * vm) {
102     return -1;
103 }
104
105 static int vtlb_local_init(struct guest_info * core) {
106     struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
107     struct vtlb_local_state * vtlb_state = NULL;
108
109     V3_Print("VTLB local initialization\n");
110
111
112     vtlb_state = (struct vtlb_local_state *)V3_Malloc(sizeof(struct vtlb_local_state));
113
114     INIT_LIST_HEAD(&(vtlb_state->page_list));
115
116     state->local_impl_data = vtlb_state;
117
118     return 0;
119 }
120
121
122 static int vtlb_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 vtlb_invalidate_shdw_pt(struct guest_info * core) {
142     return vtlb_activate_shdw_pt(core);
143 }
144
145
146 static int vtlb_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 vtlb_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 vtlb_impl =  {
184     .name = "VTLB",
185     .init = vtlb_init,
186     .deinit = vtlb_deinit,
187     .local_init = vtlb_local_init,
188     .handle_pagefault = vtlb_handle_pf,
189     .handle_invlpg = vtlb_handle_invlpg,
190     .activate_shdw_pt = vtlb_activate_shdw_pt,
191     .invalidate_shdw_pt = vtlb_invalidate_shdw_pt
192 };
193
194
195
196
197
198 register_shdw_pg_impl(&vtlb_impl);