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