From: Jack Lange Date: Sat, 6 Feb 2010 22:33:16 +0000 (-0600) Subject: reorganized swapbypass to isolate it to a special shadow paging implementation, and... X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=8a8e371fd9be4513214a0013063d87ecbc5582c1 reorganized swapbypass to isolate it to a special shadow paging implementation, and removed external state dependencies. --- diff --git a/Kconfig b/Kconfig index a9cc6ac..337f590 100644 --- a/Kconfig +++ b/Kconfig @@ -167,19 +167,19 @@ config SYMMOD Enable Symbiotic module loading -config SYMBIOTIC_SWAP - bool "Symbiotic Swap" +config SWAPBYPASS + bool "SwapBypass" default n depends on SYMBIOTIC && SYMCALL && EXPERIMENTAL help - This enables the symbiotic swap architecture + This enables the SwapBypass architecture -config SYMBIOTIC_SWAP_TELEMETRY - bool "Enable Symbiotic Swap Telemetry" +config SWAPBYPASS_TELEMETRY + bool "Enable SwapBypass Telemetry" default n - depends on TELEMETRY && SYMBIOTIC_SWAP + depends on TELEMETRY && SWAPBYPASS help - Enable the telemetry information for the symbiotic swap subsystem + Enable the telemetry information for the SwapBypass subsystem endmenu diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index ec4569e..4498705 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -40,9 +40,6 @@ #include #endif -#ifdef CONFIG_SYMBIOTIC_SWAP -#include -#endif @@ -59,9 +56,6 @@ struct v3_sym_core_state; struct v3_intr_state; -#ifdef CONFIG_SYMBIOTIC_SWAP -struct v3_sym_swap_state; -#endif @@ -153,9 +147,6 @@ struct v3_vm_info { #ifdef CONFIG_SYMBIOTIC // Symbiotic state struct v3_sym_vm_state sym_vm_state; -#ifdef CONFIG_SYMBIOTIC_SWAP - struct v3_sym_swap_state swap_state; -#endif #endif diff --git a/palacios/include/palacios/vmm_swapbypass.h b/palacios/include/palacios/vmm_swapbypass.h new file mode 100644 index 0000000..5f341b2 --- /dev/null +++ b/palacios/include/palacios/vmm_swapbypass.h @@ -0,0 +1,46 @@ +/* + * 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". + */ + +#ifndef __VMM_SWAPBYPASS_H__ +#define __VMM_SWAPBYPASS_H__ + +#ifdef __V3VEE__ + +#include + + +struct v3_swap_ops { + void * (*get_swap_entry)(uint32_t pg_index, void * private_data); +}; + + + + +int v3_register_swap_disk(struct v3_vm_info * vm, int dev_index, + struct v3_swap_ops * ops, void * private_data); + +int v3_swap_in_notify(struct v3_vm_info * vm, int pg_index, int dev_index); + + +int v3_swap_flush(struct v3_vm_info * vm); + + + +#endif +#endif diff --git a/palacios/include/palacios/vmm_sym_swap.h b/palacios/include/palacios/vmm_sym_swap.h deleted file mode 100644 index 6bd531c..0000000 --- a/palacios/include/palacios/vmm_sym_swap.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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". - */ - -#ifndef __VMM_SYM_SWAP_H__ -#define __VMM_SYM_SWAP_H__ - -#ifdef __V3VEE__ - -#include -#include -#include - - -struct v3_swap_ops { - void * (*get_swap_entry)(uint32_t pg_index, void * private_data); -}; - - -struct v3_swap_dev { - uint8_t present; - - struct v3_swap_ops * ops; - - void * private_data; -}; - - -struct v3_sym_swap_state { - struct v3_swap_dev devs[256]; - -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY - uint32_t read_faults; - uint32_t write_faults; - uint32_t flushes; - uint32_t mapped_pages; - uint32_t list_size; -#endif - - // shadow pointers - struct hashtable * shdw_ptr_ht; -}; - -// Present = 0 and Dirty = 0 -// fixme -static inline int is_swapped_pte32(pte32_t * pte) { - return ((pte->present == 0) && (*(uint32_t *)pte != 0)); -} - - - -int v3_init_sym_swap(struct v3_vm_info * vm); - -int v3_register_swap_disk(struct v3_vm_info * vm, int dev_index, - struct v3_swap_ops * ops, void * private_data); - -int v3_swap_in_notify(struct v3_vm_info * vm, int pg_index, int dev_index); - - -int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms); -addr_t v3_get_swapped_pg_addr(struct v3_vm_info * vm, pte32_t * guest_pte); -addr_t v3_map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr); - -int v3_swap_flush(struct v3_vm_info * vm); - - - -#endif -#endif diff --git a/palacios/src/devices/Kconfig b/palacios/src/devices/Kconfig index a5847ef..55b6b1e 100644 --- a/palacios/src/devices/Kconfig +++ b/palacios/src/devices/Kconfig @@ -273,19 +273,19 @@ config TMPDISK help Includes the temporary RAM disk -config SYM_SWAP - bool "Symbiotic Swap disk" +config SWAPBYPASS_DISK_CACHE + bool "SwapBypass disk cache" default y - depends on SYMBIOTIC_SWAP && (LINUX_VIRTIO_BLOCK || IDE) + depends on SWAPBYPASS && (LINUX_VIRTIO_BLOCK || IDE) help - Includes the symbiotic ram based swap disk + Includes the SwapBypass ram based swap disk cache -config SYM_SWAP2 - bool "Symbiotic Swap disk v2" +config SWAPBYPASS_DISK_CACHE2 + bool "SwapBypass disk cache v2" default y - depends on SYMBIOTIC_SWAP && (LINUX_VIRTIO_BLOCK || IDE) + depends on SWAPBYPASS && (LINUX_VIRTIO_BLOCK || IDE) help - Includes the symbiotic ram based swap disk + Includes the SwapBypass ram based swap disk cache config DISK_MODEL bool "Disk Performance Model" diff --git a/palacios/src/devices/Makefile b/palacios/src/devices/Makefile index fd2b694..8e8541b 100644 --- a/palacios/src/devices/Makefile +++ b/palacios/src/devices/Makefile @@ -17,8 +17,8 @@ obj-$(CONFIG_NVRAM) += nvram.o obj-$(CONFIG_OS_DEBUG) += os_debug.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_PIIX3) += piix3.o -obj-$(CONFIG_SYM_SWAP) += sym_swap.o -obj-$(CONFIG_SYM_SWAP2) += sym_swap2.o +obj-$(CONFIG_SWAPBYPASS_DISK_CACHE) += swapbypass_cache.o +obj-$(CONFIG_SWAPBYPASS_DISK_CACHE2) += swapbypass_cache2.o obj-$(CONFIG_DISK_MODEL) += disk_model.o obj-$(CONFIG_NE2K) += ne2k.o diff --git a/palacios/src/devices/sym_swap.c b/palacios/src/devices/swapbypass_cache.c similarity index 96% rename from palacios/src/devices/sym_swap.c rename to palacios/src/devices/swapbypass_cache.c index 85936d0..7d6dd80 100644 --- a/palacios/src/devices/sym_swap.c +++ b/palacios/src/devices/swapbypass_cache.c @@ -19,11 +19,11 @@ #include #include -#include +#include #include -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY #include #endif @@ -60,7 +60,7 @@ struct swap_state { union swap_header * hdr; -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY uint32_t pages_in; uint32_t pages_out; #endif @@ -164,7 +164,7 @@ static int swap_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * pri int i = 0; // Notify the shadow paging layer -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY swap->pages_in += length / 4096; #endif @@ -219,7 +219,7 @@ static int swap_write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * p if ((swap->active == 1) && (offset != 0)) { int i = 0; -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY swap->pages_out += length / 4096; #endif @@ -253,7 +253,7 @@ static struct v3_device_ops dev_ops = { }; -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY static void telemetry_cb(struct v3_vm_info * vm, void * private_data, char * hdr) { struct vm_device * dev = (struct vm_device *)private_data; struct swap_state * swap = (struct swap_state *)(dev->private_data); @@ -314,7 +314,7 @@ static int swap_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY if (vm->enable_telemetry == 1) { v3_add_telemetry_cb(vm, telemetry_cb, dev); } @@ -323,4 +323,4 @@ static int swap_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return 0; } -device_register("SYM_SWAP", swap_init) +device_register("SWAPBYPASS_CACHE", swap_init) diff --git a/palacios/src/devices/sym_swap2.c b/palacios/src/devices/swapbypass_cache2.c similarity index 97% rename from palacios/src/devices/sym_swap2.c rename to palacios/src/devices/swapbypass_cache2.c index 0fbc53b..72ff58f 100644 --- a/palacios/src/devices/sym_swap2.c +++ b/palacios/src/devices/swapbypass_cache2.c @@ -19,12 +19,12 @@ #include #include -#include +#include #include #include -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY #include #endif @@ -83,7 +83,7 @@ struct swap_state { struct v3_dev_blk_ops * ops; void * private_data; -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY uint32_t pages_in; uint32_t pages_out; #endif @@ -235,7 +235,7 @@ static int buf_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * priv swap->unswapped_pages += (length / 4096); -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY swap->pages_in += length / 4096; #endif @@ -384,7 +384,7 @@ static int buf_write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * pr swap->swapped_pages += written_pages; -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY swap->pages_out += length / 4096; #endif @@ -506,7 +506,7 @@ static struct v3_device_ops dev_ops = { }; -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY static void telemetry_cb(struct v3_vm_info * vm, void * private_data, char * hdr) { struct swap_state * swap = (struct swap_state *)private_data; @@ -583,7 +583,7 @@ static int connect_fn(struct v3_vm_info * vm, } -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY +#ifdef CONFIG_SWAPBYPASS_TELEMETRY if (vm->enable_telemetry == 1) { v3_add_telemetry_cb(vm, telemetry_cb, swap); @@ -617,4 +617,4 @@ static int swap_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return 0; } -device_register("SWAPCACHE", swap_init) +device_register("SWAPBYPASS_CACHE2", swap_init) diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index 76d62e9..be34589 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -64,4 +64,4 @@ obj-$(CONFIG_SYMBIOTIC) += vmm_symbiotic.o vmm_symspy.o obj-$(CONFIG_SYMCALL) += vmm_symcall.o obj-$(CONFIG_SYMMOD) += vmm_symmod.o -obj-$(CONFIG_SYMBIOTIC_SWAP) += vmm_sym_swap.o vmm_shdw_pg_swapbypass.o +obj-$(CONFIG_SWAPBYPASS) += vmm_shdw_pg_swapbypass.o diff --git a/palacios/src/palacios/vm_guest.c b/palacios/src/palacios/vm_guest.c index d0a8fb8..17b1be8 100644 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@ -436,13 +436,6 @@ int v3_init_vm(struct v3_vm_info * vm) { v3_init_dev_mgr(vm); -#ifdef CONFIG_SYMBIOTIC_SWAP - PrintDebug("initializing symbiotic swap\n"); - v3_init_sym_swap(vm); -#endif - - - // init SVM/VMX #ifdef CONFIG_SVM if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) { diff --git a/palacios/src/palacios/vmm_shdw_pg_swapbypass.c b/palacios/src/palacios/vmm_shdw_pg_swapbypass.c index 2330f6d..af23fed 100644 --- a/palacios/src/palacios/vmm_shdw_pg_swapbypass.c +++ b/palacios/src/palacios/vmm_shdw_pg_swapbypass.c @@ -18,10 +18,47 @@ */ #include +#include #include #include #include +#include +#include + + +#ifdef CONFIG_SWAPBYPASS_TELEMETRY +#include +#endif + + + + + + +// This is a hack and 32 bit linux specific.... need to fix... +struct swap_pte { + uint32_t present : 1; + uint32_t dev_index : 8; + uint32_t pg_index : 23; +}; + + +struct shadow_pointer { + uint32_t pg_index; + uint32_t dev_index; + + pte32_t * shadow_pte; + + addr_t guest_pte; + + struct list_head node; +}; + + + + + struct shadow_page_data { v3_reg_t cr3; @@ -37,10 +74,170 @@ struct swapbypass_local_state { }; +struct v3_swap_dev { + uint8_t present; + + struct v3_swap_ops * ops; + + void * private_data; +}; + + +struct swapbypass_vm_state { + struct v3_swap_dev devs[256]; + +#ifdef CONFIG_SWAPBYPASS_TELEMETRY + uint32_t read_faults; + uint32_t write_faults; + uint32_t flushes; + uint32_t mapped_pages; + uint32_t list_size; +#endif + + // shadow pointers + struct hashtable * shdw_ptr_ht; +}; + + + + +static uint_t swap_hash_fn(addr_t key) { + return v3_hash_long(key, 32); +} + + +static int swap_eq_fn(addr_t key1, addr_t key2) { + return (key1 == key2); +} + + + +static inline uint32_t get_pg_index(pte32_t * pte) { + return ((struct swap_pte *)pte)->pg_index; +} + + +static inline uint32_t get_dev_index(pte32_t * pte) { + return ((struct swap_pte *)pte)->dev_index; +} + + +// Present = 0 and Dirty = 0 +// fixme +static inline int is_swapped_pte32(pte32_t * pte) { + return ((pte->present == 0) && (*(uint32_t *)pte != 0)); +} + + + static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core); + +#ifdef CONFIG_SWAPBYPASS_TELEMETRY +static void telemetry_cb(struct v3_vm_info * vm, void * private_data, char * hdr) { + struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data); + + V3_Print("%sSymbiotic Swap:\n", hdr); + V3_Print("%s\tRead faults=%d\n", hdr, swap_state->read_faults); + V3_Print("%s\tWrite faults=%d\n", hdr, swap_state->write_faults); + V3_Print("%s\tMapped Pages=%d\n", hdr, swap_state->mapped_pages); + V3_Print("%s\tFlushes=%d\n", hdr, swap_state->flushes); + V3_Print("%s\tlist size=%d\n", hdr, swap_state->list_size); +} +#endif + + + + + + + + + +static int get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms) { + uint64_t pte_val = (uint64_t)*(uint32_t *)guest_pte; + + // symcall to check if page is in cache or on swap disk + if (v3_sym_call3(info, SYMCALL_MEM_LOOKUP, (uint64_t *)&vaddr, (uint64_t *)&pte_val, (uint64_t *)page_perms) == -1) { + PrintError("Sym call error?? that's weird... \n"); + return -1; + } + + // V3_Print("page perms = %x\n", *(uint32_t *)page_perms); + + if (vaddr == 0) { + return 1; + } + + return 0; +} + + +static addr_t get_swapped_pg_addr(struct v3_vm_info * vm, pte32_t * guest_pte) { + struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data); + int dev_index = get_dev_index(guest_pte); + struct v3_swap_dev * swp_dev = &(swap_state->devs[dev_index]); + + + if (! swp_dev->present ) { + return 0; + } + + return (addr_t)swp_dev->ops->get_swap_entry(get_pg_index(guest_pte), swp_dev->private_data); +} + + + +static addr_t map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr) { + struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data); + struct list_head * shdw_ptr_list = NULL; + struct shadow_pointer * shdw_ptr = NULL; + + + + if (swp_page_ptr == NULL) { + // PrintError("Swapped out page not found on swap device\n"); + return 0; + } + + shdw_ptr_list = (struct list_head *)v3_htable_search(swap_state->shdw_ptr_ht, (addr_t)*(uint32_t *)guest_pte); + + if (shdw_ptr_list == NULL) { + shdw_ptr_list = (struct list_head *)V3_Malloc(sizeof(struct list_head *)); +#ifdef CONFIG_SWAPBYPASS_TELEMETRY + swap_state->list_size++; +#endif + INIT_LIST_HEAD(shdw_ptr_list); + v3_htable_insert(swap_state->shdw_ptr_ht, (addr_t)*(uint32_t *)guest_pte, (addr_t)shdw_ptr_list); + } + + shdw_ptr = (struct shadow_pointer *)V3_Malloc(sizeof(struct shadow_pointer)); + + if (shdw_ptr == NULL) { + PrintError("MEMORY LEAK\n"); +#ifdef CONFIG_SWAPBYPASS_TELEMETRY + telemetry_cb(vm, NULL, ""); +#endif + return 0; + } + + shdw_ptr->shadow_pte = shadow_pte; + shdw_ptr->guest_pte = *(uint32_t *)guest_pte; + shdw_ptr->pg_index = get_pg_index(guest_pte); + shdw_ptr->dev_index = get_dev_index(guest_pte); + + // We don't check for conflicts, because it should not happen... + list_add(&(shdw_ptr->node), shdw_ptr_list); + + return PAGE_BASE_ADDR((addr_t)V3_PAddr(swp_page_ptr)); +} + + + + + #include "vmm_shdw_pg_swapbypass_32.h" #include "vmm_shdw_pg_swapbypass_32pae.h" #include "vmm_shdw_pg_swapbypass_64.h" @@ -92,9 +289,121 @@ static struct shadow_page_data * create_new_shadow_pt(struct guest_info * core) + + + +int v3_register_swap_disk(struct v3_vm_info * vm, int dev_index, + struct v3_swap_ops * ops, void * private_data) { + struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data); + + swap_state->devs[dev_index].present = 1; + swap_state->devs[dev_index].private_data = private_data; + swap_state->devs[dev_index].ops = ops; + + return 0; +} + + + + +int v3_swap_in_notify(struct v3_vm_info * vm, int pg_index, int dev_index) { + struct list_head * shdw_ptr_list = NULL; + struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data); + struct shadow_pointer * tmp_shdw_ptr = NULL; + struct shadow_pointer * shdw_ptr = NULL; + struct swap_pte guest_pte = {0, dev_index, pg_index}; + + shdw_ptr_list = (struct list_head * )v3_htable_search(swap_state->shdw_ptr_ht, *(addr_t *)&(guest_pte)); + + if (shdw_ptr_list == NULL) { + return 0; + } + + list_for_each_entry_safe(shdw_ptr, tmp_shdw_ptr, shdw_ptr_list, node) { + if ((shdw_ptr->pg_index == pg_index) && + (shdw_ptr->dev_index == dev_index)) { + + // Trigger faults for next shadow access + shdw_ptr->shadow_pte->present = 0; + + // Delete entry from list + list_del(&(shdw_ptr->node)); + V3_Free(shdw_ptr); + } + } + + return 0; +} + + + +int v3_swap_flush(struct v3_vm_info * vm) { + struct swapbypass_vm_state * swap_state = (struct swapbypass_vm_state *)(vm->shdw_impl.impl_data); + struct hashtable_iter * ht_iter = v3_create_htable_iter(swap_state->shdw_ptr_ht); + + // PrintDebug("Flushing Symbiotic Swap table\n"); + +#ifdef CONFIG_SWAPBYPASS_TELEMETRY + swap_state->flushes++; +#endif + + if (!ht_iter) { + PrintError("NULL iterator in swap flush!! Probably will crash soon...\n"); + } + + while (ht_iter->entry) { + struct shadow_pointer * tmp_shdw_ptr = NULL; + struct shadow_pointer * shdw_ptr = NULL; + struct list_head * shdw_ptr_list = (struct list_head *)v3_htable_get_iter_value(ht_iter); + + // delete all swapped entries + // we can leave the list_head structures and reuse them for the next round + + list_for_each_entry_safe(shdw_ptr, tmp_shdw_ptr, shdw_ptr_list, node) { + if (shdw_ptr == NULL) { + PrintError("Null shadow pointer in swap flush!! Probably crashing soon...\n"); + } + + // Trigger faults for next shadow access + shdw_ptr->shadow_pte->present = 0; + + // Delete entry from list + list_del(&(shdw_ptr->node)); + V3_Free(shdw_ptr); + } + + v3_htable_iter_advance(ht_iter); + } + + V3_Free(ht_iter); + + return 0; +} + + + + + + + static int sb_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { + struct v3_shdw_impl_state * impl_state = &(vm->shdw_impl); + struct swapbypass_vm_state * sb_state = NULL; + + memset(sb_state, 0, sizeof(struct swapbypass_vm_state)); + sb_state->shdw_ptr_ht = v3_create_htable(0, swap_hash_fn, swap_eq_fn); + +#ifdef CONFIG_SWAPBYPASS_TELEMETRY + if (vm->enable_telemetry) { + v3_add_telemetry_cb(vm, telemetry_cb, NULL); + } +#endif + + impl_state->impl_data = sb_state; + + PrintDebug("Initialized SwapBypass\n"); + - V3_Print("SWAPBYPASS initialization\n"); return 0; } @@ -108,7 +417,6 @@ static int sb_local_init(struct guest_info * core) { V3_Print("SWAPBYPASS local initialization\n"); - swapbypass_state = (struct swapbypass_local_state *)V3_Malloc(sizeof(struct swapbypass_local_state)); INIT_LIST_HEAD(&(swapbypass_state->page_list)); diff --git a/palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h b/palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h index e3d2460..7a0ea14 100644 --- a/palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h +++ b/palacios/src/palacios/vmm_shdw_pg_swapbypass_32.h @@ -250,7 +250,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault #endif - swp_pg_addr = v3_get_swapped_pg_addr(info->vm_info, guest_pte); + swp_pg_addr = get_swapped_pg_addr(info->vm_info, guest_pte); if (swp_pg_addr != 0) { PrintDebug("Swapped page address=%p\n", (void *)swp_pg_addr); @@ -262,7 +262,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault } */ - int sym_ret = v3_get_vaddr_perms(info, fault_addr, guest_pte, &swap_perms); + int sym_ret = get_vaddr_perms(info, fault_addr, guest_pte, &swap_perms); if (sym_ret == -1) { PrintError("Symcall error...\n"); @@ -285,7 +285,7 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault (error_code.user == 0) ) ) { addr_t swp_pg_pa = 0; - swp_pg_pa = v3_map_swp_page(info->vm_info, shadow_pte, guest_pte, (void *)swp_pg_addr); + swp_pg_pa = map_swp_page(info->vm_info, shadow_pte, guest_pte, (void *)swp_pg_addr); PrintDebug("Page fault on swapped out page (vaddr=%p) (pte=%x) (error_code=%x)\n", (void *)fault_addr, *(uint32_t *)guest_pte, *(uint32_t *)&error_code); diff --git a/palacios/src/palacios/vmm_sym_swap.c b/palacios/src/palacios/vmm_sym_swap.c deleted file mode 100644 index 72a8b43..0000000 --- a/palacios/src/palacios/vmm_sym_swap.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 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". - */ -#include - - -#include -#include -#include - -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY -#include -#endif - -// This is a hack and 32 bit linux specific.... need to fix... -struct swap_pte { - uint32_t present : 1; - uint32_t dev_index : 8; - uint32_t pg_index : 23; -}; - - -struct shadow_pointer { - uint32_t pg_index; - uint32_t dev_index; - - pte32_t * shadow_pte; - - addr_t guest_pte; - - struct list_head node; -}; - - -static uint_t swap_hash_fn(addr_t key) { - return v3_hash_long(key, 32); -} - - -static int swap_eq_fn(addr_t key1, addr_t key2) { - return (key1 == key2); -} - - - -static inline uint32_t get_pg_index(pte32_t * pte) { - return ((struct swap_pte *)pte)->pg_index; -} - - -static inline uint32_t get_dev_index(pte32_t * pte) { - return ((struct swap_pte *)pte)->dev_index; -} - - - -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY -static void telemetry_cb(struct v3_vm_info * vm, void * private_data, char * hdr) { - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - - V3_Print("%sSymbiotic Swap:\n", hdr); - V3_Print("%s\tRead faults=%d\n", hdr, swap_state->read_faults); - V3_Print("%s\tWrite faults=%d\n", hdr, swap_state->write_faults); - V3_Print("%s\tMapped Pages=%d\n", hdr, swap_state->mapped_pages); - V3_Print("%s\tFlushes=%d\n", hdr, swap_state->flushes); - V3_Print("%s\tlist size=%d\n", hdr, swap_state->list_size); -} -#endif - - -int v3_init_sym_swap(struct v3_vm_info * vm) { - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - - memset(swap_state, 0, sizeof(struct v3_sym_swap_state)); - swap_state->shdw_ptr_ht = v3_create_htable(0, swap_hash_fn, swap_eq_fn); - -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY - if (vm->enable_telemetry) { - v3_add_telemetry_cb(vm, telemetry_cb, NULL); - } -#endif - - PrintDebug("Initialized Symbiotic Swap\n"); - - return 0; -} - - -int v3_register_swap_disk(struct v3_vm_info * vm, int dev_index, - struct v3_swap_ops * ops, void * private_data) { - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - - swap_state->devs[dev_index].present = 1; - swap_state->devs[dev_index].private_data = private_data; - swap_state->devs[dev_index].ops = ops; - - return 0; -} - - - - -int v3_swap_in_notify(struct v3_vm_info * vm, int pg_index, int dev_index) { - struct list_head * shdw_ptr_list = NULL; - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - struct shadow_pointer * tmp_shdw_ptr = NULL; - struct shadow_pointer * shdw_ptr = NULL; - struct swap_pte guest_pte = {0, dev_index, pg_index}; - - shdw_ptr_list = (struct list_head * )v3_htable_search(swap_state->shdw_ptr_ht, *(addr_t *)&(guest_pte)); - - if (shdw_ptr_list == NULL) { - return 0; - } - - list_for_each_entry_safe(shdw_ptr, tmp_shdw_ptr, shdw_ptr_list, node) { - if ((shdw_ptr->pg_index == pg_index) && - (shdw_ptr->dev_index == dev_index)) { - - // Trigger faults for next shadow access - shdw_ptr->shadow_pte->present = 0; - - // Delete entry from list - list_del(&(shdw_ptr->node)); - V3_Free(shdw_ptr); - } - } - - return 0; -} - - - -int v3_swap_flush(struct v3_vm_info * vm) { - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - struct hashtable_iter * ht_iter = v3_create_htable_iter(swap_state->shdw_ptr_ht); - - // PrintDebug("Flushing Symbiotic Swap table\n"); - -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY - swap_state->flushes++; -#endif - - if (!ht_iter) { - PrintError("NULL iterator in swap flush!! Probably will crash soon...\n"); - } - - while (ht_iter->entry) { - struct shadow_pointer * tmp_shdw_ptr = NULL; - struct shadow_pointer * shdw_ptr = NULL; - struct list_head * shdw_ptr_list = (struct list_head *)v3_htable_get_iter_value(ht_iter); - - // delete all swapped entries - // we can leave the list_head structures and reuse them for the next round - - list_for_each_entry_safe(shdw_ptr, tmp_shdw_ptr, shdw_ptr_list, node) { - if (shdw_ptr == NULL) { - PrintError("Null shadow pointer in swap flush!! Probably crashing soon...\n"); - } - - // Trigger faults for next shadow access - shdw_ptr->shadow_pte->present = 0; - - // Delete entry from list - list_del(&(shdw_ptr->node)); - V3_Free(shdw_ptr); - } - - v3_htable_iter_advance(ht_iter); - } - - V3_Free(ht_iter); - - return 0; -} - -int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms) { - uint64_t pte_val = (uint64_t)*(uint32_t *)guest_pte; - - // symcall to check if page is in cache or on swap disk - if (v3_sym_call3(info, SYMCALL_MEM_LOOKUP, (uint64_t *)&vaddr, (uint64_t *)&pte_val, (uint64_t *)page_perms) == -1) { - PrintError("Sym call error?? that's weird... \n"); - return -1; - } - - // V3_Print("page perms = %x\n", *(uint32_t *)page_perms); - - if (vaddr == 0) { - return 1; - } - - return 0; -} - - - -addr_t v3_get_swapped_pg_addr(struct v3_vm_info * vm, pte32_t * guest_pte) { - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - int dev_index = get_dev_index(guest_pte); - struct v3_swap_dev * swp_dev = &(swap_state->devs[dev_index]); - - - if (! swp_dev->present ) { - return 0; - } - - return (addr_t)swp_dev->ops->get_swap_entry(get_pg_index(guest_pte), swp_dev->private_data); -} - - -addr_t v3_map_swp_page(struct v3_vm_info * vm, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr) { - struct list_head * shdw_ptr_list = NULL; - struct v3_sym_swap_state * swap_state = &(vm->swap_state); - struct shadow_pointer * shdw_ptr = NULL; - - - - if (swp_page_ptr == NULL) { - // PrintError("Swapped out page not found on swap device\n"); - return 0; - } - - shdw_ptr_list = (struct list_head *)v3_htable_search(swap_state->shdw_ptr_ht, (addr_t)*(uint32_t *)guest_pte); - - if (shdw_ptr_list == NULL) { - shdw_ptr_list = (struct list_head *)V3_Malloc(sizeof(struct list_head *)); -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY - swap_state->list_size++; -#endif - INIT_LIST_HEAD(shdw_ptr_list); - v3_htable_insert(swap_state->shdw_ptr_ht, (addr_t)*(uint32_t *)guest_pte, (addr_t)shdw_ptr_list); - } - - shdw_ptr = (struct shadow_pointer *)V3_Malloc(sizeof(struct shadow_pointer)); - - if (shdw_ptr == NULL) { - PrintError("MEMORY LEAK\n"); -#ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY - telemetry_cb(vm, NULL, ""); -#endif - return 0; - } - - shdw_ptr->shadow_pte = shadow_pte; - shdw_ptr->guest_pte = *(uint32_t *)guest_pte; - shdw_ptr->pg_index = get_pg_index(guest_pte); - shdw_ptr->dev_index = get_dev_index(guest_pte); - - // We don't check for conflicts, because it should not happen... - list_add(&(shdw_ptr->node), shdw_ptr_list); - - return PAGE_BASE_ADDR((addr_t)V3_PAddr(swp_page_ptr)); -} - - - -/* -int v3_is_mapped_fault(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte) { - struct list_head * shdw_ptr_list = NULL; - - shdw_ptr_list = (struct list_head * )v3_htable_search(swap_state->shdw_ptr_ht, *(addr_t *)&(guest_pte)); - - - if (shdw_ptr_list != NULL) { - PrintError("We faulted on a mapped in page....\n"); - return -1; - } - - return 0; -} - - -*/