Source
/******************************************************************************
* gntalloc.c
*
* Device for creating grant references (in user-space) that may be shared
* with other domains.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This driver exists to allow userspace programs in Linux to allocate kernel
* memory that will later be shared with another domain. Without this device,
* Linux userspace programs cannot create grant references.
*
* How this stuff works:
* X -> granting a page to Y
* Y -> mapping the grant from X
*
* 1. X uses the gntalloc device to allocate a page of kernel memory, P.
* 2. X creates an entry in the grant table that says domid(Y) can access P.
* This is done without a hypercall unless the grant table needs expansion.
* 3. X gives the grant reference identifier, GREF, to Y.
* 4. Y maps the page, either directly into kernel memory for use in a backend
* driver, or via a the gntdev device to map into the address space of an
* application running in Y. This is the first point at which Xen does any
* tracking of the page.
* 5. A program in X mmap()s a segment of the gntalloc device that corresponds
* to the shared page, and can now communicate with Y over the shared page.
*
*
* NOTE TO USERSPACE LIBRARIES:
* The grant allocation and mmap()ing are, naturally, two separate operations.
* You set up the sharing by calling the create ioctl() and then the mmap().
* Teardown requires munmap() and either close() or ioctl().
*
* WARNING: Since Xen does not allow a guest to forcibly end the use of a grant
* reference, this device can be used to consume kernel memory by leaving grant
* references mapped by another domain when an application exits. Therefore,
* there is a global limit on the number of pages that can be allocated. When
* all references to the page are unmapped, it will be freed during the next
* grant operation.
*/
static int limit = 1024;
module_param(limit, int, 0644);
MODULE_PARM_DESC(limit, "Maximum number of grants that may be allocated by "
"the gntalloc device");
static LIST_HEAD(gref_list);
static DEFINE_MUTEX(gref_mutex);
static int gref_size;
struct notify_info {
uint16_t pgoff:12; /* Bits 0-11: Offset of the byte to clear */
uint16_t flags:2; /* Bits 12-13: Unmap notification flags */
int event; /* Port (event channel) to notify */
};
/* Metadata on a grant reference. */
struct gntalloc_gref {
struct list_head next_gref; /* list entry gref_list */
struct list_head next_file; /* list entry file->list, if open */
struct page *page; /* The shared page */