1 #include <linux/list.h> 2 #include <linux/kernel.h> 3 4 #include "kvm/kvm.h" 5 #include "kvm/util-init.h" 6 7 #define PRIORITY_LISTS 10 8 9 static struct hlist_head init_lists[PRIORITY_LISTS]; 10 static struct hlist_head exit_lists[PRIORITY_LISTS]; 11 12 int init_list_add(struct init_item *t, int (*init)(struct kvm *), 13 int priority, const char *name) 14 { 15 t->init = init; 16 t->fn_name = name; 17 hlist_add_head(&t->n, &init_lists[priority]); 18 19 return 0; 20 } 21 22 int exit_list_add(struct init_item *t, int (*init)(struct kvm *), 23 int priority, const char *name) 24 { 25 t->init = init; 26 t->fn_name = name; 27 hlist_add_head(&t->n, &exit_lists[priority]); 28 29 return 0; 30 } 31 32 int init_list__init(struct kvm *kvm) 33 { 34 unsigned int i; 35 int r = 0; 36 struct hlist_node *n; 37 struct init_item *t; 38 39 for (i = 0; i < ARRAY_SIZE(init_lists); i++) 40 hlist_for_each_entry(t, n, &init_lists[i], n) { 41 r = t->init(kvm); 42 if (r < 0) { 43 pr_warning("Failed init: %s\n", t->fn_name); 44 goto fail; 45 } 46 } 47 48 fail: 49 return r; 50 } 51 52 int init_list__exit(struct kvm *kvm) 53 { 54 int i; 55 int r = 0; 56 struct hlist_node *n; 57 struct init_item *t; 58 59 for (i = ARRAY_SIZE(exit_lists) - 1; i >= 0; i--) 60 hlist_for_each_entry(t, n, &exit_lists[i], n) { 61 r = t->init(kvm); 62 if (r < 0) { 63 pr_warning("%s failed.\n", t->fn_name); 64 goto fail; 65 } 66 } 67 fail: 68 return r; 69 } 70