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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm_shadow_paging.h>
23 struct shadow_page_data {
27 struct list_head page_list_node;
33 struct list_head page_list;
38 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info);
41 #include "vmm_shdw_pg_tlb_32.h"
42 #include "vmm_shdw_pg_tlb_32pae.h"
43 #include "vmm_shdw_pg_tlb_64.h"
46 static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) {
47 struct shadow_page_state * state = &(info->shdw_pg_state);
48 v3_reg_t cur_cr3 = info->ctrl_regs.cr3;
49 struct shadow_page_data * page_tail = NULL;
52 if (!list_empty(&(state->page_list))) {
53 page_tail = list_tail_entry(&(state->page_list), struct shadow_page_data, page_list_node);
55 if (page_tail->cr3 != cur_cr3) {
56 PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
57 (void *)(addr_t)page_tail->page_pa,
58 (void *)(addr_t)cur_cr3,
59 (void *)(addr_t)(page_tail->cr3));
61 list_move(&(page_tail->page_list_node), &(state->page_list));
63 memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB);
72 page_tail = (struct shadow_page_data *)V3_Malloc(sizeof(struct shadow_page_data));
73 page_tail->page_pa = (addr_t)V3_AllocPages(1);
75 PrintDebug("Allocating new shadow Page: %p (cur_cr3=%p)\n",
76 (void *)(addr_t)page_tail->page_pa,
77 (void *)(addr_t)cur_cr3);
79 page_tail->cr3 = cur_cr3;
80 list_add(&(page_tail->page_list_node), &(state->page_list));
82 shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa));
83 memset((void *)shdw_page, 0, PAGE_SIZE_4KB);
90 static int vtlb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
91 struct vtlb_state * state = V3_Malloc(sizeof(struct vtlb_state));
93 INIT_LIST_HEAD(&(state->page_list));
101 int vtlb_activate_shdw_pt(struct guest_info * core, void * priv_data) {
102 switch (v3_get_vm_cpu_mode(core)) {
105 return activate_shadow_pt_32(core);
107 return activate_shadow_pt_32pae(core);
111 return activate_shadow_pt_64(core);
113 PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
120 int vtlb_invalidate_shdw_pt(struct guest_info * core, void * priv_data) {
121 return vtlb_activate_shdw_pt(core, priv_data);
125 int vtlb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t err_code, void * priv_data) {
127 switch (v3_get_vm_cpu_mode(core)) {
129 return handle_shadow_pagefault_32(core, fault_addr, error_code);
132 return handle_shadow_pagefault_32pae(core, fault_addr, error_code);
136 return handle_shadow_pagefault_64(core, fault_addr, error_code);
139 PrintError("Unhandled CPU Mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));
145 int vtlb_handle_invlpg(struct guest_info * core, addr_t vaddr, void * priv_data) {
147 switch (v3_get_vm_cpu_mode(core)) {
149 return handle_shadow_invlpg_32(core, vaddr);
151 return handle_shadow_invlpg_32pae(core, vaddr);
155 return handle_shadow_invlpg_64(core, vaddr);
157 PrintError("Invalid CPU mode: %s\n", v3_cpu_mode_to_str(v3_get_vm_cpu_mode(core)));