summaryrefslogtreecommitdiffstats
path: root/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch')
-rw-r--r--meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch262
1 files changed, 262 insertions, 0 deletions
diff --git a/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch
new file mode 100644
index 00000000..48dcf7d7
--- /dev/null
+++ b/meta-xilinx-virtualization/recipes-devtools/qemu/qemu-xilinx-8.1/0010-xen-add-map-and-unmap-callbacks-for-grant-region.patch
@@ -0,0 +1,262 @@
1From 90496d4c71e3b9334aebca118661bf72631ed0f0 Mon Sep 17 00:00:00 2001
2From: Juergen Gross <jgross@suse.com>
3Date: Fri, 26 Aug 2022 13:57:06 +0200
4Subject: [PATCH 10/11] xen: add map and unmap callbacks for grant region
5
6Add the callbacks for mapping/unmapping guest memory via grants to the
7special grant memory region.
8
9Signed-off-by: Juergen Gross <jgross@suse.com>
10Signed-off-by: Vikram Garhwal <vikram.garhwal@amd.com>
11---
12 hw/xen/xen-mapcache.c | 176 +++++++++++++++++++++++++++++++++++++++++-
13 softmmu/physmem.c | 11 ++-
14 2 files changed, 182 insertions(+), 5 deletions(-)
15
16diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c
17index 8a61c7dde6..e071328fc5 100644
18--- a/hw/xen/xen-mapcache.c
19+++ b/hw/xen/xen-mapcache.c
20@@ -9,6 +9,8 @@
21 */
22
23 #include "qemu/osdep.h"
24+#include "qemu/queue.h"
25+#include "qemu/thread.h"
26 #include "qemu/units.h"
27 #include "qemu/error-report.h"
28
29@@ -23,6 +25,8 @@
30 #include "sysemu/xen-mapcache.h"
31 #include "trace.h"
32
33+#include <xenevtchn.h>
34+#include <xengnttab.h>
35
36 //#define MAPCACHE_DEBUG
37
38@@ -385,7 +389,7 @@ uint8_t *xen_map_cache(hwaddr phys_addr, hwaddr size,
39 return p;
40 }
41
42-ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
43+static ram_addr_t xen_ram_addr_from_mapcache_try(void *ptr)
44 {
45 MapCacheEntry *entry = NULL;
46 MapCacheRev *reventry;
47@@ -594,10 +598,179 @@ uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
48 return p;
49 }
50
51+struct XENMappedGrantRegion {
52+ void *addr;
53+ unsigned int pages;
54+ unsigned int refs;
55+ unsigned int prot;
56+ uint32_t idx;
57+ QLIST_ENTRY(XENMappedGrantRegion) list;
58+};
59+
60+static xengnttab_handle *xen_region_gnttabdev;
61+static QLIST_HEAD(GrantRegionList, XENMappedGrantRegion) xen_grant_mappings =
62+ QLIST_HEAD_INITIALIZER(xen_grant_mappings);
63+static QemuMutex xen_map_mutex;
64+
65+static void *xen_map_grant_dyn(MemoryRegion **mr, hwaddr addr, hwaddr *plen,
66+ bool is_write, MemTxAttrs attrs)
67+{
68+ unsigned int page_off = addr & (XC_PAGE_SIZE - 1);
69+ unsigned int i;
70+ unsigned int total_grants = 0;
71+ unsigned int nrefs = (page_off + *plen + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
72+ uint32_t ref = (addr - XEN_GRANT_ADDR_OFF) >> XC_PAGE_SHIFT;
73+ uint32_t *refs = NULL;
74+ unsigned int prot = PROT_READ;
75+ struct XENMappedGrantRegion *mgr = NULL;
76+
77+ if (is_write) {
78+ prot |= PROT_WRITE;
79+ }
80+
81+ qemu_mutex_lock(&xen_map_mutex);
82+
83+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
84+ if (mgr->idx == ref &&
85+ mgr->pages == nrefs &&
86+ (mgr->prot & prot) == prot) {
87+ break;
88+ }
89+
90+ total_grants += mgr->pages;
91+ }
92+
93+ if (!mgr) {
94+ if (nrefs + total_grants >= XEN_MAX_VIRTIO_GRANTS) {
95+ qemu_mutex_unlock(&xen_map_mutex);
96+ return NULL;
97+ }
98+
99+ mgr = g_new(struct XENMappedGrantRegion, 1);
100+
101+ if (nrefs == 1) {
102+ refs = &ref;
103+ } else {
104+ refs = g_new(uint32_t, nrefs);
105+ for (i = 0; i < nrefs; i++) {
106+ refs[i] = ref + i;
107+ }
108+ }
109+ mgr->addr = xengnttab_map_domain_grant_refs(xen_region_gnttabdev, nrefs,
110+ xen_domid, refs, prot);
111+ if (mgr->addr) {
112+ mgr->pages = nrefs;
113+ mgr->refs = 1;
114+ mgr->prot = prot;
115+ mgr->idx = ref;
116+
117+ QLIST_INSERT_HEAD(&xen_grant_mappings, mgr, list);
118+ } else {
119+ g_free(mgr);
120+ mgr = NULL;
121+ }
122+ } else {
123+ mgr->refs++;
124+ }
125+
126+ qemu_mutex_unlock(&xen_map_mutex);
127+
128+ if (nrefs > 1) {
129+ g_free(refs);
130+ }
131+
132+ return mgr ? mgr->addr + page_off : NULL;
133+}
134+
135+static void xen_unmap_grant_dyn(MemoryRegion *mr, void *buffer, ram_addr_t addr,
136+ hwaddr len, bool is_write, hwaddr access_len)
137+{
138+ unsigned int page_off = (unsigned long)buffer & (XC_PAGE_SIZE - 1);
139+ unsigned int nrefs = (page_off + len + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT;
140+ unsigned int prot = PROT_READ;
141+ struct XENMappedGrantRegion *mgr = NULL;
142+
143+ if (is_write) {
144+ prot |= PROT_WRITE;
145+ }
146+
147+ qemu_mutex_lock(&xen_map_mutex);
148+
149+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
150+ if (mgr->addr == buffer - page_off &&
151+ mgr->pages == nrefs &&
152+ (mgr->prot & prot) == prot) {
153+ break;
154+ }
155+ }
156+ if (mgr) {
157+ mgr->refs--;
158+ if (!mgr->refs) {
159+ xengnttab_unmap(xen_region_gnttabdev, mgr->addr, nrefs);
160+
161+ QLIST_REMOVE(mgr, list);
162+ g_free(mgr);
163+ }
164+ } else {
165+ error_report("xen_unmap_grant_dyn() trying to unmap unknown buffer");
166+ }
167+
168+ qemu_mutex_unlock(&xen_map_mutex);
169+}
170+
171+static ram_addr_t xen_ram_addr_from_grant_cache(void *ptr)
172+{
173+ unsigned int page_off = (unsigned long)ptr & (XC_PAGE_SIZE - 1);
174+ struct XENMappedGrantRegion *mgr = NULL;
175+ ram_addr_t raddr = RAM_ADDR_INVALID;
176+
177+ qemu_mutex_lock(&xen_map_mutex);
178+
179+ QLIST_FOREACH(mgr, &xen_grant_mappings, list) {
180+ if (mgr->addr == ptr - page_off) {
181+ break;
182+ }
183+ }
184+
185+ if (mgr) {
186+ raddr = (mgr->idx << XC_PAGE_SHIFT) + page_off + XEN_GRANT_ADDR_OFF;
187+ }
188+
189+ qemu_mutex_unlock(&xen_map_mutex);
190+
191+ return raddr;
192+}
193+
194+ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
195+{
196+ ram_addr_t raddr;
197+
198+ raddr = xen_ram_addr_from_mapcache_try(ptr);
199+ if (raddr == RAM_ADDR_INVALID) {
200+ raddr = xen_ram_addr_from_grant_cache(ptr);
201+ }
202+
203+ return raddr;
204+}
205+
206+static const struct MemoryRegionOps xen_grant_mr_ops = {
207+ .map = xen_map_grant_dyn,
208+ .unmap = xen_unmap_grant_dyn,
209+ .endianness = DEVICE_LITTLE_ENDIAN,
210+};
211+
212 MemoryRegion *xen_init_grant_ram(void)
213 {
214 RAMBlock *block;
215
216+ qemu_mutex_init(&xen_map_mutex);
217+
218+ xen_region_gnttabdev = xengnttab_open(NULL, 0);
219+ if (xen_region_gnttabdev == NULL) {
220+ fprintf(stderr, "can't open gnttab device\n");
221+ return NULL;
222+ }
223+
224 memory_region_init(&ram_grants, NULL, "xen.grants",
225 XEN_MAX_VIRTIO_GRANTS * XC_PAGE_SIZE);
226 block = g_malloc0(sizeof(*block));
227@@ -612,6 +785,7 @@ MemoryRegion *xen_init_grant_ram(void)
228 ram_grants.ram_block = block;
229 ram_grants.ram = true;
230 ram_grants.terminates = true;
231+ ram_grants.ops = &xen_grant_mr_ops;
232 ram_block_add_list(block);
233 memory_region_add_subregion(get_system_memory(), XEN_GRANT_ADDR_OFF,
234 &ram_grants);
235diff --git a/softmmu/physmem.c b/softmmu/physmem.c
236index a1e2030424..e1057304f1 100644
237--- a/softmmu/physmem.c
238+++ b/softmmu/physmem.c
239@@ -2210,13 +2210,16 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
240
241 if (xen_enabled()) {
242 ram_addr_t ram_addr;
243+
244 RCU_READ_LOCK_GUARD();
245 ram_addr = xen_ram_addr_from_mapcache(ptr);
246- block = qemu_get_ram_block(ram_addr);
247- if (block) {
248- *offset = ram_addr - block->offset;
249+ if (ram_addr != RAM_ADDR_INVALID) {
250+ block = qemu_get_ram_block(ram_addr);
251+ if (block) {
252+ *offset = ram_addr - block->offset;
253+ }
254+ return block;
255 }
256- return block;
257 }
258
259 RCU_READ_LOCK_GUARD();
260--
2612.39.2
262