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