From: Jack Lange Date: Thu, 4 Feb 2010 23:52:50 +0000 (-0600) Subject: added swapbypass paging implemenation X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=d662cc4cc19794e57b3a0126fd05d09456e22cdc;p=palacios.git added swapbypass paging implemenation --- diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index c081e91..b03a7eb 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -53,6 +53,7 @@ obj-$(CONFIG_VMX) += vmx.o \ 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 diff --git a/palacios/src/palacios/vmm_shdw_pg_swapbypass.c b/palacios/src/palacios/vmm_shdw_pg_swapbypass.c index 282c697..2330f6d 100644 --- a/palacios/src/palacios/vmm_shdw_pg_swapbypass.c +++ b/palacios/src/palacios/vmm_shdw_pg_swapbypass.c @@ -18,7 +18,10 @@ */ #include +#include +#include +#include struct shadow_page_data { v3_reg_t cr3; @@ -28,37 +31,39 @@ struct shadow_page_data { }; -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); @@ -77,7 +82,7 @@ static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) (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); @@ -87,18 +92,34 @@ static struct shadow_page_data * create_new_shadow_pt(struct guest_info * info) -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: @@ -117,12 +138,12 @@ int vtlb_activate_shdw_pt(struct guest_info * core, void * priv_data) { 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: @@ -142,7 +163,7 @@ int vtlb_handle_pf(struct guest_info * core, addr_t fault_addr, pf_error_t err_c } -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: @@ -158,3 +179,20 @@ int vtlb_handle_invlpg(struct guest_info * core, addr_t vaddr, void * priv_data) 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); diff --git a/palacios/src/palacios/vmm_shadow_paging_32.h b/palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h similarity index 97% rename from palacios/src/palacios/vmm_shadow_paging_32.h rename to palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h index 5e1d9c9..15523ff 100644 --- a/palacios/src/palacios/vmm_shadow_paging_32.h +++ b/palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h @@ -84,10 +84,10 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa 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; } @@ -103,7 +103,7 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa 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; } @@ -117,7 +117,7 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa } 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; } @@ -223,12 +223,12 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault /* 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; @@ -314,10 +314,10 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault } } -#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; } @@ -400,7 +400,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault } 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; } diff --git a/palacios/src/palacios/vmm_shdw_pg_swapbypass_32pae.h b/palacios/src/palacios/vmm_shdw_pg_swapbypass_32pae.h new file mode 100644 index 0000000..d6ef1c7 --- /dev/null +++ b/palacios/src/palacios/vmm_shdw_pg_swapbypass_32pae.h @@ -0,0 +1,52 @@ +/* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * 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; +} + + + + diff --git a/palacios/src/palacios/vmm_shadow_paging_64.h b/palacios/src/palacios/vmm_shdw_pg_swapbypass_64.h similarity index 95% rename from palacios/src/palacios/vmm_shadow_paging_64.h rename to palacios/src/palacios/vmm_shdw_pg_swapbypass_64.h index af149fd..8f01d7c 100644 --- a/palacios/src/palacios/vmm_shadow_paging_64.h +++ b/palacios/src/palacios/vmm_shdw_pg_swapbypass_64.h @@ -93,10 +93,10 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa 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; } @@ -109,7 +109,7 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa // 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; } @@ -117,7 +117,7 @@ static inline int handle_shadow_pagefault_64(struct guest_info * info, addr_t fa } 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; } @@ -193,10 +193,10 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul 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; } @@ -209,7 +209,7 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul // 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; } @@ -217,7 +217,7 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul } 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; } @@ -285,10 +285,10 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault 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; } @@ -301,7 +301,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault // 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; } @@ -320,7 +320,7 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault } 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; } @@ -426,12 +426,12 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault 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; } @@ -510,7 +510,7 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault } 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; }