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.


1f2c6e678daac540c9f184954ab7632de1bd082f
[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 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 int v3_reset_passthrough_pts(struct guest_info * info) {
53     v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
54
55     // Delete the old direct map page tables
56     switch(mode) {
57         case REAL:
58         case PROTECTED:
59             delete_page_tables_32((pde32_t *)V3_VAddr((void *)(info->direct_map_pt)));
60             break;
61         case PROTECTED_PAE:
62         case LONG:
63         case LONG_32_COMPAT:
64             // Long mode will only use 32PAE page tables...
65             delete_page_tables_32pae((pdpe32pae_t *)V3_VAddr((void *)(info->direct_map_pt)));
66             break;
67         default:
68             PrintError("Unknown CPU Mode\n");
69             break;
70     }
71             
72     // create new direct map page table
73     v3_init_passthrough_pts(info);
74     
75     return 0;
76 }
77
78
79 int v3_activate_passthrough_pt(struct guest_info * info) {
80     // For now... But we need to change this....
81     // As soon as shadow paging becomes active the passthrough tables are hosed
82     // So this will cause chaos if it is called at that time
83
84     info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
85     //PrintError("Activate Passthrough Page tables not implemented\n");
86     return 0;
87 }
88
89
90 int v3_handle_passthrough_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
91     v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
92
93     switch(mode) {
94         case REAL:
95         case PROTECTED:
96             return handle_passthrough_pagefault_32(info, fault_addr, error_code);
97
98         case PROTECTED_PAE:
99         case LONG:
100         case LONG_32_COMPAT:
101             // Long mode will only use 32PAE page tables...
102             return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
103
104         default:
105             PrintError("Unknown CPU Mode\n");
106             break;
107     }
108     return -1;
109 }
110
111
112
113 int v3_handle_nested_pagefault(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
114     // THIS IS VERY BAD
115     v3_vm_cpu_mode_t mode = LONG;
116
117
118     PrintDebug("Nested PageFault: fault_addr=%p, error_code=%u\n",(void*)fault_addr, *(uint_t *)&error_code);
119
120     switch(mode) {
121         case REAL:
122         case PROTECTED:
123             return handle_passthrough_pagefault_32(info, fault_addr, error_code);
124
125         case PROTECTED_PAE:
126             return handle_passthrough_pagefault_32pae(info, fault_addr, error_code);
127
128         case LONG:
129         case LONG_32_COMPAT:
130             return handle_passthrough_pagefault_64(info, fault_addr, error_code);           
131         
132         default:
133             PrintError("Unknown CPU Mode\n");
134             break;
135     }
136     return -1;
137 }
138
139 int v3_invalidate_passthrough_addr(struct guest_info * info, addr_t inv_addr) {
140     v3_vm_cpu_mode_t mode = v3_get_cpu_mode(info);
141
142     switch(mode) {
143         case REAL:
144         case PROTECTED:
145             return invalidate_addr_32(info, inv_addr);
146
147         case PROTECTED_PAE:
148         case LONG:
149         case LONG_32_COMPAT:
150             // Long mode will only use 32PAE page tables...
151             return invalidate_addr_32pae(info, inv_addr);
152
153         default:
154             PrintError("Unknown CPU Mode\n");
155             break;
156     }
157     return -1;
158 }
159
160
161 int v3_invalidate_nested_addr(struct guest_info * info, addr_t inv_addr) {
162     v3_vm_cpu_mode_t mode = LONG;
163
164     switch(mode) {
165         case REAL:
166         case PROTECTED:
167             return invalidate_addr_32(info, inv_addr);
168
169         case PROTECTED_PAE:
170             return invalidate_addr_32pae(info, inv_addr);
171
172         case LONG:
173         case LONG_32_COMPAT:
174             return invalidate_addr_64(info, inv_addr);      
175         
176         default:
177             PrintError("Unknown CPU Mode\n");
178             break;
179     }
180
181     return -1;
182 }