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.


added support for memory remapping
[palacios.git] / palacios / src / palacios / vmm_direct_paging_32.h
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
22 #ifndef __VMM_DIRECT_PAGING_32_H__
23 #define __VMM_DIRECT_PAGING_32_H__
24
25 #include <palacios/vmm_mem.h>
26 #include <palacios/vmm_paging.h>
27 #include <palacios/vmm.h>
28 #include <palacios/vm_guest_mem.h>
29 #include <palacios/vm_guest.h>
30
31
32 static inline int handle_passthrough_pagefault_32(struct guest_info * info, 
33                                                   addr_t fault_addr, 
34                                                   pf_error_t error_code) {
35     // Check to see if pde and pte exist (create them if not)
36     pde32_t * pde = NULL;
37     pte32_t * pte = NULL;
38     addr_t host_addr = 0;
39     
40     int pde_index = PDE32_INDEX(fault_addr);
41     int pte_index = PTE32_INDEX(fault_addr);
42     
43     struct v3_shadow_region * region = v3_get_shadow_region(info, fault_addr);
44     
45     if (region == NULL) {
46         PrintError("Invalid region in passthrough page fault 32, addr=%p\n", 
47                    (void *)fault_addr);
48         return -1;
49     }
50     
51     host_addr = v3_get_shadow_addr(region, fault_addr);
52     
53     // Lookup the correct PDE address based on the PAGING MODE
54     if (info->shdw_pg_mode == SHADOW_PAGING) {
55         pde = CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
56     } else {
57         pde = CR3_TO_PDE32_VA(info->direct_map_pt);
58     }
59
60
61     // Fix up the PDE entry
62     if (pde[pde_index].present == 0) {
63         pte = (pte32_t *)create_generic_pt_page();
64         
65         pde[pde_index].present = 1;
66         pde[pde_index].writable = 1;
67         pde[pde_index].user_page = 1;
68         pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
69         
70     } else {
71         pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
72     }
73     
74     // Fix up the PTE entry
75     if (pte[pte_index].present == 0) {
76         
77         pte[pte_index].user_page = 1;
78         
79         if (region->host_type == SHDW_REGION_ALLOCATED) {
80             // Full access
81             pte[pte_index].present = 1;
82             pte[pte_index].writable = 1;
83             
84             pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
85         } else if (region->host_type == SHDW_REGION_WRITE_HOOK) {
86             // Only trap writes
87             pte[pte_index].present = 1;
88             pte[pte_index].writable = 0;
89             
90             pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
91         } else if (region->host_type == SHDW_REGION_FULL_HOOK) {
92             // trap all accesses
93             return v3_handle_mem_full_hook(info, fault_addr, fault_addr, region, error_code);
94         } else {
95             PrintError("Unknown Region Type...\n");
96             return -1;
97         }
98     }
99     
100     if ( (region->host_type == SHDW_REGION_WRITE_HOOK) && 
101          (error_code.write == 1) ) {
102         return v3_handle_mem_wr_hook(info, fault_addr, fault_addr, region, error_code);
103     }
104
105     
106     return 0;
107 }
108
109
110
111
112 static inline int invalidate_addr_32(struct guest_info * info, addr_t inv_addr) {
113     pde32_t * pde = NULL;
114     pte32_t * pte = NULL;
115
116     // TODO:
117     // Call INVLPGA
118
119     // clear the page table entry
120     int pde_index = PDE32_INDEX(inv_addr);
121     int pte_index = PTE32_INDEX(inv_addr);
122
123     
124     // Lookup the correct PDE address based on the PAGING MODE
125     if (info->shdw_pg_mode == SHADOW_PAGING) {
126         pde = CR3_TO_PDE32_VA(info->ctrl_regs.cr3);
127     } else {
128         pde = CR3_TO_PDE32_VA(info->direct_map_pt);
129     }    
130
131     if (pde[pde_index].present == 0) {
132         return 0;
133     } else if (pde[pde_index].large_page) {
134         pde[pde_index].present = 0;
135         return 0;
136     }
137
138     pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
139
140     pte[pte_index].present = 0;
141
142     return 0;
143 }
144
145
146 #endif