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.


Lots of pedantic error checking in Palacios proper, especially for memory
[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 V3_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     void *temp;
37
38     temp = V3_AllocPages(1);
39     if (!temp) { 
40         PrintError("Cannot allocate page\n");
41         return 0;
42     }
43
44     page = V3_VAddr(temp);
45     memset(page, 0, PAGE_SIZE);
46
47     return (addr_t)page;
48 }
49
50 // Inline handler functions for each cpu mode
51 #include "vmm_direct_paging_32.h"
52 #include "vmm_direct_paging_32pae.h"
53 #include "vmm_direct_paging_64.h"
54
55 int v3_init_passthrough_pts(struct guest_info * info) {
56     info->direct_map_pt = (addr_t)V3_PAddr((void *)create_generic_pt_page());
57     return 0;
58 }
59
60
61 int v3_free_passthrough_pts(struct guest_info * core) {
62     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
63
64     // Delete the old direct map page tables
65     switch(mode) {
66         case REAL:
67         case PROTECTED:
68             delete_page_tables_32((pde32_t *)V3_VAddr((void *)(core->direct_map_pt)));
69             break;
70         case PROTECTED_PAE:
71         case LONG:
72         case LONG_32_COMPAT:
73             // Long mode will only use 32PAE page tables...
74             delete_page_tables_32pae((pdpe32pae_t *)V3_VAddr((void *)(core->direct_map_pt)));
75             break;
76         default:
77             PrintError("Unknown CPU Mode\n");
78             return -1;
79             break;
80     }
81
82     return 0;
83 }
84
85
86 int v3_reset_passthrough_pts(struct guest_info * core) {
87
88     v3_free_passthrough_pts(core);
89
90     // create new direct map page table
91     v3_init_passthrough_pts(core);
92     
93     return 0;
94 }
95
96
97
98 int v3_activate_passthrough_pt(struct guest_info * info) {
99     // For now... But we need to change this....
100     // As soon as shadow paging becomes active the passthrough tables are hosed
101     // So this will cause chaos if it is called at that time
102
103     info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
104     //PrintError("Activate Passthrough Page tables not implemented\n");
105     return 0;
106 }
107
108
109 int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
110     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(info);
111
112     switch(mode) {
113         case REAL:
114         case PROTECTED:
115             return handle_passthrough_pagefault_32(info, fault_addr, error_code);
116
117         case PROTECTED_PAE:
118         case LONG:
119         case LONG_32_COMPAT:
120             // Long mode will only use 32PAE page tables...
121             return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
122
123         default:
124             PrintError("Unknown CPU Mode\n");
125             break;
126     }
127     return -1;
128 }
129
130
131
132 int v3_handle_nested_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
133     v3_cpu_mode_t mode = v3_get_host_cpu_mode();
134
135
136     PrintDebug("Nested PageFault: fault_addr=%p, error_code=%u\n", (void *)fault_addr, *(uint_t *)&error_code);
137
138     switch(mode) {
139         case REAL:
140         case PROTECTED:
141             return handle_passthrough_pagefault_32(info, fault_addr, error_code);
142
143         case PROTECTED_PAE:
144             return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
145
146         case LONG:
147         case LONG_32_COMPAT:
148             return handle_passthrough_pagefault_64(info, fault_addr, error_code);           
149         
150         default:
151             PrintError("Unknown CPU Mode\n");
152             break;
153     }
154     return -1;
155 }
156
157 int v3_invalidate_passthrough_addr(struct guest_info * info, addr_t inv_addr) {
158     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(info);
159
160     switch(mode) {
161         case REAL:
162         case PROTECTED:
163             return invalidate_addr_32(info, inv_addr);
164
165         case PROTECTED_PAE:
166         case LONG:
167         case LONG_32_COMPAT:
168             // Long mode will only use 32PAE page tables...
169             return invalidate_addr_32pae(info, inv_addr);
170
171         default:
172             PrintError("Unknown CPU Mode\n");
173             break;
174     }
175     return -1;
176 }
177
178
179 int v3_invalidate_nested_addr(struct guest_info * info, addr_t inv_addr) {
180
181 #ifdef __V3_64BIT__
182     v3_cpu_mode_t mode = LONG;
183 #else 
184     v3_cpu_mode_t mode = PROTECTED;
185 #endif
186
187     switch(mode) {
188         case REAL:
189         case PROTECTED:
190             return invalidate_addr_32(info, inv_addr);
191
192         case PROTECTED_PAE:
193             return invalidate_addr_32pae(info, inv_addr);
194
195         case LONG:
196         case LONG_32_COMPAT:
197             return invalidate_addr_64(info, inv_addr);      
198         
199         default:
200             PrintError("Unknown CPU Mode\n");
201             break;
202     }
203
204     return -1;
205 }