xref: /kvmtool/guest_compat.c (revision 72e13944777a6c60fbcd78ef97e06ffd00969d77)
1 #include "kvm/guest_compat.h"
2 
3 #include "kvm/mutex.h"
4 
5 #include <linux/kernel.h>
6 #include <linux/list.h>
7 
8 struct compat_message {
9 	int id;
10 	char *title;
11 	char *desc;
12 
13 	struct list_head list;
14 };
15 
16 static int id;
17 static DEFINE_MUTEX(compat_mtx);
18 static LIST_HEAD(messages);
19 
compat__free(struct compat_message * msg)20 static void compat__free(struct compat_message *msg)
21 {
22 	free(msg->title);
23 	free(msg->desc);
24 	free(msg);
25 }
26 
compat__add_message(const char * title,const char * desc)27 int compat__add_message(const char *title, const char *desc)
28 {
29 	struct compat_message *msg;
30 	int msg_id;
31 
32 	msg = malloc(sizeof(*msg));
33 	if (msg == NULL)
34 		goto cleanup;
35 
36 	msg->title = strdup(title);
37 	msg->desc = strdup(desc);
38 
39 	if (msg->title == NULL || msg->desc == NULL)
40 		goto cleanup;
41 
42 	mutex_lock(&compat_mtx);
43 
44 	msg->id = msg_id = id++;
45 	list_add_tail(&msg->list, &messages);
46 
47 	mutex_unlock(&compat_mtx);
48 
49 	return msg_id;
50 
51 cleanup:
52 	if (msg)
53 		compat__free(msg);
54 
55 	return -ENOMEM;
56 }
57 
compat__remove_message(int id)58 int compat__remove_message(int id)
59 {
60 	struct compat_message *pos, *n;
61 
62 	mutex_lock(&compat_mtx);
63 
64 	list_for_each_entry_safe(pos, n, &messages, list) {
65 		if (pos->id == id) {
66 			list_del(&pos->list);
67 			compat__free(pos);
68 
69 			mutex_unlock(&compat_mtx);
70 
71 			return 0;
72 		}
73 	}
74 
75 	mutex_unlock(&compat_mtx);
76 
77 	return -ENOENT;
78 }
79 
compat__print_all_messages(void)80 int compat__print_all_messages(void)
81 {
82 	mutex_lock(&compat_mtx);
83 
84 	while (!list_empty(&messages)) {
85 		struct compat_message *msg;
86 
87 		msg = list_first_entry(&messages, struct compat_message, list);
88 
89 		pr_warning("KVM compatibility warning.\n\t%s\n\t%s",
90 			msg->title, msg->desc);
91 
92 		list_del(&msg->list);
93 		compat__free(msg);
94 	}
95 
96 	mutex_unlock(&compat_mtx);
97 
98 	return 0;
99 }
100