obj-$(CONFIG_SHADOW_PAGING_VTLB) += vmm_shdw_pg_tlb.o
+obj-$(CONFIG_SYMBIOTIC_SWAP) += vmm_shdw_pg_swapbypass.o
obj-$(CONFIG_INSTRUMENT_VMM) += vmm_instrument.o
*/
#include <palacios/vmm_shadow_paging.h>
+#include <palacios/vmm_ctrl_regs.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vm_guest_mem.h>
struct shadow_page_data {
v3_reg_t cr3;
};
-struct vtlb_state {
+struct swapbypass_local_state {
struct list_head page_list;
};
-static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info);
+static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core);
-#include "vmm_shdw_pg_tlb_32.h"
-#include "vmm_shdw_pg_tlb_32pae.h"
-#include "vmm_shdw_pg_tlb_64.h"
+#include "vmm_shdw_pg_swapbypass_32.h"
+#include "vmm_shdw_pg_swapbypass_32pae.h"
+#include "vmm_shdw_pg_swapbypass_64.h"
-static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) {
- struct shadow_page_state * state = &(info->shdw_pg_state);
- v3_reg_t cur_cr3 = info->ctrl_regs.cr3;
+static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core) {
+ struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
+ struct swapbypass_local_state * impl_state = (struct swapbypass_local_state *)(state->local_impl_data);
+ v3_reg_t cur_cr3 = core->ctrl_regs.cr3;
struct shadow_page_data * page_tail = NULL;
addr_t shdw_page = 0;
- if (!list_empty(&(state->page_list))) {
- page_tail = list_tail_entry(&(state->page_list), struct shadow_page_data, page_list_node);
-
+ if (!list_empty(&(impl_state->page_list))) {
+ page_tail = list_tail_entry(&(impl_state->page_list), struct shadow_page_data, page_list_node);
+
+
if (page_tail->cr3 != cur_cr3) {
PrintDebug("Reusing old shadow Page: %p (cur_CR3=%p)(page_cr3=%p) \n",
(void *)(addr_t)page_tail->page_pa,
(void *)(addr_t)cur_cr3,
(void *)(addr_t)(page_tail->cr3));
- list_move(&(page_tail->page_list_node), &(state->page_list));
+ list_move(&(page_tail->page_list_node), &(impl_state->page_list));
memset(V3_VAddr((void *)(page_tail->page_pa)), 0, PAGE_SIZE_4KB);
(void *)(addr_t)cur_cr3);
page_tail->cr3 = cur_cr3;
- list_add(&(page_tail->page_list_node), &(state->page_list));
+ list_add(&(page_tail->page_list_node), &(impl_state->page_list));
shdw_page = (addr_t)V3_VAddr((void *)(page_tail->page_pa));
memset((void *)shdw_page, 0, PAGE_SIZE_4KB);
-static int vtlb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
- struct vtlb_state * state = V3_Malloc(sizeof(struct vtlb_state));
+static int sb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
+
+ V3_Print("SWAPBYPASS initialization\n");
+ return 0;
+}
+
+static int sb_deinit(struct v3_vm_info * vm) {
+ return -1;
+}
+
+static int sb_local_init(struct guest_info * core) {
+ struct v3_shdw_pg_state * state = &(core->shdw_pg_state);
+ struct swapbypass_local_state * swapbypass_state = NULL;
+
+ V3_Print("SWAPBYPASS local initialization\n");
+
+
+ swapbypass_state = (struct swapbypass_local_state *)V3_Malloc(sizeof(struct swapbypass_local_state));
- INIT_LIST_HEAD(&(state->page_list));
+ INIT_LIST_HEAD(&(swapbypass_state->page_list));
- *priv_data = state;
+ state->local_impl_data = swapbypass_state;
return 0;
}
-int vtlb_activate_shdw_pt(struct guest_info * core, void * priv_data) {
+static int sb_activate_shdw_pt(struct guest_info * core) {
switch (v3_get_vm_cpu_mode(core)) {
case PROTECTED:
return 0;
}
-int vtlb_invalidate_shdw_pt(struct guest_info * core, void * priv_data) {
- return vtlb_activate_shdw_pt(core, priv_data);
+static int sb_invalidate_shdw_pt(struct guest_info * core) {
+ return sb_activate_shdw_pt(core);
}
-int vtlb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t err_code, void * priv_data) {
+static int sb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t error_code) {
switch (v3_get_vm_cpu_mode(core)) {
case PROTECTED:
}
-int vtlb_handle_invlpg(struct guest_info * core, addr_t vaddr, void * priv_data) {
+static int sb_handle_invlpg(struct guest_info * core, addr_t vaddr) {
switch (v3_get_vm_cpu_mode(core)) {
case PROTECTED:
return -1;
}
}
+
+static struct v3_shdw_pg_impl sb_impl = {
+ .name = "SWAPBYPASS",
+ .init = sb_init,
+ .deinit = sb_deinit,
+ .local_init = sb_local_init,
+ .handle_pagefault = sb_handle_pf,
+ .handle_invlpg = sb_handle_invlpg,
+ .activate_shdw_pt = sb_activate_shdw_pt,
+ .invalidate_shdw_pt = sb_invalidate_shdw_pt
+};
+
+
+
+
+
+register_shdw_pg_impl(&sb_impl);
shadow_pde_access = v3_can_access_pde32(shadow_pd, fault_addr, error_code);
/* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
+ if (v3_is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (shdw access error=%d) (pf error code=%d)\n",
*(uint_t *)&guest_pde_access, *(uint_t *)&shadow_pde_access, *(uint_t *)&error_code);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
return -1;
}
PrintDebug("Shadow Paging User access error (shadow_pde_access=0x%x, guest_pde_access=0x%x)\n",
shadow_pde_access, guest_pde_access);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
return -1;
}
} else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) &&
(shadow_pde_access != PT_ACCESS_OK)) {
// inject page fault in guest
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
return -1;
}
/* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
+ if (v3_is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n",
guest_pte_access, *(uint_t*)&error_code);
-#ifdef CONFIG_SYMBIOTIC_SWAP
+
if (is_swapped_pte32(guest_pte)) {
pf_error_t swap_perms;
}
}
-#endif
+
// inject:
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
return -1;
}
} else {
// Inject page fault into the guest
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
return -1;
}
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+static inline int activate_shadow_pt_32pae(struct guest_info * info) {
+ PrintError("Activating 32 bit PAE page tables not implemented\n");
+ return -1;
+}
+
+
+
+
+
+
+/*
+ * *
+ * *
+ * * 32 bit PAE Page table fault handlers
+ * *
+ * *
+ */
+
+static inline int handle_shadow_pagefault_32pae(struct guest_info * info, addr_t fault_addr, pf_error_t error_code) {
+ PrintError("32 bit PAE shadow paging not implemented\n");
+ return -1;
+}
+
+
+static inline int handle_shadow_invlpg_32pae(struct guest_info * info, addr_t vaddr) {
+ PrintError("32 bit PAE shadow paging not implemented\n");
+ return -1;
+}
+
+
+
+
shadow_pml4e_access = v3_can_access_pml4e64(shadow_pml, fault_addr, error_code);
/* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pml4e_access, shadow_pml4e_access) == 1) {
+ if (v3_is_guest_pf(guest_pml4e_access, shadow_pml4e_access) == 1) {
PrintDebug("Injecting PML4E pf to guest: (guest access error=%d) (pf error code=%d)\n",
*(uint_t *)&guest_pml4e_access, *(uint_t *)&error_code);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
//
PrintDebug("Shadow Paging User access error (shadow_pml4e_access=0x%x, guest_pml4e_access=0x%x)\n",
shadow_pml4e_access, guest_pml4e_access);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
} else if ((shadow_pml4e_access != PT_ACCESS_NOT_PRESENT) &&
(shadow_pml4e_access != PT_ACCESS_OK)) {
// inject page fault in guest
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
shadow_pdpe_access = v3_can_access_pdpe64(shadow_pdp, fault_addr, error_code);
/* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pdpe_access, shadow_pdpe_access) == 1) {
+ if (v3_is_guest_pf(guest_pdpe_access, shadow_pdpe_access) == 1) {
PrintDebug("Injecting PDPE pf to guest: (guest access error=%d) (pf error code=%d)\n",
*(uint_t *)&guest_pdpe_access, *(uint_t *)&error_code);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
//
PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n",
shadow_pdpe_access, guest_pdpe_access);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
} else if ((shadow_pdpe_access != PT_ACCESS_NOT_PRESENT) &&
(shadow_pdpe_access != PT_ACCESS_OK)) {
// inject page fault in guest
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
shadow_pde_access = v3_can_access_pde64(shadow_pd, fault_addr, error_code);
/* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
+ if (v3_is_guest_pf(guest_pde_access, shadow_pde_access) == 1) {
PrintDebug("Injecting PDE pf to guest: (guest access error=%d) (pf error code=%d)\n",
*(uint_t *)&guest_pde_access, *(uint_t *)&error_code);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
//
PrintDebug("Shadow Paging User access error (shadow_pdpe_access=0x%x, guest_pdpe_access=0x%x)\n",
shadow_pde_access, guest_pde_access);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
} else if ((shadow_pde_access != PT_ACCESS_NOT_PRESENT) &&
(shadow_pde_access != PT_ACCESS_OK)) {
// inject page fault in guest
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
/* Was the page fault caused by the Guest's page tables? */
- if (is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
+ if (v3_is_guest_pf(guest_pte_access, shadow_pte_access) == 1) {
PrintDebug("Access error injecting pf to guest (guest access error=%d) (pf error code=%d)\n",
guest_pte_access, *(uint_t*)&error_code);
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}
} else {
// Inject page fault into the guest
- if (inject_guest_pf(info, fault_addr, error_code) == -1) {
+ if (v3_inject_guest_pf(info, fault_addr, error_code) == -1) {
PrintError("Could not inject guest page fault\n");
return -1;
}