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