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.


separated virtual cores from physical cores
[palacios.git] / palacios / src / palacios / vmm_direct_paging_32pae.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 #ifndef __VMM_DIRECT_PAGING_32PAE_H__
22 #define __VMM_DIRECT_PAGING_32PAE_H__
23
24 #include <palacios/vmm_mem.h>
25 #include <palacios/vmm_paging.h>
26 #include <palacios/vmm.h>
27 #include <palacios/vm_guest_mem.h>
28 #include <palacios/vm_guest.h>
29
30
31 static inline int handle_passthrough_pagefault_32pae(struct guest_info * info, 
32                                                      addr_t fault_addr, 
33                                                      pf_error_t error_code) {
34     pdpe32pae_t * pdpe = NULL;
35     pde32pae_t * pde = NULL;
36     pte32pae_t * pte = NULL;
37     addr_t host_addr = 0;
38
39     int pdpe_index = PDPE32PAE_INDEX(fault_addr);
40     int pde_index = PDE32PAE_INDEX(fault_addr);
41     int pte_index = PTE32PAE_INDEX(fault_addr);
42
43     struct v3_mem_region * region =  v3_get_mem_region(info->vm_info, info->vcpu_id, fault_addr);
44   
45     if (region == NULL) {
46         PrintError("Invalid region in passthrough page fault 32PAE, addr=%p\n", 
47                    (void *)fault_addr);
48         return -1;
49     }
50
51     // Lookup the correct PDPE address based on the PAGING MODE
52     if (info->shdw_pg_mode == SHADOW_PAGING) {
53         pdpe = CR3_TO_PDPE32PAE_VA(info->ctrl_regs.cr3);
54     } else {
55         pdpe = CR3_TO_PDPE32PAE_VA(info->direct_map_pt);
56     }
57
58     // Fix up the PDPE entry
59     if (pdpe[pdpe_index].present == 0) {
60         pde = (pde32pae_t *)create_generic_pt_page();
61    
62         pdpe[pdpe_index].present = 1;
63         // Set default PDPE Flags...
64         pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pde));    
65     } else {
66         pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pdpe[pdpe_index].pd_base_addr));
67     }
68
69
70     // Fix up the PDE entry
71     if (pde[pde_index].present == 0) {
72         pte = (pte32pae_t *)create_generic_pt_page();
73
74         pde[pde_index].present = 1;
75         pde[pde_index].writable = 1;
76         pde[pde_index].user_page = 1;
77
78         pde[pde_index].pt_base_addr = PAGE_BASE_ADDR((addr_t)V3_PAddr(pte));
79     } else {
80         pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
81     }
82
83
84     // Fix up the PTE entry
85     if (pte[pte_index].present == 0) {
86         pte[pte_index].user_page = 1;
87
88         if ((region->flags.alloced == 1) && 
89             (region->flags.read == 1)) {
90
91             pte[pte_index].present = 1;
92
93             if (region->flags.write == 1) {
94                 pte[pte_index].writable = 1;
95             } else {
96                 pte[pte_index].writable = 0;
97             }
98
99             if (v3_gpa_to_hpa(info, fault_addr, &host_addr) == -1) {
100                 PrintError("Could not translate fault address (%p)\n", (void *)fault_addr);
101                 return -1;
102             }
103
104             pte[pte_index].page_base_addr = PAGE_BASE_ADDR(host_addr);
105         } else {
106             return region->unhandled(info, fault_addr, fault_addr, region, error_code);
107         }
108     } else {
109         return region->unhandled(info, fault_addr, fault_addr, region, error_code);
110     }
111
112     return 0;
113 }
114
115
116 static inline int invalidate_addr_32pae(struct guest_info * info, addr_t inv_addr) {
117     pdpe32pae_t * pdpe = NULL;
118     pde32pae_t * pde = NULL;
119     pte32pae_t * pte = NULL;
120
121
122     // TODO:
123     // Call INVLPGA
124
125     // clear the page table entry
126     int pdpe_index = PDPE32PAE_INDEX(inv_addr);
127     int pde_index = PDE32PAE_INDEX(inv_addr);
128     int pte_index = PTE32PAE_INDEX(inv_addr);
129
130     
131     // Lookup the correct PDE address based on the PAGING MODE
132     if (info->shdw_pg_mode == SHADOW_PAGING) {
133         pdpe = CR3_TO_PDPE32PAE_VA(info->ctrl_regs.cr3);
134     } else {
135         pdpe = CR3_TO_PDPE32PAE_VA(info->direct_map_pt);
136     }    
137
138
139     if (pdpe[pdpe_index].present == 0) {
140         return 0;
141     }
142
143     pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pdpe[pdpe_index].pd_base_addr));
144
145     if (pde[pde_index].present == 0) {
146         return 0;
147     } else if (pde[pde_index].large_page) {
148         pde[pde_index].present = 0;
149         return 0;
150     }
151
152     pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR(pde[pde_index].pt_base_addr));
153
154     pte[pte_index].present = 0;
155
156     return 0;
157 }
158
159
160
161 #endif