// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/sched/task.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/iommu.h>
#include <linux/highmem.h>
#include <uapi/linux/idxd.h>
#include <linux/xarray.h>
#include "registers.h"
#include "idxd.h"

struct idxd_cdev_context {
	const char *name;
	dev_t devt;
	struct ida minor_ida;
};

/*
 * Since user file names are global in DSA devices, define their ida's as
 * global to avoid conflict file names.
 */
static DEFINE_IDA(file_ida);

/*
 * ictx is an array based off of accelerator types. enum idxd_type
 * is used as index
 */
static struct idxd_cdev_context ictx[IDXD_TYPE_MAX] = {
	{ .name = "dsa" },
	{ .name = "iax" }
};

struct idxd_user_context {
	struct idxd_wq *wq;
	struct task_struct *task;
	unsigned int pasid;
	struct mm_struct *mm;
	unsigned int flags;
	struct iommu_sva *sva;
	struct idxd_dev idxd_dev;
	u64 counters[COUNTER_MAX];
	int id;
	pid_t pid;
};

static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid);
static void idxd_xa_pasid_remove(struct idxd_user_context *ctx);

static inline struct idxd_user_context *dev_to_uctx(struct device *dev)
{
	struct idxd_dev *idxd_dev = confdev_to_idxd_dev(dev);

	return container_of(idxd_dev, struct idxd_user_context, idxd_dev);
}

static ssize_t cr_faults_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct idxd_user_context *ctx = dev_to_uctx(dev);

	return sysfs_emit(buf, "%llu\n", ctx->counters[COUNTER_FAULTS]);
}
static DEVICE_ATTR_RO(cr_faults);

static ssize_t cr_fault_failures_show(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct idxd_user_context *ctx = dev_to_uctx(dev);

	return sysfs_emit(buf, "%llu\n", ctx->counters[COUNTER_FAULT_FAILS]);
}
static DEVICE_ATTR_RO(cr_fault_failures);

static ssize_t pid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct idxd_user_context *ctx = dev_to_uctx(dev);

	return sysfs_emit(buf, "%u\n", ctx->pid);
}
static DEVICE_ATTR_RO(pid);

static struct attribute *cdev_file_attributes[] = {
	&dev_attr_cr_faults.attr,
	&dev_attr_cr_fault_failures.attr,
	&dev_attr_pid.attr,
	NULL
};

static umode_t cdev_file_attr_visible(struct kobject *kobj, struct attribute *a, int n)
{
	struct device *dev = container_of(kobj, typeof(*dev), kobj);
	struct idxd_user_context *ctx = dev_to_uctx(dev);
	struct idxd_wq *wq = ctx->wq;

	if (!wq_pasid_enabled(wq))
		return 0;

	return a->mode;
}

static const struct attribute_group cdev_file_attribute_group = {
	.attrs = cdev_file_attributes,
	.is_visible = cdev_file_attr_visible,
};

static const struct attribute_group *cdev_file_attribute_groups[] = {
	&cdev_file_attribute_group,
	NULL
};

static void idxd_file_dev_release(struct device *dev)
{
	struct idxd_user_context *ctx = dev_to_uctx(dev);
	struct idxd_wq *wq = ctx->wq;
	struct idxd_device *idxd = wq->idxd;
	int rc;

	ida_free(&file_ida, ctx->id);

	/* Wait for in-flight operations to complete. */
	if (wq_shared(wq)) {
		idxd_device_drain_pasid(idxd, ctx->pasid);
	} else {
		if (device_user_pasid_enabled(idxd)) {
			/* The wq disable in the disable pasid function will drain the wq */
			rc = idxd_wq_disable_pasid(wq);
			if (rc < 0)
				dev_err(dev, "wq disable pasid failed.\n");
		} else {
			idxd_wq_drain(wq);
		}
	}

	if (ctx->sva) {
		idxd_cdev_evl_drain_pasid(wq, ctx->pasid);
		iommu_sva_unbind_device(ctx->sva);
		idxd_xa_pasid_remove(ctx);
	}
	kfree(ctx);
	mutex_lock(&wq->wq_lock);
	idxd_wq_put(wq);
	mutex_unlock(&wq->wq_lock);
}

static const struct device_type idxd_cdev_file_type = {
	.name = "idxd_file",
	.release = idxd_file_dev_release,
	.groups = cdev_file_attribute_groups,
};

static void idxd_cdev_dev_release(struct device *dev)
{
	struct idxd_cdev *idxd_cdev = dev_to_cdev(dev);
	struct idxd_cdev_context *cdev_ctx;
	struct idxd_wq *wq = idxd_cdev->wq;

	cdev_ctx = &ictx[wq->idxd->data->type];
	ida_free(&cdev_ctx->minor_ida, idxd_cdev->minor);
	kfree(idxd_cdev);
}

static const struct device_type idxd_cdev_device_type = {
	.name = "idxd_cdev",
	.release = idxd_cdev_dev_release,
};

static inline struct idxd_cdev *inode_idxd_cdev(struct inode *inode)
{
	struct cdev *cdev = inode->i_cdev;

	return container_of(cdev, struct idxd_cdev, cdev);
}

static inline struct idxd_wq *inode_wq(struct inode *inode)
{
	struct idxd_cdev *idxd_cdev = inode_idxd_cdev(inode);

	return idxd_cdev->wq;
}

static void idxd_xa_pasid_remove(struct idxd_user_context *ctx)
{
	struct idxd_wq *wq = ctx->wq;
	void *ptr;

	mutex_lock(&wq->uc_lock);
	ptr = xa_cmpxchg(&wq->upasid_xa, ctx->pasid, ctx, NULL, GFP_KERNEL);
	if (ptr != (void *)ctx)
		dev_warn(&wq->idxd->pdev->dev, "xarray cmpxchg failed for pasid %u\n",
			 ctx->pasid);
	mutex_unlock(&wq->uc_lock);
}

void idxd_user_counter_increment(struct idxd_wq *wq, u32 pasid, int index)
{
	struct idxd_user_context *ctx;

	if (index >= COUNTER_MAX)
		return;

	mutex_lock(&wq->uc_lock);
	ctx = xa_load(&wq->upasid_xa, pasid);
	if (!ctx) {
		mutex_unlock(&wq->uc_lock);
		return;
	}
	ctx->counters[index]++;
	mutex_unlock(&wq->uc_lock);
}

static int idxd_cdev_open(struct inode *inode, struct file *filp)
{
	struct idxd_user_context *ctx;
	struct idxd_device *idxd;
	struct idxd_wq *wq;
	struct device *dev, *fdev;
	int rc = 0;
	struct iommu_sva *sva = NULL;
	unsigned int pasid;
	struct idxd_cdev *idxd_cdev;

	wq = inode_wq(inode);
	idxd = wq->idxd;
	dev = &idxd->pdev->dev;

	dev_dbg(dev, "%s called: %d\n", __func__, idxd_wq_refcount(wq));

	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	mutex_lock(&wq->wq_lock);

	if (idxd_wq_refcount(wq) > 0 && wq_dedicated(wq)) {
		rc = -EBUSY;
		goto failed;
	}

	ctx->wq = wq;
	filp->private_data = ctx;
	ctx->pid = current->pid;

	if (device_user_pasid_enabled(idxd)) {
		sva = iommu_sva_bind_device(dev, current->mm);
		if (IS_ERR(sva)) {
			rc = PTR_ERR(sva);
			dev_err(dev, "pasid allocation failed: %d\n", rc);
			goto failed;
		}

		pasid = iommu_sva_get_pasid(sva);
		if (pasid == IOMMU_PASID_INVALID) {
			rc = -EINVAL;
			goto failed_get_pasid;
		}

		ctx->sva = sva;
		ctx->pasid = pasid;
		ctx->mm = current->mm;

		mutex_lock(&wq->uc_lock);
		rc = xa_insert(&wq->upasid_xa, pasid, ctx, GFP_KERNEL);
		mutex_unlock(&wq->uc_lock);
		if (rc < 0)
			dev_warn(dev, "PASID entry already exist in xarray.\n");

		if (wq_dedicated(wq)) {
			rc = idxd_wq_set_pasid(wq, pasid);
			if (rc < 0) {
				dev_err(dev, "wq set pasid failed: %d\n", rc);
				goto failed_set_pasid;
			}
		}
	}

	idxd_cdev = wq->idxd_cdev;
	ctx->id = ida_alloc(&file_ida, GFP_KERNEL);
	if (ctx->id < 0) {
		dev_warn(dev, "ida alloc failure\n");
		goto failed_ida;
	}
	ctx->idxd_dev.type  = IDXD_DEV_CDEV_FILE;
	fdev = user_ctx_dev(ctx);
	device_initialize(fdev);
	fdev->parent = cdev_dev(idxd_cdev);
	fdev->bus = &dsa_bus_type;
	fdev->type = &idxd_cdev_file_type;

	rc = dev_set_name(fdev, "file%d", ctx->id);
	if (rc < 0) {
		dev_warn(dev, "set name failure\n");
		goto failed_dev_name;
	}

	rc = device_add(fdev);
	if (rc < 0) {
		dev_warn(dev, "file device add failure\n");
		goto failed_dev_add;
	}

	idxd_wq_get(wq);
	mutex_unlock(&wq->wq_lock);
	return 0;

failed_dev_add:
failed_dev_name:
	put_device(fdev);
failed_ida:
failed_set_pasid:
	if (device_user_pasid_enabled(idxd))
		idxd_xa_pasid_remove(ctx);
failed_get_pasid:
	if (device_user_pasid_enabled(idxd) && !IS_ERR_OR_NULL(sva))
		iommu_sva_unbind_device(sva);
failed:
	mutex_unlock(&wq->wq_lock);
	kfree(ctx);
	return rc;
}

static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid)
{
	struct idxd_device *idxd = wq->idxd;
	struct idxd_evl *evl = idxd->evl;
	union evl_status_reg status;
	u16 h, t, size;
	int ent_size = evl_ent_size(idxd);
	struct __evl_entry *entry_head;

	if (!evl)
		return;

	mutex_lock(&evl->lock);
	status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET);
	t = status.tail;
	h = status.head;
	size = evl->size;

	while (h != t) {
		entry_head = (struct __evl_entry *)(evl->log + (h * ent_size));
		if (entry_head->pasid == pasid && entry_head->wq_idx == wq->id)
			set_bit(h, evl->bmap);
		h = (h + 1) % size;
	}
	drain_workqueue(wq->wq);
	mutex_unlock(&evl->lock);
}

static int idxd_cdev_release(struct inode *node, struct file *filep)
{
	struct idxd_user_context *ctx = filep->private_data;
	struct idxd_wq *wq = ctx->wq;
	struct idxd_device *idxd = wq->idxd;
	struct device *dev = &idxd->pdev->dev;

	dev_dbg(dev, "%s called\n", __func__);
	filep->private_data = NULL;

	device_unregister(user_ctx_dev(ctx));

	return 0;
}

static int check_vma(struct idxd_wq *wq, struct vm_area_struct *vma,
		     const char *func)
{
	struct device *dev = &wq->idxd->pdev->dev;

	if ((vma->vm_end - vma->vm_start) > PAGE_SIZE) {
		dev_info_ratelimited(dev,
				     "%s: %s: mapping too large: %lu\n",
				     current->comm, func,
				     vma->vm_end - vma->vm_start);
		return -EINVAL;
	}

	return 0;
}

static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma)
{
	struct idxd_user_context *ctx = filp->private_data;
	struct idxd_wq *wq = ctx->wq;
	struct idxd_device *idxd = wq->idxd;
	struct pci_dev *pdev = idxd->pdev;
	phys_addr_t base = pci_resource_start(pdev, IDXD_WQ_BAR);
	unsigned long pfn;
	int rc;

	dev_dbg(&pdev->dev, "%s called\n", __func__);

	/*
	 * Due to an erratum in some of the devices supported by the driver,
	 * direct user submission to the device can be unsafe.
	 * (See the INTEL-SA-01084 security advisory)
	 *
	 * For the devices that exhibit this behavior, require that the user
	 * has CAP_SYS_RAWIO capabilities.
	 */
	if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO))
		return -EPERM;

	if (current->mm != ctx->mm)
		return -EPERM;

	rc = check_vma(wq, vma, __func__);
	if (rc < 0)
		return rc;

	vm_flags_set(vma, VM_DONTCOPY);
	pfn = (base + idxd_get_wq_portal_full_offset(wq->id,
				IDXD_PORTAL_LIMITED)) >> PAGE_SHIFT;
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
	vma->vm_private_data = ctx;

	return io_remap_pfn_range(vma, vma->vm_start, pfn, PAGE_SIZE,
			vma->vm_page_prot);
}

static int idxd_submit_user_descriptor(struct idxd_user_context *ctx,
				       struct dsa_hw_desc __user *udesc)
{
	struct idxd_wq *wq = ctx->wq;
	struct idxd_dev *idxd_dev = &wq->idxd->idxd_dev;
	const uint64_t comp_addr_align = is_dsa_dev(idxd_dev) ? 0x20 : 0x40;
	void __iomem *portal = idxd_wq_portal_addr(wq);
	struct dsa_hw_desc descriptor __aligned(64);
	int rc;

	rc = copy_from_user(&descriptor, udesc, sizeof(descriptor));
	if (rc)
		return -EFAULT;

	/*
	 * DSA devices are capable of indirect ("batch") command submission.
	 * On devices where direct user submissions are not safe, we cannot
	 * allow this since there is no good way for us to verify these
	 * indirect commands.
	 */
	if (is_dsa_dev(idxd_dev) && descriptor.opcode == DSA_OPCODE_BATCH &&
		!wq->idxd->user_submission_safe)
		return -EINVAL;
	/*
	 * As per the programming specification, the completion address must be
	 * aligned to 32 or 64 bytes. If this is violated the hardware
	 * engine can get very confused (security issue).
	 */
	if (!IS_ALIGNED(descriptor.completion_addr, comp_addr_align))
		return -EINVAL;

	if (wq_dedicated(wq))
		iosubmit_cmds512(portal, &descriptor, 1);
	else {
		descriptor.priv = 0;
		descriptor.pasid = ctx->pasid;
		rc = idxd_enqcmds(wq, portal, &descriptor);
		if (rc < 0)
			return rc;
	}

	return 0;
}

static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_t len,
			       loff_t *unused)
{
	struct dsa_hw_desc __user *udesc = (struct dsa_hw_desc __user *)buf;
	struct idxd_user_context *ctx = filp->private_data;
	ssize_t written = 0;
	int i;

	if (current->mm != ctx->mm)
		return -EPERM;

	for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) {
		int rc = idxd_submit_user_descriptor(ctx, udesc + i);

		if (rc)
			return written ? written : rc;

		written += sizeof(struct dsa_hw_desc);
	}

	return written;
}

static __poll_t idxd_cdev_poll(struct file *filp,
			       struct poll_table_struct *wait)
{
	struct idxd_user_context *ctx = filp->private_data;
	struct idxd_wq *wq = ctx->wq;
	struct idxd_device *idxd = wq->idxd;
	__poll_t out = 0;

	if (current->mm != ctx->mm)
		return POLLNVAL;

	poll_wait(filp, &wq->err_queue, wait);
	spin_lock(&idxd->dev_lock);
	if (idxd->sw_err.valid)
		out = EPOLLIN | EPOLLRDNORM;
	spin_unlock(&idxd->dev_lock);

	return out;
}

static const struct file_operations idxd_cdev_fops = {
	.owner = THIS_MODULE,
	.open = idxd_cdev_open,
	.release = idxd_cdev_release,
	.mmap = idxd_cdev_mmap,
	.write = idxd_cdev_write,
	.poll = idxd_cdev_poll,
};

int idxd_cdev_get_major(struct idxd_device *idxd)
{
	return MAJOR(ictx[idxd->data->type].devt);
}

int idxd_wq_add_cdev(struct idxd_wq *wq)
{
	struct idxd_device *idxd = wq->idxd;
	struct idxd_cdev *idxd_cdev;
	struct cdev *cdev;
	struct device *dev;
	struct idxd_cdev_context *cdev_ctx;
	int rc, minor;

	idxd_cdev = kzalloc(sizeof(*idxd_cdev), GFP_KERNEL);
	if (!idxd_cdev)
		return -ENOMEM;

	idxd_cdev->idxd_dev.type = IDXD_DEV_CDEV;
	idxd_cdev->wq = wq;
	cdev = &idxd_cdev->cdev;
	dev = cdev_dev(idxd_cdev);
	cdev_ctx = &ictx[wq->idxd->data->type];
	minor = ida_alloc_max(&cdev_ctx->minor_ida, MINORMASK, GFP_KERNEL);
	if (minor < 0) {
		kfree(idxd_cdev);
		return minor;
	}
	idxd_cdev->minor = minor;

	device_initialize(dev);
	dev->parent = wq_confdev(wq);
	dev->bus = &dsa_bus_type;
	dev->type = &idxd_cdev_device_type;
	dev->devt = MKDEV(MAJOR(cdev_ctx->devt), minor);

	rc = dev_set_name(dev, "%s/wq%u.%u", idxd->data->name_prefix, idxd->id, wq->id);
	if (rc < 0)
		goto err;

	wq->idxd_cdev = idxd_cdev;
	cdev_init(cdev, &idxd_cdev_fops);
	rc = cdev_device_add(cdev, dev);
	if (rc) {
		dev_dbg(&wq->idxd->pdev->dev, "cdev_add failed: %d\n", rc);
		goto err;
	}

	return 0;

 err:
	put_device(dev);
	wq->idxd_cdev = NULL;
	return rc;
}

void idxd_wq_del_cdev(struct idxd_wq *wq)
{
	struct idxd_cdev *idxd_cdev;

	idxd_cdev = wq->idxd_cdev;
	wq->idxd_cdev = NULL;
	cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev));
	put_device(cdev_dev(idxd_cdev));
}

static int idxd_user_drv_probe(struct idxd_dev *idxd_dev)
{
	struct device *dev = &idxd_dev->conf_dev;
	struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);
	struct idxd_device *idxd = wq->idxd;
	int rc;

	if (idxd->state != IDXD_DEV_ENABLED)
		return -ENXIO;

	mutex_lock(&wq->wq_lock);

	if (!idxd_wq_driver_name_match(wq, dev)) {
		idxd->cmd_status = IDXD_SCMD_WQ_NO_DRV_NAME;
		rc = -ENODEV;
		goto wq_err;
	}

	/*
	 * User type WQ is enabled only when SVA is enabled for two reasons:
	 *   - If no IOMMU or IOMMU Passthrough without SVA, userspace
	 *     can directly access physical address through the WQ.
	 *   - The IDXD cdev driver does not provide any ways to pin
	 *     user pages and translate the address from user VA to IOVA or
	 *     PA without IOMMU SVA. Therefore the application has no way
	 *     to instruct the device to perform DMA function. This makes
	 *     the cdev not usable for normal application usage.
	 */
	if (!device_user_pasid_enabled(idxd)) {
		idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU;
		dev_dbg(&idxd->pdev->dev,
			"User type WQ cannot be enabled without SVA.\n");

		rc = -EOPNOTSUPP;
		goto wq_err;
	}

	wq->wq = create_workqueue(dev_name(wq_confdev(wq)));
	if (!wq->wq) {
		rc = -ENOMEM;
		goto wq_err;
	}

	wq->type = IDXD_WQT_USER;
	rc = idxd_drv_enable_wq(wq);
	if (rc < 0)
		goto err;

	rc = idxd_wq_add_cdev(wq);
	if (rc < 0) {
		idxd->cmd_status = IDXD_SCMD_CDEV_ERR;
		goto err_cdev;
	}

	idxd->cmd_status = 0;
	mutex_unlock(&wq->wq_lock);
	return 0;

err_cdev:
	idxd_drv_disable_wq(wq);
err:
	destroy_workqueue(wq->wq);
	wq->type = IDXD_WQT_NONE;
wq_err:
	mutex_unlock(&wq->wq_lock);
	return rc;
}

static void idxd_user_drv_remove(struct idxd_dev *idxd_dev)
{
	struct idxd_wq *wq = idxd_dev_to_wq(idxd_dev);

	mutex_lock(&wq->wq_lock);
	idxd_wq_del_cdev(wq);
	idxd_drv_disable_wq(wq);
	wq->type = IDXD_WQT_NONE;
	destroy_workqueue(wq->wq);
	wq->wq = NULL;
	mutex_unlock(&wq->wq_lock);
}

static enum idxd_dev_type dev_types[] = {
	IDXD_DEV_WQ,
	IDXD_DEV_NONE,
};

struct idxd_device_driver idxd_user_drv = {
	.probe = idxd_user_drv_probe,
	.remove = idxd_user_drv_remove,
	.name = "user",
	.type = dev_types,
};
EXPORT_SYMBOL_GPL(idxd_user_drv);

int idxd_cdev_register(void)
{
	int rc, i;

	for (i = 0; i < IDXD_TYPE_MAX; i++) {
		ida_init(&ictx[i].minor_ida);
		rc = alloc_chrdev_region(&ictx[i].devt, 0, MINORMASK,
					 ictx[i].name);
		if (rc)
			goto err_free_chrdev_region;
	}

	return 0;

err_free_chrdev_region:
	for (i--; i >= 0; i--)
		unregister_chrdev_region(ictx[i].devt, MINORMASK);

	return rc;
}

void idxd_cdev_remove(void)
{
	int i;

	for (i = 0; i < IDXD_TYPE_MAX; i++) {
		unregister_chrdev_region(ictx[i].devt, MINORMASK);
		ida_destroy(&ictx[i].minor_ida);
	}
}

/**
 * idxd_copy_cr - copy completion record to user address space found by wq and
 *		  PASID
 * @wq:		work queue
 * @pasid:	PASID
 * @addr:	user fault address to write
 * @cr:		completion record
 * @len:	number of bytes to copy
 *
 * This is called by a work that handles completion record fault.
 *
 * Return: number of bytes copied.
 */
int idxd_copy_cr(struct idxd_wq *wq, ioasid_t pasid, unsigned long addr,
		 void *cr, int len)
{
	struct device *dev = &wq->idxd->pdev->dev;
	int left = len, status_size = 1;
	struct idxd_user_context *ctx;
	struct mm_struct *mm;

	mutex_lock(&wq->uc_lock);

	ctx = xa_load(&wq->upasid_xa, pasid);
	if (!ctx) {
		dev_warn(dev, "No user context\n");
		goto out;
	}

	mm = ctx->mm;
	/*
	 * The completion record fault handling work is running in kernel
	 * thread context. It temporarily switches to the mm to copy cr
	 * to addr in the mm.
	 */
	kthread_use_mm(mm);
	left = copy_to_user((void __user *)addr + status_size, cr + status_size,
			    len - status_size);
	/*
	 * Copy status only after the rest of completion record is copied
	 * successfully so that the user gets the complete completion record
	 * when a non-zero status is polled.
	 */
	if (!left) {
		u8 status;

		/*
		 * Ensure that the completion record's status field is written
		 * after the rest of the completion record has been written.
		 * This ensures that the user receives the correct completion
		 * record information once polling for a non-zero status.
		 */
		wmb();
		status = *(u8 *)cr;
		if (put_user(status, (u8 __user *)addr))
			left += status_size;
	} else {
		left += status_size;
	}
	kthread_unuse_mm(mm);

out:
	mutex_unlock(&wq->uc_lock);

	return len - left;
}
