Lines Matching +full:directory +full:- +full:based
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>
27 * buffer. This structure is common to many Xen para-virtualized
45 * e.g. if grefs are required for page directory only or the buffer
50 /* Fill page directory according to para-virtual display protocol. */
66 * page directory. Usually this is passed to the backend,
70 * \param buf shared buffer which page directory is of interest.
72 * page directory.
77 if (!buf->grefs) in xen_front_pgdir_shbuf_get_dir_start()
80 return buf->grefs[0]; in xen_front_pgdir_shbuf_get_dir_start()
90 * references onto the backing storage (buf->pages).
97 if (buf->ops && buf->ops->map) in xen_front_pgdir_shbuf_map()
98 return buf->ops->map(buf); in xen_front_pgdir_shbuf_map()
118 if (buf->ops && buf->ops->unmap) in xen_front_pgdir_shbuf_unmap()
119 return buf->ops->unmap(buf); in xen_front_pgdir_shbuf_unmap()
133 if (buf->grefs) { in xen_front_pgdir_shbuf_free()
136 for (i = 0; i < buf->num_grefs; i++) in xen_front_pgdir_shbuf_free()
137 if (buf->grefs[i] != INVALID_GRANT_REF) in xen_front_pgdir_shbuf_free()
138 gnttab_end_foreign_access(buf->grefs[i], NULL); in xen_front_pgdir_shbuf_free()
140 kfree(buf->grefs); in xen_front_pgdir_shbuf_free()
141 kfree(buf->directory); in xen_front_pgdir_shbuf_free()
149 #define XEN_NUM_GREFS_PER_PAGE ((PAGE_SIZE - \
154 * Get the number of pages the page directory consumes itself.
160 return DIV_ROUND_UP(buf->num_pages, XEN_NUM_GREFS_PER_PAGE); in get_num_pages_dir()
171 /* Only for pages the page directory consumes itself. */ in backend_calc_num_grefs()
172 buf->num_grefs = get_num_pages_dir(buf); in backend_calc_num_grefs()
184 * Number of pages the page directory consumes itself in guest_calc_num_grefs()
187 buf->num_grefs = get_num_pages_dir(buf) + buf->num_pages; in guest_calc_num_grefs()
205 if (!buf->pages || !buf->backend_map_handles || !buf->grefs) in backend_unmap()
208 unmap_ops = kcalloc(buf->num_pages, sizeof(*unmap_ops), in backend_unmap()
211 return -ENOMEM; in backend_unmap()
213 for (i = 0; i < buf->num_pages; i++) { in backend_unmap()
216 addr = xen_page_to_vaddr(buf->pages[i]); in backend_unmap()
218 buf->backend_map_handles[i]); in backend_unmap()
221 ret = gnttab_unmap_refs(unmap_ops, NULL, buf->pages, in backend_unmap()
222 buf->num_pages); in backend_unmap()
224 for (i = 0; i < buf->num_pages; i++) { in backend_unmap()
226 dev_err(&buf->xb_dev->dev, in backend_unmap()
232 dev_err(&buf->xb_dev->dev, in backend_unmap()
236 kfree(buf->backend_map_handles); in backend_unmap()
237 buf->backend_map_handles = NULL; in backend_unmap()
253 map_ops = kcalloc(buf->num_pages, sizeof(*map_ops), GFP_KERNEL); in backend_map()
255 return -ENOMEM; in backend_map()
257 buf->backend_map_handles = kcalloc(buf->num_pages, in backend_map()
258 sizeof(*buf->backend_map_handles), in backend_map()
260 if (!buf->backend_map_handles) { in backend_map()
262 return -ENOMEM; in backend_map()
266 * Read page directory to get grefs from the backend: for external in backend_map()
267 * buffer we only allocate buf->grefs for the page directory, in backend_map()
268 * so buf->num_grefs has number of pages in the page directory itself. in backend_map()
270 ptr = buf->directory; in backend_map()
271 grefs_left = buf->num_pages; in backend_map()
273 for (cur_dir_page = 0; cur_dir_page < buf->num_grefs; cur_dir_page++) { in backend_map()
284 addr = xen_page_to_vaddr(buf->pages[cur_page]); in backend_map()
287 page_dir->gref[cur_gref], in backend_map()
288 buf->xb_dev->otherend_id); in backend_map()
292 grefs_left -= to_copy; in backend_map()
295 ret = gnttab_map_refs(map_ops, NULL, buf->pages, buf->num_pages); in backend_map()
298 for (cur_page = 0; cur_page < buf->num_pages; cur_page++) { in backend_map()
300 buf->backend_map_handles[cur_page] = in backend_map()
303 buf->backend_map_handles[cur_page] = in backend_map()
306 ret = -ENXIO; in backend_map()
307 dev_err(&buf->xb_dev->dev, in backend_map()
314 dev_err(&buf->xb_dev->dev, in backend_map()
324 * Fill page directory with grant references to the pages of the
325 * page directory itself.
338 ptr = buf->directory; in backend_fill_page_dir()
341 /* Fill only grefs for the page directory itself. */ in backend_fill_page_dir()
342 for (i = 0; i < num_pages_dir - 1; i++) { in backend_fill_page_dir()
345 page_dir->gref_dir_next_page = buf->grefs[i + 1]; in backend_fill_page_dir()
350 page_dir->gref_dir_next_page = XEN_GREF_LIST_END; in backend_fill_page_dir()
354 * Fill page directory with grant references to the pages of the
355 * page directory and the buffer we share with the backend.
364 ptr = buf->directory; in guest_fill_page_dir()
369 * granted for the page directory itself. in guest_fill_page_dir()
372 grefs_left = buf->num_pages; in guest_fill_page_dir()
379 page_dir->gref_dir_next_page = XEN_GREF_LIST_END; in guest_fill_page_dir()
382 page_dir->gref_dir_next_page = buf->grefs[i + 1]; in guest_fill_page_dir()
384 memcpy(&page_dir->gref, &buf->grefs[cur_gref], in guest_fill_page_dir()
387 grefs_left -= to_copy; in guest_fill_page_dir()
407 otherend_id = buf->xb_dev->otherend_id; in guest_grant_refs_for_buffer()
408 for (i = 0; i < buf->num_pages; i++) { in guest_grant_refs_for_buffer()
414 xen_page_to_gfn(buf->pages[i]), in guest_grant_refs_for_buffer()
416 buf->grefs[gref_idx++] = cur_ref; in guest_grant_refs_for_buffer()
424 * Grant references to the page directory pages and, if
436 ret = gnttab_alloc_grant_references(buf->num_grefs, &priv_gref_head); in grant_references()
438 dev_err(&buf->xb_dev->dev, in grant_references()
443 otherend_id = buf->xb_dev->otherend_id; in grant_references()
453 frame = xen_page_to_gfn(virt_to_page(buf->directory + in grant_references()
456 buf->grefs[j++] = cur_ref; in grant_references()
459 if (buf->ops->grant_refs_for_buffer) { in grant_references()
460 ret = buf->ops->grant_refs_for_buffer(buf, &priv_gref_head, j); in grant_references()
477 buf->grefs = kcalloc(buf->num_grefs, sizeof(*buf->grefs), GFP_KERNEL); in alloc_storage()
478 if (!buf->grefs) in alloc_storage()
479 return -ENOMEM; in alloc_storage()
481 buf->directory = kcalloc(get_num_pages_dir(buf), PAGE_SIZE, GFP_KERNEL); in alloc_storage()
482 if (!buf->directory) in alloc_storage()
483 return -ENOMEM; in alloc_storage()
517 struct xen_front_pgdir_shbuf *buf = cfg->pgdir; in xen_front_pgdir_shbuf_alloc()
520 if (cfg->be_alloc) in xen_front_pgdir_shbuf_alloc()
521 buf->ops = &backend_ops; in xen_front_pgdir_shbuf_alloc()
523 buf->ops = &local_ops; in xen_front_pgdir_shbuf_alloc()
524 buf->xb_dev = cfg->xb_dev; in xen_front_pgdir_shbuf_alloc()
525 buf->num_pages = cfg->num_pages; in xen_front_pgdir_shbuf_alloc()
526 buf->pages = cfg->pages; in xen_front_pgdir_shbuf_alloc()
528 buf->ops->calc_num_grefs(buf); in xen_front_pgdir_shbuf_alloc()
538 buf->ops->fill_page_dir(buf); in xen_front_pgdir_shbuf_alloc()
548 MODULE_DESCRIPTION("Xen frontend/backend page directory based "