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