err_list: down(&file->mutex); list_del(&obj->uobject.list); up(&file->mutex); 
err_idr: idr_remove(&ib_uverbs_mr_idr, obj->uobject.id); 
ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,			 const char __user *buf, int in_len,			 int out_len){	struct ib_uverbs_reg_mr      cmd;	struct ib_uverbs_reg_mr_resp resp;	struct ib_udata              udata;	struct ib_umem_object       *obj;	struct ib_pd                *pd;	struct ib_mr                *mr;	int                          ret;	if (out_len < sizeof resp)		return -ENOSPC;	if (copy_from_user(&cmd, buf, sizeof cmd))		return -EFAULT;	INIT_UDATA(&udata, buf + sizeof cmd,		   (unsigned long) cmd.response + sizeof resp,		   in_len - sizeof cmd, out_len - sizeof resp);	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))		return -EINVAL;	obj = kmalloc(sizeof *obj, GFP_KERNEL);	if (!obj)		return -ENOMEM;	obj->uobject.context = file->ucontext;	/*	 * We ask for writable memory if any access flags other than	 * "remote read" are set.  "Local write" and "remote write"	 * obviously require write access.  "Remote atomic" can do	 * things like fetch and add, which will modify memory, and	 * "MW bind" can change permissions by binding a window.	 */	ret = ib_umem_get(file->device->ib_dev, &obj->umem,			  (void *) (unsigned long) cmd.start, cmd.length,			  !!(cmd.access_flags & ~IB_ACCESS_REMOTE_READ));	if (ret)		goto err_free;	obj->umem.virt_base = cmd.hca_va;	down(&ib_uverbs_idr_mutex);	pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);	if (!pd || pd->uobject->context != file->ucontext) {		ret = -EINVAL;		goto err_up;	}	if (!pd->device->reg_user_mr) {		ret = -ENOSYS;		goto err_up;	}	mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);	if (IS_ERR(mr)) {		ret = PTR_ERR(mr);		goto err_up;	}	mr->device  = pd->device;	mr->pd      = pd;	mr->uobject = &obj->uobject;	atomic_inc(&pd->usecnt);	atomic_set(&mr->usecnt, 0);	memset(&resp, 0, sizeof resp);	resp.lkey = mr->lkey;	resp.rkey = mr->rkey;retry:	if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) {		ret = -ENOMEM;		goto err_unreg;	}	ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id);	if (ret == -EAGAIN)		goto retry;	if (ret)		goto err_unreg;	resp.mr_handle = obj->uobject.id;	down(&file->mutex);	list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);	up(&file->mutex);	if (copy_to_user((void __user *) (unsigned long) cmd.response,			 &resp, sizeof resp)) {		ret = -EFAULT;		goto err_list;	}	up(&ib_uverbs_idr_mutex);	return in_len;err_list:	down(&file->mutex);	list_del(&obj->uobject.list);	up(&file->mutex);err_unreg:	ib_dereg_mr(mr);err_up:	up(&ib_uverbs_idr_mutex);	ib_umem_release(file->device->ib_dev, &obj->umem);err_free:	kfree(obj);	return ret;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/eb9d3cd5ce2828fbb99ed7270089ea152c8f64b3/uverbs_cmd.c/buggy/drivers/infiniband/core/uverbs_cmd.c