// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Xen frontend/backend page directory based shared buffer * helper module. * * Copyright (C) 2018 EPAM Systems Inc. * * Author: Oleksandr Andrushchenko <[email protected]> */ #include <linux/module.h> #include <linux/errno.h> #include <linux/mm.h> #include <asm/xen/hypervisor.h> #include <xen/balloon.h> #include <xen/xen.h> #include <xen/xenbus.h> #include <xen/interface/io/ring.h> #include <xen/xen-front-pgdir-shbuf.h> /* * This structure represents the structure of a shared page * that contains grant references to the pages of the shared * buffer. This structure is common to many Xen para-virtualized * protocols at include/xen/interface/io/ */ struct xen_page_directory { … }; /* * Shared buffer ops which are differently implemented * depending on the allocation mode, e.g. if the buffer * is allocated by the corresponding backend or frontend. * Some of the operations. */ struct xen_front_pgdir_shbuf_ops { … }; /* * Get granted reference to the very first page of the * page directory. Usually this is passed to the backend, * so it can find/fill the grant references to the buffer's * pages. * * \param buf shared buffer which page directory is of interest. * \return granted reference to the very first page of the * page directory. */ grant_ref_t xen_front_pgdir_shbuf_get_dir_start(struct xen_front_pgdir_shbuf *buf) { … } EXPORT_SYMBOL_GPL(…); /* * Map granted references of the shared buffer. * * Depending on the shared buffer mode of allocation * (be_alloc flag) this can either do nothing (for buffers * shared by the frontend itself) or map the provided granted * references onto the backing storage (buf->pages). * * \param buf shared buffer which grants to be mapped. * \return zero on success or a negative number on failure. */ int xen_front_pgdir_shbuf_map(struct xen_front_pgdir_shbuf *buf) { … } EXPORT_SYMBOL_GPL(…); /* * Unmap granted references of the shared buffer. * * Depending on the shared buffer mode of allocation * (be_alloc flag) this can either do nothing (for buffers * shared by the frontend itself) or unmap the provided granted * references. * * \param buf shared buffer which grants to be unmapped. * \return zero on success or a negative number on failure. */ int xen_front_pgdir_shbuf_unmap(struct xen_front_pgdir_shbuf *buf) { … } EXPORT_SYMBOL_GPL(…); /* * Free all the resources of the shared buffer. * * \param buf shared buffer which resources to be freed. */ void xen_front_pgdir_shbuf_free(struct xen_front_pgdir_shbuf *buf) { … } EXPORT_SYMBOL_GPL(…); /* * Number of grefs a page can hold with respect to the * struct xen_page_directory header. */ #define XEN_NUM_GREFS_PER_PAGE … /* * Get the number of pages the page directory consumes itself. * * \param buf shared buffer. */ static int get_num_pages_dir(struct xen_front_pgdir_shbuf *buf) { … } /* * Calculate the number of grant references needed to share the buffer * and its pages when backend allocates the buffer. * * \param buf shared buffer. */ static void backend_calc_num_grefs(struct xen_front_pgdir_shbuf *buf) { … } /* * Calculate the number of grant references needed to share the buffer * and its pages when frontend allocates the buffer. * * \param buf shared buffer. */ static void guest_calc_num_grefs(struct xen_front_pgdir_shbuf *buf) { … } #define xen_page_to_vaddr(page) … /* * Unmap the buffer previously mapped with grant references * provided by the backend. * * \param buf shared buffer. * \return zero on success or a negative number on failure. */ static int backend_unmap(struct xen_front_pgdir_shbuf *buf) { … } /* * Map the buffer with grant references provided by the backend. * * \param buf shared buffer. * \return zero on success or a negative number on failure. */ static int backend_map(struct xen_front_pgdir_shbuf *buf) { … } /* * Fill page directory with grant references to the pages of the * page directory itself. * * The grant references to the buffer pages are provided by the * backend in this case. * * \param buf shared buffer. */ static void backend_fill_page_dir(struct xen_front_pgdir_shbuf *buf) { … } /* * Fill page directory with grant references to the pages of the * page directory and the buffer we share with the backend. * * \param buf shared buffer. */ static void guest_fill_page_dir(struct xen_front_pgdir_shbuf *buf) { … } /* * Grant references to the frontend's buffer pages. * * These will be shared with the backend, so it can * access the buffer's data. * * \param buf shared buffer. * \return zero on success or a negative number on failure. */ static int guest_grant_refs_for_buffer(struct xen_front_pgdir_shbuf *buf, grant_ref_t *priv_gref_head, int gref_idx) { … } /* * Grant all the references needed to share the buffer. * * Grant references to the page directory pages and, if * needed, also to the pages of the shared buffer data. * * \param buf shared buffer. * \return zero on success or a negative number on failure. */ static int grant_references(struct xen_front_pgdir_shbuf *buf) { … } /* * Allocate all required structures to mange shared buffer. * * \param buf shared buffer. * \return zero on success or a negative number on failure. */ static int alloc_storage(struct xen_front_pgdir_shbuf *buf) { … } /* * For backend allocated buffers we don't need grant_refs_for_buffer * as those grant references are allocated at backend side. */ static const struct xen_front_pgdir_shbuf_ops backend_ops = …; /* * For locally granted references we do not need to map/unmap * the references. */ static const struct xen_front_pgdir_shbuf_ops local_ops = …; /* * Allocate a new instance of a shared buffer. * * \param cfg configuration to be used while allocating a new shared buffer. * \return zero on success or a negative number on failure. */ int xen_front_pgdir_shbuf_alloc(struct xen_front_pgdir_shbuf_cfg *cfg) { … } EXPORT_SYMBOL_GPL(…); MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …;