Wed Oct 31 16:15:28 2012 UTC ()
Pull up following revision(s) (requested by royger in ticket #640):
	sys/arch/xen/xen/xengnt.c: revision 1.25
xen: don't use grants 0-8
Not all grants from the first frame can be used, grants from 0 to 8
(both included) are reserved for external tools. Using this grants
caused system crashes and fs corruption.
Closes PR port-xen/47057 and port-xen/47056
Reviewed by bouyer@


(riz)
diff -r1.22.2.1 -r1.22.2.1.4.1 src/sys/arch/xen/xen/xengnt.c

cvs diff -r1.22.2.1 -r1.22.2.1.4.1 src/sys/arch/xen/xen/xengnt.c (expand / switch to unified diff)

--- src/sys/arch/xen/xen/xengnt.c 2012/02/23 21:19:55 1.22.2.1
+++ src/sys/arch/xen/xen/xengnt.c 2012/10/31 16:15:28 1.22.2.1.4.1
@@ -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 */
55int gnt_nr_grant_frames; 58int 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 */
57int gnt_max_grant_frames; 60int gnt_max_grant_frames;
58 61
59/* table of free grant entries */ 62/* table of free grant entries */
60grant_ref_t *gnt_entries; 63grant_ref_t *gnt_entries;
61/* last free entry */ 64/* last free entry */
62int last_gnt_entry; 65int 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 */
158static int 161static int
159xengnt_more_entries(void) 162xengnt_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 */
252static void 260static void
253xengnt_free_entry(grant_ref_t entry) 261xengnt_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
264int 273int
265xengnt_grant_access(domid_t dom, paddr_t ma, int ro, grant_ref_t *entryp) 274xengnt_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