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.


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