xref: /kvmtool/guest_compat.c (revision 572d69b1a85d3dbdd0798048f2e2ed1828c2316e)
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 
20e6694207SSasha Levin int compat__add_message(const char *title, const char *desc)
21e6694207SSasha Levin {
22e6694207SSasha Levin 	struct compat_message *msg;
23e6694207SSasha Levin 
24e6694207SSasha Levin 	msg = malloc(sizeof(*msg));
25e6694207SSasha Levin 	if (msg == NULL)
26e6694207SSasha Levin 		goto cleanup;
27e6694207SSasha Levin 
28*572d69b1SLai Jiangshan 	msg->title = strdup(title);
29*572d69b1SLai Jiangshan 	msg->desc = strdup(desc);
30e6694207SSasha Levin 
31e6694207SSasha Levin 	if (msg->title == NULL || msg->desc == NULL)
32e6694207SSasha Levin 		goto cleanup;
33e6694207SSasha Levin 
34*572d69b1SLai Jiangshan 	mutex_lock(&compat_mtx);
35*572d69b1SLai Jiangshan 
36*572d69b1SLai Jiangshan 	msg->id = id;
37e6694207SSasha Levin 	list_add_tail(&msg->list, &messages);
38e6694207SSasha Levin 
39e6694207SSasha Levin 	mutex_unlock(&compat_mtx);
40e6694207SSasha Levin 
41e6694207SSasha Levin 	return id++;
42e6694207SSasha Levin 
43e6694207SSasha Levin cleanup:
44e6694207SSasha Levin 	if (msg) {
45e6694207SSasha Levin 		free(msg->title);
46e6694207SSasha Levin 		free(msg->desc);
47e6694207SSasha Levin 		free(msg);
48e6694207SSasha Levin 	}
49e6694207SSasha Levin 
50e6694207SSasha Levin 	return -ENOMEM;
51e6694207SSasha Levin }
52e6694207SSasha Levin 
53e6694207SSasha Levin static void compat__free(struct compat_message *msg)
54e6694207SSasha Levin {
55e6694207SSasha Levin 	free(msg->title);
56e6694207SSasha Levin 	free(msg->desc);
57e6694207SSasha Levin 	free(msg);
58e6694207SSasha Levin }
59e6694207SSasha Levin 
60e6694207SSasha Levin int compat__remove_message(int id)
61e6694207SSasha Levin {
62e6694207SSasha Levin 	struct compat_message *pos, *n;
63e6694207SSasha Levin 
64e6694207SSasha Levin 	mutex_lock(&compat_mtx);
65e6694207SSasha Levin 
66e6694207SSasha Levin 	list_for_each_entry_safe(pos, n, &messages, list) {
67e6694207SSasha Levin 		if (pos->id == id) {
68e6694207SSasha Levin 			list_del(&pos->list);
69e6694207SSasha Levin 			compat__free(pos);
70e6694207SSasha Levin 
71e6694207SSasha Levin 			mutex_unlock(&compat_mtx);
72e6694207SSasha Levin 
73e6694207SSasha Levin 			return 0;
74e6694207SSasha Levin 		}
75e6694207SSasha Levin 	}
76e6694207SSasha Levin 
77e6694207SSasha Levin 	mutex_unlock(&compat_mtx);
78e6694207SSasha Levin 
79e6694207SSasha Levin 	return -ENOENT;
80e6694207SSasha Levin }
81e6694207SSasha Levin 
82e6694207SSasha Levin int compat__print_all_messages(void)
83e6694207SSasha Levin {
84e6694207SSasha Levin 	mutex_lock(&compat_mtx);
85e6694207SSasha Levin 
86e6694207SSasha Levin 	while (!list_empty(&messages)) {
87e6694207SSasha Levin 		struct compat_message *msg;
88e6694207SSasha Levin 
89e6694207SSasha Levin 		msg = list_first_entry(&messages, struct compat_message, list);
90e6694207SSasha Levin 
910026c9d4SSasha Levin 		printf("\n\n*** Compatibility Warning ***\n\n\t%s\n\n%s\n",
92e6694207SSasha Levin 			msg->title, msg->desc);
93e6694207SSasha Levin 
94e6694207SSasha Levin 		list_del(&msg->list);
95e6694207SSasha Levin 		compat__free(msg);
96e6694207SSasha Levin 	}
97e6694207SSasha Levin 
98e6694207SSasha Levin 	mutex_unlock(&compat_mtx);
99e6694207SSasha Levin 
100e6694207SSasha Levin 	return 0;
101e6694207SSasha Levin }
102