From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Authentication-Results: smtp.codeaurora.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="uDdCBpou" DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 86A50607CF Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752137AbeFFMKT (ORCPT + 25 others); Wed, 6 Jun 2018 08:10:19 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:33779 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750864AbeFFMKR (ORCPT ); Wed, 6 Jun 2018 08:10:17 -0400 X-Google-Smtp-Source: ADUXVKINm+DXv3gBZabgFUf9lMgMD1jgscRK/QAnC5Q5gyeDYlBx0VWpxeVlYFFKW89HHn1jA/GTLw== Subject: Re: [PATCH v2 7/9] xen/gntdev: Implement dma-buf export functionality To: Boris Ostrovsky , xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, konrad.wilk@oracle.com Cc: daniel.vetter@intel.com, dongwon.kim@intel.com, matthew.d.roper@intel.com, Oleksandr Andrushchenko References: <20180601114132.22596-1-andr2000@gmail.com> <20180601114132.22596-8-andr2000@gmail.com> <96dd30f5-6ac6-498f-06e7-352e46994576@oracle.com> From: Oleksandr Andrushchenko Message-ID: <117e05b3-69f6-b879-50d9-0cddd8e4c313@gmail.com> Date: Wed, 6 Jun 2018 15:10:13 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 In-Reply-To: <96dd30f5-6ac6-498f-06e7-352e46994576@oracle.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 06/05/2018 01:07 AM, Boris Ostrovsky wrote: > On 06/01/2018 07:41 AM, Oleksandr Andrushchenko wrote: >> From: Oleksandr Andrushchenko >> >> 1. Create a dma-buf from grant references provided by the foreign >> domain. By default dma-buf is backed by system memory pages, but >> by providing GNTDEV_DMA_FLAG_XXX flags it can also be created >> as a DMA write-combine/coherent buffer, e.g. allocated with >> corresponding dma_alloc_xxx API. >> Export the resulting buffer as a new dma-buf. >> >> 2. Implement waiting for the dma-buf to be released: block until the >> dma-buf with the file descriptor provided is released. >> If within the time-out provided the buffer is not released then >> -ETIMEDOUT error is returned. If the buffer with the file descriptor >> does not exist or has already been released, then -ENOENT is >> returned. For valid file descriptors this must not be treated as >> error. >> >> Signed-off-by: Oleksandr Andrushchenko >> --- >> drivers/xen/gntdev-dmabuf.c | 393 +++++++++++++++++++++++++++++++++++- >> drivers/xen/gntdev-dmabuf.h | 9 +- >> drivers/xen/gntdev.c | 90 ++++++++- >> 3 files changed, 486 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c >> index 6bedd1387bd9..f612468879b4 100644 >> --- a/drivers/xen/gntdev-dmabuf.c >> +++ b/drivers/xen/gntdev-dmabuf.c >> @@ -3,15 +3,58 @@ >> /* >> * Xen dma-buf functionality for gntdev. >> * >> + * DMA buffer implementation is based on drivers/gpu/drm/drm_prime.c. >> + * >> * Copyright (c) 2018 Oleksandr Andrushchenko, EPAM Systems Inc. >> */ >> >> +#include >> #include >> >> #include "gntdev-dmabuf.h" >> >> +struct gntdev_dmabuf { >> + struct gntdev_dmabuf_priv *priv; >> + struct dma_buf *dmabuf; >> + struct list_head next; >> + int fd; >> + >> + union { >> + struct { >> + /* Exported buffers are reference counted. */ >> + struct kref refcount; >> + >> + struct gntdev_priv *priv; >> + struct grant_map *map; >> + void (*release)(struct gntdev_priv *priv, >> + struct grant_map *map); >> + } exp; >> + } u; >> + >> + /* Number of pages this buffer has. */ >> + int nr_pages; >> + /* Pages of this buffer. */ >> + struct page **pages; >> +}; >> + >> +struct gntdev_dmabuf_wait_obj { >> + struct list_head next; >> + struct gntdev_dmabuf *gntdev_dmabuf; >> + struct completion completion; >> +}; >> + >> +struct gntdev_dmabuf_attachment { >> + struct sg_table *sgt; >> + enum dma_data_direction dir; >> +}; >> + >> struct gntdev_dmabuf_priv { >> - int dummy; >> + /* List of exported DMA buffers. */ >> + struct list_head exp_list; >> + /* List of wait objects. */ >> + struct list_head exp_wait_list; >> + /* This is the lock which protects dma_buf_xxx lists. */ >> + struct mutex lock; >> }; >> >> /* ------------------------------------------------------------------ */ >> @@ -22,19 +65,359 @@ struct gntdev_dmabuf_priv { >> /* Implementation of wait for exported DMA buffer to be released. */ >> /* ------------------------------------------------------------------ */ >> >> +static void dmabuf_exp_release(struct kref *kref); >> + >> +static struct gntdev_dmabuf_wait_obj * >> +dmabuf_exp_wait_obj_new(struct gntdev_dmabuf_priv *priv, >> + struct gntdev_dmabuf *gntdev_dmabuf) >> +{ >> + struct gntdev_dmabuf_wait_obj *obj; >> + >> + obj = kzalloc(sizeof(*obj), GFP_KERNEL); >> + if (!obj) >> + return ERR_PTR(-ENOMEM); >> + >> + init_completion(&obj->completion); >> + obj->gntdev_dmabuf = gntdev_dmabuf; >> + >> + mutex_lock(&priv->lock); >> + list_add(&obj->next, &priv->exp_wait_list); >> + /* Put our reference and wait for gntdev_dmabuf's release to fire. */ >> + kref_put(&gntdev_dmabuf->u.exp.refcount, dmabuf_exp_release); >> + mutex_unlock(&priv->lock); >> + return obj; >> +} >> + >> +static void dmabuf_exp_wait_obj_free(struct gntdev_dmabuf_priv *priv, >> + struct gntdev_dmabuf_wait_obj *obj) >> +{ >> + struct gntdev_dmabuf_wait_obj *cur_obj, *q; >> + >> + mutex_lock(&priv->lock); >> + list_for_each_entry_safe(cur_obj, q, &priv->exp_wait_list, next) >> + if (cur_obj == obj) { >> + list_del(&obj->next); >> + kfree(obj); >> + break; >> + } >> + mutex_unlock(&priv->lock); >> +} >> + >> +static int dmabuf_exp_wait_obj_wait(struct gntdev_dmabuf_wait_obj *obj, >> + u32 wait_to_ms) >> +{ >> + if (wait_for_completion_timeout(&obj->completion, >> + msecs_to_jiffies(wait_to_ms)) <= 0) >> + return -ETIMEDOUT; >> + >> + return 0; >> +} >> + >> +static void dmabuf_exp_wait_obj_signal(struct gntdev_dmabuf_priv *priv, >> + struct gntdev_dmabuf *gntdev_dmabuf) >> +{ >> + struct gntdev_dmabuf_wait_obj *obj, *q; >> + >> + list_for_each_entry_safe(obj, q, &priv->exp_wait_list, next) >> + if (obj->gntdev_dmabuf == gntdev_dmabuf) { >> + pr_debug("Found gntdev_dmabuf in the wait list, wake\n"); >> + complete_all(&obj->completion); > break ? sure, thank you >> + } >> +} >> + >> +static struct gntdev_dmabuf * >> +dmabuf_exp_wait_obj_get_by_fd(struct gntdev_dmabuf_priv *priv, int fd) >> +{ >> + struct gntdev_dmabuf *q, *gntdev_dmabuf, *ret = ERR_PTR(-ENOENT); >> + >> + mutex_lock(&priv->lock); >> + list_for_each_entry_safe(gntdev_dmabuf, q, &priv->exp_list, next) >> + if (gntdev_dmabuf->fd == fd) { >> + pr_debug("Found gntdev_dmabuf in the wait list\n"); >> + kref_get(&gntdev_dmabuf->u.exp.refcount); >> + ret = gntdev_dmabuf; >> + break; >> + } >> + mutex_unlock(&priv->lock); >> + return ret; >> +} >> + >> int gntdev_dmabuf_exp_wait_released(struct gntdev_dmabuf_priv *priv, int fd, >> int wait_to_ms) >> { >> - return -EINVAL; >> + struct gntdev_dmabuf *gntdev_dmabuf; >> + struct gntdev_dmabuf_wait_obj *obj; >> + int ret; >> + >> + pr_debug("Will wait for dma-buf with fd %d\n", fd); >> + /* >> + * Try to find the DMA buffer: if not found means that >> + * either the buffer has already been released or file descriptor >> + * provided is wrong. >> + */ >> + gntdev_dmabuf = dmabuf_exp_wait_obj_get_by_fd(priv, fd); >> + if (IS_ERR(gntdev_dmabuf)) >> + return PTR_ERR(gntdev_dmabuf); >> + >> + /* >> + * gntdev_dmabuf still exists and is reference count locked by us now, >> + * so prepare to wait: allocate wait object and add it to the wait list, >> + * so we can find it on release. >> + */ >> + obj = dmabuf_exp_wait_obj_new(priv, gntdev_dmabuf); >> + if (IS_ERR(obj)) { >> + pr_err("Failed to setup wait object, ret %ld\n", PTR_ERR(obj)); > > No need for pr_err. We are out of memory. Will remove > >> + return PTR_ERR(obj); >> +} >> + >> + ret = dmabuf_exp_wait_obj_wait(obj, wait_to_ms); >> + dmabuf_exp_wait_obj_free(priv, obj); >> + return ret; >> } >> >> /* ------------------------------------------------------------------ */ >> /* DMA buffer export support. */ >> /* ------------------------------------------------------------------ */ >> >> +static struct sg_table * >> +dmabuf_pages_to_sgt(struct page **pages, unsigned int nr_pages) >> +{ >> + struct sg_table *sgt; >> + int ret; >> + >> + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); >> + if (!sgt) { >> + ret = -ENOMEM; >> + goto out; >> + } >> + >> + ret = sg_alloc_table_from_pages(sgt, pages, nr_pages, 0, >> + nr_pages << PAGE_SHIFT, >> + GFP_KERNEL); >> + if (ret) >> + goto out; >> + >> + return sgt; >> + >> +out: >> + kfree(sgt); >> + return ERR_PTR(ret); >> +} >> + >> +static int dmabuf_exp_ops_attach(struct dma_buf *dma_buf, >> + struct device *target_dev, >> + struct dma_buf_attachment *attach) >> +{ >> + struct gntdev_dmabuf_attachment *gntdev_dmabuf_attach; >> + >> + gntdev_dmabuf_attach = kzalloc(sizeof(*gntdev_dmabuf_attach), >> + GFP_KERNEL); >> + if (!gntdev_dmabuf_attach) >> + return -ENOMEM; >> + >> + gntdev_dmabuf_attach->dir = DMA_NONE; >> + attach->priv = gntdev_dmabuf_attach; >> + /* Might need to pin the pages of the buffer now. */ > > Who is supposed to pin the pages? The caller? Ok, as we do not implement .mmap for Xen dma-buf and there is no plan to mmap kernel memory (either ballooned or dma_alloc'ed), then we can remove this comment as there is no need to pin/unpin pages. > >> + return 0; >> +} >> + >> +static void dmabuf_exp_ops_detach(struct dma_buf *dma_buf, >> + struct dma_buf_attachment *attach) >> +{ >> + struct gntdev_dmabuf_attachment *gntdev_dmabuf_attach = attach->priv; >> + >> + if (gntdev_dmabuf_attach) { >> + struct sg_table *sgt = gntdev_dmabuf_attach->sgt; >> + >> + if (sgt) { >> + if (gntdev_dmabuf_attach->dir != DMA_NONE) >> + dma_unmap_sg_attrs(attach->dev, sgt->sgl, >> + sgt->nents, >> + gntdev_dmabuf_attach->dir, >> + DMA_ATTR_SKIP_CPU_SYNC); >> + sg_free_table(sgt); >> + } >> + >> + kfree(sgt); >> + kfree(gntdev_dmabuf_attach); >> + attach->priv = NULL; >> + } >> + /* Might need to unpin the pages of the buffer now. */ > Same question. Please see above >> +} >> + >> +static struct sg_table * >> +dmabuf_exp_ops_map_dma_buf(struct dma_buf_attachment *attach, >> + enum dma_data_direction dir) >> +{ >> + struct gntdev_dmabuf_attachment *gntdev_dmabuf_attach = attach->priv; >> + struct gntdev_dmabuf *gntdev_dmabuf = attach->dmabuf->priv; >> + struct sg_table *sgt; >> + >> + pr_debug("Mapping %d pages for dev %p\n", gntdev_dmabuf->nr_pages, >> + attach->dev); >> + >> + if (WARN_ON(dir == DMA_NONE || !gntdev_dmabuf_attach)) > > WARN_ON_ONCE. Here and elsewhere. Why? The UAPI may be used by different applications, thus we might lose warnings for some of them. Having WARN_ON will show problems for multiple users, not for the first one. Does this make sense to still use WARN_ON? > >> + return ERR_PTR(-EINVAL); >> + >> + /* Return the cached mapping when possible. */ >> + if (gntdev_dmabuf_attach->dir == dir) >> + return gntdev_dmabuf_attach->sgt; >> + >> + /* >> + * Two mappings with different directions for the same attachment are >> + * not allowed. >> + */ >> + if (WARN_ON(gntdev_dmabuf_attach->dir != DMA_NONE)) >> + return ERR_PTR(-EBUSY); >> + >> + sgt = dmabuf_pages_to_sgt(gntdev_dmabuf->pages, >> + gntdev_dmabuf->nr_pages); >> + if (!IS_ERR(sgt)) { >> + if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, >> + DMA_ATTR_SKIP_CPU_SYNC)) { >> + sg_free_table(sgt); >> + kfree(sgt); >> + sgt = ERR_PTR(-ENOMEM); >> + } else { >> + gntdev_dmabuf_attach->sgt = sgt; >> + gntdev_dmabuf_attach->dir = dir; >> + } >> + } >> + if (IS_ERR(sgt)) >> + pr_err("Failed to map sg table for dev %p\n", attach->dev); >> + return sgt; >> +} >> + >> +static void dmabuf_exp_ops_unmap_dma_buf(struct dma_buf_attachment *attach, >> + struct sg_table *sgt, >> + enum dma_data_direction dir) >> +{ >> + /* Not implemented. The unmap is done at dmabuf_exp_ops_detach(). */ >> +} >> + >> +static void dmabuf_exp_release(struct kref *kref) >> +{ >> + struct gntdev_dmabuf *gntdev_dmabuf = >> + container_of(kref, struct gntdev_dmabuf, u.exp.refcount); >> + >> + dmabuf_exp_wait_obj_signal(gntdev_dmabuf->priv, gntdev_dmabuf); >> + list_del(&gntdev_dmabuf->next); >> + kfree(gntdev_dmabuf); >> +} >> + >> +static void dmabuf_exp_ops_release(struct dma_buf *dma_buf) >> +{ >> + struct gntdev_dmabuf *gntdev_dmabuf = dma_buf->priv; >> + struct gntdev_dmabuf_priv *priv = gntdev_dmabuf->priv; >> + >> + gntdev_dmabuf->u.exp.release(gntdev_dmabuf->u.exp.priv, >> + gntdev_dmabuf->u.exp.map); >> + mutex_lock(&priv->lock); >> + kref_put(&gntdev_dmabuf->u.exp.refcount, dmabuf_exp_release); >> + mutex_unlock(&priv->lock); >> +} >> + >> +static void *dmabuf_exp_ops_kmap_atomic(struct dma_buf *dma_buf, >> + unsigned long page_num) >> +{ >> + /* Not implemented. */ >> + return NULL; >> +} >> + >> +static void dmabuf_exp_ops_kunmap_atomic(struct dma_buf *dma_buf, >> + unsigned long page_num, void *addr) >> +{ >> + /* Not implemented. */ >> +} >> + >> +static void *dmabuf_exp_ops_kmap(struct dma_buf *dma_buf, >> + unsigned long page_num) >> +{ >> + /* Not implemented. */ >> + return NULL; >> +} >> + >> +static void dmabuf_exp_ops_kunmap(struct dma_buf *dma_buf, >> + unsigned long page_num, void *addr) >> +{ >> + /* Not implemented. */ >> +} >> + >> +static int dmabuf_exp_ops_mmap(struct dma_buf *dma_buf, >> + struct vm_area_struct *vma) >> +{ >> + /* Not implemented. */ >> + return 0; >> +} >> + >> +static const struct dma_buf_ops dmabuf_exp_ops = { >> + .attach = dmabuf_exp_ops_attach, >> + .detach = dmabuf_exp_ops_detach, >> + .map_dma_buf = dmabuf_exp_ops_map_dma_buf, >> + .unmap_dma_buf = dmabuf_exp_ops_unmap_dma_buf, >> + .release = dmabuf_exp_ops_release, >> + .map = dmabuf_exp_ops_kmap, >> + .map_atomic = dmabuf_exp_ops_kmap_atomic, >> + .unmap = dmabuf_exp_ops_kunmap, >> + .unmap_atomic = dmabuf_exp_ops_kunmap_atomic, >> + .mmap = dmabuf_exp_ops_mmap, >> +}; >> + >> int gntdev_dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args) >> { >> - return -EINVAL; >> + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); >> + struct gntdev_dmabuf *gntdev_dmabuf; >> + int ret = 0; >> + >> + gntdev_dmabuf = kzalloc(sizeof(*gntdev_dmabuf), GFP_KERNEL); >> + if (!gntdev_dmabuf) >> + return -ENOMEM; >> + >> + kref_init(&gntdev_dmabuf->u.exp.refcount); >> + >> + gntdev_dmabuf->priv = args->dmabuf_priv; >> + gntdev_dmabuf->nr_pages = args->count; >> + gntdev_dmabuf->pages = args->pages; >> + gntdev_dmabuf->u.exp.priv = args->priv; >> + gntdev_dmabuf->u.exp.map = args->map; >> + gntdev_dmabuf->u.exp.release = args->release; >> + >> + exp_info.exp_name = KBUILD_MODNAME; >> + if (args->dev->driver && args->dev->driver->owner) >> + exp_info.owner = args->dev->driver->owner; >> + else >> + exp_info.owner = THIS_MODULE; >> + exp_info.ops = &dmabuf_exp_ops; >> + exp_info.size = args->count << PAGE_SHIFT; >> + exp_info.flags = O_RDWR; >> + exp_info.priv = gntdev_dmabuf; >> + >> + gntdev_dmabuf->dmabuf = dma_buf_export(&exp_info); >> + if (IS_ERR(gntdev_dmabuf->dmabuf)) { >> + ret = PTR_ERR(gntdev_dmabuf->dmabuf); >> + gntdev_dmabuf->dmabuf = NULL; >> + goto fail; >> + } >> + >> + ret = dma_buf_fd(gntdev_dmabuf->dmabuf, O_CLOEXEC); >> + if (ret < 0) >> + goto fail; >> + >> + gntdev_dmabuf->fd = ret; >> + args->fd = ret; >> + >> + pr_debug("Exporting DMA buffer with fd %d\n", ret); >> + >> + mutex_lock(&args->dmabuf_priv->lock); >> + list_add(&gntdev_dmabuf->next, &args->dmabuf_priv->exp_list); >> + mutex_unlock(&args->dmabuf_priv->lock); >> + return 0; >> + >> +fail: >> + if (gntdev_dmabuf->dmabuf) >> + dma_buf_put(gntdev_dmabuf->dmabuf); >> + kfree(gntdev_dmabuf); >> + return ret; >> } >> >> /* ------------------------------------------------------------------ */ >> @@ -66,6 +449,10 @@ struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void) >> if (!priv) >> return ERR_PTR(-ENOMEM); >> >> + mutex_init(&priv->lock); >> + INIT_LIST_HEAD(&priv->exp_list); >> + INIT_LIST_HEAD(&priv->exp_wait_list); >> + >> return priv; >> } >> >> diff --git a/drivers/xen/gntdev-dmabuf.h b/drivers/xen/gntdev-dmabuf.h >> index 040b2de904ac..95c23a24f640 100644 >> --- a/drivers/xen/gntdev-dmabuf.h >> +++ b/drivers/xen/gntdev-dmabuf.h >> @@ -18,7 +18,14 @@ struct gntdev_dmabuf; >> struct device; >> >> struct gntdev_dmabuf_export_args { >> - int dummy; >> + struct gntdev_priv *priv; >> + struct grant_map *map; >> + void (*release)(struct gntdev_priv *priv, struct grant_map *map); >> + struct gntdev_dmabuf_priv *dmabuf_priv; >> + struct device *dev; >> + int count; >> + struct page **pages; >> + u32 fd; >> }; >> >> struct gntdev_dmabuf_priv *gntdev_dmabuf_init(void); >> diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c >> index 7d58dfb3e5e8..cf255d45f20f 100644 >> --- a/drivers/xen/gntdev.c >> +++ b/drivers/xen/gntdev.c >> @@ -319,6 +319,16 @@ static void gntdev_put_map(struct gntdev_priv *priv, struct grant_map *map) >> gntdev_free_map(map); >> } >> >> +#ifdef CONFIG_XEN_GNTDEV_DMABUF >> +static void gntdev_remove_map(struct gntdev_priv *priv, struct grant_map *map) >> +{ >> + mutex_lock(&priv->lock); >> + list_del(&map->next); >> + gntdev_put_map(NULL /* already removed */, map); >> + mutex_unlock(&priv->lock); >> +} >> +#endif >> + >> /* ------------------------------------------------------------------ */ >> >> static int find_grant_ptes(pte_t *pte, pgtable_t token, >> @@ -1063,12 +1073,88 @@ static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u) >> /* DMA buffer export support. */ >> /* ------------------------------------------------------------------ */ >> >> +static struct grant_map * >> +dmabuf_exp_alloc_backing_storage(struct gntdev_priv *priv, int dmabuf_flags, >> + int count) >> +{ >> + struct grant_map *map; >> + >> + if (unlikely(count <= 0)) >> + return ERR_PTR(-EINVAL); >> + >> + if ((dmabuf_flags & GNTDEV_DMA_FLAG_WC) && >> + (dmabuf_flags & GNTDEV_DMA_FLAG_COHERENT)) { >> + pr_err("Wrong dma-buf flags: either WC or coherent, not both\n"); >> + return ERR_PTR(-EINVAL); >> + } >> + >> + map = gntdev_alloc_map(priv, count, dmabuf_flags); >> + if (!map) >> + return ERR_PTR(-ENOMEM); >> + >> + if (unlikely(atomic_add_return(count, &pages_mapped) > limit)) { >> + pr_err("can't map: over limit\n"); >> + gntdev_put_map(NULL, map); >> + return ERR_PTR(-ENOMEM); >> + } >> + return map; >> +} >> + >> int gntdev_dmabuf_exp_from_refs(struct gntdev_priv *priv, int flags, >> int count, u32 domid, u32 *refs, u32 *fd) >> { >> - /* XXX: this will need to work with gntdev's map, so leave it here. */ >> + struct grant_map *map; >> + struct gntdev_dmabuf_export_args args; >> + int i, ret; >> + >> *fd = -1; >> - return -EINVAL; >> + >> + if (use_ptemod) { >> + pr_err("Cannot provide dma-buf: use_ptemode %d\n", >> + use_ptemod); > No pr_err here please. This can potentially become a DoS vector as it > comes directly from ioctl. > > I would, in fact, revisit other uses of pr_err in this file. Sure, all of pr_err can actually be pr_debug... >> + return -EINVAL; >> + } >> + >> + map = dmabuf_exp_alloc_backing_storage(priv, flags, count); > > @count comes from userspace. dmabuf_exp_alloc_backing_storage only > checks for it to be >0. Should it be checked for some sane max value? This is not easy as it is hard to tell what could be that max value. For DMA buffers if count is too big then allocation will fail, so need to check for max hereĀ  (dma_alloc_{xxx} will filter out too big allocations). For Xen balloon allocations I cannot tell what could be that max value neither. Tough question how to limit. > > -boris Thank you, Oleksandr >> + if (IS_ERR(map)) >> + return PTR_ERR(map); >> + >> + for (i = 0; i < count; i++) { >> + map->grants[i].domid = domid; >> + map->grants[i].ref = refs[i]; >> + } >> + >> + mutex_lock(&priv->lock); >> + gntdev_add_map(priv, map); >> + mutex_unlock(&priv->lock); >> + >> + map->flags |= GNTMAP_host_map; >> +#if defined(CONFIG_X86) >> + map->flags |= GNTMAP_device_map; >> +#endif >> + >> + ret = map_grant_pages(map); >> + if (ret < 0) >> + goto out; >> + >> + args.priv = priv; >> + args.map = map; >> + args.release = gntdev_remove_map; >> + args.dev = priv->dma_dev; >> + args.dmabuf_priv = priv->dmabuf_priv; >> + args.count = map->count; >> + args.pages = map->pages; >> + >> + ret = gntdev_dmabuf_exp_from_pages(&args); >> + if (ret < 0) >> + goto out; >> + >> + *fd = args.fd; >> + return 0; >> + >> +out: >> + gntdev_remove_map(priv, map); >> + return ret; >> } >> >> /* ------------------------------------------------------------------ */ From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: Re: [PATCH v2 7/9] xen/gntdev: Implement dma-buf export functionality Date: Wed, 6 Jun 2018 15:10:13 +0300 Message-ID: <117e05b3-69f6-b879-50d9-0cddd8e4c313@gmail.com> References: <20180601114132.22596-1-andr2000@gmail.com> <20180601114132.22596-8-andr2000@gmail.com> <96dd30f5-6ac6-498f-06e7-352e46994576@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x242.google.com (mail-lf0-x242.google.com [IPv6:2a00:1450:4010:c07::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 048EB6E631 for ; Wed, 6 Jun 2018 12:10:17 +0000 (UTC) Received: by mail-lf0-x242.google.com with SMTP id n15-v6so8716068lfn.10 for ; Wed, 06 Jun 2018 05:10:16 -0700 (PDT) In-Reply-To: <96dd30f5-6ac6-498f-06e7-352e46994576@oracle.com> Content-Language: en-US List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Boris Ostrovsky , xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, konrad.wilk@oracle.com Cc: daniel.vetter@intel.com, dongwon.kim@intel.com, Oleksandr Andrushchenko List-Id: dri-devel@lists.freedesktop.org T24gMDYvMDUvMjAxOCAwMTowNyBBTSwgQm9yaXMgT3N0cm92c2t5IHdyb3RlOgo+IE9uIDA2LzAx LzIwMTggMDc6NDEgQU0sIE9sZWtzYW5kciBBbmRydXNoY2hlbmtvIHdyb3RlOgo+PiBGcm9tOiBP bGVrc2FuZHIgQW5kcnVzaGNoZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBhbS5jb20+ Cj4+Cj4+IDEuIENyZWF0ZSBhIGRtYS1idWYgZnJvbSBncmFudCByZWZlcmVuY2VzIHByb3ZpZGVk IGJ5IHRoZSBmb3JlaWduCj4+ICAgICBkb21haW4uIEJ5IGRlZmF1bHQgZG1hLWJ1ZiBpcyBiYWNr ZWQgYnkgc3lzdGVtIG1lbW9yeSBwYWdlcywgYnV0Cj4+ICAgICBieSBwcm92aWRpbmcgR05UREVW X0RNQV9GTEFHX1hYWCBmbGFncyBpdCBjYW4gYWxzbyBiZSBjcmVhdGVkCj4+ICAgICBhcyBhIERN QSB3cml0ZS1jb21iaW5lL2NvaGVyZW50IGJ1ZmZlciwgZS5nLiBhbGxvY2F0ZWQgd2l0aAo+PiAg ICAgY29ycmVzcG9uZGluZyBkbWFfYWxsb2NfeHh4IEFQSS4KPj4gICAgIEV4cG9ydCB0aGUgcmVz dWx0aW5nIGJ1ZmZlciBhcyBhIG5ldyBkbWEtYnVmLgo+Pgo+PiAyLiBJbXBsZW1lbnQgd2FpdGlu ZyBmb3IgdGhlIGRtYS1idWYgdG8gYmUgcmVsZWFzZWQ6IGJsb2NrIHVudGlsIHRoZQo+PiAgICAg ZG1hLWJ1ZiB3aXRoIHRoZSBmaWxlIGRlc2NyaXB0b3IgcHJvdmlkZWQgaXMgcmVsZWFzZWQuCj4+ ICAgICBJZiB3aXRoaW4gdGhlIHRpbWUtb3V0IHByb3ZpZGVkIHRoZSBidWZmZXIgaXMgbm90IHJl bGVhc2VkIHRoZW4KPj4gICAgIC1FVElNRURPVVQgZXJyb3IgaXMgcmV0dXJuZWQuIElmIHRoZSBi dWZmZXIgd2l0aCB0aGUgZmlsZSBkZXNjcmlwdG9yCj4+ICAgICBkb2VzIG5vdCBleGlzdCBvciBo YXMgYWxyZWFkeSBiZWVuIHJlbGVhc2VkLCB0aGVuIC1FTk9FTlQgaXMKPj4gICAgIHJldHVybmVk LiBGb3IgdmFsaWQgZmlsZSBkZXNjcmlwdG9ycyB0aGlzIG11c3Qgbm90IGJlIHRyZWF0ZWQgYXMK Pj4gICAgIGVycm9yLgo+Pgo+PiBTaWduZWQtb2ZmLWJ5OiBPbGVrc2FuZHIgQW5kcnVzaGNoZW5r byA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBhbS5jb20+Cj4+IC0tLQo+PiAgIGRyaXZlcnMv eGVuL2dudGRldi1kbWFidWYuYyB8IDM5MyArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKy0KPj4gICBkcml2ZXJzL3hlbi9nbnRkZXYtZG1hYnVmLmggfCAgIDkgKy0KPj4gICBkcml2 ZXJzL3hlbi9nbnRkZXYuYyAgICAgICAgfCAgOTAgKysrKysrKystCj4+ICAgMyBmaWxlcyBjaGFu Z2VkLCA0ODYgaW5zZXJ0aW9ucygrKSwgNiBkZWxldGlvbnMoLSkKPj4KPj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMveGVuL2dudGRldi1kbWFidWYuYyBiL2RyaXZlcnMveGVuL2dudGRldi1kbWFidWYu Ywo+PiBpbmRleCA2YmVkZDEzODdiZDkuLmY2MTI0Njg4NzliNCAxMDA2NDQKPj4gLS0tIGEvZHJp dmVycy94ZW4vZ250ZGV2LWRtYWJ1Zi5jCj4+ICsrKyBiL2RyaXZlcnMveGVuL2dudGRldi1kbWFi dWYuYwo+PiBAQCAtMywxNSArMyw1OCBAQAo+PiAgIC8qCj4+ICAgICogWGVuIGRtYS1idWYgZnVu Y3Rpb25hbGl0eSBmb3IgZ250ZGV2Lgo+PiAgICAqCj4+ICsgKiBETUEgYnVmZmVyIGltcGxlbWVu dGF0aW9uIGlzIGJhc2VkIG9uIGRyaXZlcnMvZ3B1L2RybS9kcm1fcHJpbWUuYy4KPj4gKyAqCj4+ ICAgICogQ29weXJpZ2h0IChjKSAyMDE4IE9sZWtzYW5kciBBbmRydXNoY2hlbmtvLCBFUEFNIFN5 c3RlbXMgSW5jLgo+PiAgICAqLwo+PiAgIAo+PiArI2luY2x1ZGUgPGxpbnV4L2RtYS1idWYuaD4K Pj4gICAjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+PiAgIAo+PiAgICNpbmNsdWRlICJnbnRkZXYt ZG1hYnVmLmgiCj4+ICAgCj4+ICtzdHJ1Y3QgZ250ZGV2X2RtYWJ1ZiB7Cj4+ICsJc3RydWN0IGdu dGRldl9kbWFidWZfcHJpdiAqcHJpdjsKPj4gKwlzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmOwo+PiAr CXN0cnVjdCBsaXN0X2hlYWQgbmV4dDsKPj4gKwlpbnQgZmQ7Cj4+ICsKPj4gKwl1bmlvbiB7Cj4+ ICsJCXN0cnVjdCB7Cj4+ICsJCQkvKiBFeHBvcnRlZCBidWZmZXJzIGFyZSByZWZlcmVuY2UgY291 bnRlZC4gKi8KPj4gKwkJCXN0cnVjdCBrcmVmIHJlZmNvdW50Owo+PiArCj4+ICsJCQlzdHJ1Y3Qg Z250ZGV2X3ByaXYgKnByaXY7Cj4+ICsJCQlzdHJ1Y3QgZ3JhbnRfbWFwICptYXA7Cj4+ICsJCQl2 b2lkICgqcmVsZWFzZSkoc3RydWN0IGdudGRldl9wcml2ICpwcml2LAo+PiArCQkJCQlzdHJ1Y3Qg Z3JhbnRfbWFwICptYXApOwo+PiArCQl9IGV4cDsKPj4gKwl9IHU7Cj4+ICsKPj4gKwkvKiBOdW1i ZXIgb2YgcGFnZXMgdGhpcyBidWZmZXIgaGFzLiAqLwo+PiArCWludCBucl9wYWdlczsKPj4gKwkv KiBQYWdlcyBvZiB0aGlzIGJ1ZmZlci4gKi8KPj4gKwlzdHJ1Y3QgcGFnZSAqKnBhZ2VzOwo+PiAr fTsKPj4gKwo+PiArc3RydWN0IGdudGRldl9kbWFidWZfd2FpdF9vYmogewo+PiArCXN0cnVjdCBs aXN0X2hlYWQgbmV4dDsKPj4gKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1ZiAqZ250ZGV2X2RtYWJ1ZjsK Pj4gKwlzdHJ1Y3QgY29tcGxldGlvbiBjb21wbGV0aW9uOwo+PiArfTsKPj4gKwo+PiArc3RydWN0 IGdudGRldl9kbWFidWZfYXR0YWNobWVudCB7Cj4+ICsJc3RydWN0IHNnX3RhYmxlICpzZ3Q7Cj4+ ICsJZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyOwo+PiArfTsKPj4gKwo+PiAgIHN0cnVjdCBn bnRkZXZfZG1hYnVmX3ByaXYgewo+PiAtCWludCBkdW1teTsKPj4gKwkvKiBMaXN0IG9mIGV4cG9y dGVkIERNQSBidWZmZXJzLiAqLwo+PiArCXN0cnVjdCBsaXN0X2hlYWQgZXhwX2xpc3Q7Cj4+ICsJ LyogTGlzdCBvZiB3YWl0IG9iamVjdHMuICovCj4+ICsJc3RydWN0IGxpc3RfaGVhZCBleHBfd2Fp dF9saXN0Owo+PiArCS8qIFRoaXMgaXMgdGhlIGxvY2sgd2hpY2ggcHJvdGVjdHMgZG1hX2J1Zl94 eHggbGlzdHMuICovCj4+ICsJc3RydWN0IG11dGV4IGxvY2s7Cj4+ICAgfTsKPj4gICAKPj4gICAv KiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0gKi8KPj4gQEAgLTIyLDE5ICs2NSwzNTkgQEAgc3RydWN0IGdudGRldl9kbWFi dWZfcHJpdiB7Cj4+ICAgLyogSW1wbGVtZW50YXRpb24gb2Ygd2FpdCBmb3IgZXhwb3J0ZWQgRE1B IGJ1ZmZlciB0byBiZSByZWxlYXNlZC4gICAgICovCj4+ICAgLyogLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCj4+ICAg Cj4+ICtzdGF0aWMgdm9pZCBkbWFidWZfZXhwX3JlbGVhc2Uoc3RydWN0IGtyZWYgKmtyZWYpOwo+ PiArCj4+ICtzdGF0aWMgc3RydWN0IGdudGRldl9kbWFidWZfd2FpdF9vYmogKgo+PiArZG1hYnVm X2V4cF93YWl0X29ial9uZXcoc3RydWN0IGdudGRldl9kbWFidWZfcHJpdiAqcHJpdiwKPj4gKwkJ CXN0cnVjdCBnbnRkZXZfZG1hYnVmICpnbnRkZXZfZG1hYnVmKQo+PiArewo+PiArCXN0cnVjdCBn bnRkZXZfZG1hYnVmX3dhaXRfb2JqICpvYmo7Cj4+ICsKPj4gKwlvYmogPSBremFsbG9jKHNpemVv Zigqb2JqKSwgR0ZQX0tFUk5FTCk7Cj4+ICsJaWYgKCFvYmopCj4+ICsJCXJldHVybiBFUlJfUFRS KC1FTk9NRU0pOwo+PiArCj4+ICsJaW5pdF9jb21wbGV0aW9uKCZvYmotPmNvbXBsZXRpb24pOwo+ PiArCW9iai0+Z250ZGV2X2RtYWJ1ZiA9IGdudGRldl9kbWFidWY7Cj4+ICsKPj4gKwltdXRleF9s b2NrKCZwcml2LT5sb2NrKTsKPj4gKwlsaXN0X2FkZCgmb2JqLT5uZXh0LCAmcHJpdi0+ZXhwX3dh aXRfbGlzdCk7Cj4+ICsJLyogUHV0IG91ciByZWZlcmVuY2UgYW5kIHdhaXQgZm9yIGdudGRldl9k bWFidWYncyByZWxlYXNlIHRvIGZpcmUuICovCj4+ICsJa3JlZl9wdXQoJmdudGRldl9kbWFidWYt PnUuZXhwLnJlZmNvdW50LCBkbWFidWZfZXhwX3JlbGVhc2UpOwo+PiArCW11dGV4X3VubG9jaygm cHJpdi0+bG9jayk7Cj4+ICsJcmV0dXJuIG9iajsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQg ZG1hYnVmX2V4cF93YWl0X29ial9mcmVlKHN0cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYgKnByaXYs Cj4+ICsJCQkJICAgICBzdHJ1Y3QgZ250ZGV2X2RtYWJ1Zl93YWl0X29iaiAqb2JqKQo+PiArewo+ PiArCXN0cnVjdCBnbnRkZXZfZG1hYnVmX3dhaXRfb2JqICpjdXJfb2JqLCAqcTsKPj4gKwo+PiAr CW11dGV4X2xvY2soJnByaXYtPmxvY2spOwo+PiArCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShj dXJfb2JqLCBxLCAmcHJpdi0+ZXhwX3dhaXRfbGlzdCwgbmV4dCkKPj4gKwkJaWYgKGN1cl9vYmog PT0gb2JqKSB7Cj4+ICsJCQlsaXN0X2RlbCgmb2JqLT5uZXh0KTsKPj4gKwkJCWtmcmVlKG9iaik7 Cj4+ICsJCQlicmVhazsKPj4gKwkJfQo+PiArCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cj4+ ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgZG1hYnVmX2V4cF93YWl0X29ial93YWl0KHN0cnVjdCBn bnRkZXZfZG1hYnVmX3dhaXRfb2JqICpvYmosCj4+ICsJCQkJICAgIHUzMiB3YWl0X3RvX21zKQo+ PiArewo+PiArCWlmICh3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJm9iai0+Y29tcGxldGlv biwKPj4gKwkJCW1zZWNzX3RvX2ppZmZpZXMod2FpdF90b19tcykpIDw9IDApCj4+ICsJCXJldHVy biAtRVRJTUVET1VUOwo+PiArCj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2 b2lkIGRtYWJ1Zl9leHBfd2FpdF9vYmpfc2lnbmFsKHN0cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYg KnByaXYsCj4+ICsJCQkJICAgICAgIHN0cnVjdCBnbnRkZXZfZG1hYnVmICpnbnRkZXZfZG1hYnVm KQo+PiArewo+PiArCXN0cnVjdCBnbnRkZXZfZG1hYnVmX3dhaXRfb2JqICpvYmosICpxOwo+PiAr Cj4+ICsJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKG9iaiwgcSwgJnByaXYtPmV4cF93YWl0X2xp c3QsIG5leHQpCj4+ICsJCWlmIChvYmotPmdudGRldl9kbWFidWYgPT0gZ250ZGV2X2RtYWJ1Zikg ewo+PiArCQkJcHJfZGVidWcoIkZvdW5kIGdudGRldl9kbWFidWYgaW4gdGhlIHdhaXQgbGlzdCwg d2FrZVxuIik7Cj4+ICsJCQljb21wbGV0ZV9hbGwoJm9iai0+Y29tcGxldGlvbik7Cj4gYnJlYWsg PwpzdXJlLCB0aGFuayB5b3UKPj4gKwkJfQo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IGdu dGRldl9kbWFidWYgKgo+PiArZG1hYnVmX2V4cF93YWl0X29ial9nZXRfYnlfZmQoc3RydWN0IGdu dGRldl9kbWFidWZfcHJpdiAqcHJpdiwgaW50IGZkKQo+PiArewo+PiArCXN0cnVjdCBnbnRkZXZf ZG1hYnVmICpxLCAqZ250ZGV2X2RtYWJ1ZiwgKnJldCA9IEVSUl9QVFIoLUVOT0VOVCk7Cj4+ICsK Pj4gKwltdXRleF9sb2NrKCZwcml2LT5sb2NrKTsKPj4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3Nh ZmUoZ250ZGV2X2RtYWJ1ZiwgcSwgJnByaXYtPmV4cF9saXN0LCBuZXh0KQo+PiArCQlpZiAoZ250 ZGV2X2RtYWJ1Zi0+ZmQgPT0gZmQpIHsKPj4gKwkJCXByX2RlYnVnKCJGb3VuZCBnbnRkZXZfZG1h YnVmIGluIHRoZSB3YWl0IGxpc3RcbiIpOwo+PiArCQkJa3JlZl9nZXQoJmdudGRldl9kbWFidWYt PnUuZXhwLnJlZmNvdW50KTsKPj4gKwkJCXJldCA9IGdudGRldl9kbWFidWY7Cj4+ICsJCQlicmVh azsKPj4gKwkJfQo+PiArCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cj4+ICsJcmV0dXJuIHJl dDsKPj4gK30KPj4gKwo+PiAgIGludCBnbnRkZXZfZG1hYnVmX2V4cF93YWl0X3JlbGVhc2VkKHN0 cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYgKnByaXYsIGludCBmZCwKPj4gICAJCQkJICAgIGludCB3 YWl0X3RvX21zKQo+PiAgIHsKPj4gLQlyZXR1cm4gLUVJTlZBTDsKPj4gKwlzdHJ1Y3QgZ250ZGV2 X2RtYWJ1ZiAqZ250ZGV2X2RtYWJ1ZjsKPj4gKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1Zl93YWl0X29i aiAqb2JqOwo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwlwcl9kZWJ1ZygiV2lsbCB3YWl0IGZvciBk bWEtYnVmIHdpdGggZmQgJWRcbiIsIGZkKTsKPj4gKwkvKgo+PiArCSAqIFRyeSB0byBmaW5kIHRo ZSBETUEgYnVmZmVyOiBpZiBub3QgZm91bmQgbWVhbnMgdGhhdAo+PiArCSAqIGVpdGhlciB0aGUg YnVmZmVyIGhhcyBhbHJlYWR5IGJlZW4gcmVsZWFzZWQgb3IgZmlsZSBkZXNjcmlwdG9yCj4+ICsJ ICogcHJvdmlkZWQgaXMgd3JvbmcuCj4+ICsJICovCj4+ICsJZ250ZGV2X2RtYWJ1ZiA9IGRtYWJ1 Zl9leHBfd2FpdF9vYmpfZ2V0X2J5X2ZkKHByaXYsIGZkKTsKPj4gKwlpZiAoSVNfRVJSKGdudGRl dl9kbWFidWYpKQo+PiArCQlyZXR1cm4gUFRSX0VSUihnbnRkZXZfZG1hYnVmKTsKPj4gKwo+PiAr CS8qCj4+ICsJICogZ250ZGV2X2RtYWJ1ZiBzdGlsbCBleGlzdHMgYW5kIGlzIHJlZmVyZW5jZSBj b3VudCBsb2NrZWQgYnkgdXMgbm93LAo+PiArCSAqIHNvIHByZXBhcmUgdG8gd2FpdDogYWxsb2Nh dGUgd2FpdCBvYmplY3QgYW5kIGFkZCBpdCB0byB0aGUgd2FpdCBsaXN0LAo+PiArCSAqIHNvIHdl IGNhbiBmaW5kIGl0IG9uIHJlbGVhc2UuCj4+ICsJICovCj4+ICsJb2JqID0gZG1hYnVmX2V4cF93 YWl0X29ial9uZXcocHJpdiwgZ250ZGV2X2RtYWJ1Zik7Cj4+ICsJaWYgKElTX0VSUihvYmopKSB7 Cj4+ICsJCXByX2VycigiRmFpbGVkIHRvIHNldHVwIHdhaXQgb2JqZWN0LCByZXQgJWxkXG4iLCBQ VFJfRVJSKG9iaikpOwo+Cj4gTm8gbmVlZCBmb3IgcHJfZXJyLiBXZSBhcmUgb3V0IG9mIG1lbW9y eS4KV2lsbCByZW1vdmUKPgo+PiArCQlyZXR1cm4gUFRSX0VSUihvYmopOwo+PiArfQo+PiArCj4+ ICsJcmV0ID0gZG1hYnVmX2V4cF93YWl0X29ial93YWl0KG9iaiwgd2FpdF90b19tcyk7Cj4+ICsJ ZG1hYnVmX2V4cF93YWl0X29ial9mcmVlKHByaXYsIG9iaik7Cj4+ICsJcmV0dXJuIHJldDsKPj4g ICB9Cj4+ICAgCj4+ICAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCj4+ICAgLyogRE1BIGJ1ZmZlciBleHBvcnQg c3VwcG9ydC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCj4+ICAg LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tICovCj4+ICAgCj4+ICtzdGF0aWMgc3RydWN0IHNnX3RhYmxlICoKPj4gK2Rt YWJ1Zl9wYWdlc190b19zZ3Qoc3RydWN0IHBhZ2UgKipwYWdlcywgdW5zaWduZWQgaW50IG5yX3Bh Z2VzKQo+PiArewo+PiArCXN0cnVjdCBzZ190YWJsZSAqc2d0Owo+PiArCWludCByZXQ7Cj4+ICsK Pj4gKwlzZ3QgPSBrbWFsbG9jKHNpemVvZigqc2d0KSwgR0ZQX0tFUk5FTCk7Cj4+ICsJaWYgKCFz Z3QpIHsKPj4gKwkJcmV0ID0gLUVOT01FTTsKPj4gKwkJZ290byBvdXQ7Cj4+ICsJfQo+PiArCj4+ ICsJcmV0ID0gc2dfYWxsb2NfdGFibGVfZnJvbV9wYWdlcyhzZ3QsIHBhZ2VzLCBucl9wYWdlcywg MCwKPj4gKwkJCQkJbnJfcGFnZXMgPDwgUEFHRV9TSElGVCwKPj4gKwkJCQkJR0ZQX0tFUk5FTCk7 Cj4+ICsJaWYgKHJldCkKPj4gKwkJZ290byBvdXQ7Cj4+ICsKPj4gKwlyZXR1cm4gc2d0Owo+PiAr Cj4+ICtvdXQ6Cj4+ICsJa2ZyZWUoc2d0KTsKPj4gKwlyZXR1cm4gRVJSX1BUUihyZXQpOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgaW50IGRtYWJ1Zl9leHBfb3BzX2F0dGFjaChzdHJ1Y3QgZG1hX2J1 ZiAqZG1hX2J1ZiwKPj4gKwkJCQkgc3RydWN0IGRldmljZSAqdGFyZ2V0X2RldiwKPj4gKwkJCQkg c3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNoKQo+PiArewo+PiArCXN0cnVjdCBnbnRk ZXZfZG1hYnVmX2F0dGFjaG1lbnQgKmdudGRldl9kbWFidWZfYXR0YWNoOwo+PiArCj4+ICsJZ250 ZGV2X2RtYWJ1Zl9hdHRhY2ggPSBremFsbG9jKHNpemVvZigqZ250ZGV2X2RtYWJ1Zl9hdHRhY2gp LAo+PiArCQkJCSAgICAgICBHRlBfS0VSTkVMKTsKPj4gKwlpZiAoIWdudGRldl9kbWFidWZfYXR0 YWNoKQo+PiArCQlyZXR1cm4gLUVOT01FTTsKPj4gKwo+PiArCWdudGRldl9kbWFidWZfYXR0YWNo LT5kaXIgPSBETUFfTk9ORTsKPj4gKwlhdHRhY2gtPnByaXYgPSBnbnRkZXZfZG1hYnVmX2F0dGFj aDsKPj4gKwkvKiBNaWdodCBuZWVkIHRvIHBpbiB0aGUgcGFnZXMgb2YgdGhlIGJ1ZmZlciBub3cu ICovCj4KPiBXaG8gaXMgc3VwcG9zZWQgdG8gcGluIHRoZSBwYWdlcz8gVGhlIGNhbGxlcj8KT2ss IGFzIHdlIGRvIG5vdCBpbXBsZW1lbnQgLm1tYXAgZm9yIFhlbiBkbWEtYnVmIGFuZCB0aGVyZSBp cwpubyBwbGFuIHRvIG1tYXAga2VybmVsIG1lbW9yeSAoZWl0aGVyIGJhbGxvb25lZCBvciBkbWFf YWxsb2MnZWQpLAp0aGVuIHdlIGNhbiByZW1vdmUgdGhpcyBjb21tZW50IGFzIHRoZXJlIGlzIG5v IG5lZWQgdG8gcGluL3VucGluCnBhZ2VzLgo+Cj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4g K3N0YXRpYyB2b2lkIGRtYWJ1Zl9leHBfb3BzX2RldGFjaChzdHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1 ZiwKPj4gKwkJCQkgIHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQgKmF0dGFjaCkKPj4gK3sKPj4g KwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1Zl9hdHRhY2htZW50ICpnbnRkZXZfZG1hYnVmX2F0dGFjaCA9 IGF0dGFjaC0+cHJpdjsKPj4gKwo+PiArCWlmIChnbnRkZXZfZG1hYnVmX2F0dGFjaCkgewo+PiAr CQlzdHJ1Y3Qgc2dfdGFibGUgKnNndCA9IGdudGRldl9kbWFidWZfYXR0YWNoLT5zZ3Q7Cj4+ICsK Pj4gKwkJaWYgKHNndCkgewo+PiArCQkJaWYgKGdudGRldl9kbWFidWZfYXR0YWNoLT5kaXIgIT0g RE1BX05PTkUpCj4+ICsJCQkJZG1hX3VubWFwX3NnX2F0dHJzKGF0dGFjaC0+ZGV2LCBzZ3QtPnNn bCwKPj4gKwkJCQkJCSAgIHNndC0+bmVudHMsCj4+ICsJCQkJCQkgICBnbnRkZXZfZG1hYnVmX2F0 dGFjaC0+ZGlyLAo+PiArCQkJCQkJICAgRE1BX0FUVFJfU0tJUF9DUFVfU1lOQyk7Cj4+ICsJCQlz Z19mcmVlX3RhYmxlKHNndCk7Cj4+ICsJCX0KPj4gKwo+PiArCQlrZnJlZShzZ3QpOwo+PiArCQlr ZnJlZShnbnRkZXZfZG1hYnVmX2F0dGFjaCk7Cj4+ICsJCWF0dGFjaC0+cHJpdiA9IE5VTEw7Cj4+ ICsJfQo+PiArCS8qIE1pZ2h0IG5lZWQgdG8gdW5waW4gdGhlIHBhZ2VzIG9mIHRoZSBidWZmZXIg bm93LiAqLwo+IFNhbWUgcXVlc3Rpb24uClBsZWFzZSBzZWUgYWJvdmUKPj4gK30KPj4gKwo+PiAr c3RhdGljIHN0cnVjdCBzZ190YWJsZSAqCj4+ICtkbWFidWZfZXhwX29wc19tYXBfZG1hX2J1Zihz dHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICphdHRhY2gsCj4+ICsJCQkgICBlbnVtIGRtYV9kYXRh X2RpcmVjdGlvbiBkaXIpCj4+ICt7Cj4+ICsJc3RydWN0IGdudGRldl9kbWFidWZfYXR0YWNobWVu dCAqZ250ZGV2X2RtYWJ1Zl9hdHRhY2ggPSBhdHRhY2gtPnByaXY7Cj4+ICsJc3RydWN0IGdudGRl dl9kbWFidWYgKmdudGRldl9kbWFidWYgPSBhdHRhY2gtPmRtYWJ1Zi0+cHJpdjsKPj4gKwlzdHJ1 Y3Qgc2dfdGFibGUgKnNndDsKPj4gKwo+PiArCXByX2RlYnVnKCJNYXBwaW5nICVkIHBhZ2VzIGZv ciBkZXYgJXBcbiIsIGdudGRldl9kbWFidWYtPm5yX3BhZ2VzLAo+PiArCQkgYXR0YWNoLT5kZXYp Owo+PiArCj4+ICsJaWYgKFdBUk5fT04oZGlyID09IERNQV9OT05FIHx8ICFnbnRkZXZfZG1hYnVm X2F0dGFjaCkpCj4KPiBXQVJOX09OX09OQ0UuIEhlcmUgYW5kIGVsc2V3aGVyZS4KV2h5PyBUaGUg VUFQSSBtYXkgYmUgdXNlZCBieSBkaWZmZXJlbnQgYXBwbGljYXRpb25zLCB0aHVzIHdlIG1pZ2h0 Cmxvc2Ugd2FybmluZ3MgZm9yIHNvbWUgb2YgdGhlbS4gSGF2aW5nIFdBUk5fT04gd2lsbCBzaG93 IHByb2JsZW1zCmZvciBtdWx0aXBsZSB1c2Vycywgbm90IGZvciB0aGUgZmlyc3Qgb25lLgpEb2Vz IHRoaXMgbWFrZSBzZW5zZSB0byBzdGlsbCB1c2UgV0FSTl9PTj8KPgo+PiArCQlyZXR1cm4gRVJS X1BUUigtRUlOVkFMKTsKPj4gKwo+PiArCS8qIFJldHVybiB0aGUgY2FjaGVkIG1hcHBpbmcgd2hl biBwb3NzaWJsZS4gKi8KPj4gKwlpZiAoZ250ZGV2X2RtYWJ1Zl9hdHRhY2gtPmRpciA9PSBkaXIp Cj4+ICsJCXJldHVybiBnbnRkZXZfZG1hYnVmX2F0dGFjaC0+c2d0Owo+PiArCj4+ICsJLyoKPj4g KwkgKiBUd28gbWFwcGluZ3Mgd2l0aCBkaWZmZXJlbnQgZGlyZWN0aW9ucyBmb3IgdGhlIHNhbWUg YXR0YWNobWVudCBhcmUKPj4gKwkgKiBub3QgYWxsb3dlZC4KPj4gKwkgKi8KPj4gKwlpZiAoV0FS Tl9PTihnbnRkZXZfZG1hYnVmX2F0dGFjaC0+ZGlyICE9IERNQV9OT05FKSkKPj4gKwkJcmV0dXJu IEVSUl9QVFIoLUVCVVNZKTsKPj4gKwo+PiArCXNndCA9IGRtYWJ1Zl9wYWdlc190b19zZ3QoZ250 ZGV2X2RtYWJ1Zi0+cGFnZXMsCj4+ICsJCQkJICBnbnRkZXZfZG1hYnVmLT5ucl9wYWdlcyk7Cj4+ ICsJaWYgKCFJU19FUlIoc2d0KSkgewo+PiArCQlpZiAoIWRtYV9tYXBfc2dfYXR0cnMoYXR0YWNo LT5kZXYsIHNndC0+c2dsLCBzZ3QtPm5lbnRzLCBkaXIsCj4+ICsJCQkJICAgICAgRE1BX0FUVFJf U0tJUF9DUFVfU1lOQykpIHsKPj4gKwkJCXNnX2ZyZWVfdGFibGUoc2d0KTsKPj4gKwkJCWtmcmVl KHNndCk7Cj4+ICsJCQlzZ3QgPSBFUlJfUFRSKC1FTk9NRU0pOwo+PiArCQl9IGVsc2Ugewo+PiAr CQkJZ250ZGV2X2RtYWJ1Zl9hdHRhY2gtPnNndCA9IHNndDsKPj4gKwkJCWdudGRldl9kbWFidWZf YXR0YWNoLT5kaXIgPSBkaXI7Cj4+ICsJCX0KPj4gKwl9Cj4+ICsJaWYgKElTX0VSUihzZ3QpKQo+ PiArCQlwcl9lcnIoIkZhaWxlZCB0byBtYXAgc2cgdGFibGUgZm9yIGRldiAlcFxuIiwgYXR0YWNo LT5kZXYpOwo+PiArCXJldHVybiBzZ3Q7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGRtYWJ1 Zl9leHBfb3BzX3VubWFwX2RtYV9idWYoc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNo LAo+PiArCQkJCQkgc3RydWN0IHNnX3RhYmxlICpzZ3QsCj4+ICsJCQkJCSBlbnVtIGRtYV9kYXRh X2RpcmVjdGlvbiBkaXIpCj4+ICt7Cj4+ICsJLyogTm90IGltcGxlbWVudGVkLiBUaGUgdW5tYXAg aXMgZG9uZSBhdCBkbWFidWZfZXhwX29wc19kZXRhY2goKS4gKi8KPj4gK30KPj4gKwo+PiArc3Rh dGljIHZvaWQgZG1hYnVmX2V4cF9yZWxlYXNlKHN0cnVjdCBrcmVmICprcmVmKQo+PiArewo+PiAr CXN0cnVjdCBnbnRkZXZfZG1hYnVmICpnbnRkZXZfZG1hYnVmID0KPj4gKwkJY29udGFpbmVyX29m KGtyZWYsIHN0cnVjdCBnbnRkZXZfZG1hYnVmLCB1LmV4cC5yZWZjb3VudCk7Cj4+ICsKPj4gKwlk bWFidWZfZXhwX3dhaXRfb2JqX3NpZ25hbChnbnRkZXZfZG1hYnVmLT5wcml2LCBnbnRkZXZfZG1h YnVmKTsKPj4gKwlsaXN0X2RlbCgmZ250ZGV2X2RtYWJ1Zi0+bmV4dCk7Cj4+ICsJa2ZyZWUoZ250 ZGV2X2RtYWJ1Zik7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGRtYWJ1Zl9leHBfb3BzX3Jl bGVhc2Uoc3RydWN0IGRtYV9idWYgKmRtYV9idWYpCj4+ICt7Cj4+ICsJc3RydWN0IGdudGRldl9k bWFidWYgKmdudGRldl9kbWFidWYgPSBkbWFfYnVmLT5wcml2Owo+PiArCXN0cnVjdCBnbnRkZXZf ZG1hYnVmX3ByaXYgKnByaXYgPSBnbnRkZXZfZG1hYnVmLT5wcml2Owo+PiArCj4+ICsJZ250ZGV2 X2RtYWJ1Zi0+dS5leHAucmVsZWFzZShnbnRkZXZfZG1hYnVmLT51LmV4cC5wcml2LAo+PiArCQkJ CSAgICAgZ250ZGV2X2RtYWJ1Zi0+dS5leHAubWFwKTsKPj4gKwltdXRleF9sb2NrKCZwcml2LT5s b2NrKTsKPj4gKwlrcmVmX3B1dCgmZ250ZGV2X2RtYWJ1Zi0+dS5leHAucmVmY291bnQsIGRtYWJ1 Zl9leHBfcmVsZWFzZSk7Cj4+ICsJbXV0ZXhfdW5sb2NrKCZwcml2LT5sb2NrKTsKPj4gK30KPj4g Kwo+PiArc3RhdGljIHZvaWQgKmRtYWJ1Zl9leHBfb3BzX2ttYXBfYXRvbWljKHN0cnVjdCBkbWFf YnVmICpkbWFfYnVmLAo+PiArCQkJCQl1bnNpZ25lZCBsb25nIHBhZ2VfbnVtKQo+PiArewo+PiAr CS8qIE5vdCBpbXBsZW1lbnRlZC4gKi8KPj4gKwlyZXR1cm4gTlVMTDsKPj4gK30KPj4gKwo+PiAr c3RhdGljIHZvaWQgZG1hYnVmX2V4cF9vcHNfa3VubWFwX2F0b21pYyhzdHJ1Y3QgZG1hX2J1ZiAq ZG1hX2J1ZiwKPj4gKwkJCQkJIHVuc2lnbmVkIGxvbmcgcGFnZV9udW0sIHZvaWQgKmFkZHIpCj4+ ICt7Cj4+ICsJLyogTm90IGltcGxlbWVudGVkLiAqLwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9p ZCAqZG1hYnVmX2V4cF9vcHNfa21hcChzdHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1ZiwKPj4gKwkJCQkg dW5zaWduZWQgbG9uZyBwYWdlX251bSkKPj4gK3sKPj4gKwkvKiBOb3QgaW1wbGVtZW50ZWQuICov Cj4+ICsJcmV0dXJuIE5VTEw7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGRtYWJ1Zl9leHBf b3BzX2t1bm1hcChzdHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1ZiwKPj4gKwkJCQkgIHVuc2lnbmVkIGxv bmcgcGFnZV9udW0sIHZvaWQgKmFkZHIpCj4+ICt7Cj4+ICsJLyogTm90IGltcGxlbWVudGVkLiAq Lwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGRtYWJ1Zl9leHBfb3BzX21tYXAoc3RydWN0IGRt YV9idWYgKmRtYV9idWYsCj4+ICsJCQkgICAgICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEp Cj4+ICt7Cj4+ICsJLyogTm90IGltcGxlbWVudGVkLiAqLwo+PiArCXJldHVybiAwOwo+PiArfQo+ PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRtYV9idWZfb3BzIGRtYWJ1Zl9leHBfb3BzID0g IHsKPj4gKwkuYXR0YWNoID0gZG1hYnVmX2V4cF9vcHNfYXR0YWNoLAo+PiArCS5kZXRhY2ggPSBk bWFidWZfZXhwX29wc19kZXRhY2gsCj4+ICsJLm1hcF9kbWFfYnVmID0gZG1hYnVmX2V4cF9vcHNf bWFwX2RtYV9idWYsCj4+ICsJLnVubWFwX2RtYV9idWYgPSBkbWFidWZfZXhwX29wc191bm1hcF9k bWFfYnVmLAo+PiArCS5yZWxlYXNlID0gZG1hYnVmX2V4cF9vcHNfcmVsZWFzZSwKPj4gKwkubWFw ID0gZG1hYnVmX2V4cF9vcHNfa21hcCwKPj4gKwkubWFwX2F0b21pYyA9IGRtYWJ1Zl9leHBfb3Bz X2ttYXBfYXRvbWljLAo+PiArCS51bm1hcCA9IGRtYWJ1Zl9leHBfb3BzX2t1bm1hcCwKPj4gKwku dW5tYXBfYXRvbWljID0gZG1hYnVmX2V4cF9vcHNfa3VubWFwX2F0b21pYywKPj4gKwkubW1hcCA9 IGRtYWJ1Zl9leHBfb3BzX21tYXAsCj4+ICt9Owo+PiArCj4+ICAgaW50IGdudGRldl9kbWFidWZf ZXhwX2Zyb21fcGFnZXMoc3RydWN0IGdudGRldl9kbWFidWZfZXhwb3J0X2FyZ3MgKmFyZ3MpCj4+ ICAgewo+PiAtCXJldHVybiAtRUlOVkFMOwo+PiArCURFRklORV9ETUFfQlVGX0VYUE9SVF9JTkZP KGV4cF9pbmZvKTsKPj4gKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1ZiAqZ250ZGV2X2RtYWJ1ZjsKPj4g KwlpbnQgcmV0ID0gMDsKPj4gKwo+PiArCWdudGRldl9kbWFidWYgPSBremFsbG9jKHNpemVvZigq Z250ZGV2X2RtYWJ1ZiksIEdGUF9LRVJORUwpOwo+PiArCWlmICghZ250ZGV2X2RtYWJ1ZikKPj4g KwkJcmV0dXJuIC1FTk9NRU07Cj4+ICsKPj4gKwlrcmVmX2luaXQoJmdudGRldl9kbWFidWYtPnUu ZXhwLnJlZmNvdW50KTsKPj4gKwo+PiArCWdudGRldl9kbWFidWYtPnByaXYgPSBhcmdzLT5kbWFi dWZfcHJpdjsKPj4gKwlnbnRkZXZfZG1hYnVmLT5ucl9wYWdlcyA9IGFyZ3MtPmNvdW50Owo+PiAr CWdudGRldl9kbWFidWYtPnBhZ2VzID0gYXJncy0+cGFnZXM7Cj4+ICsJZ250ZGV2X2RtYWJ1Zi0+ dS5leHAucHJpdiA9IGFyZ3MtPnByaXY7Cj4+ICsJZ250ZGV2X2RtYWJ1Zi0+dS5leHAubWFwID0g YXJncy0+bWFwOwo+PiArCWdudGRldl9kbWFidWYtPnUuZXhwLnJlbGVhc2UgPSBhcmdzLT5yZWxl YXNlOwo+PiArCj4+ICsJZXhwX2luZm8uZXhwX25hbWUgPSBLQlVJTERfTU9ETkFNRTsKPj4gKwlp ZiAoYXJncy0+ZGV2LT5kcml2ZXIgJiYgYXJncy0+ZGV2LT5kcml2ZXItPm93bmVyKQo+PiArCQll eHBfaW5mby5vd25lciA9IGFyZ3MtPmRldi0+ZHJpdmVyLT5vd25lcjsKPj4gKwllbHNlCj4+ICsJ CWV4cF9pbmZvLm93bmVyID0gVEhJU19NT0RVTEU7Cj4+ICsJZXhwX2luZm8ub3BzID0gJmRtYWJ1 Zl9leHBfb3BzOwo+PiArCWV4cF9pbmZvLnNpemUgPSBhcmdzLT5jb3VudCA8PCBQQUdFX1NISUZU Owo+PiArCWV4cF9pbmZvLmZsYWdzID0gT19SRFdSOwo+PiArCWV4cF9pbmZvLnByaXYgPSBnbnRk ZXZfZG1hYnVmOwo+PiArCj4+ICsJZ250ZGV2X2RtYWJ1Zi0+ZG1hYnVmID0gZG1hX2J1Zl9leHBv cnQoJmV4cF9pbmZvKTsKPj4gKwlpZiAoSVNfRVJSKGdudGRldl9kbWFidWYtPmRtYWJ1ZikpIHsK Pj4gKwkJcmV0ID0gUFRSX0VSUihnbnRkZXZfZG1hYnVmLT5kbWFidWYpOwo+PiArCQlnbnRkZXZf ZG1hYnVmLT5kbWFidWYgPSBOVUxMOwo+PiArCQlnb3RvIGZhaWw7Cj4+ICsJfQo+PiArCj4+ICsJ cmV0ID0gZG1hX2J1Zl9mZChnbnRkZXZfZG1hYnVmLT5kbWFidWYsIE9fQ0xPRVhFQyk7Cj4+ICsJ aWYgKHJldCA8IDApCj4+ICsJCWdvdG8gZmFpbDsKPj4gKwo+PiArCWdudGRldl9kbWFidWYtPmZk ID0gcmV0Owo+PiArCWFyZ3MtPmZkID0gcmV0Owo+PiArCj4+ICsJcHJfZGVidWcoIkV4cG9ydGlu ZyBETUEgYnVmZmVyIHdpdGggZmQgJWRcbiIsIHJldCk7Cj4+ICsKPj4gKwltdXRleF9sb2NrKCZh cmdzLT5kbWFidWZfcHJpdi0+bG9jayk7Cj4+ICsJbGlzdF9hZGQoJmdudGRldl9kbWFidWYtPm5l eHQsICZhcmdzLT5kbWFidWZfcHJpdi0+ZXhwX2xpc3QpOwo+PiArCW11dGV4X3VubG9jaygmYXJn cy0+ZG1hYnVmX3ByaXYtPmxvY2spOwo+PiArCXJldHVybiAwOwo+PiArCj4+ICtmYWlsOgo+PiAr CWlmIChnbnRkZXZfZG1hYnVmLT5kbWFidWYpCj4+ICsJCWRtYV9idWZfcHV0KGdudGRldl9kbWFi dWYtPmRtYWJ1Zik7Cj4+ICsJa2ZyZWUoZ250ZGV2X2RtYWJ1Zik7Cj4+ICsJcmV0dXJuIHJldDsK Pj4gICB9Cj4+ICAgCj4+ICAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCj4+IEBAIC02Niw2ICs0NDksMTAgQEAg c3RydWN0IGdudGRldl9kbWFidWZfcHJpdiAqZ250ZGV2X2RtYWJ1Zl9pbml0KHZvaWQpCj4+ICAg CWlmICghcHJpdikKPj4gICAJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwo+PiAgIAo+PiArCW11 dGV4X2luaXQoJnByaXYtPmxvY2spOwo+PiArCUlOSVRfTElTVF9IRUFEKCZwcml2LT5leHBfbGlz dCk7Cj4+ICsJSU5JVF9MSVNUX0hFQUQoJnByaXYtPmV4cF93YWl0X2xpc3QpOwo+PiArCj4+ICAg CXJldHVybiBwcml2Owo+PiAgIH0KPj4gICAKPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMveGVuL2du dGRldi1kbWFidWYuaCBiL2RyaXZlcnMveGVuL2dudGRldi1kbWFidWYuaAo+PiBpbmRleCAwNDBi MmRlOTA0YWMuLjk1YzIzYTI0ZjY0MCAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy94ZW4vZ250ZGV2 LWRtYWJ1Zi5oCj4+ICsrKyBiL2RyaXZlcnMveGVuL2dudGRldi1kbWFidWYuaAo+PiBAQCAtMTgs NyArMTgsMTQgQEAgc3RydWN0IGdudGRldl9kbWFidWY7Cj4+ICAgc3RydWN0IGRldmljZTsKPj4g ICAKPj4gICBzdHJ1Y3QgZ250ZGV2X2RtYWJ1Zl9leHBvcnRfYXJncyB7Cj4+IC0JaW50IGR1bW15 Owo+PiArCXN0cnVjdCBnbnRkZXZfcHJpdiAqcHJpdjsKPj4gKwlzdHJ1Y3QgZ3JhbnRfbWFwICpt YXA7Cj4+ICsJdm9pZCAoKnJlbGVhc2UpKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJpdiwgc3RydWN0 IGdyYW50X21hcCAqbWFwKTsKPj4gKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1Zl9wcml2ICpkbWFidWZf cHJpdjsKPj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4+ICsJaW50IGNvdW50Owo+PiArCXN0cnVj dCBwYWdlICoqcGFnZXM7Cj4+ICsJdTMyIGZkOwo+PiAgIH07Cj4+ICAgCj4+ICAgc3RydWN0IGdu dGRldl9kbWFidWZfcHJpdiAqZ250ZGV2X2RtYWJ1Zl9pbml0KHZvaWQpOwo+PiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy94ZW4vZ250ZGV2LmMgYi9kcml2ZXJzL3hlbi9nbnRkZXYuYwo+PiBpbmRleCA3 ZDU4ZGZiM2U1ZTguLmNmMjU1ZDQ1ZjIwZiAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy94ZW4vZ250 ZGV2LmMKPj4gKysrIGIvZHJpdmVycy94ZW4vZ250ZGV2LmMKPj4gQEAgLTMxOSw2ICszMTksMTYg QEAgc3RhdGljIHZvaWQgZ250ZGV2X3B1dF9tYXAoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCBz dHJ1Y3QgZ3JhbnRfbWFwICptYXApCj4+ICAgCWdudGRldl9mcmVlX21hcChtYXApOwo+PiAgIH0K Pj4gICAKPj4gKyNpZmRlZiBDT05GSUdfWEVOX0dOVERFVl9ETUFCVUYKPj4gK3N0YXRpYyB2b2lk IGdudGRldl9yZW1vdmVfbWFwKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJpdiwgc3RydWN0IGdyYW50 X21hcCAqbWFwKQo+PiArewo+PiArCW11dGV4X2xvY2soJnByaXYtPmxvY2spOwo+PiArCWxpc3Rf ZGVsKCZtYXAtPm5leHQpOwo+PiArCWdudGRldl9wdXRfbWFwKE5VTEwgLyogYWxyZWFkeSByZW1v dmVkICovLCBtYXApOwo+PiArCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cj4+ICt9Cj4+ICsj ZW5kaWYKPj4gKwo+PiAgIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwo+PiAgIAo+PiAgIHN0YXRpYyBpbnQgZmlu ZF9ncmFudF9wdGVzKHB0ZV90ICpwdGUsIHBndGFibGVfdCB0b2tlbiwKPj4gQEAgLTEwNjMsMTIg KzEwNzMsODggQEAgc3RhdGljIGxvbmcgZ250ZGV2X2lvY3RsX2dyYW50X2NvcHkoc3RydWN0IGdu dGRldl9wcml2ICpwcml2LCB2b2lkIF9fdXNlciAqdSkKPj4gICAvKiBETUEgYnVmZmVyIGV4cG9y dCBzdXBwb3J0LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KPj4g ICAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0gKi8KPj4gICAKPj4gK3N0YXRpYyBzdHJ1Y3QgZ3JhbnRfbWFwICoKPj4g K2RtYWJ1Zl9leHBfYWxsb2NfYmFja2luZ19zdG9yYWdlKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJp diwgaW50IGRtYWJ1Zl9mbGFncywKPj4gKwkJCQkgaW50IGNvdW50KQo+PiArewo+PiArCXN0cnVj dCBncmFudF9tYXAgKm1hcDsKPj4gKwo+PiArCWlmICh1bmxpa2VseShjb3VudCA8PSAwKSkKPj4g KwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4+ICsKPj4gKwlpZiAoKGRtYWJ1Zl9mbGFncyAm IEdOVERFVl9ETUFfRkxBR19XQykgJiYKPj4gKwkgICAgKGRtYWJ1Zl9mbGFncyAmIEdOVERFVl9E TUFfRkxBR19DT0hFUkVOVCkpIHsKPj4gKwkJcHJfZXJyKCJXcm9uZyBkbWEtYnVmIGZsYWdzOiBl aXRoZXIgV0Mgb3IgY29oZXJlbnQsIG5vdCBib3RoXG4iKTsKPj4gKwkJcmV0dXJuIEVSUl9QVFIo LUVJTlZBTCk7Cj4+ICsJfQo+PiArCj4+ICsJbWFwID0gZ250ZGV2X2FsbG9jX21hcChwcml2LCBj b3VudCwgZG1hYnVmX2ZsYWdzKTsKPj4gKwlpZiAoIW1hcCkKPj4gKwkJcmV0dXJuIEVSUl9QVFIo LUVOT01FTSk7Cj4+ICsKPj4gKwlpZiAodW5saWtlbHkoYXRvbWljX2FkZF9yZXR1cm4oY291bnQs ICZwYWdlc19tYXBwZWQpID4gbGltaXQpKSB7Cj4+ICsJCXByX2VycigiY2FuJ3QgbWFwOiBvdmVy IGxpbWl0XG4iKTsKPj4gKwkJZ250ZGV2X3B1dF9tYXAoTlVMTCwgbWFwKTsKPj4gKwkJcmV0dXJu IEVSUl9QVFIoLUVOT01FTSk7Cj4+ICsJfQo+PiArCXJldHVybiBtYXA7Cj4+ICt9Cj4+ICsKPj4g ICBpbnQgZ250ZGV2X2RtYWJ1Zl9leHBfZnJvbV9yZWZzKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJp diwgaW50IGZsYWdzLAo+PiAgIAkJCQlpbnQgY291bnQsIHUzMiBkb21pZCwgdTMyICpyZWZzLCB1 MzIgKmZkKQo+PiAgIHsKPj4gLQkvKiBYWFg6IHRoaXMgd2lsbCBuZWVkIHRvIHdvcmsgd2l0aCBn bnRkZXYncyBtYXAsIHNvIGxlYXZlIGl0IGhlcmUuICovCj4+ICsJc3RydWN0IGdyYW50X21hcCAq bWFwOwo+PiArCXN0cnVjdCBnbnRkZXZfZG1hYnVmX2V4cG9ydF9hcmdzIGFyZ3M7Cj4+ICsJaW50 IGksIHJldDsKPj4gKwo+PiAgIAkqZmQgPSAtMTsKPj4gLQlyZXR1cm4gLUVJTlZBTDsKPj4gKwo+ PiArCWlmICh1c2VfcHRlbW9kKSB7Cj4+ICsJCXByX2VycigiQ2Fubm90IHByb3ZpZGUgZG1hLWJ1 ZjogdXNlX3B0ZW1vZGUgJWRcbiIsCj4+ICsJCSAgICAgICB1c2VfcHRlbW9kKTsKPiBObyBwcl9l cnIgaGVyZSBwbGVhc2UuIFRoaXMgY2FuIHBvdGVudGlhbGx5IGJlY29tZSBhIERvUyB2ZWN0b3Ig YXMgaXQKPiBjb21lcyBkaXJlY3RseSBmcm9tIGlvY3RsLgo+Cj4gSSB3b3VsZCwgaW4gZmFjdCwg cmV2aXNpdCBvdGhlciB1c2VzIG9mIHByX2VyciBpbiB0aGlzIGZpbGUuClN1cmUsIGFsbCBvZiBw cl9lcnIgY2FuIGFjdHVhbGx5IGJlIHByX2RlYnVnLi4uCj4+ICsJCXJldHVybiAtRUlOVkFMOwo+ PiArCX0KPj4gKwo+PiArCW1hcCA9IGRtYWJ1Zl9leHBfYWxsb2NfYmFja2luZ19zdG9yYWdlKHBy aXYsIGZsYWdzLCBjb3VudCk7Cj4KPiBAY291bnQgY29tZXMgZnJvbSB1c2Vyc3BhY2UuIGRtYWJ1 Zl9leHBfYWxsb2NfYmFja2luZ19zdG9yYWdlIG9ubHkKPiBjaGVja3MgZm9yIGl0IHRvIGJlID4w LiBTaG91bGQgaXQgYmUgY2hlY2tlZCBmb3Igc29tZSBzYW5lIG1heCB2YWx1ZT8KVGhpcyBpcyBu b3QgZWFzeSBhcyBpdCBpcyBoYXJkIHRvIHRlbGwgd2hhdCBjb3VsZCBiZSB0aGF0Cm1heCB2YWx1 ZS4gRm9yIERNQSBidWZmZXJzIGlmIGNvdW50IGlzIHRvbyBiaWcgdGhlbiBhbGxvY2F0aW9uCndp bGwgZmFpbCwgc28gbmVlZCB0byBjaGVjayBmb3IgbWF4IGhlcmXCoCAoZG1hX2FsbG9jX3t4eHh9 IHdpbGwKZmlsdGVyIG91dCB0b28gYmlnIGFsbG9jYXRpb25zKS4KRm9yIFhlbiBiYWxsb29uIGFs bG9jYXRpb25zIEkgY2Fubm90IHRlbGwgd2hhdCBjb3VsZCBiZSB0aGF0Cm1heCB2YWx1ZSBuZWl0 aGVyLiBUb3VnaCBxdWVzdGlvbiBob3cgdG8gbGltaXQuCj4KPiAtYm9yaXMKVGhhbmsgeW91LApP bGVrc2FuZHIKPj4gKwlpZiAoSVNfRVJSKG1hcCkpCj4+ICsJCXJldHVybiBQVFJfRVJSKG1hcCk7 Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewo+PiArCQltYXAtPmdyYW50 c1tpXS5kb21pZCA9IGRvbWlkOwo+PiArCQltYXAtPmdyYW50c1tpXS5yZWYgPSByZWZzW2ldOwo+ PiArCX0KPj4gKwo+PiArCW11dGV4X2xvY2soJnByaXYtPmxvY2spOwo+PiArCWdudGRldl9hZGRf bWFwKHByaXYsIG1hcCk7Cj4+ICsJbXV0ZXhfdW5sb2NrKCZwcml2LT5sb2NrKTsKPj4gKwo+PiAr CW1hcC0+ZmxhZ3MgfD0gR05UTUFQX2hvc3RfbWFwOwo+PiArI2lmIGRlZmluZWQoQ09ORklHX1g4 NikKPj4gKwltYXAtPmZsYWdzIHw9IEdOVE1BUF9kZXZpY2VfbWFwOwo+PiArI2VuZGlmCj4+ICsK Pj4gKwlyZXQgPSBtYXBfZ3JhbnRfcGFnZXMobWFwKTsKPj4gKwlpZiAocmV0IDwgMCkKPj4gKwkJ Z290byBvdXQ7Cj4+ICsKPj4gKwlhcmdzLnByaXYgPSBwcml2Owo+PiArCWFyZ3MubWFwID0gbWFw Owo+PiArCWFyZ3MucmVsZWFzZSA9IGdudGRldl9yZW1vdmVfbWFwOwo+PiArCWFyZ3MuZGV2ID0g cHJpdi0+ZG1hX2RldjsKPj4gKwlhcmdzLmRtYWJ1Zl9wcml2ID0gcHJpdi0+ZG1hYnVmX3ByaXY7 Cj4+ICsJYXJncy5jb3VudCA9IG1hcC0+Y291bnQ7Cj4+ICsJYXJncy5wYWdlcyA9IG1hcC0+cGFn ZXM7Cj4+ICsKPj4gKwlyZXQgPSBnbnRkZXZfZG1hYnVmX2V4cF9mcm9tX3BhZ2VzKCZhcmdzKTsK Pj4gKwlpZiAocmV0IDwgMCkKPj4gKwkJZ290byBvdXQ7Cj4+ICsKPj4gKwkqZmQgPSBhcmdzLmZk Owo+PiArCXJldHVybiAwOwo+PiArCj4+ICtvdXQ6Cj4+ICsJZ250ZGV2X3JlbW92ZV9tYXAocHJp diwgbWFwKTsKPj4gKwlyZXR1cm4gcmV0Owo+PiAgIH0KPj4gICAKPj4gICAvKiAtLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0g Ki8KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1k ZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczov L2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=