xref: /kvmtool/util/init.c (revision a24ecd1fca4263f0ce79dcbcdafd30032d334b9d)
150cb6dc9SSasha Levin #include <linux/list.h>
250cb6dc9SSasha Levin #include <linux/kernel.h>
350cb6dc9SSasha Levin 
450cb6dc9SSasha Levin #include "kvm/kvm.h"
550cb6dc9SSasha Levin #include "kvm/util-init.h"
650cb6dc9SSasha Levin 
750cb6dc9SSasha Levin #define PRIORITY_LISTS 10
850cb6dc9SSasha Levin 
950cb6dc9SSasha Levin static struct hlist_head init_lists[PRIORITY_LISTS];
1050cb6dc9SSasha Levin static struct hlist_head exit_lists[PRIORITY_LISTS];
1150cb6dc9SSasha Levin 
init_list_add(struct init_item * t,int (* init)(struct kvm *),int priority,const char * name)1250cb6dc9SSasha Levin int init_list_add(struct init_item *t, int (*init)(struct kvm *),
1350cb6dc9SSasha Levin 			int priority, const char *name)
1450cb6dc9SSasha Levin {
1550cb6dc9SSasha Levin 	t->init = init;
1650cb6dc9SSasha Levin 	t->fn_name = name;
1750cb6dc9SSasha Levin 	hlist_add_head(&t->n, &init_lists[priority]);
1850cb6dc9SSasha Levin 
1950cb6dc9SSasha Levin 	return 0;
2050cb6dc9SSasha Levin }
2150cb6dc9SSasha Levin 
exit_list_add(struct init_item * t,int (* init)(struct kvm *),int priority,const char * name)2250cb6dc9SSasha Levin int exit_list_add(struct init_item *t, int (*init)(struct kvm *),
2350cb6dc9SSasha Levin 			int priority, const char *name)
2450cb6dc9SSasha Levin {
2550cb6dc9SSasha Levin 	t->init = init;
2650cb6dc9SSasha Levin 	t->fn_name = name;
2750cb6dc9SSasha Levin 	hlist_add_head(&t->n, &exit_lists[priority]);
2850cb6dc9SSasha Levin 
2950cb6dc9SSasha Levin 	return 0;
3050cb6dc9SSasha Levin }
3150cb6dc9SSasha Levin 
init_list__init(struct kvm * kvm)3250cb6dc9SSasha Levin int init_list__init(struct kvm *kvm)
3350cb6dc9SSasha Levin {
3450cb6dc9SSasha Levin 	unsigned int i;
3550cb6dc9SSasha Levin 	int r = 0;
3650cb6dc9SSasha Levin 	struct init_item *t;
3750cb6dc9SSasha Levin 
3850cb6dc9SSasha Levin 	for (i = 0; i < ARRAY_SIZE(init_lists); i++)
39*a24ecd1fSMarc Zyngier 		hlist_for_each_entry(t, &init_lists[i], n) {
4050cb6dc9SSasha Levin 			r = t->init(kvm);
4150cb6dc9SSasha Levin 			if (r < 0) {
4250cb6dc9SSasha Levin 				pr_warning("Failed init: %s\n", t->fn_name);
4350cb6dc9SSasha Levin 				goto fail;
4450cb6dc9SSasha Levin 			}
4550cb6dc9SSasha Levin 		}
4650cb6dc9SSasha Levin 
4750cb6dc9SSasha Levin fail:
4850cb6dc9SSasha Levin 	return r;
4950cb6dc9SSasha Levin }
5050cb6dc9SSasha Levin 
init_list__exit(struct kvm * kvm)5150cb6dc9SSasha Levin int init_list__exit(struct kvm *kvm)
5250cb6dc9SSasha Levin {
5350cb6dc9SSasha Levin 	int i;
5450cb6dc9SSasha Levin 	int r = 0;
5550cb6dc9SSasha Levin 	struct init_item *t;
5650cb6dc9SSasha Levin 
5750cb6dc9SSasha Levin 	for (i = ARRAY_SIZE(exit_lists) - 1; i >= 0; i--)
58*a24ecd1fSMarc Zyngier 		hlist_for_each_entry(t, &exit_lists[i], n) {
5950cb6dc9SSasha Levin 			r = t->init(kvm);
6050cb6dc9SSasha Levin 			if (r < 0) {
6150cb6dc9SSasha Levin 				pr_warning("%s failed.\n", t->fn_name);
6250cb6dc9SSasha Levin 				goto fail;
6350cb6dc9SSasha Levin 			}
6450cb6dc9SSasha Levin 		}
6550cb6dc9SSasha Levin fail:
6650cb6dc9SSasha Levin 	return r;
6750cb6dc9SSasha Levin }
68