| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: xengnt.c,v 1.22.2.1 2012/02/23 21:19:55 riz Exp $ */ | | 1 | /* $NetBSD: xengnt.c,v 1.22.2.1.4.1 2012/10/31 16:15:28 riz Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2006 Manuel Bouyer. | | 4 | * Copyright (c) 2006 Manuel Bouyer. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * | | 14 | * |
| @@ -16,51 +16,54 @@ | | | @@ -16,51 +16,54 @@ |
16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | * | | 25 | * |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | #include <sys/cdefs.h> | | 28 | #include <sys/cdefs.h> |
29 | __KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1.22.2.1 2012/02/23 21:19:55 riz Exp $"); | | 29 | __KERNEL_RCSID(0, "$NetBSD: xengnt.c,v 1.22.2.1.4.1 2012/10/31 16:15:28 riz Exp $"); |
30 | | | 30 | |
31 | #include <sys/types.h> | | 31 | #include <sys/types.h> |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/systm.h> | | 33 | #include <sys/systm.h> |
34 | #include <sys/malloc.h> | | 34 | #include <sys/malloc.h> |
35 | #include <sys/queue.h> | | 35 | #include <sys/queue.h> |
36 | #include <sys/extent.h> | | 36 | #include <sys/extent.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/mutex.h> | | 38 | #include <sys/mutex.h> |
39 | #include <uvm/uvm.h> | | 39 | #include <uvm/uvm.h> |
40 | | | 40 | |
41 | #include <xen/hypervisor.h> | | 41 | #include <xen/hypervisor.h> |
42 | #include <xen/xen.h> | | 42 | #include <xen/xen.h> |
43 | #include <xen/granttables.h> | | 43 | #include <xen/granttables.h> |
44 | | | 44 | |
45 | /* #define XENDEBUG */ | | 45 | /* #define XENDEBUG */ |
46 | #ifdef XENDEBUG | | 46 | #ifdef XENDEBUG |
47 | #define DPRINTF(x) printf x | | 47 | #define DPRINTF(x) printf x |
48 | #else | | 48 | #else |
49 | #define DPRINTF(x) | | 49 | #define DPRINTF(x) |
50 | #endif | | 50 | #endif |
51 | | | 51 | |
52 | #define NR_GRANT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_t)) | | 52 | #define NR_GRANT_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(grant_entry_t)) |
53 | | | 53 | |
| | | 54 | /* External tools reserve first few grant table entries. */ |
| | | 55 | #define NR_RESERVED_ENTRIES 8 |
| | | 56 | |
54 | /* Current number of frames making up the grant table */ | | 57 | /* Current number of frames making up the grant table */ |
55 | int gnt_nr_grant_frames; | | 58 | int gnt_nr_grant_frames; |
56 | /* Maximum number of frames that can make up the grant table */ | | 59 | /* Maximum number of frames that can make up the grant table */ |
57 | int gnt_max_grant_frames; | | 60 | int gnt_max_grant_frames; |
58 | | | 61 | |
59 | /* table of free grant entries */ | | 62 | /* table of free grant entries */ |
60 | grant_ref_t *gnt_entries; | | 63 | grant_ref_t *gnt_entries; |
61 | /* last free entry */ | | 64 | /* last free entry */ |
62 | int last_gnt_entry; | | 65 | int last_gnt_entry; |
63 | /* empty entry in the list */ | | 66 | /* empty entry in the list */ |
64 | #define XENGNT_NO_ENTRY 0xffffffff | | 67 | #define XENGNT_NO_ENTRY 0xffffffff |
65 | | | 68 | |
66 | /* VM address of the grant table */ | | 69 | /* VM address of the grant table */ |
| @@ -151,27 +154,27 @@ xengnt_suspend(void) { | | | @@ -151,27 +154,27 @@ xengnt_suspend(void) { |
151 | } | | 154 | } |
152 | | | 155 | |
153 | | | 156 | |
154 | /* | | 157 | /* |
155 | * Add another page to the grant table | | 158 | * Add another page to the grant table |
156 | * Returns 0 on success, ENOMEM on failure | | 159 | * Returns 0 on success, ENOMEM on failure |
157 | */ | | 160 | */ |
158 | static int | | 161 | static int |
159 | xengnt_more_entries(void) | | 162 | xengnt_more_entries(void) |
160 | { | | 163 | { |
161 | gnttab_setup_table_t setup; | | 164 | gnttab_setup_table_t setup; |
162 | u_long *pages; | | 165 | u_long *pages; |
163 | int nframes_new = gnt_nr_grant_frames + 1; | | 166 | int nframes_new = gnt_nr_grant_frames + 1; |
164 | int i; | | 167 | int i, start_gnt; |
165 | KASSERT(mutex_owned(&grant_lock)); | | 168 | KASSERT(mutex_owned(&grant_lock)); |
166 | | | 169 | |
167 | if (gnt_nr_grant_frames == gnt_max_grant_frames) | | 170 | if (gnt_nr_grant_frames == gnt_max_grant_frames) |
168 | return ENOMEM; | | 171 | return ENOMEM; |
169 | | | 172 | |
170 | pages = malloc(nframes_new * sizeof(u_long), M_DEVBUF, M_NOWAIT); | | 173 | pages = malloc(nframes_new * sizeof(u_long), M_DEVBUF, M_NOWAIT); |
171 | if (pages == NULL) | | 174 | if (pages == NULL) |
172 | return ENOMEM; | | 175 | return ENOMEM; |
173 | | | 176 | |
174 | setup.dom = DOMID_SELF; | | 177 | setup.dom = DOMID_SELF; |
175 | setup.nr_frames = nframes_new; | | 178 | setup.nr_frames = nframes_new; |
176 | xenguest_handle(setup.frame_list) = pages; | | 179 | xenguest_handle(setup.frame_list) = pages; |
177 | | | 180 | |
| @@ -194,29 +197,34 @@ xengnt_more_entries(void) | | | @@ -194,29 +197,34 @@ xengnt_more_entries(void) |
194 | (char *)grant_table + gnt_nr_grant_frames * PAGE_SIZE)); | | 197 | (char *)grant_table + gnt_nr_grant_frames * PAGE_SIZE)); |
195 | | | 198 | |
196 | /* | | 199 | /* |
197 | * map between grant_table addresses and the machine addresses of | | 200 | * map between grant_table addresses and the machine addresses of |
198 | * the grant table frames | | 201 | * the grant table frames |
199 | */ | | 202 | */ |
200 | pmap_kenter_ma(((vaddr_t)grant_table) + gnt_nr_grant_frames * PAGE_SIZE, | | 203 | pmap_kenter_ma(((vaddr_t)grant_table) + gnt_nr_grant_frames * PAGE_SIZE, |
201 | ((paddr_t)pages[gnt_nr_grant_frames]) << PAGE_SHIFT, | | 204 | ((paddr_t)pages[gnt_nr_grant_frames]) << PAGE_SHIFT, |
202 | VM_PROT_WRITE, 0); | | 205 | VM_PROT_WRITE, 0); |
203 | pmap_update(pmap_kernel()); | | 206 | pmap_update(pmap_kernel()); |
204 | | | 207 | |
205 | /* | | 208 | /* |
206 | * add the grant entries associated to the last grant table frame | | 209 | * add the grant entries associated to the last grant table frame |
207 | * and mark them as free | | 210 | * and mark them as free. Prevent using the first grants (from 0 to 8) |
| | | 211 | * since they are used by the tools. |
208 | */ | | 212 | */ |
209 | for (i = gnt_nr_grant_frames * NR_GRANT_ENTRIES_PER_PAGE; | | 213 | start_gnt = (gnt_nr_grant_frames * NR_GRANT_ENTRIES_PER_PAGE) < |
| | | 214 | (NR_RESERVED_ENTRIES + 1) ? |
| | | 215 | (NR_RESERVED_ENTRIES + 1) : |
| | | 216 | (gnt_nr_grant_frames * NR_GRANT_ENTRIES_PER_PAGE); |
| | | 217 | for (i = start_gnt; |
210 | i < nframes_new * NR_GRANT_ENTRIES_PER_PAGE; | | 218 | i < nframes_new * NR_GRANT_ENTRIES_PER_PAGE; |
211 | i++) { | | 219 | i++) { |
212 | KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY); | | 220 | KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY); |
213 | gnt_entries[last_gnt_entry] = i; | | 221 | gnt_entries[last_gnt_entry] = i; |
214 | last_gnt_entry++; | | 222 | last_gnt_entry++; |
215 | } | | 223 | } |
216 | gnt_nr_grant_frames = nframes_new; | | 224 | gnt_nr_grant_frames = nframes_new; |
217 | free(pages, M_DEVBUF); | | 225 | free(pages, M_DEVBUF); |
218 | return 0; | | 226 | return 0; |
219 | } | | 227 | } |
220 | | | 228 | |
221 | /* | | 229 | /* |
222 | * Returns a reference to the first free entry in grant table | | 230 | * Returns a reference to the first free entry in grant table |
| @@ -230,39 +238,40 @@ xengnt_get_entry(void) | | | @@ -230,39 +238,40 @@ xengnt_get_entry(void) |
230 | | | 238 | |
231 | if (last_gnt_entry == 0) { | | 239 | if (last_gnt_entry == 0) { |
232 | if (xengnt_more_entries()) { | | 240 | if (xengnt_more_entries()) { |
233 | if (ratecheck(&xengnt_nonmemtime, &xengnt_nonmemintvl)) | | 241 | if (ratecheck(&xengnt_nonmemtime, &xengnt_nonmemintvl)) |
234 | printf("xengnt_get_entry: out of grant " | | 242 | printf("xengnt_get_entry: out of grant " |
235 | "table entries\n"); | | 243 | "table entries\n"); |
236 | return XENGNT_NO_ENTRY; | | 244 | return XENGNT_NO_ENTRY; |
237 | } | | 245 | } |
238 | } | | 246 | } |
239 | KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY); | | 247 | KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY); |
240 | last_gnt_entry--; | | 248 | last_gnt_entry--; |
241 | entry = gnt_entries[last_gnt_entry]; | | 249 | entry = gnt_entries[last_gnt_entry]; |
242 | gnt_entries[last_gnt_entry] = XENGNT_NO_ENTRY; | | 250 | gnt_entries[last_gnt_entry] = XENGNT_NO_ENTRY; |
243 | KASSERT(entry != XENGNT_NO_ENTRY); | | 251 | KASSERT(entry != XENGNT_NO_ENTRY && entry > NR_RESERVED_ENTRIES); |
244 | KASSERT(last_gnt_entry >= 0); | | 252 | KASSERT(last_gnt_entry >= 0); |
245 | KASSERT(last_gnt_entry <= gnt_max_grant_frames * NR_GRANT_ENTRIES_PER_PAGE); | | 253 | KASSERT(last_gnt_entry <= gnt_max_grant_frames * NR_GRANT_ENTRIES_PER_PAGE); |
246 | return entry; | | 254 | return entry; |
247 | } | | 255 | } |
248 | | | 256 | |
249 | /* | | 257 | /* |
250 | * Mark the grant table entry as free | | 258 | * Mark the grant table entry as free |
251 | */ | | 259 | */ |
252 | static void | | 260 | static void |
253 | xengnt_free_entry(grant_ref_t entry) | | 261 | xengnt_free_entry(grant_ref_t entry) |
254 | { | | 262 | { |
255 | mutex_enter(&grant_lock); | | 263 | mutex_enter(&grant_lock); |
| | | 264 | KASSERT(entry > NR_RESERVED_ENTRIES); |
256 | KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY); | | 265 | KASSERT(gnt_entries[last_gnt_entry] == XENGNT_NO_ENTRY); |
257 | KASSERT(last_gnt_entry >= 0); | | 266 | KASSERT(last_gnt_entry >= 0); |
258 | KASSERT(last_gnt_entry <= gnt_max_grant_frames * NR_GRANT_ENTRIES_PER_PAGE); | | 267 | KASSERT(last_gnt_entry <= gnt_max_grant_frames * NR_GRANT_ENTRIES_PER_PAGE); |
259 | gnt_entries[last_gnt_entry] = entry; | | 268 | gnt_entries[last_gnt_entry] = entry; |
260 | last_gnt_entry++; | | 269 | last_gnt_entry++; |
261 | mutex_exit(&grant_lock); | | 270 | mutex_exit(&grant_lock); |
262 | } | | 271 | } |
263 | | | 272 | |
264 | int | | 273 | int |
265 | xengnt_grant_access(domid_t dom, paddr_t ma, int ro, grant_ref_t *entryp) | | 274 | xengnt_grant_access(domid_t dom, paddr_t ma, int ro, grant_ref_t *entryp) |
266 | { | | 275 | { |
267 | mutex_enter(&grant_lock); | | 276 | mutex_enter(&grant_lock); |
268 | | | 277 | |