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.


freeing of virtual paging state during guest deinitialization
[palacios.git] / palacios / src / palacios / vmm_direct_paging.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, Steven Jaconette <stevenjaconette2007@u.northwestern.edu> 
11  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
12  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
13  * All rights reserved.
14  *
15  * Author: Steven Jaconette <stevenjaconette2007@u.northwestern.edu>
16  *
17  * This is free software.  You are permitted to use,
18  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
19  */
20
21 #include <palacios/vmm_direct_paging.h>
22 #include <palacios/vmm_paging.h>
23 #include <palacios/vmm.h>
24 #include <palacios/vm_guest_mem.h>
25 #include <palacios/vm_guest.h>
26
27
28 #ifndef CONFIG_DEBUG_NESTED_PAGING
29 #undef PrintDebug
30 #define PrintDebug(fmt, args...)
31 #endif
32
33
34 static addr_t create_generic_pt_page() {
35     void * page = 0;
36     page = V3_VAddr(V3_AllocPages(1));
37     memset(page, 0, PAGE_SIZE);
38
39     return (addr_t)page;
40 }
41
42 // Inline handler functions for each cpu mode
43 #include "vmm_direct_paging_32.h"
44 #include "vmm_direct_paging_32pae.h"
45 #include "vmm_direct_paging_64.h"
46
47 int v3_init_passthrough_pts(struct guest_info * info) {
48     info->direct_map_pt = (addr_t)V3_PAddr((void *)create_generic_pt_page());
49     return 0;
50 }
51
52
53 int v3_free_passthrough_pts(struct guest_info * core) {
54     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
55
56     // Delete the old direct map page tables
57     switch(mode) {
58         case REAL:
59         case PROTECTED:
60             delete_page_tables_32((pde32_t *)V3_VAddr((void *)(core->direct_map_pt)));
61             break;
62         case PROTECTED_PAE:
63         case LONG:
64         case LONG_32_COMPAT:
65             // Long mode will only use 32PAE page tables...
66             delete_page_tables_32pae((pdpe32pae_t *)V3_VAddr((void *)(core->direct_map_pt)));
67             break;
68         default:
69             PrintError("Unknown CPU Mode\n");
70             return -1;
71             break;
72     }
73
74     return 0;
75 }
76
77
78 int v3_reset_passthrough_pts(struct guest_info * core) {
79
80     v3_free_passthrough_pts(core);
81
82     // create new direct map page table
83     v3_init_passthrough_pts(core);
84     
85     return 0;
86 }
87
88
89
90 int v3_activate_passthrough_pt(struct guest_info * info) {
91     // For now... But we need to change this....
92     // As soon as shadow paging becomes active the passthrough tables are hosed
93     // So this will cause chaos if it is called at that time
94
95     info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
96     //PrintError("Activate Passthrough Page tables not implemented\n");
97     return 0;
98 }
99
100
101 int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
102     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(info);
103
104     switch(mode) {
105         case REAL:
106         case PROTECTED:
107             return handle_passthrough_pagefault_32(info, fault_addr, error_code);
108
109         case PROTECTED_PAE:
110         case LONG:
111         case LONG_32_COMPAT:
112             // Long mode will only use 32PAE page tables...
113             return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
114
115         default:
116             PrintError("Unknown CPU Mode\n");
117             break;
118     }
119     return -1;
120 }
121
122
123
124 int v3_handle_nested_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
125     v3_cpu_mode_t mode = v3_get_host_cpu_mode();
126
127
128     PrintDebug("Nested PageFault: fault_addr=%p, error_code=%u\n", (void *)fault_addr, *(uint_t *)&error_code);
129
130     switch(mode) {
131         case REAL:
132         case PROTECTED:
133             return handle_passthrough_pagefault_32(info, fault_addr, error_code);
134
135         case PROTECTED_PAE:
136             return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
137
138         case LONG:
139         case LONG_32_COMPAT:
140             return handle_passthrough_pagefault_64(info, fault_addr, error_code);           
141         
142         default:
143             PrintError("Unknown CPU Mode\n");
144             break;
145     }
146     return -1;
147 }
148
149 int v3_invalidate_passthrough_addr(struct guest_info * info, addr_t inv_addr) {
150     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(info);
151
152     switch(mode) {
153         case REAL:
154         case PROTECTED:
155             return invalidate_addr_32(info, inv_addr);
156
157         case PROTECTED_PAE:
158         case LONG:
159         case LONG_32_COMPAT:
160             // Long mode will only use 32PAE page tables...
161             return invalidate_addr_32pae(info, inv_addr);
162
163         default:
164             PrintError("Unknown CPU Mode\n");
165             break;
166     }
167     return -1;
168 }
169
170
171 int v3_invalidate_nested_addr(struct guest_info * info, addr_t inv_addr) {
172     v3_cpu_mode_t mode = LONG;
173
174     switch(mode) {
175         case REAL:
176         case PROTECTED:
177             return invalidate_addr_32(info, inv_addr);
178
179         case PROTECTED_PAE:
180             return invalidate_addr_32pae(info, inv_addr);
181
182         case LONG:
183         case LONG_32_COMPAT:
184             return invalidate_addr_64(info, inv_addr);      
185         
186         default:
187             PrintError("Unknown CPU Mode\n");
188             break;
189     }
190
191     return -1;
192 }