aboutsummaryrefslogtreecommitdiff
path: root/sys/xen/gntdev.h
blob: 18b3b8154486b7b31a6d107291e768b96438c07a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*-
 * Copyright (c) 2016 Akshay Jaggi <jaggi@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * gntdev.h
 *
 * Interface to /dev/xen/gntdev.
 *
 * This device provides the user with two kinds of functionalities:
 * 1. Grant Allocation
 *    Allocate a page of our own memory, and share it with a foreign domain.
 * 2. Grant Mapping
 *    Map a grant allocated by a foreign domain, into our own memory.
 *
 *
 * Grant Allocation
 *
 * Steps to allocate a grant:
 * 1. Do an `IOCTL_GNTDEV_ALLOC_GREF ioctl`, with
 *     - `domid`, as the domain-id of the foreign domain
 *     - `flags`, ORed with GNTDEV_ALLOC_FLAG_WRITABLE if you want the foreign
 *       domain to have write access to the shared memory
 *     - `count`, with the number of pages to share with the foreign domain
 *
 *    Ensure that the structure you allocate has enough memory to store
 *    all the allocated grant-refs, i.e., you need to allocate
 *    (sizeof(struct ioctl_gntdev_alloc_gref) + (count - 1)*sizeof(uint32_t))
 *    bytes of memory.
 *
 * 2. Mmap the address given in `index` after a successful ioctl.
 *    This will give you access to the granted pages.
 *
 * Note:
 * 1. The grant is not removed until all three of the following conditions
 *    are met
 *     - The region is not mmaped. That is, munmap() has been called if
 *       the region was mmapped previously.
 *     - IOCTL_GNTDEV_DEALLOC_GREF ioctl has been performed. After you
 *       perform this ioctl, you can no longer mmap or set notify on
 *       the grant.
 *     - The foreign domain has stopped using the grant.
 * 2. Granted pages can only belong to one mmap region.
 * 3. Every page of granted memory is a unit in itself. What this means
 *    is that you can set a unmap notification for each of the granted
 *    pages, individually; you can mmap and dealloc-ioctl a contiguous
 *    range of allocated grants (even if alloc-ioctls were performed
 *    individually), etc.
 *
 *
 * Grant Mapping
 *
 * Steps to map a grant:
 * 1. Do a `IOCTL_GNTDEV_MAP_GRANT_REF` ioctl, with
 *     - `count`, as the number of foreign grants to map
 *     - `refs[i].domid`, as the domain id of the foreign domain
 *     - `refs[i].ref`, as the grant-ref for the grant to be mapped
 *
 * 2. Mmap the address given in `index` after a successful ioctl.
 *    This will give you access to the mapped pages.
 *
 * Note:
 * 1. The map hypercall is not made till the region is mmapped.
 * 2. The unit is defined by the map ioctl. This means that only one
 *    unmap notification can be set on a group of pages that were
 *    mapped together in one ioctl, and also no single mmaping of contiguous
 *    grant-maps is possible.
 * 3. You can mmap the same grant-map region multiple times.
 * 4. The grant is not unmapped until both of the following conditions are met
 *     - The region is not mmaped. That is, munmap() has been called for
 *       as many times as the grant was mmapped.
 *     - IOCTL_GNTDEV_UNMAP_GRANT_REF ioctl has been called.
 * 5. IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR ioctl gives index and count of
 *    a grant-map from the virtual address of the location where the grant
 *    is mmapped.
 *
 *
 * IOCTL_GNTDEV_SET_UNMAP_NOTIFY
 * This ioctl allows us to set notifications to be made when the grant is
 * either unmapped (in case of a mapped grant), or when it is ready to be
 * deallocated by us, ie, the grant is no more mmapped, and the dealloc
 * ioctl has been called (in case of an allocated grant). OR `action` with
 * the required notification masks, and fill in the appropriate fields.
 *  - UNMAP_NOTIFY_CLEAR_BYTE clears the byte at `index`, where index is
 *    the address of the byte in file address space.
 *  - UNMAP_NOTIFY_SEND_EVENT sends an event channel notification on
 *    `event_channel_port`
 * In case of multiple notify ioctls, only the last one survives.
 *
 * $FreeBSD$
 */

#ifndef __XEN_GNTDEV_H__
#define __XEN_GNTDEV_H__

#include <sys/types.h>

#define IOCTL_GNTDEV_SET_UNMAP_NOTIFY					\
	_IOW('E', 0, struct ioctl_gntdev_unmap_notify)
struct ioctl_gntdev_unmap_notify {
    /* IN parameters */
    uint64_t index;
    uint32_t action;
    uint32_t event_channel_port;
};

#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
#define UNMAP_NOTIFY_SEND_EVENT 0x2

/*-------------------- Grant Allocation IOCTLs  ------------------------------*/

#define IOCTL_GNTDEV_ALLOC_GREF						\
	_IOWR('E', 1, struct ioctl_gntdev_alloc_gref)
struct ioctl_gntdev_alloc_gref {
    /* IN parameters */
    uint16_t domid;
    uint16_t flags;
    uint32_t count;
    /* OUT parameters */
    uint64_t index;
    /* Variable OUT parameter */
    uint32_t *gref_ids;
};

#define GNTDEV_ALLOC_FLAG_WRITABLE 1

#define IOCTL_GNTDEV_DEALLOC_GREF					\
	_IOW('E', 2, struct ioctl_gntdev_dealloc_gref)
struct ioctl_gntdev_dealloc_gref {
    /* IN parameters */
    uint64_t index;
    uint32_t count;
};

/*-------------------- Grant Mapping IOCTLs  ---------------------------------*/

struct ioctl_gntdev_grant_ref {
    uint32_t domid;
    uint32_t ref;
};

#define IOCTL_GNTDEV_MAP_GRANT_REF					\
	_IOWR('E', 3, struct ioctl_gntdev_map_grant_ref)
struct ioctl_gntdev_map_grant_ref {
    /* IN parameters */
    uint32_t count;
    uint32_t pad0;
    /* OUT parameters */
    uint64_t index;
    /* Variable IN parameter */
    struct ioctl_gntdev_grant_ref *refs;
};

#define IOCTL_GNTDEV_UNMAP_GRANT_REF					\
	_IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref)
struct ioctl_gntdev_unmap_grant_ref {
    /* IN parameters */
    uint64_t index;
    uint32_t count;
};

#define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR				\
	_IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr)
struct ioctl_gntdev_get_offset_for_vaddr {
    /* IN parameters */
    uint64_t vaddr;
    /* OUT parameters */
    uint64_t offset;
    uint32_t count;
};

#endif /* __XEN_GNTDEV_H__ */