1 /* 2 * QEMU paravirtual RDMA - Generic RDMA backend 3 * 4 * Copyright (C) 2018 Oracle 5 * Copyright (C) 2018 Red Hat Inc 6 * 7 * Authors: 8 * Yuval Shaia <yuval.shaia@oracle.com> 9 * Marcel Apfelbaum <marcel@redhat.com> 10 * 11 * This work is licensed under the terms of the GNU GPL, version 2 or later. 12 * See the COPYING file in the top-level directory. 13 * 14 */ 15 16 #include "qemu/osdep.h" 17 #include "qapi/qmp/qlist.h" 18 #include "qapi/qmp/qnum.h" 19 #include "trace.h" 20 #include "rdma_utils.h" 21 22 void *rdma_pci_dma_map(PCIDevice *dev, dma_addr_t addr, dma_addr_t plen) 23 { 24 void *p; 25 hwaddr len = plen; 26 27 if (!addr) { 28 rdma_error_report("addr is NULL"); 29 return NULL; 30 } 31 32 p = pci_dma_map(dev, addr, &len, DMA_DIRECTION_TO_DEVICE); 33 if (!p) { 34 rdma_error_report("pci_dma_map fail, addr=0x%"PRIx64", len=%"PRId64, 35 addr, len); 36 return NULL; 37 } 38 39 if (len != plen) { 40 rdma_pci_dma_unmap(dev, p, len); 41 return NULL; 42 } 43 44 trace_rdma_pci_dma_map(addr, p, len); 45 46 return p; 47 } 48 49 void rdma_pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len) 50 { 51 trace_rdma_pci_dma_unmap(buffer); 52 if (buffer) { 53 pci_dma_unmap(dev, buffer, len, DMA_DIRECTION_TO_DEVICE, 0); 54 } 55 } 56 57 void rdma_protected_qlist_init(RdmaProtectedQList *list) 58 { 59 qemu_mutex_init(&list->lock); 60 list->list = qlist_new(); 61 } 62 63 void rdma_protected_qlist_destroy(RdmaProtectedQList *list) 64 { 65 if (list->list) { 66 qlist_destroy_obj(QOBJECT(list->list)); 67 qemu_mutex_destroy(&list->lock); 68 list->list = NULL; 69 } 70 } 71 72 void rdma_protected_qlist_append_int64(RdmaProtectedQList *list, int64_t value) 73 { 74 qemu_mutex_lock(&list->lock); 75 qlist_append_int(list->list, value); 76 qemu_mutex_unlock(&list->lock); 77 } 78 79 int64_t rdma_protected_qlist_pop_int64(RdmaProtectedQList *list) 80 { 81 QObject *obj; 82 83 qemu_mutex_lock(&list->lock); 84 obj = qlist_pop(list->list); 85 qemu_mutex_unlock(&list->lock); 86 87 if (!obj) { 88 return -ENOENT; 89 } 90 91 return qnum_get_uint(qobject_to(QNum, obj)); 92 } 93 94 void rdma_protected_gslist_init(RdmaProtectedGSList *list) 95 { 96 qemu_mutex_init(&list->lock); 97 } 98 99 void rdma_protected_gslist_destroy(RdmaProtectedGSList *list) 100 { 101 if (list->list) { 102 g_slist_free(list->list); 103 list->list = NULL; 104 } 105 } 106 107 void rdma_protected_gslist_append_int32(RdmaProtectedGSList *list, 108 int32_t value) 109 { 110 qemu_mutex_lock(&list->lock); 111 list->list = g_slist_prepend(list->list, GINT_TO_POINTER(value)); 112 qemu_mutex_unlock(&list->lock); 113 } 114 115 void rdma_protected_gslist_remove_int32(RdmaProtectedGSList *list, 116 int32_t value) 117 { 118 qemu_mutex_lock(&list->lock); 119 list->list = g_slist_remove(list->list, GINT_TO_POINTER(value)); 120 qemu_mutex_unlock(&list->lock); 121 } 122