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