xref: /openbmc/qemu/hw/rdma/rdma_utils.c (revision 8e6fe6b8)
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