static int __rt_shm_heap_open(struct task_struct *curr, struct pt_regs *regs) { unsigned long name; int size; int suprt, in_kheap; unsigned long off; unsigned long opaque; void *ret; extern void *_shm_alloc(unsigned long name, int size, int suprt, int in_kheap, unsigned long *opaque); if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(size)) || !__xn_access_ok(curr, VERIFY_WRITE, __xn_reg_arg5(regs), sizeof(off))) return 0; name = (unsigned long)__xn_reg_arg1(regs); /* Size of heap space. */ __xn_copy_from_user(curr, &size, (void __user *)__xn_reg_arg2(regs), sizeof(size)); /* Creation mode. */ suprt = (int)__xn_reg_arg3(regs); in_kheap = (int)__xn_reg_arg4(regs); ret = _shm_alloc(name, size, suprt, in_kheap, &opaque); if (!ret) goto free_and_fail; off = xnheap_mapped_offset((xnheap_t *)opaque, ret); size = (int)((xnheap_t *)opaque)->extentsize; __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &size, sizeof(size)); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg5(regs), &off, sizeof(off)); return (int)opaque; free_and_fail: return 0; }
static int __sc_halloc(struct task_struct *curr, struct pt_regs *regs) { vrtxheap_t *heap; char *buf = NULL; u_long bsize; int err, hid; spl_t s; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg3(regs), sizeof(buf))) return -EFAULT; hid = __xn_reg_arg1(regs); bsize = (u_long)__xn_reg_arg2(regs); xnlock_get_irqsave(&nklock, s); heap = xnmap_fetch(vrtx_heap_idmap, hid); if (!heap || heap->mm != curr->mm) { /* Allocation requests must be issued from the same * process which created the heap. */ err = ER_ID; goto unlock_and_exit; } buf = sc_halloc(hid, bsize, &err); /* Convert the allocated buffer kernel-based address to the equivalent area into the caller's address space. */ if (!err) buf = heap->mapbase + xnheap_mapped_offset(&heap->sysheap, buf); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg3(regs), &buf, sizeof(buf)); return err; }
static int __sc_gblock(struct task_struct *curr, struct pt_regs *regs) { char *buf = NULL; vrtxpt_t *pt; int err, pid; spl_t s; if (!__xn_access_ok (curr, VERIFY_WRITE, __xn_reg_arg2(regs), sizeof(buf))) return -EFAULT; pid = __xn_reg_arg1(regs); xnlock_get_irqsave(&nklock, s); pt = xnmap_fetch(vrtx_pt_idmap, pid); if (!pt || pt->mm != curr->mm) { /* Allocation requests must be issued from the same * process which created the partition. */ err = ER_PID; goto unlock_and_exit; } buf = sc_gblock(pid, &err); /* Convert the allocated buffer kernel-based address to the equivalent area into the caller's address space. */ if (!err) buf = pt->mapbase + xnheap_mapped_offset(pt->sysheap, buf); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); __xn_copy_to_user(curr, (void __user *)__xn_reg_arg2(regs), &buf, sizeof(buf)); return err; }