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.


New Shadow paging implementation to allow pluggable shadow paging implementations
[palacios.releases.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
22
23 struct shadow_page_data {
24     v3_reg_t cr3;
25     addr_t page_pa;
26   
27     struct list_head page_list_node;
28 };
29
30
31 struct vtlb_state {
32  
33     struct list_head page_list;
34
35 };
36
37
38 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info);
39
40
41 #include "vmm_shdw_pg_tlb_32.h"
42 #include "vmm_shdw_pg_tlb_32pae.h"
43 #include "vmm_shdw_pg_tlb_64.h"
44
45
46 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) {
47     struct shadow_page_state * state = &(info->shdw_pg_state);
48     v3_reg_t cur_cr3 = info->ctrl_regs.cr3;
49     struct shadow_page_data * page_tail = NULL;
50     addr_t shdw_page = 0;
51
52     if (!list_empty(&(state->page_list))) {
53         page_tail = list_tail_entry(&(state->page_list), struct shadow_page_data, page_list_node);
54     
55         if (page_tail->cr3 != cur_cr3) {
56             PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
57                        (void *)(addr_t)page_tail->page_pa, 
58                        (void *)(addr_t)cur_cr3, 
59                        (void *)(addr_t)(page_tail->cr3));
60
61             list_move(&(page_tail->page_list_node), &(state->page_list));
62
63             memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB);
64
65
66             return page_tail;
67         }
68     }
69
70     // else  
71
72     page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data));
73     page_tail->page_pa = (addr_t)V3_AllocPages(1);
74
75     PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n", 
76                (void *)(addr_t)page_tail->page_pa, 
77                (void *)(addr_t)cur_cr3);
78
79     page_tail->cr3 = cur_cr3;
80     list_add(&(page_tail->page_list_node), &(state->page_list));
81
82     shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa));
83     memset((void *)shdw_page, 0, PAGE_SIZE_4KB);
84
85     return page_tail;
86 }
87
88
89
90 static int vtlb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
91     struct vtlb_state * state = V3_Malloc(sizeof(struct vtlb_state));
92
93     INIT_LIST_HEAD(&(state->page_list));
94
95     *priv_data = state;
96
97     return 0;
98 }
99
100
101 int vtlb_activate_shdw_pt(struct guest_info * core, void * priv_data) {
102     switch (v3_get_vm_cpu_mode(core)) {
103
104         case PROTECTED:
105             return activate_shadow_pt_32(core);
106         case PROTECTED_PAE:
107             return activate_shadow_pt_32pae(core);
108         case LONG:
109         case LONG_32_COMPAT:
110         case LONG_16_COMPAT:
111             return activate_shadow_pt_64(core);
112         default:
113             PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
114             return -1;
115     }
116
117     return 0;
118 }
119
120 int vtlb_invalidate_shdw_pt(struct guest_info * core, void * priv_data) {
121     return vtlb_activate_shdw_pt(core, priv_data);
122 }
123
124
125 int vtlb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t err_code, void * priv_data) {
126
127         switch (v3_get_vm_cpu_mode(core)) {
128             case PROTECTED:
129                 return handle_shadow_pagefault_32(core, fault_addr, error_code);
130                 break;
131             case PROTECTED_PAE:
132                 return handle_shadow_pagefault_32pae(core, fault_addr, error_code);
133             case LONG:
134             case LONG_32_COMPAT:
135             case LONG_16_COMPAT:
136                 return handle_shadow_pagefault_64(core, fault_addr, error_code);
137                 break;
138             default:
139                 PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
140                 return -1;
141         }
142 }
143
144
145 int vtlb_handle_invlpg(struct guest_info * core, addr_t vaddr, void * priv_data) {
146
147     switch (v3_get_vm_cpu_mode(core)) {
148         case PROTECTED:
149             return handle_shadow_invlpg_32(core, vaddr);
150         case PROTECTED_PAE:
151             return handle_shadow_invlpg_32pae(core, vaddr);
152         case LONG:
153         case LONG_32_COMPAT:
154         case LONG_16_COMPAT:
155             return handle_shadow_invlpg_64(core, vaddr);
156         default:
157             PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
158             return -1;
159     }
160 }