2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2012, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
22 #include <palacios/vmm_events.h>
23 #include <palacios/vm_guest.h>
27 int v3_init_events(struct v3_vm_info * vm) {
28 struct v3_event_map * map = &(vm->event_map);
31 map->events = V3_Malloc(sizeof(struct list_head) * V3_EVENT_INVALID);
33 if (map->events == NULL) {
34 PrintError("Error: could not allocate event map\n");
38 for (i = 0; i < V3_EVENT_INVALID; i++) {
39 INIT_LIST_HEAD(&(map->events[i]));
45 int v3_deinit_events(struct v3_vm_info * vm) {
46 struct v3_event_map * map = &(vm->event_map);
49 for (i = 0; i < V3_EVENT_INVALID; i++) {
50 if (!list_empty(&(map->events[i]))) {
51 struct v3_notifier * tmp_notifier = NULL;
52 struct v3_notifier * safe_notifier = NULL;
53 PrintError("Found orphan notifier for event %d. Probable memory leak detected.\n", i);
55 list_for_each_entry_safe(tmp_notifier, safe_notifier, &(map->events[i]), node) {
56 list_del(&(tmp_notifier->node));
57 V3_Free(tmp_notifier);
70 struct v3_notifier * v3_subscribe_event(struct v3_vm_info * vm,
71 v3_event_type_t event_type,
72 void (*notify)(struct guest_info * core,
73 v3_event_type_t event_type,
77 struct guest_info * current_core) {
78 struct v3_event_map * map = &(vm->event_map);
79 struct v3_notifier * notifier = NULL;
81 if (event_type >= V3_EVENT_INVALID) {
82 PrintError("Tried to request illegal event (%d)\n", event_type);
86 notifier = V3_Malloc(sizeof(struct v3_notifier));
88 if (notifier == NULL) {
89 PrintError("Error: Could not allocate notifier\n");
93 memset(notifier, 0, sizeof(struct v3_notifier));
95 notifier->notify = notify;
96 notifier->priv_data = priv_data;
97 notifier->event_type = event_type;
99 if ((vm->run_state == VM_RUNNING) ||
100 (vm->run_state == VM_SIMULATING)) {
101 while (v3_raise_barrier(vm, current_core) == -1);
102 list_add(&(notifier->node), &(map->events[event_type]));
103 v3_lower_barrier(vm);
105 // No need to lock the list
106 list_add(&(notifier->node), &(map->events[event_type]));
113 int v3_unsubscribe_event(struct v3_vm_info * vm, struct v3_notifier * notifier,
114 struct guest_info * current_core) {
115 struct v3_event_map * map = &(vm->event_map);
116 struct v3_notifier * tmp_notifier = NULL;
117 struct v3_notifier * safe_notifier = NULL;
119 if (notifier == NULL) {
120 PrintError("Could not unsubscribe invalid event notifier\n");
124 if (notifier->event_type >= V3_EVENT_INVALID) {
125 PrintError("Could not unsubscribe from invalid event\n");
129 if ((vm->run_state == VM_RUNNING) ||
130 (vm->run_state == VM_SIMULATING)) {
131 while (v3_raise_barrier(vm, current_core) == -1);
135 list_for_each_entry_safe(tmp_notifier, safe_notifier, &(map->events[notifier->event_type]), node) {
136 if (tmp_notifier == notifier) {
137 list_del(&(tmp_notifier->node));
138 V3_Free(tmp_notifier);
143 if ((vm->run_state == VM_RUNNING) ||
144 (vm->run_state == VM_SIMULATING)) {
145 v3_lower_barrier(vm);