From: Peter Dinda Date: Fri, 27 Jun 2014 00:54:50 +0000 (-0500) Subject: Linux front-end for memory tracking interface X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=4a3b35137e700165754d61c4e791c0a8e51c770c;p=palacios.git Linux front-end for memory tracking interface --- diff --git a/linux_module/Makefile b/linux_module/Makefile index b27cf77..8c6c426 100644 --- a/linux_module/Makefile +++ b/linux_module/Makefile @@ -36,6 +36,8 @@ v3vee-$(V3_CONFIG_HOST_DEVICE) += iface-host-dev.o v3vee-$(V3_CONFIG_GRAPHICS_CONSOLE) += iface-graphics-console.o v3vee-$(V3_CONFIG_EXT_MACH_CHECK) += mcheck.o +v3vee-$(V3_CONFIG_MEM_TRACK) += memtrack.o + v3vee-$(V3_CONFIG_HOST_PMU) += iface-pmu.o v3vee-$(V3_CONFIG_HOST_PWRSTAT) += iface-pwrstat.o diff --git a/linux_module/memtrack.c b/linux_module/memtrack.c new file mode 100644 index 0000000..367a473 --- /dev/null +++ b/linux_module/memtrack.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "palacios.h" +#include "memtrack.h" +#include "linux-exts.h" +#include "vm.h" + + +static int memtrack_size(struct v3_guest *guest, + unsigned int ioctl, + unsigned long arg, + void *priv_data) +{ + struct v3_mem_track_sizes size; + + v3_mem_track_get_sizes(guest->v3_ctx,&size.num_cores,&size.num_pages); + + + if (copy_to_user((void __user *)arg, &size, sizeof(struct v3_mem_track_sizes))) { + ERROR("palacios: unable to copy sizes to user\n"); + return -EFAULT; + } + + return 0; + +} + +static int memtrack_cmd(struct v3_guest *guest, + unsigned int ioctl, + unsigned long arg, + void *priv_data) +{ + struct v3_mem_track_cmd cmd; + + if (copy_from_user(&cmd,(void __user *)arg,sizeof(struct v3_mem_track_cmd))) { + ERROR("palacios: unable to copy memory tracking command from user\n"); + return -EFAULT; + } + + if (cmd.request == V3_MEM_TRACK_START) { + if (v3_mem_track_start(guest->v3_ctx, cmd.config.access_type, cmd.config.reset_type, cmd.config.period)) { + ERROR("palacios: unable to start memory tracking\n"); + return -EFAULT; + } + } else if (cmd.request == V3_MEM_TRACK_STOP) { + if (v3_mem_track_stop(guest->v3_ctx)) { + ERROR("palacios: unable to stop memory tracking\n"); + return -EFAULT; + } + } else { + ERROR("palacios: unknown memory tracking request\n"); + return -EFAULT; + } + + return 0; + +} + + +#define MIN(x,y) ( (x) < (y) ? (x) : (y) ) +#define CEIL_DIV(x,y) ( ( (x) / (y) ) + !!( (x) % (y) ) ) + + +static int memtrack_snap(struct v3_guest *guest, + unsigned int ioctl, + unsigned long arg, + void *priv_data) +{ + v3_mem_track_snapshot temp; + struct v3_core_mem_track ctemp; + uint32_t num_cores; + uint32_t i; + uint64_t header_size; + uint64_t core_header_size; + uint64_t offset_to_num_cores; + + v3_mem_track_snapshot *user_snap=0; + v3_mem_track_snapshot *sys_snap=0; + + + offset_to_num_cores = (uint64_t)&(temp.num_cores) - (uint64_t)&temp; + header_size = (uint64_t)&(temp.core[0]) - (uint64_t)&temp; + core_header_size = (uint64_t)&(ctemp.access_bitmap) - (uint64_t)&ctemp; + + INFO("offset_to_num_cores=%llu header_size=%llu core_header_size=%llu\n", + offset_to_num_cores, header_size, core_header_size); + + if (copy_from_user(&num_cores,((void __user *)arg) + offset_to_num_cores,sizeof(num_cores))) { + ERROR("palacios: cannot copy number of cores from user\n"); + goto fail; + } + + INFO("num_cores=%u",num_cores); + + if (!(user_snap=palacios_alloc(sizeof(v3_mem_track_snapshot) + num_cores * sizeof(struct v3_core_mem_track)))) { + ERROR("palacios: cannot allocate memory for copying user snapshot\n"); + goto fail; + } + + if (copy_from_user(user_snap,(void __user *)arg,sizeof(v3_mem_track_snapshot) + num_cores*sizeof(struct v3_core_mem_track))) { + ERROR("palacios: cannot copy user memory track snapshot request\n"); + goto fail; + } + + // Now we have the user's target - note that num_pages and access_bitmap need to be supplied + + if (!(sys_snap=v3_mem_track_take_snapshot(guest->v3_ctx))) { + ERROR("palacios: unable to get snapshot from core\n"); + goto fail; + } + + INFO("snapshot: numcores=%u, core[0].num_pages=%llu, request_numcores=%u\n", + sys_snap->num_cores, sys_snap->core[0].num_pages, num_cores); + + // Copy the meta data + if (copy_to_user((void __user *)arg, sys_snap, header_size)) { + ERROR("palacios: unable to copy meta data\n"); + goto fail; + } + + // Now per core + for (i=0;inum_cores);i++) { + // copy metadata + if (copy_to_user((void __user *)(arg + header_size + i * sizeof(struct v3_core_mem_track)), + &sys_snap->core[i], + core_header_size)) { + ERROR("palacios: unable to copy core meta data\n"); + goto fail; + } + + // copy the bitmap + if (copy_to_user((void __user *) user_snap->core[i].access_bitmap, + sys_snap->core[i].access_bitmap, + CEIL_DIV(MIN(user_snap->core[i].num_pages,sys_snap->core[i].num_pages),8))) { + ERROR("palacios: unable to copy core data\n"); + return -1; + } + } + + v3_mem_track_free_snapshot(sys_snap); + palacios_free(user_snap); + return 0; + + fail: + if (sys_snap) { + v3_mem_track_free_snapshot(sys_snap); + } + if (user_snap) { + palacios_free(user_snap); + } + return -EFAULT; +} + + + + + + + + +static int memtrack_init( void ) +{ + // nothing yet + return 0; +} + + +static int memtrack_deinit( void ) { + + // nothing yet + return 0; +} + + + +static int guest_memtrack_init(struct v3_guest * guest, void ** vm_data) +{ + + add_guest_ctrl(guest, V3_VM_MEM_TRACK_SIZE, memtrack_size, guest); + add_guest_ctrl(guest, V3_VM_MEM_TRACK_CMD, memtrack_cmd, guest); + add_guest_ctrl(guest, V3_VM_MEM_TRACK_SNAP, memtrack_snap, guest); + + return 0; +} + + +static int guest_memtrack_deinit(struct v3_guest * guest, void * vm_data) { + + remove_guest_ctrl(guest,V3_VM_MEM_TRACK_SNAP); + remove_guest_ctrl(guest,V3_VM_MEM_TRACK_CMD); + remove_guest_ctrl(guest, V3_VM_MEM_TRACK_SIZE); + + return 0; +} + + + +static struct linux_ext memtrack_ext = { + .name = "MEMTRACK_EXTENSION", + .init = memtrack_init, + .deinit = memtrack_deinit, + .guest_init = guest_memtrack_init, + .guest_deinit = guest_memtrack_deinit +}; + + +register_extension(&memtrack_ext); diff --git a/linux_module/memtrack.h b/linux_module/memtrack.h new file mode 100644 index 0000000..fa64ebe --- /dev/null +++ b/linux_module/memtrack.h @@ -0,0 +1,31 @@ +/* + * Palacios Memory Tracking Userland Interface + * Copyright (c) 2014 Peter Dinda + */ + +#ifndef __PALACIOS_MEMTRACK_H__ +#define __PALACIOS_MEMTRACK_H__ + +#include + +#define V3_VM_MEM_TRACK_SIZE 300 +#define V3_VM_MEM_TRACK_CMD 301 +#define V3_VM_MEM_TRACK_SNAP 302 + + +// Used to get needed info to allocate requests +struct v3_mem_track_sizes { + uint64_t num_cores; + uint64_t num_pages; +}; + +// These are sent for start and stop requests +struct v3_mem_track_cmd { + enum { V3_MEM_TRACK_START, V3_MEM_TRACK_STOP} request; + struct v3_vm_mem_track config; // for "start" +}; + + +// A snapshot request consists of the v3_mem_track_snapshot to fill out + +#endif diff --git a/linux_module/palacios.h b/linux_module/palacios.h index b4c17e6..3c023ff 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -44,6 +44,10 @@ #define V3_VM_FB_INPUT 257 #define V3_VM_FB_QUERY 258 +#define V3_VM_MEM_TRACK_SIZE 300 +#define V3_VM_MEM_TRACK_CMD 301 +#define V3_VM_MEM_TRACK_SNAP 302 + #define V3_VM_HOST_DEV_CONNECT 10245 #define V3_VM_KSTREAM_USER_CONNECT 11245