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