Lines Matching +full:y +full:- +full:rc
4 * Device for creating grant references (in user-space) that may be shared
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * X -> granting a page to Y
24 * Y -> mapping the grant from X
27 * 2. X creates an entry in the grant table that says domid(Y) can access P.
29 * 3. X gives the grant reference identifier, GREF, to Y.
30 * 4. Y maps the page, either directly into kernel memory for use in a backend
32 * application running in Y. This is the first point at which Xen does any
35 * to the shared page, and can now communicate with Y over the shared page.
83 uint16_t pgoff:12; /* Bits 0-11: Offset of the byte to clear */
84 uint16_t flags:2; /* Bits 12-13: Unmap notification flags */
91 struct list_head next_file; /* list entry file->list, if open */
94 unsigned int users; /* Use count - when zero, waiting on Xen */
116 if (!gref->users) in do_cleanup()
124 int i, rc, readonly; in add_grefs() local
129 readonly = !(op->flags & GNTALLOC_FLAG_WRITABLE); in add_grefs()
130 for (i = 0; i < op->count; i++) { in add_grefs()
133 rc = -ENOMEM; in add_grefs()
136 list_add_tail(&gref->next_gref, &queue_gref); in add_grefs()
137 list_add_tail(&gref->next_file, &queue_file); in add_grefs()
138 gref->users = 1; in add_grefs()
139 gref->file_index = op->index + i * PAGE_SIZE; in add_grefs()
140 gref->page = alloc_page(GFP_KERNEL|__GFP_ZERO); in add_grefs()
141 if (!gref->page) { in add_grefs()
142 rc = -ENOMEM; in add_grefs()
147 rc = gnttab_grant_foreign_access(op->domid, in add_grefs()
148 xen_page_to_gfn(gref->page), in add_grefs()
150 if (rc < 0) in add_grefs()
152 gref_ids[i] = gref->gref_id = rc; in add_grefs()
158 list_splice_tail(&queue_file, &priv->list); in add_grefs()
165 gref_size -= (op->count - i); in add_grefs()
168 list_del(&gref->next_file); in add_grefs()
172 /* It's possible for the target domain to map the just-allocated grant in add_grefs()
181 return rc; in add_grefs()
186 if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { in __del_gref()
187 uint8_t *tmp = kmap(gref->page); in __del_gref()
188 tmp[gref->notify.pgoff] = 0; in __del_gref()
189 kunmap(gref->page); in __del_gref()
191 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { in __del_gref()
192 notify_remote_via_evtchn(gref->notify.event); in __del_gref()
193 evtchn_put(gref->notify.event); in __del_gref()
196 gref->notify.flags = 0; in __del_gref()
198 if (gref->gref_id) { in __del_gref()
199 if (gnttab_query_foreign_access(gref->gref_id)) in __del_gref()
202 if (!gnttab_end_foreign_access_ref(gref->gref_id, 0)) in __del_gref()
205 gnttab_free_grant_reference(gref->gref_id); in __del_gref()
208 gref_size--; in __del_gref()
209 list_del(&gref->next_gref); in __del_gref()
211 if (gref->page) in __del_gref()
212 __free_page(gref->page); in __del_gref()
222 list_for_each_entry(gref, &priv->list, next_file) { in find_grefs()
223 if (gref->file_index == index && !rv) in find_grefs()
226 if (gref->file_index != index) in find_grefs()
229 count--; in find_grefs()
238 * -------------------------------------
240 * -------------------------------------
249 INIT_LIST_HEAD(&priv->list); in gntalloc_open()
251 filp->private_data = priv; in gntalloc_open()
258 return -ENOMEM; in gntalloc_open()
263 struct gntalloc_file_private_data *priv = filp->private_data; in gntalloc_release()
269 while (!list_empty(&priv->list)) { in gntalloc_release()
270 gref = list_entry(priv->list.next, in gntalloc_release()
272 list_del(&gref->next_file); in gntalloc_release()
273 gref->users--; in gntalloc_release()
274 if (gref->users == 0) in gntalloc_release()
286 int rc = 0; in gntalloc_ioctl_alloc() local
293 rc = -EFAULT; in gntalloc_ioctl_alloc()
299 rc = -ENOMEM; in gntalloc_ioctl_alloc()
311 rc = -ENOSPC; in gntalloc_ioctl_alloc()
315 op.index = priv->index; in gntalloc_ioctl_alloc()
316 priv->index += op.count * PAGE_SIZE; in gntalloc_ioctl_alloc()
319 rc = add_grefs(&op, gref_ids, priv); in gntalloc_ioctl_alloc()
320 if (rc < 0) in gntalloc_ioctl_alloc()
327 * release - which it will do by segfaulting when it tries to access the in gntalloc_ioctl_alloc()
331 rc = -EFAULT; in gntalloc_ioctl_alloc()
334 if (copy_to_user(arg->gref_ids, gref_ids, in gntalloc_ioctl_alloc()
336 rc = -EFAULT; in gntalloc_ioctl_alloc()
343 return rc; in gntalloc_ioctl_alloc()
349 int i, rc = 0; in gntalloc_ioctl_dealloc() local
356 rc = -EFAULT; in gntalloc_ioctl_dealloc()
368 n = list_entry(gref->next_file.next, in gntalloc_ioctl_dealloc()
370 list_del(&gref->next_file); in gntalloc_ioctl_dealloc()
371 gref->users--; in gntalloc_ioctl_dealloc()
375 rc = -EINVAL; in gntalloc_ioctl_dealloc()
382 return rc; in gntalloc_ioctl_dealloc()
392 int rc; in gntalloc_ioctl_unmap_notify() local
395 return -EFAULT; in gntalloc_ioctl_unmap_notify()
397 index = op.index & ~(PAGE_SIZE - 1); in gntalloc_ioctl_unmap_notify()
398 pgoff = op.index & (PAGE_SIZE - 1); in gntalloc_ioctl_unmap_notify()
404 rc = -ENOENT; in gntalloc_ioctl_unmap_notify()
409 rc = -EINVAL; in gntalloc_ioctl_unmap_notify()
422 rc = -EINVAL; in gntalloc_ioctl_unmap_notify()
427 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) in gntalloc_ioctl_unmap_notify()
428 evtchn_put(gref->notify.event); in gntalloc_ioctl_unmap_notify()
430 gref->notify.flags = op.action; in gntalloc_ioctl_unmap_notify()
431 gref->notify.pgoff = pgoff; in gntalloc_ioctl_unmap_notify()
432 gref->notify.event = op.event_channel_port; in gntalloc_ioctl_unmap_notify()
433 rc = 0; in gntalloc_ioctl_unmap_notify()
437 return rc; in gntalloc_ioctl_unmap_notify()
443 struct gntalloc_file_private_data *priv = filp->private_data; in gntalloc_ioctl()
456 return -ENOIOCTLCMD; in gntalloc_ioctl()
464 struct gntalloc_vma_private_data *priv = vma->vm_private_data; in gntalloc_vma_open()
470 priv->users++; in gntalloc_vma_open()
476 struct gntalloc_vma_private_data *priv = vma->vm_private_data; in gntalloc_vma_close()
484 priv->users--; in gntalloc_vma_close()
485 if (priv->users == 0) { in gntalloc_vma_close()
486 gref = priv->gref; in gntalloc_vma_close()
487 for (i = 0; i < priv->count; i++) { in gntalloc_vma_close()
488 gref->users--; in gntalloc_vma_close()
489 next = list_entry(gref->next_gref.next, in gntalloc_vma_close()
491 if (gref->users == 0) in gntalloc_vma_close()
507 struct gntalloc_file_private_data *priv = filp->private_data; in gntalloc_mmap()
513 if (!(vma->vm_flags & VM_SHARED)) { in gntalloc_mmap()
515 return -EINVAL; in gntalloc_mmap()
520 return -ENOMEM; in gntalloc_mmap()
525 priv, vm_priv, vma->vm_pgoff, count); in gntalloc_mmap()
527 gref = find_grefs(priv, vma->vm_pgoff << PAGE_SHIFT, count); in gntalloc_mmap()
529 rv = -ENOENT; in gntalloc_mmap()
536 vm_priv->gref = gref; in gntalloc_mmap()
537 vm_priv->users = 1; in gntalloc_mmap()
538 vm_priv->count = count; in gntalloc_mmap()
540 vma->vm_private_data = vm_priv; in gntalloc_mmap()
542 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; in gntalloc_mmap()
544 vma->vm_ops = &gntalloc_vmops; in gntalloc_mmap()
547 gref->users++; in gntalloc_mmap()
548 rv = vm_insert_page(vma, vma->vm_start + i * PAGE_SIZE, in gntalloc_mmap()
549 gref->page); in gntalloc_mmap()
553 gref = list_entry(gref->next_file.next, in gntalloc_mmap()
572 * -------------------------------------
574 * -------------------------------------
587 return -ENODEV; in gntalloc_init()
612 MODULE_DESCRIPTION("User-space grant reference allocator driver");