xen-vtx-unstable
annotate linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c @ 6396:56a2232377f1
Fix grant-ref allocation in netfront.
Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Thu Aug 25 14:30:06 2005 +0000 (2005-08-25) |
parents | 522bc50588ed |
children | 3428d58a85e1 b54144915ae6 0610add7c3fe b4b3f6be5226 |
rev | line source |
---|---|
cl349@4693 | 1 /****************************************************************************** |
cl349@4693 | 2 * gnttab.c |
cl349@4693 | 3 * |
cl349@4693 | 4 * Two sets of functionality: |
cl349@4693 | 5 * 1. Granting foreign access to our memory reservation. |
cl349@4693 | 6 * 2. Accessing others' memory reservations via grant references. |
cl349@4693 | 7 * (i.e., mechanisms for both sender and recipient of grant references) |
cl349@4693 | 8 * |
cl349@4693 | 9 * Copyright (c) 2005, Christopher Clark |
cl349@4693 | 10 * Copyright (c) 2004, K A Fraser |
cl349@4693 | 11 */ |
cl349@4693 | 12 |
cl349@4693 | 13 #include <linux/config.h> |
cl349@4693 | 14 #include <linux/module.h> |
cl349@4693 | 15 #include <linux/sched.h> |
cl349@4693 | 16 #include <asm/pgtable.h> |
cl349@4693 | 17 #include <asm/fixmap.h> |
cl349@4693 | 18 #include <asm/uaccess.h> |
cl349@4693 | 19 #include <asm-xen/xen_proc.h> |
cl349@4693 | 20 #include <asm-xen/linux-public/privcmd.h> |
cl349@4693 | 21 #include <asm-xen/gnttab.h> |
kaf24@5402 | 22 #include <asm-xen/synch_bitops.h> |
cl349@4693 | 23 |
cl349@4693 | 24 #if 1 |
cl349@4693 | 25 #define ASSERT(_p) \ |
cl349@4693 | 26 if ( !(_p) ) { printk(KERN_ALERT"Assertion '%s': line %d, file %s\n", \ |
cl349@4693 | 27 #_p , __LINE__, __FILE__); *(int*)0=0; } |
cl349@4693 | 28 #else |
cl349@4693 | 29 #define ASSERT(_p) ((void)0) |
cl349@4693 | 30 #endif |
cl349@4693 | 31 |
cl349@4693 | 32 #define WPRINTK(fmt, args...) \ |
cl349@4693 | 33 printk(KERN_WARNING "xen_grant: " fmt, ##args) |
cl349@4693 | 34 |
cl349@4693 | 35 |
cl349@4693 | 36 EXPORT_SYMBOL(gnttab_grant_foreign_access); |
kaf24@6396 | 37 EXPORT_SYMBOL(gnttab_end_foreign_access_ref); |
cl349@4693 | 38 EXPORT_SYMBOL(gnttab_end_foreign_access); |
cl349@4693 | 39 EXPORT_SYMBOL(gnttab_query_foreign_access); |
cl349@4693 | 40 EXPORT_SYMBOL(gnttab_grant_foreign_transfer); |
kaf24@6396 | 41 EXPORT_SYMBOL(gnttab_end_foreign_transfer_ref); |
cl349@4693 | 42 EXPORT_SYMBOL(gnttab_end_foreign_transfer); |
cl349@4693 | 43 EXPORT_SYMBOL(gnttab_alloc_grant_references); |
cl349@4693 | 44 EXPORT_SYMBOL(gnttab_free_grant_references); |
cl349@6347 | 45 EXPORT_SYMBOL(gnttab_free_grant_reference); |
cl349@4693 | 46 EXPORT_SYMBOL(gnttab_claim_grant_reference); |
cl349@4693 | 47 EXPORT_SYMBOL(gnttab_release_grant_reference); |
cl349@4693 | 48 EXPORT_SYMBOL(gnttab_grant_foreign_access_ref); |
cl349@4693 | 49 EXPORT_SYMBOL(gnttab_grant_foreign_transfer_ref); |
cl349@4693 | 50 |
cl349@6349 | 51 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) |
cl349@6349 | 52 #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1) |
cl349@6349 | 53 |
cl349@6349 | 54 static grant_ref_t gnttab_list[NR_GRANT_ENTRIES]; |
cl349@6349 | 55 static int gnttab_free_count = NR_GRANT_ENTRIES; |
cl349@4693 | 56 static grant_ref_t gnttab_free_head; |
cl349@6349 | 57 static spinlock_t gnttab_list_lock = SPIN_LOCK_UNLOCKED; |
cl349@4693 | 58 |
cl349@4693 | 59 static grant_entry_t *shared; |
cl349@4693 | 60 |
cl349@6339 | 61 static struct gnttab_free_callback *gnttab_free_callback_list = NULL; |
cl349@4693 | 62 |
cl349@6349 | 63 static int |
cl349@6349 | 64 get_free_entries(int count) |
cl349@4693 | 65 { |
cl349@6349 | 66 unsigned long flags; |
cl349@6349 | 67 int ref; |
cl349@6349 | 68 grant_ref_t head; |
cl349@6349 | 69 spin_lock_irqsave(&gnttab_list_lock, flags); |
cl349@6349 | 70 if (gnttab_free_count < count) { |
cl349@6349 | 71 spin_unlock_irqrestore(&gnttab_list_lock, flags); |
cl349@6349 | 72 return -1; |
cl349@6349 | 73 } |
cl349@6349 | 74 ref = head = gnttab_free_head; |
cl349@6349 | 75 gnttab_free_count -= count; |
cl349@6349 | 76 while (count-- > 1) |
cl349@6349 | 77 head = gnttab_list[head]; |
cl349@6349 | 78 gnttab_free_head = gnttab_list[head]; |
cl349@6349 | 79 gnttab_list[head] = GNTTAB_LIST_END; |
cl349@6349 | 80 spin_unlock_irqrestore(&gnttab_list_lock, flags); |
cl349@6349 | 81 return ref; |
cl349@4693 | 82 } |
cl349@4693 | 83 |
cl349@6349 | 84 #define get_free_entry() get_free_entries(1) |
cl349@6349 | 85 |
cl349@6349 | 86 static void |
cl349@6349 | 87 do_free_callbacks(void) |
cl349@6339 | 88 { |
cl349@6346 | 89 struct gnttab_free_callback *callback = gnttab_free_callback_list, *next; |
cl349@6339 | 90 gnttab_free_callback_list = NULL; |
cl349@6339 | 91 while (callback) { |
cl349@6342 | 92 next = callback->next; |
cl349@6349 | 93 if (gnttab_free_count >= callback->count) { |
cl349@6349 | 94 callback->next = NULL; |
cl349@6349 | 95 callback->fn(callback->arg); |
cl349@6349 | 96 } else { |
cl349@6349 | 97 callback->next = gnttab_free_callback_list; |
cl349@6349 | 98 gnttab_free_callback_list = callback; |
cl349@6349 | 99 } |
cl349@6342 | 100 callback = next; |
cl349@6339 | 101 } |
cl349@4693 | 102 } |
cl349@4693 | 103 |
cl349@4693 | 104 static inline void |
cl349@6349 | 105 check_free_callbacks(void) |
cl349@4693 | 106 { |
cl349@6349 | 107 if (unlikely(gnttab_free_callback_list)) |
cl349@6349 | 108 do_free_callbacks(); |
cl349@6349 | 109 } |
cl349@6349 | 110 |
cl349@6349 | 111 static void |
cl349@6349 | 112 put_free_entry(grant_ref_t ref) |
cl349@6349 | 113 { |
cl349@6346 | 114 unsigned long flags; |
cl349@6349 | 115 spin_lock_irqsave(&gnttab_list_lock, flags); |
cl349@6349 | 116 gnttab_list[ref] = gnttab_free_head; |
cl349@6349 | 117 gnttab_free_head = ref; |
cl349@6349 | 118 gnttab_free_count++; |
cl349@6349 | 119 check_free_callbacks(); |
cl349@6349 | 120 spin_unlock_irqrestore(&gnttab_list_lock, flags); |
cl349@4693 | 121 } |
cl349@4693 | 122 |
cl349@4693 | 123 /* |
cl349@4693 | 124 * Public grant-issuing interface functions |
cl349@4693 | 125 */ |
cl349@4693 | 126 |
cl349@4693 | 127 int |
cl349@6349 | 128 gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly) |
cl349@4693 | 129 { |
cl349@4693 | 130 int ref; |
cl349@4693 | 131 |
cl349@4693 | 132 if ( unlikely((ref = get_free_entry()) == -1) ) |
cl349@4693 | 133 return -ENOSPC; |
cl349@4693 | 134 |
cl349@4693 | 135 shared[ref].frame = frame; |
cl349@4693 | 136 shared[ref].domid = domid; |
cl349@4693 | 137 wmb(); |
cl349@4693 | 138 shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); |
cl349@4693 | 139 |
cl349@4693 | 140 return ref; |
cl349@4693 | 141 } |
cl349@4693 | 142 |
cl349@4693 | 143 void |
cl349@6349 | 144 gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, |
cl349@6349 | 145 unsigned long frame, int readonly) |
cl349@4693 | 146 { |
cl349@4693 | 147 shared[ref].frame = frame; |
cl349@4693 | 148 shared[ref].domid = domid; |
cl349@4693 | 149 wmb(); |
cl349@4693 | 150 shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0); |
cl349@4693 | 151 } |
cl349@4693 | 152 |
cl349@4693 | 153 |
cl349@4693 | 154 int |
cl349@6349 | 155 gnttab_query_foreign_access(grant_ref_t ref) |
cl349@4693 | 156 { |
cl349@4693 | 157 u16 nflags; |
cl349@4693 | 158 |
cl349@4693 | 159 nflags = shared[ref].flags; |
cl349@4693 | 160 |
cl349@4693 | 161 return ( nflags & (GTF_reading|GTF_writing) ); |
cl349@4693 | 162 } |
cl349@4693 | 163 |
cl349@4693 | 164 void |
kaf24@6396 | 165 gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly) |
cl349@4693 | 166 { |
cl349@4693 | 167 u16 flags, nflags; |
cl349@4693 | 168 |
cl349@4693 | 169 nflags = shared[ref].flags; |
cl349@4693 | 170 do { |
cl349@4693 | 171 if ( (flags = nflags) & (GTF_reading|GTF_writing) ) |
cl349@4693 | 172 printk(KERN_ALERT "WARNING: g.e. still in use!\n"); |
cl349@4693 | 173 } |
sos22@5391 | 174 while ( (nflags = synch_cmpxchg(&shared[ref].flags, flags, 0)) != flags ); |
kaf24@6396 | 175 } |
cl349@4693 | 176 |
kaf24@6396 | 177 void |
kaf24@6396 | 178 gnttab_end_foreign_access(grant_ref_t ref, int readonly) |
kaf24@6396 | 179 { |
kaf24@6396 | 180 gnttab_end_foreign_access_ref(ref, readonly); |
cl349@4693 | 181 put_free_entry(ref); |
cl349@4693 | 182 } |
cl349@4693 | 183 |
cl349@4693 | 184 int |
cl349@6349 | 185 gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn) |
cl349@4693 | 186 { |
cl349@4693 | 187 int ref; |
cl349@4693 | 188 |
cl349@4693 | 189 if ( unlikely((ref = get_free_entry()) == -1) ) |
cl349@4693 | 190 return -ENOSPC; |
cl349@4693 | 191 |
cl349@4693 | 192 shared[ref].frame = pfn; |
cl349@4693 | 193 shared[ref].domid = domid; |
cl349@4693 | 194 wmb(); |
cl349@4693 | 195 shared[ref].flags = GTF_accept_transfer; |
cl349@4693 | 196 |
cl349@4693 | 197 return ref; |
cl349@4693 | 198 } |
cl349@4693 | 199 |
cl349@4693 | 200 void |
cl349@6349 | 201 gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, |
cl349@6349 | 202 unsigned long pfn) |
cl349@4693 | 203 { |
cl349@4693 | 204 shared[ref].frame = pfn; |
cl349@4693 | 205 shared[ref].domid = domid; |
cl349@4693 | 206 wmb(); |
cl349@4693 | 207 shared[ref].flags = GTF_accept_transfer; |
cl349@4693 | 208 } |
cl349@4693 | 209 |
cl349@4693 | 210 unsigned long |
kaf24@6396 | 211 gnttab_end_foreign_transfer_ref(grant_ref_t ref) |
cl349@4693 | 212 { |
cl349@4693 | 213 unsigned long frame = 0; |
cl349@4693 | 214 u16 flags; |
cl349@4693 | 215 |
cl349@4693 | 216 flags = shared[ref].flags; |
kaf24@6396 | 217 |
cl349@4693 | 218 /* |
cl349@4693 | 219 * If a transfer is committed then wait for the frame address to appear. |
cl349@4693 | 220 * Otherwise invalidate the grant entry against future use. |
cl349@4693 | 221 */ |
cl349@4693 | 222 if ( likely(flags != GTF_accept_transfer) || |
sos22@5391 | 223 (synch_cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) ) |
cl349@4693 | 224 while ( unlikely((frame = shared[ref].frame) == 0) ) |
cl349@4693 | 225 cpu_relax(); |
cl349@4693 | 226 |
kaf24@6396 | 227 return frame; |
kaf24@6396 | 228 } |
kaf24@6396 | 229 |
kaf24@6396 | 230 unsigned long |
kaf24@6396 | 231 gnttab_end_foreign_transfer(grant_ref_t ref) |
kaf24@6396 | 232 { |
kaf24@6396 | 233 unsigned long frame = gnttab_end_foreign_transfer_ref(ref); |
cl349@4693 | 234 put_free_entry(ref); |
cl349@4693 | 235 return frame; |
cl349@4693 | 236 } |
cl349@4693 | 237 |
cl349@4693 | 238 void |
cl349@6349 | 239 gnttab_free_grant_reference(grant_ref_t ref) |
cl349@4693 | 240 { |
cl349@6339 | 241 |
cl349@6339 | 242 put_free_entry(ref); |
cl349@6339 | 243 } |
cl349@4693 | 244 |
cl349@6339 | 245 void |
cl349@6349 | 246 gnttab_free_grant_references(grant_ref_t head) |
cl349@4693 | 247 { |
cl349@6339 | 248 grant_ref_t ref; |
cl349@6349 | 249 unsigned long flags; |
cl349@6349 | 250 int count = 1; |
cl349@6349 | 251 if (head == GNTTAB_LIST_END) |
cl349@6349 | 252 return; |
cl349@6349 | 253 spin_lock_irqsave(&gnttab_list_lock, flags); |
cl349@6349 | 254 ref = head; |
cl349@6349 | 255 while (gnttab_list[ref] != GNTTAB_LIST_END) { |
cl349@6349 | 256 ref = gnttab_list[ref]; |
cl349@6349 | 257 count++; |
vh249@5272 | 258 } |
cl349@6349 | 259 gnttab_list[ref] = gnttab_free_head; |
cl349@6349 | 260 gnttab_free_head = head; |
cl349@6349 | 261 gnttab_free_count += count; |
cl349@6349 | 262 check_free_callbacks(); |
cl349@6349 | 263 spin_unlock_irqrestore(&gnttab_list_lock, flags); |
cl349@4693 | 264 } |
cl349@4693 | 265 |
cl349@4693 | 266 int |
cl349@6349 | 267 gnttab_alloc_grant_references(u16 count, grant_ref_t *head) |
cl349@4693 | 268 { |
cl349@6349 | 269 int h = get_free_entries(count); |
cl349@4693 | 270 |
cl349@6349 | 271 if (h == -1) |
cl349@6349 | 272 return -ENOSPC; |
cl349@4693 | 273 |
cl349@4693 | 274 *head = h; |
cl349@4693 | 275 |
cl349@4693 | 276 return 0; |
cl349@4693 | 277 } |
cl349@4693 | 278 |
cl349@4693 | 279 int |
cl349@6349 | 280 gnttab_claim_grant_reference(grant_ref_t *private_head) |
cl349@4693 | 281 { |
cl349@6349 | 282 grant_ref_t g = *private_head; |
cl349@6349 | 283 if (unlikely(g == GNTTAB_LIST_END)) |
cl349@4693 | 284 return -ENOSPC; |
cl349@6349 | 285 *private_head = gnttab_list[g]; |
cl349@4693 | 286 return g; |
cl349@4693 | 287 } |
cl349@4693 | 288 |
cl349@4693 | 289 void |
cl349@6349 | 290 gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release) |
cl349@4693 | 291 { |
cl349@6349 | 292 gnttab_list[release] = *private_head; |
cl349@4693 | 293 *private_head = release; |
cl349@4693 | 294 } |
cl349@4693 | 295 |
cl349@6339 | 296 void |
cl349@6339 | 297 gnttab_request_free_callback(struct gnttab_free_callback *callback, |
cl349@6349 | 298 void (*fn)(void *), void *arg, u16 count) |
cl349@4693 | 299 { |
cl349@6346 | 300 unsigned long flags; |
cl349@6349 | 301 spin_lock_irqsave(&gnttab_list_lock, flags); |
cl349@6342 | 302 if (callback->next) |
cl349@6349 | 303 goto out; |
cl349@6342 | 304 callback->fn = fn; |
cl349@6342 | 305 callback->arg = arg; |
cl349@6349 | 306 callback->count = count; |
cl349@6339 | 307 callback->next = gnttab_free_callback_list; |
cl349@6339 | 308 gnttab_free_callback_list = callback; |
cl349@6349 | 309 check_free_callbacks(); |
cl349@6349 | 310 out: |
cl349@6349 | 311 spin_unlock_irqrestore(&gnttab_list_lock, flags); |
cl349@4693 | 312 } |
cl349@4693 | 313 |
cl349@4693 | 314 /* |
cl349@4693 | 315 * ProcFS operations |
cl349@4693 | 316 */ |
cl349@4693 | 317 |
cl349@4693 | 318 #ifdef CONFIG_PROC_FS |
cl349@4693 | 319 |
cl349@4693 | 320 static struct proc_dir_entry *grant_pde; |
cl349@4693 | 321 |
cl349@6349 | 322 static int |
cl349@6349 | 323 grant_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
cl349@6349 | 324 unsigned long data) |
cl349@4693 | 325 { |
cl349@4693 | 326 int ret; |
cl349@4693 | 327 privcmd_hypercall_t hypercall; |
cl349@4693 | 328 |
cl349@4693 | 329 /* XXX Need safety checks here if using for anything other |
cl349@4693 | 330 * than debugging */ |
cl349@4693 | 331 return -ENOSYS; |
cl349@4693 | 332 |
cl349@4693 | 333 if ( cmd != IOCTL_PRIVCMD_HYPERCALL ) |
cl349@4693 | 334 return -ENOSYS; |
cl349@4693 | 335 |
cl349@4693 | 336 if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) ) |
cl349@4693 | 337 return -EFAULT; |
cl349@4693 | 338 |
cl349@4693 | 339 if ( hypercall.op != __HYPERVISOR_grant_table_op ) |
cl349@4693 | 340 return -ENOSYS; |
cl349@4693 | 341 |
cl349@4693 | 342 /* hypercall-invoking asm taken from privcmd.c */ |
cl349@4693 | 343 __asm__ __volatile__ ( |
cl349@4693 | 344 "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; " |
cl349@4693 | 345 "movl 4(%%eax),%%ebx ;" |
cl349@4693 | 346 "movl 8(%%eax),%%ecx ;" |
cl349@4693 | 347 "movl 12(%%eax),%%edx ;" |
cl349@4693 | 348 "movl 16(%%eax),%%esi ;" |
cl349@4693 | 349 "movl 20(%%eax),%%edi ;" |
cl349@4693 | 350 "movl (%%eax),%%eax ;" |
cl349@4693 | 351 TRAP_INSTR "; " |
cl349@4693 | 352 "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx" |
cl349@4693 | 353 : "=a" (ret) : "0" (&hypercall) : "memory" ); |
cl349@4693 | 354 |
cl349@4693 | 355 return ret; |
cl349@4693 | 356 } |
cl349@4693 | 357 |
cl349@4693 | 358 static struct file_operations grant_file_ops = { |
cl349@4693 | 359 ioctl: grant_ioctl, |
cl349@4693 | 360 }; |
cl349@4693 | 361 |
cl349@6349 | 362 static int |
cl349@6349 | 363 grant_read(char *page, char **start, off_t off, int count, int *eof, |
cl349@6349 | 364 void *data) |
cl349@4693 | 365 { |
cl349@4693 | 366 int len; |
cl349@4693 | 367 unsigned int i; |
cl349@4693 | 368 grant_entry_t *gt; |
cl349@4693 | 369 |
cl349@4693 | 370 gt = (grant_entry_t *)shared; |
cl349@4693 | 371 len = 0; |
cl349@4693 | 372 |
cl349@4693 | 373 for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) |
cl349@4693 | 374 /* TODO: safety catch here until this can handle >PAGE_SIZE output */ |
cl349@4693 | 375 if (len > (PAGE_SIZE - 200)) |
cl349@4693 | 376 { |
cl349@4693 | 377 len += sprintf( page + len, "Truncated.\n"); |
cl349@4693 | 378 break; |
cl349@4693 | 379 } |
cl349@4693 | 380 |
cl349@4693 | 381 if ( gt[i].flags ) |
cl349@4693 | 382 len += sprintf( page + len, |
cl349@4693 | 383 "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", |
cl349@4693 | 384 i, |
cl349@4693 | 385 gt[i].flags, |
cl349@4693 | 386 gt[i].domid, |
cl349@4693 | 387 gt[i].frame ); |
cl349@4693 | 388 |
cl349@4693 | 389 *eof = 1; |
cl349@4693 | 390 return len; |
cl349@4693 | 391 } |
cl349@4693 | 392 |
cl349@6349 | 393 static int |
cl349@6349 | 394 grant_write(struct file *file, const char __user *buffer, unsigned long count, |
cl349@6349 | 395 void *data) |
cl349@4693 | 396 { |
cl349@4693 | 397 /* TODO: implement this */ |
cl349@4693 | 398 return -ENOSYS; |
cl349@4693 | 399 } |
cl349@4693 | 400 |
cl349@4693 | 401 #endif /* CONFIG_PROC_FS */ |
cl349@4693 | 402 |
cl349@6349 | 403 int |
cl349@6349 | 404 gnttab_resume(void) |
cl349@4693 | 405 { |
cl349@4693 | 406 gnttab_setup_table_t setup; |
cl349@4693 | 407 unsigned long frames[NR_GRANT_FRAMES]; |
cl349@4693 | 408 int i; |
cl349@4693 | 409 |
cl349@4693 | 410 setup.dom = DOMID_SELF; |
cl349@4693 | 411 setup.nr_frames = NR_GRANT_FRAMES; |
cl349@4693 | 412 setup.frame_list = frames; |
cl349@4693 | 413 |
cl349@4693 | 414 BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0); |
cl349@4693 | 415 BUG_ON(setup.status != 0); |
cl349@4693 | 416 |
cl349@4693 | 417 for ( i = 0; i < NR_GRANT_FRAMES; i++ ) |
cl349@4777 | 418 set_fixmap(FIX_GNTTAB_END - i, frames[i] << PAGE_SHIFT); |
cl349@4693 | 419 |
cl349@4693 | 420 return 0; |
cl349@4693 | 421 } |
cl349@4693 | 422 |
cl349@6349 | 423 int |
cl349@6349 | 424 gnttab_suspend(void) |
cl349@4693 | 425 { |
cl349@4693 | 426 int i; |
cl349@4693 | 427 |
cl349@4693 | 428 for ( i = 0; i < NR_GRANT_FRAMES; i++ ) |
cl349@4693 | 429 clear_fixmap(FIX_GNTTAB_END - i); |
cl349@4693 | 430 |
cl349@4693 | 431 return 0; |
cl349@4693 | 432 } |
cl349@4693 | 433 |
cl349@6349 | 434 static int __init |
cl349@6349 | 435 gnttab_init(void) |
cl349@4693 | 436 { |
cl349@4693 | 437 int i; |
cl349@4693 | 438 |
cl349@4693 | 439 BUG_ON(gnttab_resume()); |
cl349@4693 | 440 |
cl349@4693 | 441 shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB_END); |
cl349@4693 | 442 |
cl349@4693 | 443 for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) |
cl349@6349 | 444 gnttab_list[i] = i + 1; |
cl349@4693 | 445 |
cl349@4693 | 446 #ifdef CONFIG_PROC_FS |
cl349@4693 | 447 /* |
cl349@4693 | 448 * /proc/xen/grant : used by libxc to access grant tables |
cl349@4693 | 449 */ |
cl349@4693 | 450 if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL ) |
cl349@4693 | 451 { |
cl349@4693 | 452 WPRINTK("Unable to create grant xen proc entry\n"); |
cl349@4693 | 453 return -1; |
cl349@4693 | 454 } |
cl349@4693 | 455 |
cl349@4693 | 456 grant_file_ops.read = grant_pde->proc_fops->read; |
cl349@4693 | 457 grant_file_ops.write = grant_pde->proc_fops->write; |
cl349@4693 | 458 |
cl349@4693 | 459 grant_pde->proc_fops = &grant_file_ops; |
cl349@4693 | 460 |
cl349@4693 | 461 grant_pde->read_proc = &grant_read; |
cl349@4693 | 462 grant_pde->write_proc = &grant_write; |
cl349@4693 | 463 #endif |
cl349@4693 | 464 |
cl349@4693 | 465 printk("Grant table initialized\n"); |
cl349@4693 | 466 return 0; |
cl349@4693 | 467 } |
cl349@4693 | 468 |
cl349@4693 | 469 __initcall(gnttab_init); |