From: Jack Lange Date: Thu, 26 Jul 2012 20:36:25 +0000 (-0400) Subject: added event hooking framework X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=e8069ad305c7b50fefb0cc602d9ca53324e6cc9e;hp=3848474666fa030031e14b9fdea4caf886e034ca;p=palacios.git added event hooking framework --- diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 9cee679..9e6ea21 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -40,7 +40,7 @@ #include #include #include - +#include #ifdef V3_CONFIG_TELEMETRY #include @@ -162,6 +162,7 @@ struct v3_vm_info { struct v3_msr_map msr_map; struct v3_cpuid_map cpuid_map; struct v3_exit_map exit_map; + struct v3_event_map event_map; v3_hypercall_map_t hcall_map; diff --git a/palacios/include/palacios/vmm_events.h b/palacios/include/palacios/vmm_events.h new file mode 100644 index 0000000..477ff67 --- /dev/null +++ b/palacios/include/palacios/vmm_events.h @@ -0,0 +1,99 @@ +/* + * 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) 2012, Jack Lange + * Copyright (c) 2012, 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_EVENTS_H__ +#define __VMM_EVENTS_H__ + +#ifdef __V3VEE__ + +#include +#include + +struct guest_info; +struct v3_vm_info; + +typedef enum { + V3_EVENT_INVALID /* This entry must always be last */ +} v3_event_type_t; + + +struct v3_event_map { + struct list_head * events; // array of events + +}; + + +int v3_init_events(struct v3_vm_info * vm); +int v3_deinit_events(struct v3_vm_info * vm); + + +struct v3_notifier { + + void (*notify)(struct guest_info * core, + v3_event_type_t event_type, + void * priv_data, + void * event_data); + void * priv_data; + + struct list_head node; + +}; + + +int v3_request_event(struct v3_vm_info * vm, + v3_event_type_t event_type, + void (*notify)(struct guest_info * core, + v3_event_type_t event_type, + void * priv_data, + void * event_data), + void * priv_data, + struct guest_info * current_core); + + + +#include + +#ifdef __VM_EVENTS_H2___ /* Just ignore the man behind the curtain.... */ + +static void inline v3_dispatch_event(struct guest_info * core, + v3_event_type_t event_type, + void * event_data) { + struct v3_notifier * tmp_notifier = NULL; + + if (event_type >= V3_EVENT_INVALID) { + PrintError("Tried to dispatch illegal event (%d)\n", event_type); + return; + } + + list_for_each_entry(tmp_notifier, &(core->vm_info->event_map.events[event_type]), node) { + tmp_notifier->notify(core, event_type, tmp_notifier->priv_data, event_data); + } + +} + +#endif +#define __VM_EVENTS_H2___ + + + + + +#endif + +#endif diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index ef6c90e..5cde6ea 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -37,7 +37,8 @@ obj-y := \ vmm_bitmap.o \ vmm_barrier.o \ vmm_timeout.o \ - vmm_exits.o + vmm_exits.o \ + vmm_events.o obj-$(V3_CONFIG_XED) += vmm_xed.o diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index b7b1d7a..3db11ce 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -18,6 +18,7 @@ */ + #include #include @@ -38,6 +39,8 @@ #include #include + + #ifdef V3_CONFIG_CHECKPOINT #include #endif diff --git a/palacios/src/palacios/vm_guest.c b/palacios/src/palacios/vm_guest.c index 365fc62..d94d465 100644 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@ -217,18 +217,18 @@ static int info_hcall(struct guest_info * core, uint_t hcall_id, void * priv_dat int v3_init_vm(struct v3_vm_info * vm) { extern v3_cpu_arch_t v3_mach_type; - + v3_init_events(vm); #ifdef V3_CONFIG_TELEMETRY v3_init_telemetry(vm); #endif + v3_init_exit_hooks(vm); v3_init_hypercall_map(vm); v3_init_io_map(vm); v3_init_msr_map(vm); v3_init_cpuid_map(vm); v3_init_host_events(vm); - v3_init_exit_hooks(vm); v3_init_intr_routers(vm); v3_init_ext_manager(vm); @@ -350,6 +350,7 @@ int v3_free_vm_internal(struct v3_vm_info * vm) { v3_deinit_telemetry(vm); #endif + v3_deinit_events(vm); return 0; diff --git a/palacios/src/palacios/vmm_events.c b/palacios/src/palacios/vmm_events.c new file mode 100644 index 0000000..0c565f2 --- /dev/null +++ b/palacios/src/palacios/vmm_events.c @@ -0,0 +1,107 @@ +/* + * 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) 2012, Jack Lange + * Copyright (c) 2012, 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 + + + +int v3_init_events(struct v3_vm_info * vm) { + struct v3_event_map * map = &(vm->event_map); + int i = 0; + + map->events = V3_Malloc(sizeof(struct list_head) * V3_EVENT_INVALID); + + if (map->events == NULL) { + PrintError("Error: could not allocate event map\n"); + return -1; + } + + for (i = 0; i < V3_EVENT_INVALID; i++) { + INIT_LIST_HEAD(&(map->events[i])); + } + + return 0; +} + +int v3_deinit_events(struct v3_vm_info * vm) { + struct v3_event_map * map = &(vm->event_map); + int i = 0; + + for (i = 0; i < V3_EVENT_INVALID; i++) { + if (!list_empty(&(map->events[i]))) { + struct v3_notifier * tmp_notifier = NULL; + struct v3_notifier * safe_notifier = NULL; + PrintError("Found orphan notifier for event %d. Probable memory leak detected.\n", i); + + list_for_each_entry_safe(tmp_notifier, safe_notifier, &(map->events[i]), node) { + list_del(&(tmp_notifier->node)); + V3_Free(tmp_notifier); + } + } + } + + + V3_Free(map->events); + + return 0; + +} + + +int v3_request_event(struct v3_vm_info * vm, + v3_event_type_t event_type, + void (*notify)(struct guest_info * core, + v3_event_type_t event_type, + void * priv_data, + void * event_data), + void * priv_data, + struct guest_info * current_core) { + struct v3_event_map * map = &(vm->event_map); + struct v3_notifier * notifier = NULL; + + if (event_type >= V3_EVENT_INVALID) { + PrintError("Tried to request illegal event (%d)\n", event_type); + return -1; + } + + + notifier = V3_Malloc(sizeof(struct v3_notifier)); + + if (notifier == NULL) { + PrintError("Error: Could not allocate notifier\n"); + return -1; + } + + memset(notifier, 0, sizeof(struct v3_notifier)); + + notifier->notify = notify; + notifier->priv_data = priv_data; + + while (v3_raise_barrier(vm, current_core) == -1); + list_add(&(notifier->node), &(map->events[event_type])); + v3_lower_barrier(vm); + + + return 0; +} + +