From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752101AbeFALm3 (ORCPT ); Fri, 1 Jun 2018 07:42:29 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:33779 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751092AbeFALlw (ORCPT ); Fri, 1 Jun 2018 07:41:52 -0400 X-Google-Smtp-Source: ADUXVKLbo0auvw9ZYm5/TZK5OHCuGPgT+OozLXIlPmdlwSLV5J2DtONW3Jql4gVejXvDcYRXdkWI6Q== From: Oleksandr Andrushchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Cc: daniel.vetter@intel.com, andr2000@gmail.com, dongwon.kim@intel.com, matthew.d.roper@intel.com, Oleksandr Andrushchenko Subject: [PATCH v2 7/9] xen/gntdev: Implement dma-buf export functionality Date: Fri, 1 Jun 2018 14:41:30 +0300 Message-Id: <20180601114132.22596-8-andr2000@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180601114132.22596-1-andr2000@gmail.com> References: <20180601114132.22596-1-andr2000@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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); + } +} + +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)); + 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. */ + 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. */ +} + +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)) + 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); + return -EINVAL; + } + + map = dmabuf_exp_alloc_backing_storage(priv, flags, count); + 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; } /* ------------------------------------------------------------------ */ -- 2.17.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: [PATCH v2 7/9] xen/gntdev: Implement dma-buf export functionality Date: Fri, 1 Jun 2018 14:41:30 +0300 Message-ID: <20180601114132.22596-8-andr2000@gmail.com> References: <20180601114132.22596-1-andr2000@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x244.google.com (mail-lf0-x244.google.com [IPv6:2a00:1450:4010:c07::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 503826E67A for ; Fri, 1 Jun 2018 11:41:52 +0000 (UTC) Received: by mail-lf0-x244.google.com with SMTP id n18-v6so14357251lfh.10 for ; Fri, 01 Jun 2018 04:41:52 -0700 (PDT) In-Reply-To: <20180601114132.22596-1-andr2000@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Cc: andr2000@gmail.com, daniel.vetter@intel.com, dongwon.kim@intel.com, Oleksandr Andrushchenko List-Id: dri-devel@lists.freedesktop.org RnJvbTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVw YW0uY29tPgoKMS4gQ3JlYXRlIGEgZG1hLWJ1ZiBmcm9tIGdyYW50IHJlZmVyZW5jZXMgcHJvdmlk ZWQgYnkgdGhlIGZvcmVpZ24KICAgZG9tYWluLiBCeSBkZWZhdWx0IGRtYS1idWYgaXMgYmFja2Vk IGJ5IHN5c3RlbSBtZW1vcnkgcGFnZXMsIGJ1dAogICBieSBwcm92aWRpbmcgR05UREVWX0RNQV9G TEFHX1hYWCBmbGFncyBpdCBjYW4gYWxzbyBiZSBjcmVhdGVkCiAgIGFzIGEgRE1BIHdyaXRlLWNv bWJpbmUvY29oZXJlbnQgYnVmZmVyLCBlLmcuIGFsbG9jYXRlZCB3aXRoCiAgIGNvcnJlc3BvbmRp bmcgZG1hX2FsbG9jX3h4eCBBUEkuCiAgIEV4cG9ydCB0aGUgcmVzdWx0aW5nIGJ1ZmZlciBhcyBh IG5ldyBkbWEtYnVmLgoKMi4gSW1wbGVtZW50IHdhaXRpbmcgZm9yIHRoZSBkbWEtYnVmIHRvIGJl IHJlbGVhc2VkOiBibG9jayB1bnRpbCB0aGUKICAgZG1hLWJ1ZiB3aXRoIHRoZSBmaWxlIGRlc2Ny aXB0b3IgcHJvdmlkZWQgaXMgcmVsZWFzZWQuCiAgIElmIHdpdGhpbiB0aGUgdGltZS1vdXQgcHJv dmlkZWQgdGhlIGJ1ZmZlciBpcyBub3QgcmVsZWFzZWQgdGhlbgogICAtRVRJTUVET1VUIGVycm9y IGlzIHJldHVybmVkLiBJZiB0aGUgYnVmZmVyIHdpdGggdGhlIGZpbGUgZGVzY3JpcHRvcgogICBk b2VzIG5vdCBleGlzdCBvciBoYXMgYWxyZWFkeSBiZWVuIHJlbGVhc2VkLCB0aGVuIC1FTk9FTlQg aXMKICAgcmV0dXJuZWQuIEZvciB2YWxpZCBmaWxlIGRlc2NyaXB0b3JzIHRoaXMgbXVzdCBub3Qg YmUgdHJlYXRlZCBhcwogICBlcnJvci4KClNpZ25lZC1vZmYtYnk6IE9sZWtzYW5kciBBbmRydXNo Y2hlbmtvIDxvbGVrc2FuZHJfYW5kcnVzaGNoZW5rb0BlcGFtLmNvbT4KLS0tCiBkcml2ZXJzL3hl bi9nbnRkZXYtZG1hYnVmLmMgfCAzOTMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KystCiBkcml2ZXJzL3hlbi9nbnRkZXYtZG1hYnVmLmggfCAgIDkgKy0KIGRyaXZlcnMveGVuL2du dGRldi5jICAgICAgICB8ICA5MCArKysrKysrKy0KIDMgZmlsZXMgY2hhbmdlZCwgNDg2IGluc2Vy dGlvbnMoKyksIDYgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vZ250ZGV2 LWRtYWJ1Zi5jIGIvZHJpdmVycy94ZW4vZ250ZGV2LWRtYWJ1Zi5jCmluZGV4IDZiZWRkMTM4N2Jk OS4uZjYxMjQ2ODg3OWI0IDEwMDY0NAotLS0gYS9kcml2ZXJzL3hlbi9nbnRkZXYtZG1hYnVmLmMK KysrIGIvZHJpdmVycy94ZW4vZ250ZGV2LWRtYWJ1Zi5jCkBAIC0zLDE1ICszLDU4IEBACiAvKgog ICogWGVuIGRtYS1idWYgZnVuY3Rpb25hbGl0eSBmb3IgZ250ZGV2LgogICoKKyAqIERNQSBidWZm ZXIgaW1wbGVtZW50YXRpb24gaXMgYmFzZWQgb24gZHJpdmVycy9ncHUvZHJtL2RybV9wcmltZS5j LgorICoKICAqIENvcHlyaWdodCAoYykgMjAxOCBPbGVrc2FuZHIgQW5kcnVzaGNoZW5rbywgRVBB TSBTeXN0ZW1zIEluYy4KICAqLwogCisjaW5jbHVkZSA8bGludXgvZG1hLWJ1Zi5oPgogI2luY2x1 ZGUgPGxpbnV4L3NsYWIuaD4KIAogI2luY2x1ZGUgImdudGRldi1kbWFidWYuaCIKIAorc3RydWN0 IGdudGRldl9kbWFidWYgeworCXN0cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYgKnByaXY7CisJc3Ry dWN0IGRtYV9idWYgKmRtYWJ1ZjsKKwlzdHJ1Y3QgbGlzdF9oZWFkIG5leHQ7CisJaW50IGZkOwor CisJdW5pb24geworCQlzdHJ1Y3QgeworCQkJLyogRXhwb3J0ZWQgYnVmZmVycyBhcmUgcmVmZXJl bmNlIGNvdW50ZWQuICovCisJCQlzdHJ1Y3Qga3JlZiByZWZjb3VudDsKKworCQkJc3RydWN0IGdu dGRldl9wcml2ICpwcml2OworCQkJc3RydWN0IGdyYW50X21hcCAqbWFwOworCQkJdm9pZCAoKnJl bGVhc2UpKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJpdiwKKwkJCQkJc3RydWN0IGdyYW50X21hcCAq bWFwKTsKKwkJfSBleHA7CisJfSB1OworCisJLyogTnVtYmVyIG9mIHBhZ2VzIHRoaXMgYnVmZmVy IGhhcy4gKi8KKwlpbnQgbnJfcGFnZXM7CisJLyogUGFnZXMgb2YgdGhpcyBidWZmZXIuICovCisJ c3RydWN0IHBhZ2UgKipwYWdlczsKK307CisKK3N0cnVjdCBnbnRkZXZfZG1hYnVmX3dhaXRfb2Jq IHsKKwlzdHJ1Y3QgbGlzdF9oZWFkIG5leHQ7CisJc3RydWN0IGdudGRldl9kbWFidWYgKmdudGRl dl9kbWFidWY7CisJc3RydWN0IGNvbXBsZXRpb24gY29tcGxldGlvbjsKK307CisKK3N0cnVjdCBn bnRkZXZfZG1hYnVmX2F0dGFjaG1lbnQgeworCXN0cnVjdCBzZ190YWJsZSAqc2d0OworCWVudW0g ZG1hX2RhdGFfZGlyZWN0aW9uIGRpcjsKK307CisKIHN0cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYg ewotCWludCBkdW1teTsKKwkvKiBMaXN0IG9mIGV4cG9ydGVkIERNQSBidWZmZXJzLiAqLworCXN0 cnVjdCBsaXN0X2hlYWQgZXhwX2xpc3Q7CisJLyogTGlzdCBvZiB3YWl0IG9iamVjdHMuICovCisJ c3RydWN0IGxpc3RfaGVhZCBleHBfd2FpdF9saXN0OworCS8qIFRoaXMgaXMgdGhlIGxvY2sgd2hp Y2ggcHJvdGVjdHMgZG1hX2J1Zl94eHggbGlzdHMuICovCisJc3RydWN0IG11dGV4IGxvY2s7CiB9 OwogCiAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0gKi8KQEAgLTIyLDE5ICs2NSwzNTkgQEAgc3RydWN0IGdudGRldl9k bWFidWZfcHJpdiB7CiAvKiBJbXBsZW1lbnRhdGlvbiBvZiB3YWl0IGZvciBleHBvcnRlZCBETUEg YnVmZmVyIHRvIGJlIHJlbGVhc2VkLiAgICAgKi8KIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogCitzdGF0aWMg dm9pZCBkbWFidWZfZXhwX3JlbGVhc2Uoc3RydWN0IGtyZWYgKmtyZWYpOworCitzdGF0aWMgc3Ry dWN0IGdudGRldl9kbWFidWZfd2FpdF9vYmogKgorZG1hYnVmX2V4cF93YWl0X29ial9uZXcoc3Ry dWN0IGdudGRldl9kbWFidWZfcHJpdiAqcHJpdiwKKwkJCXN0cnVjdCBnbnRkZXZfZG1hYnVmICpn bnRkZXZfZG1hYnVmKQoreworCXN0cnVjdCBnbnRkZXZfZG1hYnVmX3dhaXRfb2JqICpvYmo7CisK KwlvYmogPSBremFsbG9jKHNpemVvZigqb2JqKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFvYmopCisJ CXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOworCisJaW5pdF9jb21wbGV0aW9uKCZvYmotPmNvbXBs ZXRpb24pOworCW9iai0+Z250ZGV2X2RtYWJ1ZiA9IGdudGRldl9kbWFidWY7CisKKwltdXRleF9s b2NrKCZwcml2LT5sb2NrKTsKKwlsaXN0X2FkZCgmb2JqLT5uZXh0LCAmcHJpdi0+ZXhwX3dhaXRf bGlzdCk7CisJLyogUHV0IG91ciByZWZlcmVuY2UgYW5kIHdhaXQgZm9yIGdudGRldl9kbWFidWYn cyByZWxlYXNlIHRvIGZpcmUuICovCisJa3JlZl9wdXQoJmdudGRldl9kbWFidWYtPnUuZXhwLnJl ZmNvdW50LCBkbWFidWZfZXhwX3JlbGVhc2UpOworCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7 CisJcmV0dXJuIG9iajsKK30KKworc3RhdGljIHZvaWQgZG1hYnVmX2V4cF93YWl0X29ial9mcmVl KHN0cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYgKnByaXYsCisJCQkJICAgICBzdHJ1Y3QgZ250ZGV2 X2RtYWJ1Zl93YWl0X29iaiAqb2JqKQoreworCXN0cnVjdCBnbnRkZXZfZG1hYnVmX3dhaXRfb2Jq ICpjdXJfb2JqLCAqcTsKKworCW11dGV4X2xvY2soJnByaXYtPmxvY2spOworCWxpc3RfZm9yX2Vh Y2hfZW50cnlfc2FmZShjdXJfb2JqLCBxLCAmcHJpdi0+ZXhwX3dhaXRfbGlzdCwgbmV4dCkKKwkJ aWYgKGN1cl9vYmogPT0gb2JqKSB7CisJCQlsaXN0X2RlbCgmb2JqLT5uZXh0KTsKKwkJCWtmcmVl KG9iaik7CisJCQlicmVhazsKKwkJfQorCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cit9CisK K3N0YXRpYyBpbnQgZG1hYnVmX2V4cF93YWl0X29ial93YWl0KHN0cnVjdCBnbnRkZXZfZG1hYnVm X3dhaXRfb2JqICpvYmosCisJCQkJICAgIHUzMiB3YWl0X3RvX21zKQoreworCWlmICh3YWl0X2Zv cl9jb21wbGV0aW9uX3RpbWVvdXQoJm9iai0+Y29tcGxldGlvbiwKKwkJCW1zZWNzX3RvX2ppZmZp ZXMod2FpdF90b19tcykpIDw9IDApCisJCXJldHVybiAtRVRJTUVET1VUOworCisJcmV0dXJuIDA7 Cit9CisKK3N0YXRpYyB2b2lkIGRtYWJ1Zl9leHBfd2FpdF9vYmpfc2lnbmFsKHN0cnVjdCBnbnRk ZXZfZG1hYnVmX3ByaXYgKnByaXYsCisJCQkJICAgICAgIHN0cnVjdCBnbnRkZXZfZG1hYnVmICpn bnRkZXZfZG1hYnVmKQoreworCXN0cnVjdCBnbnRkZXZfZG1hYnVmX3dhaXRfb2JqICpvYmosICpx OworCisJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKG9iaiwgcSwgJnByaXYtPmV4cF93YWl0X2xp c3QsIG5leHQpCisJCWlmIChvYmotPmdudGRldl9kbWFidWYgPT0gZ250ZGV2X2RtYWJ1Zikgewor CQkJcHJfZGVidWcoIkZvdW5kIGdudGRldl9kbWFidWYgaW4gdGhlIHdhaXQgbGlzdCwgd2FrZVxu Iik7CisJCQljb21wbGV0ZV9hbGwoJm9iai0+Y29tcGxldGlvbik7CisJCX0KK30KKworc3RhdGlj IHN0cnVjdCBnbnRkZXZfZG1hYnVmICoKK2RtYWJ1Zl9leHBfd2FpdF9vYmpfZ2V0X2J5X2ZkKHN0 cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYgKnByaXYsIGludCBmZCkKK3sKKwlzdHJ1Y3QgZ250ZGV2 X2RtYWJ1ZiAqcSwgKmdudGRldl9kbWFidWYsICpyZXQgPSBFUlJfUFRSKC1FTk9FTlQpOworCisJ bXV0ZXhfbG9jaygmcHJpdi0+bG9jayk7CisJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGdudGRl dl9kbWFidWYsIHEsICZwcml2LT5leHBfbGlzdCwgbmV4dCkKKwkJaWYgKGdudGRldl9kbWFidWYt PmZkID09IGZkKSB7CisJCQlwcl9kZWJ1ZygiRm91bmQgZ250ZGV2X2RtYWJ1ZiBpbiB0aGUgd2Fp dCBsaXN0XG4iKTsKKwkJCWtyZWZfZ2V0KCZnbnRkZXZfZG1hYnVmLT51LmV4cC5yZWZjb3VudCk7 CisJCQlyZXQgPSBnbnRkZXZfZG1hYnVmOworCQkJYnJlYWs7CisJCX0KKwltdXRleF91bmxvY2so JnByaXYtPmxvY2spOworCXJldHVybiByZXQ7Cit9CisKIGludCBnbnRkZXZfZG1hYnVmX2V4cF93 YWl0X3JlbGVhc2VkKHN0cnVjdCBnbnRkZXZfZG1hYnVmX3ByaXYgKnByaXYsIGludCBmZCwKIAkJ CQkgICAgaW50IHdhaXRfdG9fbXMpCiB7Ci0JcmV0dXJuIC1FSU5WQUw7CisJc3RydWN0IGdudGRl dl9kbWFidWYgKmdudGRldl9kbWFidWY7CisJc3RydWN0IGdudGRldl9kbWFidWZfd2FpdF9vYmog Km9iajsKKwlpbnQgcmV0OworCisJcHJfZGVidWcoIldpbGwgd2FpdCBmb3IgZG1hLWJ1ZiB3aXRo IGZkICVkXG4iLCBmZCk7CisJLyoKKwkgKiBUcnkgdG8gZmluZCB0aGUgRE1BIGJ1ZmZlcjogaWYg bm90IGZvdW5kIG1lYW5zIHRoYXQKKwkgKiBlaXRoZXIgdGhlIGJ1ZmZlciBoYXMgYWxyZWFkeSBi ZWVuIHJlbGVhc2VkIG9yIGZpbGUgZGVzY3JpcHRvcgorCSAqIHByb3ZpZGVkIGlzIHdyb25nLgor CSAqLworCWdudGRldl9kbWFidWYgPSBkbWFidWZfZXhwX3dhaXRfb2JqX2dldF9ieV9mZChwcml2 LCBmZCk7CisJaWYgKElTX0VSUihnbnRkZXZfZG1hYnVmKSkKKwkJcmV0dXJuIFBUUl9FUlIoZ250 ZGV2X2RtYWJ1Zik7CisKKwkvKgorCSAqIGdudGRldl9kbWFidWYgc3RpbGwgZXhpc3RzIGFuZCBp cyByZWZlcmVuY2UgY291bnQgbG9ja2VkIGJ5IHVzIG5vdywKKwkgKiBzbyBwcmVwYXJlIHRvIHdh aXQ6IGFsbG9jYXRlIHdhaXQgb2JqZWN0IGFuZCBhZGQgaXQgdG8gdGhlIHdhaXQgbGlzdCwKKwkg KiBzbyB3ZSBjYW4gZmluZCBpdCBvbiByZWxlYXNlLgorCSAqLworCW9iaiA9IGRtYWJ1Zl9leHBf d2FpdF9vYmpfbmV3KHByaXYsIGdudGRldl9kbWFidWYpOworCWlmIChJU19FUlIob2JqKSkgewor CQlwcl9lcnIoIkZhaWxlZCB0byBzZXR1cCB3YWl0IG9iamVjdCwgcmV0ICVsZFxuIiwgUFRSX0VS UihvYmopKTsKKwkJcmV0dXJuIFBUUl9FUlIob2JqKTsKK30KKworCXJldCA9IGRtYWJ1Zl9leHBf d2FpdF9vYmpfd2FpdChvYmosIHdhaXRfdG9fbXMpOworCWRtYWJ1Zl9leHBfd2FpdF9vYmpfZnJl ZShwcml2LCBvYmopOworCXJldHVybiByZXQ7CiB9CiAKIC8qIC0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogLyogRE1B IGJ1ZmZlciBleHBvcnQgc3VwcG9ydC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICovCiAvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KIAorc3RhdGljIHN0cnVjdCBzZ190YWJsZSAqCitk bWFidWZfcGFnZXNfdG9fc2d0KHN0cnVjdCBwYWdlICoqcGFnZXMsIHVuc2lnbmVkIGludCBucl9w YWdlcykKK3sKKwlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsKKwlpbnQgcmV0OworCisJc2d0ID0ga21h bGxvYyhzaXplb2YoKnNndCksIEdGUF9LRVJORUwpOworCWlmICghc2d0KSB7CisJCXJldCA9IC1F Tk9NRU07CisJCWdvdG8gb3V0OworCX0KKworCXJldCA9IHNnX2FsbG9jX3RhYmxlX2Zyb21fcGFn ZXMoc2d0LCBwYWdlcywgbnJfcGFnZXMsIDAsCisJCQkJCW5yX3BhZ2VzIDw8IFBBR0VfU0hJRlQs CisJCQkJCUdGUF9LRVJORUwpOworCWlmIChyZXQpCisJCWdvdG8gb3V0OworCisJcmV0dXJuIHNn dDsKKworb3V0OgorCWtmcmVlKHNndCk7CisJcmV0dXJuIEVSUl9QVFIocmV0KTsKK30KKworc3Rh dGljIGludCBkbWFidWZfZXhwX29wc19hdHRhY2goc3RydWN0IGRtYV9idWYgKmRtYV9idWYsCisJ CQkJIHN0cnVjdCBkZXZpY2UgKnRhcmdldF9kZXYsCisJCQkJIHN0cnVjdCBkbWFfYnVmX2F0dGFj aG1lbnQgKmF0dGFjaCkKK3sKKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1Zl9hdHRhY2htZW50ICpnbnRk ZXZfZG1hYnVmX2F0dGFjaDsKKworCWdudGRldl9kbWFidWZfYXR0YWNoID0ga3phbGxvYyhzaXpl b2YoKmdudGRldl9kbWFidWZfYXR0YWNoKSwKKwkJCQkgICAgICAgR0ZQX0tFUk5FTCk7CisJaWYg KCFnbnRkZXZfZG1hYnVmX2F0dGFjaCkKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlnbnRkZXZfZG1h YnVmX2F0dGFjaC0+ZGlyID0gRE1BX05PTkU7CisJYXR0YWNoLT5wcml2ID0gZ250ZGV2X2RtYWJ1 Zl9hdHRhY2g7CisJLyogTWlnaHQgbmVlZCB0byBwaW4gdGhlIHBhZ2VzIG9mIHRoZSBidWZmZXIg bm93LiAqLworCXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCBkbWFidWZfZXhwX29wc19kZXRh Y2goc3RydWN0IGRtYV9idWYgKmRtYV9idWYsCisJCQkJICBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2ht ZW50ICphdHRhY2gpCit7CisJc3RydWN0IGdudGRldl9kbWFidWZfYXR0YWNobWVudCAqZ250ZGV2 X2RtYWJ1Zl9hdHRhY2ggPSBhdHRhY2gtPnByaXY7CisKKwlpZiAoZ250ZGV2X2RtYWJ1Zl9hdHRh Y2gpIHsKKwkJc3RydWN0IHNnX3RhYmxlICpzZ3QgPSBnbnRkZXZfZG1hYnVmX2F0dGFjaC0+c2d0 OworCisJCWlmIChzZ3QpIHsKKwkJCWlmIChnbnRkZXZfZG1hYnVmX2F0dGFjaC0+ZGlyICE9IERN QV9OT05FKQorCQkJCWRtYV91bm1hcF9zZ19hdHRycyhhdHRhY2gtPmRldiwgc2d0LT5zZ2wsCisJ CQkJCQkgICBzZ3QtPm5lbnRzLAorCQkJCQkJICAgZ250ZGV2X2RtYWJ1Zl9hdHRhY2gtPmRpciwK KwkJCQkJCSAgIERNQV9BVFRSX1NLSVBfQ1BVX1NZTkMpOworCQkJc2dfZnJlZV90YWJsZShzZ3Qp OworCQl9CisKKwkJa2ZyZWUoc2d0KTsKKwkJa2ZyZWUoZ250ZGV2X2RtYWJ1Zl9hdHRhY2gpOwor CQlhdHRhY2gtPnByaXYgPSBOVUxMOworCX0KKwkvKiBNaWdodCBuZWVkIHRvIHVucGluIHRoZSBw YWdlcyBvZiB0aGUgYnVmZmVyIG5vdy4gKi8KK30KKworc3RhdGljIHN0cnVjdCBzZ190YWJsZSAq CitkbWFidWZfZXhwX29wc19tYXBfZG1hX2J1ZihzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICph dHRhY2gsCisJCQkgICBlbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIpCit7CisJc3RydWN0IGdu dGRldl9kbWFidWZfYXR0YWNobWVudCAqZ250ZGV2X2RtYWJ1Zl9hdHRhY2ggPSBhdHRhY2gtPnBy aXY7CisJc3RydWN0IGdudGRldl9kbWFidWYgKmdudGRldl9kbWFidWYgPSBhdHRhY2gtPmRtYWJ1 Zi0+cHJpdjsKKwlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsKKworCXByX2RlYnVnKCJNYXBwaW5nICVk IHBhZ2VzIGZvciBkZXYgJXBcbiIsIGdudGRldl9kbWFidWYtPm5yX3BhZ2VzLAorCQkgYXR0YWNo LT5kZXYpOworCisJaWYgKFdBUk5fT04oZGlyID09IERNQV9OT05FIHx8ICFnbnRkZXZfZG1hYnVm X2F0dGFjaCkpCisJCXJldHVybiBFUlJfUFRSKC1FSU5WQUwpOworCisJLyogUmV0dXJuIHRoZSBj YWNoZWQgbWFwcGluZyB3aGVuIHBvc3NpYmxlLiAqLworCWlmIChnbnRkZXZfZG1hYnVmX2F0dGFj aC0+ZGlyID09IGRpcikKKwkJcmV0dXJuIGdudGRldl9kbWFidWZfYXR0YWNoLT5zZ3Q7CisKKwkv KgorCSAqIFR3byBtYXBwaW5ncyB3aXRoIGRpZmZlcmVudCBkaXJlY3Rpb25zIGZvciB0aGUgc2Ft ZSBhdHRhY2htZW50IGFyZQorCSAqIG5vdCBhbGxvd2VkLgorCSAqLworCWlmIChXQVJOX09OKGdu dGRldl9kbWFidWZfYXR0YWNoLT5kaXIgIT0gRE1BX05PTkUpKQorCQlyZXR1cm4gRVJSX1BUUigt RUJVU1kpOworCisJc2d0ID0gZG1hYnVmX3BhZ2VzX3RvX3NndChnbnRkZXZfZG1hYnVmLT5wYWdl cywKKwkJCQkgIGdudGRldl9kbWFidWYtPm5yX3BhZ2VzKTsKKwlpZiAoIUlTX0VSUihzZ3QpKSB7 CisJCWlmICghZG1hX21hcF9zZ19hdHRycyhhdHRhY2gtPmRldiwgc2d0LT5zZ2wsIHNndC0+bmVu dHMsIGRpciwKKwkJCQkgICAgICBETUFfQVRUUl9TS0lQX0NQVV9TWU5DKSkgeworCQkJc2dfZnJl ZV90YWJsZShzZ3QpOworCQkJa2ZyZWUoc2d0KTsKKwkJCXNndCA9IEVSUl9QVFIoLUVOT01FTSk7 CisJCX0gZWxzZSB7CisJCQlnbnRkZXZfZG1hYnVmX2F0dGFjaC0+c2d0ID0gc2d0OworCQkJZ250 ZGV2X2RtYWJ1Zl9hdHRhY2gtPmRpciA9IGRpcjsKKwkJfQorCX0KKwlpZiAoSVNfRVJSKHNndCkp CisJCXByX2VycigiRmFpbGVkIHRvIG1hcCBzZyB0YWJsZSBmb3IgZGV2ICVwXG4iLCBhdHRhY2gt PmRldik7CisJcmV0dXJuIHNndDsKK30KKworc3RhdGljIHZvaWQgZG1hYnVmX2V4cF9vcHNfdW5t YXBfZG1hX2J1ZihzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICphdHRhY2gsCisJCQkJCSBzdHJ1 Y3Qgc2dfdGFibGUgKnNndCwKKwkJCQkJIGVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpcikKK3sK KwkvKiBOb3QgaW1wbGVtZW50ZWQuIFRoZSB1bm1hcCBpcyBkb25lIGF0IGRtYWJ1Zl9leHBfb3Bz X2RldGFjaCgpLiAqLworfQorCitzdGF0aWMgdm9pZCBkbWFidWZfZXhwX3JlbGVhc2Uoc3RydWN0 IGtyZWYgKmtyZWYpCit7CisJc3RydWN0IGdudGRldl9kbWFidWYgKmdudGRldl9kbWFidWYgPQor CQljb250YWluZXJfb2Yoa3JlZiwgc3RydWN0IGdudGRldl9kbWFidWYsIHUuZXhwLnJlZmNvdW50 KTsKKworCWRtYWJ1Zl9leHBfd2FpdF9vYmpfc2lnbmFsKGdudGRldl9kbWFidWYtPnByaXYsIGdu dGRldl9kbWFidWYpOworCWxpc3RfZGVsKCZnbnRkZXZfZG1hYnVmLT5uZXh0KTsKKwlrZnJlZShn bnRkZXZfZG1hYnVmKTsKK30KKworc3RhdGljIHZvaWQgZG1hYnVmX2V4cF9vcHNfcmVsZWFzZShz dHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1ZikKK3sKKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1ZiAqZ250ZGV2 X2RtYWJ1ZiA9IGRtYV9idWYtPnByaXY7CisJc3RydWN0IGdudGRldl9kbWFidWZfcHJpdiAqcHJp diA9IGdudGRldl9kbWFidWYtPnByaXY7CisKKwlnbnRkZXZfZG1hYnVmLT51LmV4cC5yZWxlYXNl KGdudGRldl9kbWFidWYtPnUuZXhwLnByaXYsCisJCQkJICAgICBnbnRkZXZfZG1hYnVmLT51LmV4 cC5tYXApOworCW11dGV4X2xvY2soJnByaXYtPmxvY2spOworCWtyZWZfcHV0KCZnbnRkZXZfZG1h YnVmLT51LmV4cC5yZWZjb3VudCwgZG1hYnVmX2V4cF9yZWxlYXNlKTsKKwltdXRleF91bmxvY2so JnByaXYtPmxvY2spOworfQorCitzdGF0aWMgdm9pZCAqZG1hYnVmX2V4cF9vcHNfa21hcF9hdG9t aWMoc3RydWN0IGRtYV9idWYgKmRtYV9idWYsCisJCQkJCXVuc2lnbmVkIGxvbmcgcGFnZV9udW0p Cit7CisJLyogTm90IGltcGxlbWVudGVkLiAqLworCXJldHVybiBOVUxMOworfQorCitzdGF0aWMg dm9pZCBkbWFidWZfZXhwX29wc19rdW5tYXBfYXRvbWljKHN0cnVjdCBkbWFfYnVmICpkbWFfYnVm LAorCQkJCQkgdW5zaWduZWQgbG9uZyBwYWdlX251bSwgdm9pZCAqYWRkcikKK3sKKwkvKiBOb3Qg aW1wbGVtZW50ZWQuICovCit9CisKK3N0YXRpYyB2b2lkICpkbWFidWZfZXhwX29wc19rbWFwKHN0 cnVjdCBkbWFfYnVmICpkbWFfYnVmLAorCQkJCSB1bnNpZ25lZCBsb25nIHBhZ2VfbnVtKQorewor CS8qIE5vdCBpbXBsZW1lbnRlZC4gKi8KKwlyZXR1cm4gTlVMTDsKK30KKworc3RhdGljIHZvaWQg ZG1hYnVmX2V4cF9vcHNfa3VubWFwKHN0cnVjdCBkbWFfYnVmICpkbWFfYnVmLAorCQkJCSAgdW5z aWduZWQgbG9uZyBwYWdlX251bSwgdm9pZCAqYWRkcikKK3sKKwkvKiBOb3QgaW1wbGVtZW50ZWQu ICovCit9CisKK3N0YXRpYyBpbnQgZG1hYnVmX2V4cF9vcHNfbW1hcChzdHJ1Y3QgZG1hX2J1ZiAq ZG1hX2J1ZiwKKwkJCSAgICAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKK3sKKwkvKiBO b3QgaW1wbGVtZW50ZWQuICovCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qg ZG1hX2J1Zl9vcHMgZG1hYnVmX2V4cF9vcHMgPSAgeworCS5hdHRhY2ggPSBkbWFidWZfZXhwX29w c19hdHRhY2gsCisJLmRldGFjaCA9IGRtYWJ1Zl9leHBfb3BzX2RldGFjaCwKKwkubWFwX2RtYV9i dWYgPSBkbWFidWZfZXhwX29wc19tYXBfZG1hX2J1ZiwKKwkudW5tYXBfZG1hX2J1ZiA9IGRtYWJ1 Zl9leHBfb3BzX3VubWFwX2RtYV9idWYsCisJLnJlbGVhc2UgPSBkbWFidWZfZXhwX29wc19yZWxl YXNlLAorCS5tYXAgPSBkbWFidWZfZXhwX29wc19rbWFwLAorCS5tYXBfYXRvbWljID0gZG1hYnVm X2V4cF9vcHNfa21hcF9hdG9taWMsCisJLnVubWFwID0gZG1hYnVmX2V4cF9vcHNfa3VubWFwLAor CS51bm1hcF9hdG9taWMgPSBkbWFidWZfZXhwX29wc19rdW5tYXBfYXRvbWljLAorCS5tbWFwID0g ZG1hYnVmX2V4cF9vcHNfbW1hcCwKK307CisKIGludCBnbnRkZXZfZG1hYnVmX2V4cF9mcm9tX3Bh Z2VzKHN0cnVjdCBnbnRkZXZfZG1hYnVmX2V4cG9ydF9hcmdzICphcmdzKQogewotCXJldHVybiAt RUlOVkFMOworCURFRklORV9ETUFfQlVGX0VYUE9SVF9JTkZPKGV4cF9pbmZvKTsKKwlzdHJ1Y3Qg Z250ZGV2X2RtYWJ1ZiAqZ250ZGV2X2RtYWJ1ZjsKKwlpbnQgcmV0ID0gMDsKKworCWdudGRldl9k bWFidWYgPSBremFsbG9jKHNpemVvZigqZ250ZGV2X2RtYWJ1ZiksIEdGUF9LRVJORUwpOworCWlm ICghZ250ZGV2X2RtYWJ1ZikKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlrcmVmX2luaXQoJmdudGRl dl9kbWFidWYtPnUuZXhwLnJlZmNvdW50KTsKKworCWdudGRldl9kbWFidWYtPnByaXYgPSBhcmdz LT5kbWFidWZfcHJpdjsKKwlnbnRkZXZfZG1hYnVmLT5ucl9wYWdlcyA9IGFyZ3MtPmNvdW50Owor CWdudGRldl9kbWFidWYtPnBhZ2VzID0gYXJncy0+cGFnZXM7CisJZ250ZGV2X2RtYWJ1Zi0+dS5l eHAucHJpdiA9IGFyZ3MtPnByaXY7CisJZ250ZGV2X2RtYWJ1Zi0+dS5leHAubWFwID0gYXJncy0+ bWFwOworCWdudGRldl9kbWFidWYtPnUuZXhwLnJlbGVhc2UgPSBhcmdzLT5yZWxlYXNlOworCisJ ZXhwX2luZm8uZXhwX25hbWUgPSBLQlVJTERfTU9ETkFNRTsKKwlpZiAoYXJncy0+ZGV2LT5kcml2 ZXIgJiYgYXJncy0+ZGV2LT5kcml2ZXItPm93bmVyKQorCQlleHBfaW5mby5vd25lciA9IGFyZ3Mt PmRldi0+ZHJpdmVyLT5vd25lcjsKKwllbHNlCisJCWV4cF9pbmZvLm93bmVyID0gVEhJU19NT0RV TEU7CisJZXhwX2luZm8ub3BzID0gJmRtYWJ1Zl9leHBfb3BzOworCWV4cF9pbmZvLnNpemUgPSBh cmdzLT5jb3VudCA8PCBQQUdFX1NISUZUOworCWV4cF9pbmZvLmZsYWdzID0gT19SRFdSOworCWV4 cF9pbmZvLnByaXYgPSBnbnRkZXZfZG1hYnVmOworCisJZ250ZGV2X2RtYWJ1Zi0+ZG1hYnVmID0g ZG1hX2J1Zl9leHBvcnQoJmV4cF9pbmZvKTsKKwlpZiAoSVNfRVJSKGdudGRldl9kbWFidWYtPmRt YWJ1ZikpIHsKKwkJcmV0ID0gUFRSX0VSUihnbnRkZXZfZG1hYnVmLT5kbWFidWYpOworCQlnbnRk ZXZfZG1hYnVmLT5kbWFidWYgPSBOVUxMOworCQlnb3RvIGZhaWw7CisJfQorCisJcmV0ID0gZG1h X2J1Zl9mZChnbnRkZXZfZG1hYnVmLT5kbWFidWYsIE9fQ0xPRVhFQyk7CisJaWYgKHJldCA8IDAp CisJCWdvdG8gZmFpbDsKKworCWdudGRldl9kbWFidWYtPmZkID0gcmV0OworCWFyZ3MtPmZkID0g cmV0OworCisJcHJfZGVidWcoIkV4cG9ydGluZyBETUEgYnVmZmVyIHdpdGggZmQgJWRcbiIsIHJl dCk7CisKKwltdXRleF9sb2NrKCZhcmdzLT5kbWFidWZfcHJpdi0+bG9jayk7CisJbGlzdF9hZGQo JmdudGRldl9kbWFidWYtPm5leHQsICZhcmdzLT5kbWFidWZfcHJpdi0+ZXhwX2xpc3QpOworCW11 dGV4X3VubG9jaygmYXJncy0+ZG1hYnVmX3ByaXYtPmxvY2spOworCXJldHVybiAwOworCitmYWls OgorCWlmIChnbnRkZXZfZG1hYnVmLT5kbWFidWYpCisJCWRtYV9idWZfcHV0KGdudGRldl9kbWFi dWYtPmRtYWJ1Zik7CisJa2ZyZWUoZ250ZGV2X2RtYWJ1Zik7CisJcmV0dXJuIHJldDsKIH0KIAog LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tICovCkBAIC02Niw2ICs0NDksMTAgQEAgc3RydWN0IGdudGRldl9kbWFidWZf cHJpdiAqZ250ZGV2X2RtYWJ1Zl9pbml0KHZvaWQpCiAJaWYgKCFwcml2KQogCQlyZXR1cm4gRVJS X1BUUigtRU5PTUVNKTsKIAorCW11dGV4X2luaXQoJnByaXYtPmxvY2spOworCUlOSVRfTElTVF9I RUFEKCZwcml2LT5leHBfbGlzdCk7CisJSU5JVF9MSVNUX0hFQUQoJnByaXYtPmV4cF93YWl0X2xp c3QpOworCiAJcmV0dXJuIHByaXY7CiB9CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMveGVuL2dudGRl di1kbWFidWYuaCBiL2RyaXZlcnMveGVuL2dudGRldi1kbWFidWYuaAppbmRleCAwNDBiMmRlOTA0 YWMuLjk1YzIzYTI0ZjY0MCAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4vZ250ZGV2LWRtYWJ1Zi5o CisrKyBiL2RyaXZlcnMveGVuL2dudGRldi1kbWFidWYuaApAQCAtMTgsNyArMTgsMTQgQEAgc3Ry dWN0IGdudGRldl9kbWFidWY7CiBzdHJ1Y3QgZGV2aWNlOwogCiBzdHJ1Y3QgZ250ZGV2X2RtYWJ1 Zl9leHBvcnRfYXJncyB7Ci0JaW50IGR1bW15OworCXN0cnVjdCBnbnRkZXZfcHJpdiAqcHJpdjsK KwlzdHJ1Y3QgZ3JhbnRfbWFwICptYXA7CisJdm9pZCAoKnJlbGVhc2UpKHN0cnVjdCBnbnRkZXZf cHJpdiAqcHJpdiwgc3RydWN0IGdyYW50X21hcCAqbWFwKTsKKwlzdHJ1Y3QgZ250ZGV2X2RtYWJ1 Zl9wcml2ICpkbWFidWZfcHJpdjsKKwlzdHJ1Y3QgZGV2aWNlICpkZXY7CisJaW50IGNvdW50Owor CXN0cnVjdCBwYWdlICoqcGFnZXM7CisJdTMyIGZkOwogfTsKIAogc3RydWN0IGdudGRldl9kbWFi dWZfcHJpdiAqZ250ZGV2X2RtYWJ1Zl9pbml0KHZvaWQpOwpkaWZmIC0tZ2l0IGEvZHJpdmVycy94 ZW4vZ250ZGV2LmMgYi9kcml2ZXJzL3hlbi9nbnRkZXYuYwppbmRleCA3ZDU4ZGZiM2U1ZTguLmNm MjU1ZDQ1ZjIwZiAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4vZ250ZGV2LmMKKysrIGIvZHJpdmVy cy94ZW4vZ250ZGV2LmMKQEAgLTMxOSw2ICszMTksMTYgQEAgc3RhdGljIHZvaWQgZ250ZGV2X3B1 dF9tYXAoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCBzdHJ1Y3QgZ3JhbnRfbWFwICptYXApCiAJ Z250ZGV2X2ZyZWVfbWFwKG1hcCk7CiB9CiAKKyNpZmRlZiBDT05GSUdfWEVOX0dOVERFVl9ETUFC VUYKK3N0YXRpYyB2b2lkIGdudGRldl9yZW1vdmVfbWFwKHN0cnVjdCBnbnRkZXZfcHJpdiAqcHJp diwgc3RydWN0IGdyYW50X21hcCAqbWFwKQoreworCW11dGV4X2xvY2soJnByaXYtPmxvY2spOwor CWxpc3RfZGVsKCZtYXAtPm5leHQpOworCWdudGRldl9wdXRfbWFwKE5VTEwgLyogYWxyZWFkeSBy ZW1vdmVkICovLCBtYXApOworCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cit9CisjZW5kaWYK KwogLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tICovCiAKIHN0YXRpYyBpbnQgZmluZF9ncmFudF9wdGVzKHB0ZV90ICpw dGUsIHBndGFibGVfdCB0b2tlbiwKQEAgLTEwNjMsMTIgKzEwNzMsODggQEAgc3RhdGljIGxvbmcg Z250ZGV2X2lvY3RsX2dyYW50X2NvcHkoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCB2b2lkIF9f dXNlciAqdSkKIC8qIERNQSBidWZmZXIgZXhwb3J0IHN1cHBvcnQuICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAqLwogLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAKK3N0YXRpYyBzdHJ1 Y3QgZ3JhbnRfbWFwICoKK2RtYWJ1Zl9leHBfYWxsb2NfYmFja2luZ19zdG9yYWdlKHN0cnVjdCBn bnRkZXZfcHJpdiAqcHJpdiwgaW50IGRtYWJ1Zl9mbGFncywKKwkJCQkgaW50IGNvdW50KQorewor CXN0cnVjdCBncmFudF9tYXAgKm1hcDsKKworCWlmICh1bmxpa2VseShjb3VudCA8PSAwKSkKKwkJ cmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7CisKKwlpZiAoKGRtYWJ1Zl9mbGFncyAmIEdOVERFVl9E TUFfRkxBR19XQykgJiYKKwkgICAgKGRtYWJ1Zl9mbGFncyAmIEdOVERFVl9ETUFfRkxBR19DT0hF UkVOVCkpIHsKKwkJcHJfZXJyKCJXcm9uZyBkbWEtYnVmIGZsYWdzOiBlaXRoZXIgV0Mgb3IgY29o ZXJlbnQsIG5vdCBib3RoXG4iKTsKKwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7CisJfQorCisJ bWFwID0gZ250ZGV2X2FsbG9jX21hcChwcml2LCBjb3VudCwgZG1hYnVmX2ZsYWdzKTsKKwlpZiAo IW1hcCkKKwkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CisKKwlpZiAodW5saWtlbHkoYXRvbWlj X2FkZF9yZXR1cm4oY291bnQsICZwYWdlc19tYXBwZWQpID4gbGltaXQpKSB7CisJCXByX2Vycigi Y2FuJ3QgbWFwOiBvdmVyIGxpbWl0XG4iKTsKKwkJZ250ZGV2X3B1dF9tYXAoTlVMTCwgbWFwKTsK KwkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CisJfQorCXJldHVybiBtYXA7Cit9CisKIGludCBn bnRkZXZfZG1hYnVmX2V4cF9mcm9tX3JlZnMoc3RydWN0IGdudGRldl9wcml2ICpwcml2LCBpbnQg ZmxhZ3MsCiAJCQkJaW50IGNvdW50LCB1MzIgZG9taWQsIHUzMiAqcmVmcywgdTMyICpmZCkKIHsK LQkvKiBYWFg6IHRoaXMgd2lsbCBuZWVkIHRvIHdvcmsgd2l0aCBnbnRkZXYncyBtYXAsIHNvIGxl YXZlIGl0IGhlcmUuICovCisJc3RydWN0IGdyYW50X21hcCAqbWFwOworCXN0cnVjdCBnbnRkZXZf ZG1hYnVmX2V4cG9ydF9hcmdzIGFyZ3M7CisJaW50IGksIHJldDsKKwogCSpmZCA9IC0xOwotCXJl dHVybiAtRUlOVkFMOworCisJaWYgKHVzZV9wdGVtb2QpIHsKKwkJcHJfZXJyKCJDYW5ub3QgcHJv dmlkZSBkbWEtYnVmOiB1c2VfcHRlbW9kZSAlZFxuIiwKKwkJICAgICAgIHVzZV9wdGVtb2QpOwor CQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwltYXAgPSBkbWFidWZfZXhwX2FsbG9jX2JhY2tpbmdf c3RvcmFnZShwcml2LCBmbGFncywgY291bnQpOworCWlmIChJU19FUlIobWFwKSkKKwkJcmV0dXJu IFBUUl9FUlIobWFwKTsKKworCWZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CisJCW1hcC0+ Z3JhbnRzW2ldLmRvbWlkID0gZG9taWQ7CisJCW1hcC0+Z3JhbnRzW2ldLnJlZiA9IHJlZnNbaV07 CisJfQorCisJbXV0ZXhfbG9jaygmcHJpdi0+bG9jayk7CisJZ250ZGV2X2FkZF9tYXAocHJpdiwg bWFwKTsKKwltdXRleF91bmxvY2soJnByaXYtPmxvY2spOworCisJbWFwLT5mbGFncyB8PSBHTlRN QVBfaG9zdF9tYXA7CisjaWYgZGVmaW5lZChDT05GSUdfWDg2KQorCW1hcC0+ZmxhZ3MgfD0gR05U TUFQX2RldmljZV9tYXA7CisjZW5kaWYKKworCXJldCA9IG1hcF9ncmFudF9wYWdlcyhtYXApOwor CWlmIChyZXQgPCAwKQorCQlnb3RvIG91dDsKKworCWFyZ3MucHJpdiA9IHByaXY7CisJYXJncy5t YXAgPSBtYXA7CisJYXJncy5yZWxlYXNlID0gZ250ZGV2X3JlbW92ZV9tYXA7CisJYXJncy5kZXYg PSBwcml2LT5kbWFfZGV2OworCWFyZ3MuZG1hYnVmX3ByaXYgPSBwcml2LT5kbWFidWZfcHJpdjsK KwlhcmdzLmNvdW50ID0gbWFwLT5jb3VudDsKKwlhcmdzLnBhZ2VzID0gbWFwLT5wYWdlczsKKwor CXJldCA9IGdudGRldl9kbWFidWZfZXhwX2Zyb21fcGFnZXMoJmFyZ3MpOworCWlmIChyZXQgPCAw KQorCQlnb3RvIG91dDsKKworCSpmZCA9IGFyZ3MuZmQ7CisJcmV0dXJuIDA7CisKK291dDoKKwln bnRkZXZfcmVtb3ZlX21hcChwcml2LCBtYXApOworCXJldHVybiByZXQ7CiB9CiAKIC8qIC0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLSAqLwotLSAKMi4xNy4wCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVz a3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9k cmktZGV2ZWwK