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
compat__free(struct compat_message * msg)20b24e316aSLai Jiangshan static void compat__free(struct compat_message *msg)
21b24e316aSLai Jiangshan {
22b24e316aSLai Jiangshan free(msg->title);
23b24e316aSLai Jiangshan free(msg->desc);
24b24e316aSLai Jiangshan free(msg);
25b24e316aSLai Jiangshan }
26b24e316aSLai Jiangshan
compat__add_message(const char * title,const char * desc)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:
52b24e316aSLai Jiangshan if (msg)
53b24e316aSLai Jiangshan compat__free(msg);
54e6694207SSasha Levin
55e6694207SSasha Levin return -ENOMEM;
56e6694207SSasha Levin }
57e6694207SSasha Levin
compat__remove_message(int id)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
compat__print_all_messages(void)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
89*72e13944SAlexandru Elisei pr_warning("KVM compatibility warning.\n\t%s\n\t%s",
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