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()
173 return rc; in add_grefs()
178 if (gref->notify.flags & UNMAP_NOTIFY_CLEAR_BYTE) { in __del_gref()
179 uint8_t *tmp = kmap_local_page(gref->page); in __del_gref()
180 tmp[gref->notify.pgoff] = 0; in __del_gref()
183 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { in __del_gref()
184 notify_remote_via_evtchn(gref->notify.event); in __del_gref()
185 evtchn_put(gref->notify.event); in __del_gref()
188 gref->notify.flags = 0; in __del_gref()
190 if (gref->gref_id) { in __del_gref()
191 if (gref->page) in __del_gref()
192 gnttab_end_foreign_access(gref->gref_id, gref->page); in __del_gref()
194 gnttab_free_grant_reference(gref->gref_id); in __del_gref()
197 gref_size--; in __del_gref()
198 list_del(&gref->next_gref); in __del_gref()
208 list_for_each_entry(gref, &priv->list, next_file) { in find_grefs()
209 if (gref->file_index == index && !rv) in find_grefs()
212 if (gref->file_index != index) in find_grefs()
215 count--; in find_grefs()
224 * -------------------------------------
226 * -------------------------------------
235 INIT_LIST_HEAD(&priv->list); in gntalloc_open()
237 filp->private_data = priv; in gntalloc_open()
244 return -ENOMEM; in gntalloc_open()
249 struct gntalloc_file_private_data *priv = filp->private_data; in gntalloc_release()
255 while (!list_empty(&priv->list)) { in gntalloc_release()
256 gref = list_entry(priv->list.next, in gntalloc_release()
258 list_del(&gref->next_file); in gntalloc_release()
259 gref->users--; in gntalloc_release()
260 if (gref->users == 0) in gntalloc_release()
272 int rc = 0; in gntalloc_ioctl_alloc() local
279 rc = -EFAULT; in gntalloc_ioctl_alloc()
285 rc = -ENOMEM; in gntalloc_ioctl_alloc()
297 rc = -ENOSPC; in gntalloc_ioctl_alloc()
301 op.index = priv->index; in gntalloc_ioctl_alloc()
302 priv->index += op.count * PAGE_SIZE; in gntalloc_ioctl_alloc()
305 rc = add_grefs(&op, gref_ids, priv); in gntalloc_ioctl_alloc()
306 if (rc < 0) in gntalloc_ioctl_alloc()
313 * release - which it will do by segfaulting when it tries to access the in gntalloc_ioctl_alloc()
317 rc = -EFAULT; in gntalloc_ioctl_alloc()
320 if (copy_to_user(arg->gref_ids_flex, gref_ids, in gntalloc_ioctl_alloc()
322 rc = -EFAULT; in gntalloc_ioctl_alloc()
329 return rc; in gntalloc_ioctl_alloc()
335 int i, rc = 0; in gntalloc_ioctl_dealloc() local
342 rc = -EFAULT; in gntalloc_ioctl_dealloc()
354 n = list_entry(gref->next_file.next, in gntalloc_ioctl_dealloc()
356 list_del(&gref->next_file); in gntalloc_ioctl_dealloc()
357 gref->users--; in gntalloc_ioctl_dealloc()
361 rc = -EINVAL; in gntalloc_ioctl_dealloc()
368 return rc; in gntalloc_ioctl_dealloc()
378 int rc; in gntalloc_ioctl_unmap_notify() local
381 return -EFAULT; in gntalloc_ioctl_unmap_notify()
383 index = op.index & ~(PAGE_SIZE - 1); in gntalloc_ioctl_unmap_notify()
384 pgoff = op.index & (PAGE_SIZE - 1); in gntalloc_ioctl_unmap_notify()
390 rc = -ENOENT; in gntalloc_ioctl_unmap_notify()
395 rc = -EINVAL; in gntalloc_ioctl_unmap_notify()
408 rc = -EINVAL; in gntalloc_ioctl_unmap_notify()
413 if (gref->notify.flags & UNMAP_NOTIFY_SEND_EVENT) in gntalloc_ioctl_unmap_notify()
414 evtchn_put(gref->notify.event); in gntalloc_ioctl_unmap_notify()
416 gref->notify.flags = op.action; in gntalloc_ioctl_unmap_notify()
417 gref->notify.pgoff = pgoff; in gntalloc_ioctl_unmap_notify()
418 gref->notify.event = op.event_channel_port; in gntalloc_ioctl_unmap_notify()
419 rc = 0; in gntalloc_ioctl_unmap_notify()
423 return rc; in gntalloc_ioctl_unmap_notify()
429 struct gntalloc_file_private_data *priv = filp->private_data; in gntalloc_ioctl()
442 return -ENOIOCTLCMD; in gntalloc_ioctl()
450 struct gntalloc_vma_private_data *priv = vma->vm_private_data; in gntalloc_vma_open()
456 priv->users++; in gntalloc_vma_open()
462 struct gntalloc_vma_private_data *priv = vma->vm_private_data; in gntalloc_vma_close()
470 priv->users--; in gntalloc_vma_close()
471 if (priv->users == 0) { in gntalloc_vma_close()
472 gref = priv->gref; in gntalloc_vma_close()
473 for (i = 0; i < priv->count; i++) { in gntalloc_vma_close()
474 gref->users--; in gntalloc_vma_close()
475 next = list_entry(gref->next_gref.next, in gntalloc_vma_close()
477 if (gref->users == 0) in gntalloc_vma_close()
493 struct gntalloc_file_private_data *priv = filp->private_data; in gntalloc_mmap()
499 if (!(vma->vm_flags & VM_SHARED)) { in gntalloc_mmap()
501 return -EINVAL; in gntalloc_mmap()
506 return -ENOMEM; in gntalloc_mmap()
511 priv, vm_priv, vma->vm_pgoff, count); in gntalloc_mmap()
513 gref = find_grefs(priv, vma->vm_pgoff << PAGE_SHIFT, count); in gntalloc_mmap()
515 rv = -ENOENT; in gntalloc_mmap()
522 vm_priv->gref = gref; in gntalloc_mmap()
523 vm_priv->users = 1; in gntalloc_mmap()
524 vm_priv->count = count; in gntalloc_mmap()
526 vma->vm_private_data = vm_priv; in gntalloc_mmap()
530 vma->vm_ops = &gntalloc_vmops; in gntalloc_mmap()
533 gref->users++; in gntalloc_mmap()
534 rv = vm_insert_page(vma, vma->vm_start + i * PAGE_SIZE, in gntalloc_mmap()
535 gref->page); in gntalloc_mmap()
539 gref = list_entry(gref->next_file.next, in gntalloc_mmap()
558 * -------------------------------------
560 * -------------------------------------
573 return -ENODEV; in gntalloc_init()
598 MODULE_DESCRIPTION("User-space grant reference allocator driver");