Lines Matching +full:display +full:- +full:backend
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
4 * Xen frontend/backend page directory based shared buffer
22 #include <xen/xen-front-pgdir-shbuf.h>
36 * buffer. This structure is common to many Xen para-virtualized
47 * is allocated by the corresponding backend or frontend.
58 /* Fill page directory according to para-virtual display protocol. */
74 * page directory. Usually this is passed to the backend,
85 if (!buf->grefs) in xen_front_pgdir_shbuf_get_dir_start()
88 return buf->grefs[0]; in xen_front_pgdir_shbuf_get_dir_start()
98 * references onto the backing storage (buf->pages).
105 if (buf->ops && buf->ops->map) in xen_front_pgdir_shbuf_map()
106 return buf->ops->map(buf); in xen_front_pgdir_shbuf_map()
126 if (buf->ops && buf->ops->unmap) in xen_front_pgdir_shbuf_unmap()
127 return buf->ops->unmap(buf); in xen_front_pgdir_shbuf_unmap()
141 if (buf->grefs) { in xen_front_pgdir_shbuf_free()
144 for (i = 0; i < buf->num_grefs; i++) in xen_front_pgdir_shbuf_free()
145 if (buf->grefs[i] != GRANT_INVALID_REF) in xen_front_pgdir_shbuf_free()
146 gnttab_end_foreign_access(buf->grefs[i], in xen_front_pgdir_shbuf_free()
149 kfree(buf->grefs); in xen_front_pgdir_shbuf_free()
150 kfree(buf->directory); in xen_front_pgdir_shbuf_free()
158 #define XEN_NUM_GREFS_PER_PAGE ((PAGE_SIZE - \
169 return DIV_ROUND_UP(buf->num_pages, XEN_NUM_GREFS_PER_PAGE); in get_num_pages_dir()
174 * and its pages when backend allocates the buffer.
181 buf->num_grefs = get_num_pages_dir(buf); in backend_calc_num_grefs()
196 buf->num_grefs = get_num_pages_dir(buf) + buf->num_pages; in guest_calc_num_grefs()
204 * provided by the backend.
214 if (!buf->pages || !buf->backend_map_handles || !buf->grefs) in backend_unmap()
217 unmap_ops = kcalloc(buf->num_pages, sizeof(*unmap_ops), in backend_unmap()
220 return -ENOMEM; in backend_unmap()
222 for (i = 0; i < buf->num_pages; i++) { in backend_unmap()
225 addr = xen_page_to_vaddr(buf->pages[i]); in backend_unmap()
227 buf->backend_map_handles[i]); in backend_unmap()
230 ret = gnttab_unmap_refs(unmap_ops, NULL, buf->pages, in backend_unmap()
231 buf->num_pages); in backend_unmap()
233 for (i = 0; i < buf->num_pages; i++) { in backend_unmap()
235 dev_err(&buf->xb_dev->dev, in backend_unmap()
241 dev_err(&buf->xb_dev->dev, in backend_unmap()
245 kfree(buf->backend_map_handles); in backend_unmap()
246 buf->backend_map_handles = NULL; in backend_unmap()
251 * Map the buffer with grant references provided by the backend.
262 map_ops = kcalloc(buf->num_pages, sizeof(*map_ops), GFP_KERNEL); in backend_map()
264 return -ENOMEM; in backend_map()
266 buf->backend_map_handles = kcalloc(buf->num_pages, in backend_map()
267 sizeof(*buf->backend_map_handles), in backend_map()
269 if (!buf->backend_map_handles) { in backend_map()
271 return -ENOMEM; in backend_map()
275 * Read page directory to get grefs from the backend: for external in backend_map()
276 * buffer we only allocate buf->grefs for the page directory, in backend_map()
277 * so buf->num_grefs has number of pages in the page directory itself. in backend_map()
279 ptr = buf->directory; in backend_map()
280 grefs_left = buf->num_pages; in backend_map()
282 for (cur_dir_page = 0; cur_dir_page < buf->num_grefs; cur_dir_page++) { in backend_map()
293 addr = xen_page_to_vaddr(buf->pages[cur_page]); in backend_map()
296 page_dir->gref[cur_gref], in backend_map()
297 buf->xb_dev->otherend_id); in backend_map()
301 grefs_left -= to_copy; in backend_map()
304 ret = gnttab_map_refs(map_ops, NULL, buf->pages, buf->num_pages); in backend_map()
307 for (cur_page = 0; cur_page < buf->num_pages; cur_page++) { in backend_map()
308 buf->backend_map_handles[cur_page] = map_ops[cur_page].handle; in backend_map()
310 dev_err(&buf->xb_dev->dev, in backend_map()
316 dev_err(&buf->xb_dev->dev, in backend_map()
330 * backend in this case.
340 ptr = buf->directory; in backend_fill_page_dir()
344 for (i = 0; i < num_pages_dir - 1; i++) { in backend_fill_page_dir()
347 page_dir->gref_dir_next_page = buf->grefs[i + 1]; in backend_fill_page_dir()
352 page_dir->gref_dir_next_page = GRANT_INVALID_REF; in backend_fill_page_dir()
357 * page directory and the buffer we share with the backend.
366 ptr = buf->directory; in guest_fill_page_dir()
374 grefs_left = buf->num_pages; in guest_fill_page_dir()
381 page_dir->gref_dir_next_page = GRANT_INVALID_REF; in guest_fill_page_dir()
384 page_dir->gref_dir_next_page = buf->grefs[i + 1]; in guest_fill_page_dir()
386 memcpy(&page_dir->gref, &buf->grefs[cur_gref], in guest_fill_page_dir()
389 grefs_left -= to_copy; in guest_fill_page_dir()
397 * These will be shared with the backend, so it can
409 otherend_id = buf->xb_dev->otherend_id; in guest_grant_refs_for_buffer()
410 for (i = 0; i < buf->num_pages; i++) { in guest_grant_refs_for_buffer()
416 xen_page_to_gfn(buf->pages[i]), in guest_grant_refs_for_buffer()
418 buf->grefs[gref_idx++] = cur_ref; in guest_grant_refs_for_buffer()
438 ret = gnttab_alloc_grant_references(buf->num_grefs, &priv_gref_head); in grant_references()
440 dev_err(&buf->xb_dev->dev, in grant_references()
445 otherend_id = buf->xb_dev->otherend_id; in grant_references()
455 frame = xen_page_to_gfn(virt_to_page(buf->directory + in grant_references()
458 buf->grefs[j++] = cur_ref; in grant_references()
461 if (buf->ops->grant_refs_for_buffer) { in grant_references()
462 ret = buf->ops->grant_refs_for_buffer(buf, &priv_gref_head, j); in grant_references()
479 buf->grefs = kcalloc(buf->num_grefs, sizeof(*buf->grefs), GFP_KERNEL); in alloc_storage()
480 if (!buf->grefs) in alloc_storage()
481 return -ENOMEM; in alloc_storage()
483 buf->directory = kcalloc(get_num_pages_dir(buf), PAGE_SIZE, GFP_KERNEL); in alloc_storage()
484 if (!buf->directory) in alloc_storage()
485 return -ENOMEM; in alloc_storage()
491 * For backend allocated buffers we don't need grant_refs_for_buffer
492 * as those grant references are allocated at backend side.
519 struct xen_front_pgdir_shbuf *buf = cfg->pgdir; in xen_front_pgdir_shbuf_alloc()
522 if (cfg->be_alloc) in xen_front_pgdir_shbuf_alloc()
523 buf->ops = &backend_ops; in xen_front_pgdir_shbuf_alloc()
525 buf->ops = &local_ops; in xen_front_pgdir_shbuf_alloc()
526 buf->xb_dev = cfg->xb_dev; in xen_front_pgdir_shbuf_alloc()
527 buf->num_pages = cfg->num_pages; in xen_front_pgdir_shbuf_alloc()
528 buf->pages = cfg->pages; in xen_front_pgdir_shbuf_alloc()
530 buf->ops->calc_num_grefs(buf); in xen_front_pgdir_shbuf_alloc()
540 buf->ops->fill_page_dir(buf); in xen_front_pgdir_shbuf_alloc()
550 MODULE_DESCRIPTION("Xen frontend/backend page directory based "