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()
309 buf->backend_map_handles[cur_page] = in backend_map()
312 buf->backend_map_handles[cur_page] = in backend_map()
315 ret = -ENXIO; in backend_map()
316 dev_err(&buf->xb_dev->dev, in backend_map()
323 dev_err(&buf->xb_dev->dev, in backend_map()
337 * backend in this case.
347 ptr = buf->directory; in backend_fill_page_dir()
351 for (i = 0; i < num_pages_dir - 1; i++) { in backend_fill_page_dir()
354 page_dir->gref_dir_next_page = buf->grefs[i + 1]; in backend_fill_page_dir()
359 page_dir->gref_dir_next_page = GRANT_INVALID_REF; in backend_fill_page_dir()
364 * page directory and the buffer we share with the backend.
373 ptr = buf->directory; in guest_fill_page_dir()
381 grefs_left = buf->num_pages; in guest_fill_page_dir()
388 page_dir->gref_dir_next_page = GRANT_INVALID_REF; in guest_fill_page_dir()
391 page_dir->gref_dir_next_page = buf->grefs[i + 1]; in guest_fill_page_dir()
393 memcpy(&page_dir->gref, &buf->grefs[cur_gref], in guest_fill_page_dir()
396 grefs_left -= to_copy; in guest_fill_page_dir()
404 * These will be shared with the backend, so it can
416 otherend_id = buf->xb_dev->otherend_id; in guest_grant_refs_for_buffer()
417 for (i = 0; i < buf->num_pages; i++) { in guest_grant_refs_for_buffer()
423 xen_page_to_gfn(buf->pages[i]), in guest_grant_refs_for_buffer()
425 buf->grefs[gref_idx++] = cur_ref; in guest_grant_refs_for_buffer()
445 ret = gnttab_alloc_grant_references(buf->num_grefs, &priv_gref_head); in grant_references()
447 dev_err(&buf->xb_dev->dev, in grant_references()
452 otherend_id = buf->xb_dev->otherend_id; in grant_references()
462 frame = xen_page_to_gfn(virt_to_page(buf->directory + in grant_references()
465 buf->grefs[j++] = cur_ref; in grant_references()
468 if (buf->ops->grant_refs_for_buffer) { in grant_references()
469 ret = buf->ops->grant_refs_for_buffer(buf, &priv_gref_head, j); in grant_references()
486 buf->grefs = kcalloc(buf->num_grefs, sizeof(*buf->grefs), GFP_KERNEL); in alloc_storage()
487 if (!buf->grefs) in alloc_storage()
488 return -ENOMEM; in alloc_storage()
490 buf->directory = kcalloc(get_num_pages_dir(buf), PAGE_SIZE, GFP_KERNEL); in alloc_storage()
491 if (!buf->directory) in alloc_storage()
492 return -ENOMEM; in alloc_storage()
498 * For backend allocated buffers we don't need grant_refs_for_buffer
499 * as those grant references are allocated at backend side.
526 struct xen_front_pgdir_shbuf *buf = cfg->pgdir; in xen_front_pgdir_shbuf_alloc()
529 if (cfg->be_alloc) in xen_front_pgdir_shbuf_alloc()
530 buf->ops = &backend_ops; in xen_front_pgdir_shbuf_alloc()
532 buf->ops = &local_ops; in xen_front_pgdir_shbuf_alloc()
533 buf->xb_dev = cfg->xb_dev; in xen_front_pgdir_shbuf_alloc()
534 buf->num_pages = cfg->num_pages; in xen_front_pgdir_shbuf_alloc()
535 buf->pages = cfg->pages; in xen_front_pgdir_shbuf_alloc()
537 buf->ops->calc_num_grefs(buf); in xen_front_pgdir_shbuf_alloc()
547 buf->ops->fill_page_dir(buf); in xen_front_pgdir_shbuf_alloc()
557 MODULE_DESCRIPTION("Xen frontend/backend page directory based "