From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753567AbdLSTmg (ORCPT ); Tue, 19 Dec 2017 14:42:36 -0500 Received: from mga01.intel.com ([192.55.52.88]:17633 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753234AbdLSTg6 (ORCPT ); Tue, 19 Dec 2017 14:36:58 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,428,1508828400"; d="scan'208";a="4018620" From: Dongwon Kim To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dongwon.kim@intel.com Subject: [RFC PATCH 41/60] hyper_dmabuf: re-organize driver source Date: Tue, 19 Dec 2017 11:29:57 -0800 Message-Id: <1513711816-2618-41-git-send-email-dongwon.kim@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> References: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Re-orginized source code for more intuitive structure For this, 1. driver's file operations other than ioctls have been moved to hyper_dmabuf_drv.c. 2. Separated out dma-buf operations from hyper_dmabuf_ops.c and put those in a new file, 'hyper_dmabuf_ops.c'. Remaining part (SGT core management) is also put in the a new file, 'hyper_dmabuf_sgt_proc.c'. hyper_dmabuf_imp.c and hyper_dmabuf_imp.h are removed as a result. 3. Header files and Makefile are also updated accordingly. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/Makefile | 3 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 95 ++- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 682 --------------------- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h | 48 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 136 +--- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c | 1 - drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c | 471 ++++++++++++++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h | 32 + .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c | 258 ++++++++ drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h | 41 ++ 11 files changed, 920 insertions(+), 849 deletions(-) delete mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c delete mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h diff --git a/drivers/xen/hyper_dmabuf/Makefile b/drivers/xen/hyper_dmabuf/Makefile index 8865f50..5040b9f 100644 --- a/drivers/xen/hyper_dmabuf/Makefile +++ b/drivers/xen/hyper_dmabuf/Makefile @@ -7,7 +7,8 @@ ifneq ($(KERNELRELEASE),) $(TARGET_MODULE)-objs := hyper_dmabuf_drv.o \ hyper_dmabuf_ioctl.o \ hyper_dmabuf_list.o \ - hyper_dmabuf_imp.o \ + hyper_dmabuf_sgl_proc.o \ + hyper_dmabuf_ops.o \ hyper_dmabuf_msg.o \ hyper_dmabuf_id.o \ hyper_dmabuf_remote_sync.o \ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index c802c3e..8c488d7 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -28,10 +28,13 @@ #include #include +#include #include #include +#include #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_conf.h" +#include "hyper_dmabuf_ioctl.h" #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_list.h" #include "hyper_dmabuf_id.h" @@ -44,12 +47,94 @@ extern struct hyper_dmabuf_backend_ops xen_backend_ops; MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Intel Corporation"); -int register_device(void); -int unregister_device(void); - struct hyper_dmabuf_private hyper_dmabuf_private; -/*===============================================================================================*/ +long hyper_dmabuf_ioctl(struct file *filp, + unsigned int cmd, unsigned long param); + +void hyper_dmabuf_emergency_release(struct hyper_dmabuf_sgt_info* sgt_info, + void *attr); + +int hyper_dmabuf_open(struct inode *inode, struct file *filp) +{ + int ret = 0; + + /* Do not allow exclusive open */ + if (filp->f_flags & O_EXCL) + return -EBUSY; + + /* + * Initialize backend if neededm, + * use mutex to prevent race conditions when + * two userspace apps will open device at the same time + */ + mutex_lock(&hyper_dmabuf_private.lock); + + if (!hyper_dmabuf_private.backend_initialized) { + hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); + + ret = hyper_dmabuf_private.backend_ops->init_comm_env(); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "failed to initiailize hypervisor-specific comm env\n"); + } else { + hyper_dmabuf_private.backend_initialized = true; + } + } + + mutex_unlock(&hyper_dmabuf_private.lock); + + return ret; +} + +int hyper_dmabuf_release(struct inode *inode, struct file *filp) +{ + hyper_dmabuf_foreach_exported(hyper_dmabuf_emergency_release, filp); + + return 0; +} + +static struct file_operations hyper_dmabuf_driver_fops = +{ + .owner = THIS_MODULE, + .open = hyper_dmabuf_open, + .release = hyper_dmabuf_release, + .unlocked_ioctl = hyper_dmabuf_ioctl, +}; + +static struct miscdevice hyper_dmabuf_miscdev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "xen/hyper_dmabuf", + .fops = &hyper_dmabuf_driver_fops, +}; + +int register_device(void) +{ + int ret = 0; + + ret = misc_register(&hyper_dmabuf_miscdev); + + if (ret) { + printk(KERN_ERR "hyper_dmabuf: driver can't be registered\n"); + return ret; + } + + hyper_dmabuf_private.device = hyper_dmabuf_miscdev.this_device; + + /* TODO: Check if there is a different way to initialize dma mask nicely */ + dma_coerce_mask_and_coherent(hyper_dmabuf_private.device, DMA_BIT_MASK(64)); + + return ret; +} + +void unregister_device(void) +{ + dev_info(hyper_dmabuf_private.device, + "hyper_dmabuf: unregister_device() is called\n"); + + misc_deregister(&hyper_dmabuf_miscdev); +} + static int __init hyper_dmabuf_drv_init(void) { int ret = 0; @@ -103,7 +188,6 @@ static int __init hyper_dmabuf_drv_init(void) return ret; } -/*-----------------------------------------------------------------------------------------------*/ static void hyper_dmabuf_drv_exit(void) { #ifdef CONFIG_HYPER_DMABUF_SYSFS @@ -128,7 +212,6 @@ static void hyper_dmabuf_drv_exit(void) unregister_device(); } -/*===============================================================================================*/ module_init(hyper_dmabuf_drv_init); module_exit(hyper_dmabuf_drv_exit); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c deleted file mode 100644 index 2bf0835..0000000 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright © 2017 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Dongwon Kim - * Mateusz Polrola - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "hyper_dmabuf_drv.h" -#include "hyper_dmabuf_struct.h" -#include "hyper_dmabuf_imp.h" -#include "hyper_dmabuf_id.h" -#include "hyper_dmabuf_msg.h" -#include "hyper_dmabuf_list.h" - -extern struct hyper_dmabuf_private hyper_dmabuf_private; - -#define REFS_PER_PAGE (PAGE_SIZE/sizeof(grant_ref_t)) - -int dmabuf_refcount(struct dma_buf *dma_buf) -{ - if ((dma_buf != NULL) && (dma_buf->file != NULL)) - return file_count(dma_buf->file); - - return -1; -} - -/* return total number of pages referenced by a sgt - * for pre-calculation of # of pages behind a given sgt - */ -static int hyper_dmabuf_get_num_pgs(struct sg_table *sgt) -{ - struct scatterlist *sgl; - int length, i; - /* at least one page */ - int num_pages = 1; - - sgl = sgt->sgl; - - length = sgl->length - PAGE_SIZE + sgl->offset; - num_pages += ((length + PAGE_SIZE - 1)/PAGE_SIZE); /* round-up */ - - for (i = 1; i < sgt->nents; i++) { - sgl = sg_next(sgl); - num_pages += ((sgl->length + PAGE_SIZE - 1) / PAGE_SIZE); /* round-up */ - } - - return num_pages; -} - -/* extract pages directly from struct sg_table */ -struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) -{ - struct hyper_dmabuf_pages_info *pinfo; - int i, j, k; - int length; - struct scatterlist *sgl; - - pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL); - if (!pinfo) - return NULL; - - pinfo->pages = kmalloc(sizeof(struct page *)*hyper_dmabuf_get_num_pgs(sgt), GFP_KERNEL); - if (!pinfo->pages) - return NULL; - - sgl = sgt->sgl; - - pinfo->nents = 1; - pinfo->frst_ofst = sgl->offset; - pinfo->pages[0] = sg_page(sgl); - length = sgl->length - PAGE_SIZE + sgl->offset; - i = 1; - - while (length > 0) { - pinfo->pages[i] = nth_page(sg_page(sgl), i); - length -= PAGE_SIZE; - pinfo->nents++; - i++; - } - - for (j = 1; j < sgt->nents; j++) { - sgl = sg_next(sgl); - pinfo->pages[i++] = sg_page(sgl); - length = sgl->length - PAGE_SIZE; - pinfo->nents++; - k = 1; - - while (length > 0) { - pinfo->pages[i++] = nth_page(sg_page(sgl), k++); - length -= PAGE_SIZE; - pinfo->nents++; - } - } - - /* - * lenght at that point will be 0 or negative, - * so to calculate last page size just add it to PAGE_SIZE - */ - pinfo->last_len = PAGE_SIZE + length; - - return pinfo; -} - -/* create sg_table with given pages and other parameters */ -struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, - int frst_ofst, int last_len, int nents) -{ - struct sg_table *sgt; - struct scatterlist *sgl; - int i, ret; - - sgt = kmalloc(sizeof(struct sg_table), GFP_KERNEL); - if (!sgt) { - return NULL; - } - - ret = sg_alloc_table(sgt, nents, GFP_KERNEL); - if (ret) { - if (sgt) { - sg_free_table(sgt); - kfree(sgt); - } - - return NULL; - } - - sgl = sgt->sgl; - - sg_set_page(sgl, pages[0], PAGE_SIZE-frst_ofst, frst_ofst); - - for (i=1; i 1) /* more than one page */ { - sgl = sg_next(sgl); - sg_set_page(sgl, pages[i], last_len, 0); - } - - return sgt; -} - -int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int force) -{ - struct sgt_list *sgtl; - struct attachment_list *attachl; - struct kmap_vaddr_list *va_kmapl; - struct vmap_vaddr_list *va_vmapl; - struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; - - if (!sgt_info) { - dev_err(hyper_dmabuf_private.device, "invalid hyper_dmabuf_id\n"); - return -EINVAL; - } - - /* if force != 1, sgt_info can be released only if - * there's no activity on exported dma-buf on importer - * side. - */ - if (!force && - sgt_info->importer_exported) { - dev_warn(hyper_dmabuf_private.device, "dma-buf is used by importer\n"); - return -EPERM; - } - - /* force == 1 is not recommended */ - while (!list_empty(&sgt_info->va_kmapped->list)) { - va_kmapl = list_first_entry(&sgt_info->va_kmapped->list, - struct kmap_vaddr_list, list); - - dma_buf_kunmap(sgt_info->dma_buf, 1, va_kmapl->vaddr); - list_del(&va_kmapl->list); - kfree(va_kmapl); - } - - while (!list_empty(&sgt_info->va_vmapped->list)) { - va_vmapl = list_first_entry(&sgt_info->va_vmapped->list, - struct vmap_vaddr_list, list); - - dma_buf_vunmap(sgt_info->dma_buf, va_vmapl->vaddr); - list_del(&va_vmapl->list); - kfree(va_vmapl); - } - - while (!list_empty(&sgt_info->active_sgts->list)) { - attachl = list_first_entry(&sgt_info->active_attached->list, - struct attachment_list, list); - - sgtl = list_first_entry(&sgt_info->active_sgts->list, - struct sgt_list, list); - - dma_buf_unmap_attachment(attachl->attach, sgtl->sgt, - DMA_BIDIRECTIONAL); - list_del(&sgtl->list); - kfree(sgtl); - } - - while (!list_empty(&sgt_info->active_sgts->list)) { - attachl = list_first_entry(&sgt_info->active_attached->list, - struct attachment_list, list); - - dma_buf_detach(sgt_info->dma_buf, attachl->attach); - list_del(&attachl->list); - kfree(attachl); - } - - /* Start cleanup of buffer in reverse order to exporting */ - ops->unshare_pages(&sgt_info->refs_info, sgt_info->nents); - - /* unmap dma-buf */ - dma_buf_unmap_attachment(sgt_info->active_attached->attach, - sgt_info->active_sgts->sgt, - DMA_BIDIRECTIONAL); - - /* detatch dma-buf */ - dma_buf_detach(sgt_info->dma_buf, sgt_info->active_attached->attach); - - /* close connection to dma-buf completely */ - dma_buf_put(sgt_info->dma_buf); - sgt_info->dma_buf = NULL; - - kfree(sgt_info->active_sgts); - kfree(sgt_info->active_attached); - kfree(sgt_info->va_kmapped); - kfree(sgt_info->va_vmapped); - - return 0; -} - -#define WAIT_AFTER_SYNC_REQ 0 - -inline int hyper_dmabuf_sync_request(hyper_dmabuf_id_t hid, int dmabuf_ops) -{ - struct hyper_dmabuf_req *req; - struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; - int operands[5]; - int i; - int ret; - - operands[0] = hid.id; - - for (i=0; i<3; i++) - operands[i+1] = hid.rng_key[i]; - - operands[4] = dmabuf_ops; - - req = kcalloc(1, sizeof(*req), GFP_KERNEL); - - if (!req) { - dev_err(hyper_dmabuf_private.device, - "No memory left to be allocated\n"); - return -ENOMEM; - } - - hyper_dmabuf_create_request(req, HYPER_DMABUF_OPS_TO_SOURCE, &operands[0]); - - /* send request and wait for a response */ - ret = ops->send_req(HYPER_DMABUF_DOM_ID(hid), req, WAIT_AFTER_SYNC_REQ); - - kfree(req); - - return ret; -} - -static int hyper_dmabuf_ops_attach(struct dma_buf* dmabuf, struct device* dev, - struct dma_buf_attachment *attach) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!attach->dmabuf->priv) - return -EINVAL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attach->dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_ATTACH); - - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - return ret; - } - - return 0; -} - -static void hyper_dmabuf_ops_detach(struct dma_buf* dmabuf, struct dma_buf_attachment *attach) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!attach->dmabuf->priv) - return; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attach->dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_DETACH); - - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } -} - -static struct sg_table* hyper_dmabuf_ops_map(struct dma_buf_attachment *attachment, - enum dma_data_direction dir) -{ - struct sg_table *st; - struct hyper_dmabuf_imported_sgt_info *sgt_info; - struct hyper_dmabuf_pages_info *page_info; - int ret; - - if (!attachment->dmabuf->priv) - return NULL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attachment->dmabuf->priv; - - /* extract pages from sgt */ - page_info = hyper_dmabuf_ext_pgs(sgt_info->sgt); - - if (!page_info) { - return NULL; - } - - /* create a new sg_table with extracted pages */ - st = hyper_dmabuf_create_sgt(page_info->pages, page_info->frst_ofst, - page_info->last_len, page_info->nents); - if (!st) - goto err_free_sg; - - if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { - goto err_free_sg; - } - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_MAP); - - kfree(page_info->pages); - kfree(page_info); - - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return st; - -err_free_sg: - if (st) { - sg_free_table(st); - kfree(st); - } - - return NULL; -} - -static void hyper_dmabuf_ops_unmap(struct dma_buf_attachment *attachment, - struct sg_table *sg, - enum dma_data_direction dir) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!attachment->dmabuf->priv) - return; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attachment->dmabuf->priv; - - dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); - - sg_free_table(sg); - kfree(sg); - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_UNMAP); - - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } -} - -static void hyper_dmabuf_ops_release(struct dma_buf *dma_buf) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; - int ret; - int final_release; - - if (!dma_buf->priv) - return; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dma_buf->priv; - - if (!dmabuf_refcount(sgt_info->dma_buf)) { - sgt_info->dma_buf = NULL; - } - - sgt_info->num_importers--; - - if (sgt_info->num_importers == 0) { - ops->unmap_shared_pages(&sgt_info->refs_info, sgt_info->nents); - - if (sgt_info->sgt) { - sg_free_table(sgt_info->sgt); - kfree(sgt_info->sgt); - sgt_info->sgt = NULL; - } - } - - final_release = sgt_info && !sgt_info->valid && - !sgt_info->num_importers; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_RELEASE); - if (ret < 0) { - dev_warn(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - /* - * Check if buffer is still valid and if not remove it from imported list. - * That has to be done after sending sync request - */ - if (final_release) { - hyper_dmabuf_remove_imported(sgt_info->hid); - kfree(sgt_info); - } -} - -static int hyper_dmabuf_ops_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction dir) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return -EINVAL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_BEGIN_CPU_ACCESS); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return ret; -} - -static int hyper_dmabuf_ops_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction dir) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return -EINVAL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_END_CPU_ACCESS); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return 0; -} - -static void *hyper_dmabuf_ops_kmap_atomic(struct dma_buf *dmabuf, unsigned long pgnum) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return NULL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_KMAP_ATOMIC); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return NULL; /* for now NULL.. need to return the address of mapped region */ -} - -static void hyper_dmabuf_ops_kunmap_atomic(struct dma_buf *dmabuf, unsigned long pgnum, void *vaddr) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_KUNMAP_ATOMIC); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } -} - -static void *hyper_dmabuf_ops_kmap(struct dma_buf *dmabuf, unsigned long pgnum) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return NULL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_KMAP); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return NULL; /* for now NULL.. need to return the address of mapped region */ -} - -static void hyper_dmabuf_ops_kunmap(struct dma_buf *dmabuf, unsigned long pgnum, void *vaddr) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_KUNMAP); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } -} - -static int hyper_dmabuf_ops_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return -EINVAL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_MMAP); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return ret; -} - -static void *hyper_dmabuf_ops_vmap(struct dma_buf *dmabuf) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return NULL; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_VMAP); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } - - return NULL; -} - -static void hyper_dmabuf_ops_vunmap(struct dma_buf *dmabuf, void *vaddr) -{ - struct hyper_dmabuf_imported_sgt_info *sgt_info; - int ret; - - if (!dmabuf->priv) - return; - - sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; - - ret = hyper_dmabuf_sync_request(sgt_info->hid, - HYPER_DMABUF_OPS_VUNMAP); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); - } -} - -static const struct dma_buf_ops hyper_dmabuf_ops = { - .attach = hyper_dmabuf_ops_attach, - .detach = hyper_dmabuf_ops_detach, - .map_dma_buf = hyper_dmabuf_ops_map, - .unmap_dma_buf = hyper_dmabuf_ops_unmap, - .release = hyper_dmabuf_ops_release, - .begin_cpu_access = (void*)hyper_dmabuf_ops_begin_cpu_access, - .end_cpu_access = (void*)hyper_dmabuf_ops_end_cpu_access, - .map_atomic = hyper_dmabuf_ops_kmap_atomic, - .unmap_atomic = hyper_dmabuf_ops_kunmap_atomic, - .map = hyper_dmabuf_ops_kmap, - .unmap = hyper_dmabuf_ops_kunmap, - .mmap = hyper_dmabuf_ops_mmap, - .vmap = hyper_dmabuf_ops_vmap, - .vunmap = hyper_dmabuf_ops_vunmap, -}; - -/* exporting dmabuf as fd */ -int hyper_dmabuf_export_fd(struct hyper_dmabuf_imported_sgt_info *dinfo, int flags) -{ - int fd = -1; - - /* call hyper_dmabuf_export_dmabuf and create - * and bind a handle for it then release - */ - hyper_dmabuf_export_dma_buf(dinfo); - - if (dinfo->dma_buf) { - fd = dma_buf_fd(dinfo->dma_buf, flags); - } - - return fd; -} - -void hyper_dmabuf_export_dma_buf(struct hyper_dmabuf_imported_sgt_info *dinfo) -{ - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - - exp_info.ops = &hyper_dmabuf_ops; - - /* multiple of PAGE_SIZE, not considering offset */ - exp_info.size = dinfo->sgt->nents * PAGE_SIZE; - exp_info.flags = /* not sure about flag */0; - exp_info.priv = dinfo; - - dinfo->dma_buf = dma_buf_export(&exp_info); -} diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h deleted file mode 100644 index eda075b3..0000000 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2017 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -#ifndef __HYPER_DMABUF_IMP_H__ -#define __HYPER_DMABUF_IMP_H__ - -#include -#include "hyper_dmabuf_struct.h" - -/* extract pages directly from struct sg_table */ -struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt); - -/* create sg_table with given pages and other parameters */ -struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, - int frst_ofst, int last_len, int nents); - -int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int force); - -void hyper_dmabuf_free_sgt(struct sg_table *sgt); - -int hyper_dmabuf_export_fd(struct hyper_dmabuf_imported_sgt_info *dinfo, int flags); - -void hyper_dmabuf_export_dma_buf(struct hyper_dmabuf_imported_sgt_info *dinfo); - -int dmabuf_refcount(struct dma_buf *dma_buf); - -#endif /* __HYPER_DMABUF_IMP_H__ */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 9d05d66..283fe5a 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -41,7 +41,8 @@ #include "hyper_dmabuf_ioctl.h" #include "hyper_dmabuf_list.h" #include "hyper_dmabuf_msg.h" -#include "hyper_dmabuf_imp.h" +#include "hyper_dmabuf_sgl_proc.h" +#include "hyper_dmabuf_ops.h" #include "hyper_dmabuf_query.h" extern struct hyper_dmabuf_private hyper_dmabuf_private; @@ -618,7 +619,29 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) return 0; } -static const struct hyper_dmabuf_ioctl_desc hyper_dmabuf_ioctls[] = { +void hyper_dmabuf_emergency_release(struct hyper_dmabuf_sgt_info* sgt_info, + void *attr) +{ + struct ioctl_hyper_dmabuf_unexport unexport_attr; + struct file *filp = (struct file*) attr; + + if (!filp || !sgt_info) + return; + + if (sgt_info->filp == filp) { + dev_dbg(hyper_dmabuf_private.device, + "Executing emergency release of buffer {id:%d key:%d %d %d}\n", + sgt_info->hid.id, sgt_info->hid.rng_key[0], + sgt_info->hid.rng_key[1], sgt_info->hid.rng_key[2]); + + unexport_attr.hid = sgt_info->hid; + unexport_attr.delay_ms = 0; + + hyper_dmabuf_unexport_ioctl(filp, &unexport_attr); + } +} + +const struct hyper_dmabuf_ioctl_desc hyper_dmabuf_ioctls[] = { HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_TX_CH_SETUP, hyper_dmabuf_tx_ch_setup_ioctl, 0), HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_RX_CH_SETUP, hyper_dmabuf_rx_ch_setup_ioctl, 0), HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_EXPORT_REMOTE, hyper_dmabuf_export_remote_ioctl, 0), @@ -627,7 +650,7 @@ static const struct hyper_dmabuf_ioctl_desc hyper_dmabuf_ioctls[] = { HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_QUERY, hyper_dmabuf_query_ioctl, 0), }; -static long hyper_dmabuf_ioctl(struct file *filp, +long hyper_dmabuf_ioctl(struct file *filp, unsigned int cmd, unsigned long param) { const struct hyper_dmabuf_ioctl_desc *ioctl = NULL; @@ -672,110 +695,3 @@ static long hyper_dmabuf_ioctl(struct file *filp, return ret; } - -int hyper_dmabuf_open(struct inode *inode, struct file *filp) -{ - int ret = 0; - - /* Do not allow exclusive open */ - if (filp->f_flags & O_EXCL) - return -EBUSY; - - /* - * Initialize backend if neededm, - * use mutex to prevent race conditions when - * two userspace apps will open device at the same time - */ - mutex_lock(&hyper_dmabuf_private.lock); - - if (!hyper_dmabuf_private.backend_initialized) { - hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); - - ret = hyper_dmabuf_private.backend_ops->init_comm_env(); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "failed to initiailize hypervisor-specific comm env\n"); - } else { - hyper_dmabuf_private.backend_initialized = true; - } - } - - mutex_unlock(&hyper_dmabuf_private.lock); - - return ret; -} - -static void hyper_dmabuf_emergency_release(struct hyper_dmabuf_sgt_info* sgt_info, - void *attr) -{ - struct ioctl_hyper_dmabuf_unexport unexport_attr; - struct file *filp = (struct file*) attr; - - if (!filp || !sgt_info) - return; - - if (sgt_info->filp == filp) { - dev_dbg(hyper_dmabuf_private.device, - "Executing emergency release of buffer {id:%d key:%d %d %d}\n", - sgt_info->hid.id, sgt_info->hid.rng_key[0], - sgt_info->hid.rng_key[1], sgt_info->hid.rng_key[2]); - - unexport_attr.hid = sgt_info->hid; - unexport_attr.delay_ms = 0; - - hyper_dmabuf_unexport_ioctl(filp, &unexport_attr); - } -} - -int hyper_dmabuf_release(struct inode *inode, struct file *filp) -{ - hyper_dmabuf_foreach_exported(hyper_dmabuf_emergency_release, filp); - - return 0; -} - -/*===============================================================================================*/ -static struct file_operations hyper_dmabuf_driver_fops = -{ - .owner = THIS_MODULE, - .open = hyper_dmabuf_open, - .release = hyper_dmabuf_release, - .unlocked_ioctl = hyper_dmabuf_ioctl, -}; - -static struct miscdevice hyper_dmabuf_miscdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "xen/hyper_dmabuf", - .fops = &hyper_dmabuf_driver_fops, -}; - -static const char device_name[] = "hyper_dmabuf"; - -/*===============================================================================================*/ -int register_device(void) -{ - int ret = 0; - - ret = misc_register(&hyper_dmabuf_miscdev); - - if (ret) { - printk(KERN_ERR "hyper_dmabuf: driver can't be registered\n"); - return ret; - } - - hyper_dmabuf_private.device = hyper_dmabuf_miscdev.this_device; - - /* TODO: Check if there is a different way to initialize dma mask nicely */ - dma_coerce_mask_and_coherent(hyper_dmabuf_private.device, DMA_BIT_MASK(64)); - - return ret; -} - -/*-----------------------------------------------------------------------------------------------*/ -void unregister_device(void) -{ - dev_info(hyper_dmabuf_private.device, - "hyper_dmabuf: unregister_device() is called\n"); - - misc_deregister(&hyper_dmabuf_miscdev); -} diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c index 12ebad3..c516df8 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c @@ -35,7 +35,6 @@ #include #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_drv.h" -#include "hyper_dmabuf_imp.h" #include "hyper_dmabuf_remote_sync.h" #include "hyper_dmabuf_list.h" diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c new file mode 100644 index 0000000..81cb09f --- /dev/null +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c @@ -0,0 +1,471 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Dongwon Kim + * Mateusz Polrola + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hyper_dmabuf_drv.h" +#include "hyper_dmabuf_struct.h" +#include "hyper_dmabuf_ops.h" +#include "hyper_dmabuf_sgl_proc.h" +#include "hyper_dmabuf_id.h" +#include "hyper_dmabuf_msg.h" +#include "hyper_dmabuf_list.h" + +#define WAIT_AFTER_SYNC_REQ 0 +#define REFS_PER_PAGE (PAGE_SIZE/sizeof(grant_ref_t)) + +extern struct hyper_dmabuf_private hyper_dmabuf_private; + +inline int hyper_dmabuf_sync_request(hyper_dmabuf_id_t hid, int dmabuf_ops) +{ + struct hyper_dmabuf_req *req; + struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; + int operands[5]; + int i; + int ret; + + operands[0] = hid.id; + + for (i=0; i<3; i++) + operands[i+1] = hid.rng_key[i]; + + operands[4] = dmabuf_ops; + + req = kcalloc(1, sizeof(*req), GFP_KERNEL); + + if (!req) { + dev_err(hyper_dmabuf_private.device, + "No memory left to be allocated\n"); + return -ENOMEM; + } + + hyper_dmabuf_create_request(req, HYPER_DMABUF_OPS_TO_SOURCE, &operands[0]); + + /* send request and wait for a response */ + ret = ops->send_req(HYPER_DMABUF_DOM_ID(hid), req, WAIT_AFTER_SYNC_REQ); + + kfree(req); + + return ret; +} + +static int hyper_dmabuf_ops_attach(struct dma_buf* dmabuf, struct device* dev, + struct dma_buf_attachment *attach) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!attach->dmabuf->priv) + return -EINVAL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attach->dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_ATTACH); + + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + return ret; + } + + return 0; +} + +static void hyper_dmabuf_ops_detach(struct dma_buf* dmabuf, struct dma_buf_attachment *attach) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!attach->dmabuf->priv) + return; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attach->dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_DETACH); + + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } +} + +static struct sg_table* hyper_dmabuf_ops_map(struct dma_buf_attachment *attachment, + enum dma_data_direction dir) +{ + struct sg_table *st; + struct hyper_dmabuf_imported_sgt_info *sgt_info; + struct hyper_dmabuf_pages_info *page_info; + int ret; + + if (!attachment->dmabuf->priv) + return NULL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attachment->dmabuf->priv; + + /* extract pages from sgt */ + page_info = hyper_dmabuf_ext_pgs(sgt_info->sgt); + + if (!page_info) { + return NULL; + } + + /* create a new sg_table with extracted pages */ + st = hyper_dmabuf_create_sgt(page_info->pages, page_info->frst_ofst, + page_info->last_len, page_info->nents); + if (!st) + goto err_free_sg; + + if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { + goto err_free_sg; + } + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_MAP); + + kfree(page_info->pages); + kfree(page_info); + + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return st; + +err_free_sg: + if (st) { + sg_free_table(st); + kfree(st); + } + + return NULL; +} + +static void hyper_dmabuf_ops_unmap(struct dma_buf_attachment *attachment, + struct sg_table *sg, + enum dma_data_direction dir) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!attachment->dmabuf->priv) + return; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attachment->dmabuf->priv; + + dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); + + sg_free_table(sg); + kfree(sg); + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_UNMAP); + + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } +} + +static void hyper_dmabuf_ops_release(struct dma_buf *dma_buf) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; + int ret; + int final_release; + + if (!dma_buf->priv) + return; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dma_buf->priv; + + if (!dmabuf_refcount(sgt_info->dma_buf)) { + sgt_info->dma_buf = NULL; + } + + sgt_info->num_importers--; + + if (sgt_info->num_importers == 0) { + ops->unmap_shared_pages(&sgt_info->refs_info, sgt_info->nents); + + if (sgt_info->sgt) { + sg_free_table(sgt_info->sgt); + kfree(sgt_info->sgt); + sgt_info->sgt = NULL; + } + } + + final_release = sgt_info && !sgt_info->valid && + !sgt_info->num_importers; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_RELEASE); + if (ret < 0) { + dev_warn(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + /* + * Check if buffer is still valid and if not remove it from imported list. + * That has to be done after sending sync request + */ + if (final_release) { + hyper_dmabuf_remove_imported(sgt_info->hid); + kfree(sgt_info); + } +} + +static int hyper_dmabuf_ops_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction dir) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return -EINVAL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_BEGIN_CPU_ACCESS); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return ret; +} + +static int hyper_dmabuf_ops_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction dir) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return -EINVAL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_END_CPU_ACCESS); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return 0; +} + +static void *hyper_dmabuf_ops_kmap_atomic(struct dma_buf *dmabuf, unsigned long pgnum) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return NULL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_KMAP_ATOMIC); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return NULL; /* for now NULL.. need to return the address of mapped region */ +} + +static void hyper_dmabuf_ops_kunmap_atomic(struct dma_buf *dmabuf, unsigned long pgnum, void *vaddr) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_KUNMAP_ATOMIC); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } +} + +static void *hyper_dmabuf_ops_kmap(struct dma_buf *dmabuf, unsigned long pgnum) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return NULL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_KMAP); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return NULL; /* for now NULL.. need to return the address of mapped region */ +} + +static void hyper_dmabuf_ops_kunmap(struct dma_buf *dmabuf, unsigned long pgnum, void *vaddr) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_KUNMAP); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } +} + +static int hyper_dmabuf_ops_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return -EINVAL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_MMAP); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return ret; +} + +static void *hyper_dmabuf_ops_vmap(struct dma_buf *dmabuf) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return NULL; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_VMAP); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } + + return NULL; +} + +static void hyper_dmabuf_ops_vunmap(struct dma_buf *dmabuf, void *vaddr) +{ + struct hyper_dmabuf_imported_sgt_info *sgt_info; + int ret; + + if (!dmabuf->priv) + return; + + sgt_info = (struct hyper_dmabuf_imported_sgt_info *)dmabuf->priv; + + ret = hyper_dmabuf_sync_request(sgt_info->hid, + HYPER_DMABUF_OPS_VUNMAP); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + } +} + +static const struct dma_buf_ops hyper_dmabuf_ops = { + .attach = hyper_dmabuf_ops_attach, + .detach = hyper_dmabuf_ops_detach, + .map_dma_buf = hyper_dmabuf_ops_map, + .unmap_dma_buf = hyper_dmabuf_ops_unmap, + .release = hyper_dmabuf_ops_release, + .begin_cpu_access = (void*)hyper_dmabuf_ops_begin_cpu_access, + .end_cpu_access = (void*)hyper_dmabuf_ops_end_cpu_access, + .map_atomic = hyper_dmabuf_ops_kmap_atomic, + .unmap_atomic = hyper_dmabuf_ops_kunmap_atomic, + .map = hyper_dmabuf_ops_kmap, + .unmap = hyper_dmabuf_ops_kunmap, + .mmap = hyper_dmabuf_ops_mmap, + .vmap = hyper_dmabuf_ops_vmap, + .vunmap = hyper_dmabuf_ops_vunmap, +}; + +/* exporting dmabuf as fd */ +int hyper_dmabuf_export_fd(struct hyper_dmabuf_imported_sgt_info *dinfo, int flags) +{ + int fd = -1; + + /* call hyper_dmabuf_export_dmabuf and create + * and bind a handle for it then release + */ + hyper_dmabuf_export_dma_buf(dinfo); + + if (dinfo->dma_buf) { + fd = dma_buf_fd(dinfo->dma_buf, flags); + } + + return fd; +} + +void hyper_dmabuf_export_dma_buf(struct hyper_dmabuf_imported_sgt_info *dinfo) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + + exp_info.ops = &hyper_dmabuf_ops; + + /* multiple of PAGE_SIZE, not considering offset */ + exp_info.size = dinfo->sgt->nents * PAGE_SIZE; + exp_info.flags = /* not sure about flag */0; + exp_info.priv = dinfo; + + dinfo->dma_buf = dma_buf_export(&exp_info); +} diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h new file mode 100644 index 0000000..8c06fc6 --- /dev/null +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef __HYPER_DMABUF_OPS_H__ +#define __HYPER_DMABUF_OPS_H__ + +int hyper_dmabuf_export_fd(struct hyper_dmabuf_imported_sgt_info *dinfo, int flags); + +void hyper_dmabuf_export_dma_buf(struct hyper_dmabuf_imported_sgt_info *dinfo); + +#endif /* __HYPER_DMABUF_IMP_H__ */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c index be1d395..9004406 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c @@ -37,7 +37,7 @@ #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_id.h" #include "hyper_dmabuf_msg.h" -#include "hyper_dmabuf_imp.h" +#include "hyper_dmabuf_sgl_proc.h" extern struct hyper_dmabuf_private hyper_dmabuf_private; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c new file mode 100644 index 0000000..c2d013a --- /dev/null +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c @@ -0,0 +1,258 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Dongwon Kim + * Mateusz Polrola + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "hyper_dmabuf_drv.h" +#include "hyper_dmabuf_struct.h" +#include "hyper_dmabuf_sgl_proc.h" +#include "hyper_dmabuf_id.h" +#include "hyper_dmabuf_msg.h" +#include "hyper_dmabuf_list.h" + +extern struct hyper_dmabuf_private hyper_dmabuf_private; + +#define REFS_PER_PAGE (PAGE_SIZE/sizeof(grant_ref_t)) + +int dmabuf_refcount(struct dma_buf *dma_buf) +{ + if ((dma_buf != NULL) && (dma_buf->file != NULL)) + return file_count(dma_buf->file); + + return -1; +} + +/* return total number of pages referenced by a sgt + * for pre-calculation of # of pages behind a given sgt + */ +static int hyper_dmabuf_get_num_pgs(struct sg_table *sgt) +{ + struct scatterlist *sgl; + int length, i; + /* at least one page */ + int num_pages = 1; + + sgl = sgt->sgl; + + length = sgl->length - PAGE_SIZE + sgl->offset; + num_pages += ((length + PAGE_SIZE - 1)/PAGE_SIZE); /* round-up */ + + for (i = 1; i < sgt->nents; i++) { + sgl = sg_next(sgl); + num_pages += ((sgl->length + PAGE_SIZE - 1) / PAGE_SIZE); /* round-up */ + } + + return num_pages; +} + +/* extract pages directly from struct sg_table */ +struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) +{ + struct hyper_dmabuf_pages_info *pinfo; + int i, j, k; + int length; + struct scatterlist *sgl; + + pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL); + if (!pinfo) + return NULL; + + pinfo->pages = kmalloc(sizeof(struct page *)*hyper_dmabuf_get_num_pgs(sgt), GFP_KERNEL); + if (!pinfo->pages) + return NULL; + + sgl = sgt->sgl; + + pinfo->nents = 1; + pinfo->frst_ofst = sgl->offset; + pinfo->pages[0] = sg_page(sgl); + length = sgl->length - PAGE_SIZE + sgl->offset; + i = 1; + + while (length > 0) { + pinfo->pages[i] = nth_page(sg_page(sgl), i); + length -= PAGE_SIZE; + pinfo->nents++; + i++; + } + + for (j = 1; j < sgt->nents; j++) { + sgl = sg_next(sgl); + pinfo->pages[i++] = sg_page(sgl); + length = sgl->length - PAGE_SIZE; + pinfo->nents++; + k = 1; + + while (length > 0) { + pinfo->pages[i++] = nth_page(sg_page(sgl), k++); + length -= PAGE_SIZE; + pinfo->nents++; + } + } + + /* + * lenght at that point will be 0 or negative, + * so to calculate last page size just add it to PAGE_SIZE + */ + pinfo->last_len = PAGE_SIZE + length; + + return pinfo; +} + +/* create sg_table with given pages and other parameters */ +struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, + int frst_ofst, int last_len, int nents) +{ + struct sg_table *sgt; + struct scatterlist *sgl; + int i, ret; + + sgt = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!sgt) { + return NULL; + } + + ret = sg_alloc_table(sgt, nents, GFP_KERNEL); + if (ret) { + if (sgt) { + sg_free_table(sgt); + kfree(sgt); + } + + return NULL; + } + + sgl = sgt->sgl; + + sg_set_page(sgl, pages[0], PAGE_SIZE-frst_ofst, frst_ofst); + + for (i=1; i 1) /* more than one page */ { + sgl = sg_next(sgl); + sg_set_page(sgl, pages[i], last_len, 0); + } + + return sgt; +} + +int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int force) +{ + struct sgt_list *sgtl; + struct attachment_list *attachl; + struct kmap_vaddr_list *va_kmapl; + struct vmap_vaddr_list *va_vmapl; + struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; + + if (!sgt_info) { + dev_err(hyper_dmabuf_private.device, "invalid hyper_dmabuf_id\n"); + return -EINVAL; + } + + /* if force != 1, sgt_info can be released only if + * there's no activity on exported dma-buf on importer + * side. + */ + if (!force && + sgt_info->importer_exported) { + dev_warn(hyper_dmabuf_private.device, "dma-buf is used by importer\n"); + return -EPERM; + } + + /* force == 1 is not recommended */ + while (!list_empty(&sgt_info->va_kmapped->list)) { + va_kmapl = list_first_entry(&sgt_info->va_kmapped->list, + struct kmap_vaddr_list, list); + + dma_buf_kunmap(sgt_info->dma_buf, 1, va_kmapl->vaddr); + list_del(&va_kmapl->list); + kfree(va_kmapl); + } + + while (!list_empty(&sgt_info->va_vmapped->list)) { + va_vmapl = list_first_entry(&sgt_info->va_vmapped->list, + struct vmap_vaddr_list, list); + + dma_buf_vunmap(sgt_info->dma_buf, va_vmapl->vaddr); + list_del(&va_vmapl->list); + kfree(va_vmapl); + } + + while (!list_empty(&sgt_info->active_sgts->list)) { + attachl = list_first_entry(&sgt_info->active_attached->list, + struct attachment_list, list); + + sgtl = list_first_entry(&sgt_info->active_sgts->list, + struct sgt_list, list); + + dma_buf_unmap_attachment(attachl->attach, sgtl->sgt, + DMA_BIDIRECTIONAL); + list_del(&sgtl->list); + kfree(sgtl); + } + + while (!list_empty(&sgt_info->active_sgts->list)) { + attachl = list_first_entry(&sgt_info->active_attached->list, + struct attachment_list, list); + + dma_buf_detach(sgt_info->dma_buf, attachl->attach); + list_del(&attachl->list); + kfree(attachl); + } + + /* Start cleanup of buffer in reverse order to exporting */ + ops->unshare_pages(&sgt_info->refs_info, sgt_info->nents); + + /* unmap dma-buf */ + dma_buf_unmap_attachment(sgt_info->active_attached->attach, + sgt_info->active_sgts->sgt, + DMA_BIDIRECTIONAL); + + /* detatch dma-buf */ + dma_buf_detach(sgt_info->dma_buf, sgt_info->active_attached->attach); + + /* close connection to dma-buf completely */ + dma_buf_put(sgt_info->dma_buf); + sgt_info->dma_buf = NULL; + + kfree(sgt_info->active_sgts); + kfree(sgt_info->active_attached); + kfree(sgt_info->va_kmapped); + kfree(sgt_info->va_vmapped); + + return 0; +} diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h new file mode 100644 index 0000000..237ccf5 --- /dev/null +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h @@ -0,0 +1,41 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef __HYPER_DMABUF_IMP_H__ +#define __HYPER_DMABUF_IMP_H__ + +int dmabuf_refcount(struct dma_buf *dma_buf); + +/* extract pages directly from struct sg_table */ +struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt); + +/* create sg_table with given pages and other parameters */ +struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, + int frst_ofst, int last_len, int nents); + +int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int force); + +void hyper_dmabuf_free_sgt(struct sg_table *sgt); + +#endif /* __HYPER_DMABUF_IMP_H__ */ -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dongwon Kim Subject: [RFC PATCH 41/60] hyper_dmabuf: re-organize driver source Date: Tue, 19 Dec 2017 11:29:57 -0800 Message-ID: <1513711816-2618-41-git-send-email-dongwon.kim@intel.com> References: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To: linux-kernel@vger.kernel.org Cc: xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dri-devel@lists.freedesktop.org, dongwon.kim@intel.com List-Id: dri-devel@lists.freedesktop.org UmUtb3JnaW5pemVkIHNvdXJjZSBjb2RlIGZvciBtb3JlIGludHVpdGl2ZSBzdHJ1Y3R1cmUKCkZv ciB0aGlzLAoKMS4gZHJpdmVyJ3MgZmlsZSBvcGVyYXRpb25zIG90aGVyIHRoYW4gaW9jdGxzIGhh dmUgYmVlbiBtb3ZlZCB0bwpoeXBlcl9kbWFidWZfZHJ2LmMuCgoyLiBTZXBhcmF0ZWQgb3V0IGRt YS1idWYgb3BlcmF0aW9ucyBmcm9tIGh5cGVyX2RtYWJ1Zl9vcHMuYwphbmQgcHV0IHRob3NlIGlu IGEgbmV3IGZpbGUsICdoeXBlcl9kbWFidWZfb3BzLmMnLiBSZW1haW5pbmcgcGFydAooU0dUIGNv cmUgbWFuYWdlbWVudCkgaXMgYWxzbyBwdXQgaW4gdGhlIGEgbmV3IGZpbGUsCidoeXBlcl9kbWFi dWZfc2d0X3Byb2MuYycuIGh5cGVyX2RtYWJ1Zl9pbXAuYyBhbmQgaHlwZXJfZG1hYnVmX2ltcC5o CmFyZSByZW1vdmVkIGFzIGEgcmVzdWx0LgoKMy4gSGVhZGVyIGZpbGVzIGFuZCBNYWtlZmlsZSBh cmUgYWxzbyB1cGRhdGVkIGFjY29yZGluZ2x5LgoKU2lnbmVkLW9mZi1ieTogRG9uZ3dvbiBLaW0g PGRvbmd3b24ua2ltQGludGVsLmNvbT4KLS0tCiBkcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvTWFr ZWZpbGUgICAgICAgICAgICAgICAgICB8ICAgMyArLQogZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVm L2h5cGVyX2RtYWJ1Zl9kcnYuYyAgICAgICAgfCAgOTUgKystCiBkcml2ZXJzL3hlbi9oeXBlcl9k bWFidWYvaHlwZXJfZG1hYnVmX2ltcC5jICAgICAgICB8IDY4MiAtLS0tLS0tLS0tLS0tLS0tLS0t LS0KIGRyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfaW1wLmggICAgICAgIHwg IDQ4IC0tCiBkcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX2lvY3RsLmMgICAg ICB8IDEzNiArLS0tCiBkcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX21zZy5j ICAgICAgICB8ICAgMSAtCiBkcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX29w cy5jICAgICAgICB8IDQ3MSArKysrKysrKysrKysrKwogZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVm L2h5cGVyX2RtYWJ1Zl9vcHMuaCAgICAgICAgfCAgMzIgKwogLi4uL3hlbi9oeXBlcl9kbWFidWYv aHlwZXJfZG1hYnVmX3JlbW90ZV9zeW5jLmMgICAgfCAgIDIgKy0KIGRyaXZlcnMveGVuL2h5cGVy X2RtYWJ1Zi9oeXBlcl9kbWFidWZfc2dsX3Byb2MuYyAgIHwgMjU4ICsrKysrKysrCiBkcml2ZXJz L3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX3NnbF9wcm9jLmggICB8ICA0MSArKwogMTEg ZmlsZXMgY2hhbmdlZCwgOTIwIGluc2VydGlvbnMoKyksIDg0OSBkZWxldGlvbnMoLSkKIGRlbGV0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX2ltcC5j CiBkZWxldGUgbW9kZSAxMDA2NDQgZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1 Zl9pbXAuaAogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBl cl9kbWFidWZfb3BzLmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3hlbi9oeXBlcl9kbWFi dWYvaHlwZXJfZG1hYnVmX29wcy5oCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy94ZW4vaHlw ZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9zZ2xfcHJvYy5jCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJp dmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9zZ2xfcHJvYy5oCgpkaWZmIC0tZ2l0 IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL01ha2VmaWxlIGIvZHJpdmVycy94ZW4vaHlwZXJf ZG1hYnVmL01ha2VmaWxlCmluZGV4IDg4NjVmNTAuLjUwNDBiOWYgMTAwNjQ0Ci0tLSBhL2RyaXZl cnMveGVuL2h5cGVyX2RtYWJ1Zi9NYWtlZmlsZQorKysgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFi dWYvTWFrZWZpbGUKQEAgLTcsNyArNyw4IEBAIGlmbmVxICgkKEtFUk5FTFJFTEVBU0UpLCkKIAkk KFRBUkdFVF9NT0RVTEUpLW9ianMgOj0gaHlwZXJfZG1hYnVmX2Rydi5vIFwKICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIGh5cGVyX2RtYWJ1Zl9pb2N0bC5vIFwKICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIGh5cGVyX2RtYWJ1Zl9saXN0Lm8gXAotCQkJCSBoeXBlcl9k bWFidWZfaW1wLm8gXAorCQkJCSBoeXBlcl9kbWFidWZfc2dsX3Byb2MubyBcCisJCQkJIGh5cGVy X2RtYWJ1Zl9vcHMubyBcCiAJCQkJIGh5cGVyX2RtYWJ1Zl9tc2cubyBcCiAJCQkJIGh5cGVyX2Rt YWJ1Zl9pZC5vIFwKIAkJCQkgaHlwZXJfZG1hYnVmX3JlbW90ZV9zeW5jLm8gXApkaWZmIC0tZ2l0 IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9kcnYuYyBiL2RyaXZlcnMv eGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfZHJ2LmMKaW5kZXggYzgwMmMzZS4uOGM0ODhk NyAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9kcnYu YworKysgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX2Rydi5jCkBAIC0y OCwxMCArMjgsMTMgQEAKIAogI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KICNpbmNsdWRlIDxsaW51 eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9taXNjZGV2aWNlLmg+CiAjaW5jbHVkZSA8bGlu dXgvd29ya3F1ZXVlLmg+CiAjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CisjaW5jbHVkZSA8bGlu dXgvZG1hLWJ1Zi5oPgogI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9kcnYuaCIKICNpbmNsdWRlICJo eXBlcl9kbWFidWZfY29uZi5oIgorI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9pb2N0bC5oIgogI2lu Y2x1ZGUgImh5cGVyX2RtYWJ1Zl9tc2cuaCIKICNpbmNsdWRlICJoeXBlcl9kbWFidWZfbGlzdC5o IgogI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9pZC5oIgpAQCAtNDQsMTIgKzQ3LDk0IEBAIGV4dGVy biBzdHJ1Y3QgaHlwZXJfZG1hYnVmX2JhY2tlbmRfb3BzIHhlbl9iYWNrZW5kX29wczsKIE1PRFVM RV9MSUNFTlNFKCJHUEwgYW5kIGFkZGl0aW9uYWwgcmlnaHRzIik7CiBNT0RVTEVfQVVUSE9SKCJJ bnRlbCBDb3Jwb3JhdGlvbiIpOwogCi1pbnQgcmVnaXN0ZXJfZGV2aWNlKHZvaWQpOwotaW50IHVu cmVnaXN0ZXJfZGV2aWNlKHZvaWQpOwotCiBzdHJ1Y3QgaHlwZXJfZG1hYnVmX3ByaXZhdGUgaHlw ZXJfZG1hYnVmX3ByaXZhdGU7CiAKLS8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT0qLworbG9uZyBoeXBlcl9kbWFidWZfaW9jdGwoc3RydWN0IGZpbGUgKmZpbHAsCisJCQl1 bnNpZ25lZCBpbnQgY21kLCB1bnNpZ25lZCBsb25nIHBhcmFtKTsKKwordm9pZCBoeXBlcl9kbWFi dWZfZW1lcmdlbmN5X3JlbGVhc2Uoc3RydWN0IGh5cGVyX2RtYWJ1Zl9zZ3RfaW5mbyogc2d0X2lu Zm8sCisJCQkJICAgIHZvaWQgKmF0dHIpOworCitpbnQgaHlwZXJfZG1hYnVmX29wZW4oc3RydWN0 IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbHApCit7CisJaW50IHJldCA9IDA7CisKKwkv KiBEbyBub3QgYWxsb3cgZXhjbHVzaXZlIG9wZW4gKi8KKwlpZiAoZmlscC0+Zl9mbGFncyAmIE9f RVhDTCkKKwkJcmV0dXJuIC1FQlVTWTsKKworCS8qCisJICogSW5pdGlhbGl6ZSBiYWNrZW5kIGlm IG5lZWRlZG0sCisJICogdXNlIG11dGV4IHRvIHByZXZlbnQgcmFjZSBjb25kaXRpb25zIHdoZW4K KwkgKiB0d28gdXNlcnNwYWNlIGFwcHMgd2lsbCBvcGVuIGRldmljZSBhdCB0aGUgc2FtZSB0aW1l CisJICovCisJbXV0ZXhfbG9jaygmaHlwZXJfZG1hYnVmX3ByaXZhdGUubG9jayk7CisKKwlpZiAo IWh5cGVyX2RtYWJ1Zl9wcml2YXRlLmJhY2tlbmRfaW5pdGlhbGl6ZWQpIHsKKwkJaHlwZXJfZG1h YnVmX3ByaXZhdGUuZG9taWQgPSBoeXBlcl9kbWFidWZfcHJpdmF0ZS5iYWNrZW5kX29wcy0+Z2V0 X3ZtX2lkKCk7CisKKwkJcmV0ID0gaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9vcHMtPmlu aXRfY29tbV9lbnYoKTsKKwkgICAgICAgIGlmIChyZXQgPCAwKSB7CisJCQlkZXZfZXJyKGh5cGVy X2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJCQkiZmFpbGVkIHRvIGluaXRpYWlsaXplIGh5cGVy dmlzb3Itc3BlY2lmaWMgY29tbSBlbnZcbiIpOworCQl9IGVsc2UgeworCQkJaHlwZXJfZG1hYnVm X3ByaXZhdGUuYmFja2VuZF9pbml0aWFsaXplZCA9IHRydWU7CisJCX0KKwl9CisKKwltdXRleF91 bmxvY2soJmh5cGVyX2RtYWJ1Zl9wcml2YXRlLmxvY2spOworCisJcmV0dXJuIHJldDsKK30KKwor aW50IGh5cGVyX2RtYWJ1Zl9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxl ICpmaWxwKQoreworCWh5cGVyX2RtYWJ1Zl9mb3JlYWNoX2V4cG9ydGVkKGh5cGVyX2RtYWJ1Zl9l bWVyZ2VuY3lfcmVsZWFzZSwgZmlscCk7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHN0cnVj dCBmaWxlX29wZXJhdGlvbnMgaHlwZXJfZG1hYnVmX2RyaXZlcl9mb3BzID0KK3sKKwkub3duZXIg PSBUSElTX01PRFVMRSwKKwkub3BlbiA9IGh5cGVyX2RtYWJ1Zl9vcGVuLAorCS5yZWxlYXNlID0g aHlwZXJfZG1hYnVmX3JlbGVhc2UsCisJLnVubG9ja2VkX2lvY3RsID0gaHlwZXJfZG1hYnVmX2lv Y3RsLAorfTsKKworc3RhdGljIHN0cnVjdCBtaXNjZGV2aWNlIGh5cGVyX2RtYWJ1Zl9taXNjZGV2 ID0geworCS5taW5vciA9IE1JU0NfRFlOQU1JQ19NSU5PUiwKKwkubmFtZSA9ICJ4ZW4vaHlwZXJf ZG1hYnVmIiwKKwkuZm9wcyA9ICZoeXBlcl9kbWFidWZfZHJpdmVyX2ZvcHMsCit9OworCitpbnQg cmVnaXN0ZXJfZGV2aWNlKHZvaWQpCit7CisJaW50IHJldCA9IDA7CisKKwlyZXQgPSBtaXNjX3Jl Z2lzdGVyKCZoeXBlcl9kbWFidWZfbWlzY2Rldik7CisKKwlpZiAocmV0KSB7CisJCXByaW50ayhL RVJOX0VSUiAiaHlwZXJfZG1hYnVmOiBkcml2ZXIgY2FuJ3QgYmUgcmVnaXN0ZXJlZFxuIik7CisJ CXJldHVybiByZXQ7CisJfQorCisJaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlID0gaHlwZXJf ZG1hYnVmX21pc2NkZXYudGhpc19kZXZpY2U7CisKKwkvKiBUT0RPOiBDaGVjayBpZiB0aGVyZSBp cyBhIGRpZmZlcmVudCB3YXkgdG8gaW5pdGlhbGl6ZSBkbWEgbWFzayBuaWNlbHkgKi8KKwlkbWFf Y29lcmNlX21hc2tfYW5kX2NvaGVyZW50KGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwgRE1B X0JJVF9NQVNLKDY0KSk7CisKKwlyZXR1cm4gcmV0OworfQorCit2b2lkIHVucmVnaXN0ZXJfZGV2 aWNlKHZvaWQpCit7CisJZGV2X2luZm8oaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQki aHlwZXJfZG1hYnVmOiB1bnJlZ2lzdGVyX2RldmljZSgpIGlzIGNhbGxlZFxuIik7CisKKwltaXNj X2RlcmVnaXN0ZXIoJmh5cGVyX2RtYWJ1Zl9taXNjZGV2KTsKK30KKwogc3RhdGljIGludCBfX2lu aXQgaHlwZXJfZG1hYnVmX2Rydl9pbml0KHZvaWQpCiB7CiAJaW50IHJldCA9IDA7CkBAIC0xMDMs NyArMTg4LDYgQEAgc3RhdGljIGludCBfX2luaXQgaHlwZXJfZG1hYnVmX2Rydl9pbml0KHZvaWQp CiAJcmV0dXJuIHJldDsKIH0KIAotLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLSovCiBzdGF0aWMgdm9pZCBoeXBlcl9kbWFidWZfZHJ2X2V4aXQodm9pZCkKIHsKICNpZmRl ZiBDT05GSUdfSFlQRVJfRE1BQlVGX1NZU0ZTCkBAIC0xMjgsNyArMjEyLDYgQEAgc3RhdGljIHZv aWQgaHlwZXJfZG1hYnVmX2Rydl9leGl0KHZvaWQpCiAKIAl1bnJlZ2lzdGVyX2RldmljZSgpOwog fQotLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCiAKIG1vZHVsZV9p bml0KGh5cGVyX2RtYWJ1Zl9kcnZfaW5pdCk7CiBtb2R1bGVfZXhpdChoeXBlcl9kbWFidWZfZHJ2 X2V4aXQpOwpkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1 Zl9pbXAuYyBiL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfaW1wLmMKZGVs ZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJiZjA4MzUuLjAwMDAwMDAKLS0tIGEvZHJpdmVy cy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9pbXAuYworKysgL2Rldi9udWxsCkBAIC0x LDY4MiArMCwwIEBACi0vKgotICogQ29weXJpZ2h0IMKpIDIwMTcgSW50ZWwgQ29ycG9yYXRpb24K LSAqCi0gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8g YW55IHBlcnNvbiBvYnRhaW5pbmcgYQotICogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3Nv Y2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLSAqIHRvIGRlYWwg aW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxp bWl0YXRpb24KLSAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJs aXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAotICogYW5kL29yIHNlbGwgY29waWVzIG9mIHRo ZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlCi0gKiBTb2Z0d2Fy ZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRp b25zOgotICoKLSAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Np b24gbm90aWNlIChpbmNsdWRpbmcgdGhlIG5leHQKLSAqIHBhcmFncmFwaCkgc2hhbGwgYmUgaW5j bHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUKLSAqIFNv ZnR3YXJlLgotICoKLSAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VU IFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi0gKiBJTVBMSUVELCBJTkNMVURJTkcg QlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLSAq IEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJ TiBOTyBFVkVOVCBTSEFMTAotICogVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUg TElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKLSAqIExJQUJJTElUWSwgV0hF VEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5H Ci0gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBU SEUgVVNFIE9SIE9USEVSIERFQUxJTkdTCi0gKiBJTiBUSEUgU09GVFdBUkUuCi0gKgotICogQXV0 aG9yczoKLSAqICAgIERvbmd3b24gS2ltIDxkb25nd29uLmtpbUBpbnRlbC5jb20+Ci0gKiAgICBN YXRldXN6IFBvbHJvbGEgPG1hdGV1c3p4LnBvdHJvbGFAaW50ZWwuY29tPgotICoKLSAqLwotCi0j aW5jbHVkZSA8bGludXgva2VybmVsLmg+Ci0jaW5jbHVkZSA8bGludXgvZXJybm8uaD4KLSNpbmNs dWRlIDxsaW51eC9zbGFiLmg+Ci0jaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Ci0jaW5jbHVkZSA8 bGludXgvZG1hLWJ1Zi5oPgotI2luY2x1ZGUgPHhlbi9ncmFudF90YWJsZS5oPgotI2luY2x1ZGUg PGFzbS94ZW4vcGFnZS5oPgotI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9kcnYuaCIKLSNpbmNsdWRl ICJoeXBlcl9kbWFidWZfc3RydWN0LmgiCi0jaW5jbHVkZSAiaHlwZXJfZG1hYnVmX2ltcC5oIgot I2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9pZC5oIgotI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9tc2cu aCIKLSNpbmNsdWRlICJoeXBlcl9kbWFidWZfbGlzdC5oIgotCi1leHRlcm4gc3RydWN0IGh5cGVy X2RtYWJ1Zl9wcml2YXRlIGh5cGVyX2RtYWJ1Zl9wcml2YXRlOwotCi0jZGVmaW5lIFJFRlNfUEVS X1BBR0UgKFBBR0VfU0laRS9zaXplb2YoZ3JhbnRfcmVmX3QpKQotCi1pbnQgZG1hYnVmX3JlZmNv dW50KHN0cnVjdCBkbWFfYnVmICpkbWFfYnVmKQotewotCWlmICgoZG1hX2J1ZiAhPSBOVUxMKSAm JiAoZG1hX2J1Zi0+ZmlsZSAhPSBOVUxMKSkKLQkJcmV0dXJuIGZpbGVfY291bnQoZG1hX2J1Zi0+ ZmlsZSk7Ci0KLQlyZXR1cm4gLTE7Ci19Ci0KLS8qIHJldHVybiB0b3RhbCBudW1iZXIgb2YgcGFn ZXMgcmVmZXJlbmNlZCBieSBhIHNndAotICogZm9yIHByZS1jYWxjdWxhdGlvbiBvZiAjIG9mIHBh Z2VzIGJlaGluZCBhIGdpdmVuIHNndAotICovCi1zdGF0aWMgaW50IGh5cGVyX2RtYWJ1Zl9nZXRf bnVtX3BncyhzdHJ1Y3Qgc2dfdGFibGUgKnNndCkKLXsKLQlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNn bDsKLQlpbnQgbGVuZ3RoLCBpOwotCS8qIGF0IGxlYXN0IG9uZSBwYWdlICovCi0JaW50IG51bV9w YWdlcyA9IDE7Ci0KLQlzZ2wgPSBzZ3QtPnNnbDsKLQotCWxlbmd0aCA9IHNnbC0+bGVuZ3RoIC0g UEFHRV9TSVpFICsgc2dsLT5vZmZzZXQ7Ci0JbnVtX3BhZ2VzICs9ICgobGVuZ3RoICsgUEFHRV9T SVpFIC0gMSkvUEFHRV9TSVpFKTsgLyogcm91bmQtdXAgKi8KLQotCWZvciAoaSA9IDE7IGkgPCBz Z3QtPm5lbnRzOyBpKyspIHsKLQkJc2dsID0gc2dfbmV4dChzZ2wpOwotCQludW1fcGFnZXMgKz0g KChzZ2wtPmxlbmd0aCArIFBBR0VfU0laRSAtIDEpIC8gUEFHRV9TSVpFKTsgLyogcm91bmQtdXAg Ki8KLQl9Ci0KLQlyZXR1cm4gbnVtX3BhZ2VzOwotfQotCi0vKiBleHRyYWN0IHBhZ2VzIGRpcmVj dGx5IGZyb20gc3RydWN0IHNnX3RhYmxlICovCi1zdHJ1Y3QgaHlwZXJfZG1hYnVmX3BhZ2VzX2lu Zm8gKmh5cGVyX2RtYWJ1Zl9leHRfcGdzKHN0cnVjdCBzZ190YWJsZSAqc2d0KQotewotCXN0cnVj dCBoeXBlcl9kbWFidWZfcGFnZXNfaW5mbyAqcGluZm87Ci0JaW50IGksIGosIGs7Ci0JaW50IGxl bmd0aDsKLQlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnbDsKLQotCXBpbmZvID0ga21hbGxvYyhzaXpl b2YoKnBpbmZvKSwgR0ZQX0tFUk5FTCk7Ci0JaWYgKCFwaW5mbykKLQkJcmV0dXJuIE5VTEw7Ci0K LQlwaW5mby0+cGFnZXMgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgcGFnZSAqKSpoeXBlcl9kbWFi dWZfZ2V0X251bV9wZ3Moc2d0KSwgR0ZQX0tFUk5FTCk7Ci0JaWYgKCFwaW5mby0+cGFnZXMpCi0J CXJldHVybiBOVUxMOwotCi0Jc2dsID0gc2d0LT5zZ2w7Ci0KLQlwaW5mby0+bmVudHMgPSAxOwot CXBpbmZvLT5mcnN0X29mc3QgPSBzZ2wtPm9mZnNldDsKLQlwaW5mby0+cGFnZXNbMF0gPSBzZ19w YWdlKHNnbCk7Ci0JbGVuZ3RoID0gc2dsLT5sZW5ndGggLSBQQUdFX1NJWkUgKyBzZ2wtPm9mZnNl dDsKLQlpID0gMTsKLQotCXdoaWxlIChsZW5ndGggPiAwKSB7Ci0JCXBpbmZvLT5wYWdlc1tpXSA9 IG50aF9wYWdlKHNnX3BhZ2Uoc2dsKSwgaSk7Ci0JCWxlbmd0aCAtPSBQQUdFX1NJWkU7Ci0JCXBp bmZvLT5uZW50cysrOwotCQlpKys7Ci0JfQotCi0JZm9yIChqID0gMTsgaiA8IHNndC0+bmVudHM7 IGorKykgewotCQlzZ2wgPSBzZ19uZXh0KHNnbCk7Ci0JCXBpbmZvLT5wYWdlc1tpKytdID0gc2df cGFnZShzZ2wpOwotCQlsZW5ndGggPSBzZ2wtPmxlbmd0aCAtIFBBR0VfU0laRTsKLQkJcGluZm8t Pm5lbnRzKys7Ci0JCWsgPSAxOwotCi0JCXdoaWxlIChsZW5ndGggPiAwKSB7Ci0JCQlwaW5mby0+ cGFnZXNbaSsrXSA9IG50aF9wYWdlKHNnX3BhZ2Uoc2dsKSwgaysrKTsKLQkJCWxlbmd0aCAtPSBQ QUdFX1NJWkU7Ci0JCQlwaW5mby0+bmVudHMrKzsKLQkJfQotCX0KLQotCS8qCi0JICogbGVuZ2h0 IGF0IHRoYXQgcG9pbnQgd2lsbCBiZSAwIG9yIG5lZ2F0aXZlLAotCSAqIHNvIHRvIGNhbGN1bGF0 ZSBsYXN0IHBhZ2Ugc2l6ZSBqdXN0IGFkZCBpdCB0byBQQUdFX1NJWkUKLQkgKi8KLQlwaW5mby0+ bGFzdF9sZW4gPSBQQUdFX1NJWkUgKyBsZW5ndGg7Ci0KLQlyZXR1cm4gcGluZm87Ci19Ci0KLS8q IGNyZWF0ZSBzZ190YWJsZSB3aXRoIGdpdmVuIHBhZ2VzIGFuZCBvdGhlciBwYXJhbWV0ZXJzICov Ci1zdHJ1Y3Qgc2dfdGFibGUqIGh5cGVyX2RtYWJ1Zl9jcmVhdGVfc2d0KHN0cnVjdCBwYWdlICoq cGFnZXMsCi0JCQkJCSBpbnQgZnJzdF9vZnN0LCBpbnQgbGFzdF9sZW4sIGludCBuZW50cykKLXsK LQlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsKLQlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnbDsKLQlpbnQg aSwgcmV0OwotCi0Jc2d0ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IHNnX3RhYmxlKSwgR0ZQX0tF Uk5FTCk7Ci0JaWYgKCFzZ3QpIHsKLQkJcmV0dXJuIE5VTEw7Ci0JfQotCi0JcmV0ID0gc2dfYWxs b2NfdGFibGUoc2d0LCBuZW50cywgR0ZQX0tFUk5FTCk7Ci0JaWYgKHJldCkgewotCQlpZiAoc2d0 KSB7Ci0JCQlzZ19mcmVlX3RhYmxlKHNndCk7Ci0JCQlrZnJlZShzZ3QpOwotCQl9Ci0KLQkJcmV0 dXJuIE5VTEw7Ci0JfQotCi0Jc2dsID0gc2d0LT5zZ2w7Ci0KLQlzZ19zZXRfcGFnZShzZ2wsIHBh Z2VzWzBdLCBQQUdFX1NJWkUtZnJzdF9vZnN0LCBmcnN0X29mc3QpOwotCi0JZm9yIChpPTE7IGk8 bmVudHMtMTsgaSsrKSB7Ci0JCXNnbCA9IHNnX25leHQoc2dsKTsKLQkJc2dfc2V0X3BhZ2Uoc2ds LCBwYWdlc1tpXSwgUEFHRV9TSVpFLCAwKTsKLQl9Ci0KLQlpZiAobmVudHMgPiAxKSAvKiBtb3Jl IHRoYW4gb25lIHBhZ2UgKi8gewotCQlzZ2wgPSBzZ19uZXh0KHNnbCk7Ci0JCXNnX3NldF9wYWdl KHNnbCwgcGFnZXNbaV0sIGxhc3RfbGVuLCAwKTsKLQl9Ci0KLQlyZXR1cm4gc2d0OwotfQotCi1p bnQgaHlwZXJfZG1hYnVmX2NsZWFudXBfc2d0X2luZm8oc3RydWN0IGh5cGVyX2RtYWJ1Zl9zZ3Rf aW5mbyAqc2d0X2luZm8sIGludCBmb3JjZSkKLXsKLQlzdHJ1Y3Qgc2d0X2xpc3QgKnNndGw7Ci0J c3RydWN0IGF0dGFjaG1lbnRfbGlzdCAqYXR0YWNobDsKLQlzdHJ1Y3Qga21hcF92YWRkcl9saXN0 ICp2YV9rbWFwbDsKLQlzdHJ1Y3Qgdm1hcF92YWRkcl9saXN0ICp2YV92bWFwbDsKLQlzdHJ1Y3Qg aHlwZXJfZG1hYnVmX2JhY2tlbmRfb3BzICpvcHMgPSBoeXBlcl9kbWFidWZfcHJpdmF0ZS5iYWNr ZW5kX29wczsKLQotCWlmICghc2d0X2luZm8pIHsKLQkJZGV2X2VycihoeXBlcl9kbWFidWZfcHJp dmF0ZS5kZXZpY2UsICJpbnZhbGlkIGh5cGVyX2RtYWJ1Zl9pZFxuIik7Ci0JCXJldHVybiAtRUlO VkFMOwotCX0KLQotCS8qIGlmIGZvcmNlICE9IDEsIHNndF9pbmZvIGNhbiBiZSByZWxlYXNlZCBv bmx5IGlmCi0JICogdGhlcmUncyBubyBhY3Rpdml0eSBvbiBleHBvcnRlZCBkbWEtYnVmIG9uIGlt cG9ydGVyCi0JICogc2lkZS4KLQkgKi8KLQlpZiAoIWZvcmNlICYmCi0JICAgIHNndF9pbmZvLT5p bXBvcnRlcl9leHBvcnRlZCkgewotCQlkZXZfd2FybihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZp Y2UsICJkbWEtYnVmIGlzIHVzZWQgYnkgaW1wb3J0ZXJcbiIpOwotCQlyZXR1cm4gLUVQRVJNOwot CX0KLQotCS8qIGZvcmNlID09IDEgaXMgbm90IHJlY29tbWVuZGVkICovCi0Jd2hpbGUgKCFsaXN0 X2VtcHR5KCZzZ3RfaW5mby0+dmFfa21hcHBlZC0+bGlzdCkpIHsKLQkJdmFfa21hcGwgPSBsaXN0 X2ZpcnN0X2VudHJ5KCZzZ3RfaW5mby0+dmFfa21hcHBlZC0+bGlzdCwKLQkJCQkJICAgIHN0cnVj dCBrbWFwX3ZhZGRyX2xpc3QsIGxpc3QpOwotCi0JCWRtYV9idWZfa3VubWFwKHNndF9pbmZvLT5k bWFfYnVmLCAxLCB2YV9rbWFwbC0+dmFkZHIpOwotCQlsaXN0X2RlbCgmdmFfa21hcGwtPmxpc3Qp OwotCQlrZnJlZSh2YV9rbWFwbCk7Ci0JfQotCi0Jd2hpbGUgKCFsaXN0X2VtcHR5KCZzZ3RfaW5m by0+dmFfdm1hcHBlZC0+bGlzdCkpIHsKLQkJdmFfdm1hcGwgPSBsaXN0X2ZpcnN0X2VudHJ5KCZz Z3RfaW5mby0+dmFfdm1hcHBlZC0+bGlzdCwKLQkJCQkJICAgIHN0cnVjdCB2bWFwX3ZhZGRyX2xp c3QsIGxpc3QpOwotCi0JCWRtYV9idWZfdnVubWFwKHNndF9pbmZvLT5kbWFfYnVmLCB2YV92bWFw bC0+dmFkZHIpOwotCQlsaXN0X2RlbCgmdmFfdm1hcGwtPmxpc3QpOwotCQlrZnJlZSh2YV92bWFw bCk7Ci0JfQotCi0Jd2hpbGUgKCFsaXN0X2VtcHR5KCZzZ3RfaW5mby0+YWN0aXZlX3NndHMtPmxp c3QpKSB7Ci0JCWF0dGFjaGwgPSBsaXN0X2ZpcnN0X2VudHJ5KCZzZ3RfaW5mby0+YWN0aXZlX2F0 dGFjaGVkLT5saXN0LAotCQkJCQkgICBzdHJ1Y3QgYXR0YWNobWVudF9saXN0LCBsaXN0KTsKLQot CQlzZ3RsID0gbGlzdF9maXJzdF9lbnRyeSgmc2d0X2luZm8tPmFjdGl2ZV9zZ3RzLT5saXN0LAot CQkJCQlzdHJ1Y3Qgc2d0X2xpc3QsIGxpc3QpOwotCi0JCWRtYV9idWZfdW5tYXBfYXR0YWNobWVu dChhdHRhY2hsLT5hdHRhY2gsIHNndGwtPnNndCwKLQkJCQkJIERNQV9CSURJUkVDVElPTkFMKTsK LQkJbGlzdF9kZWwoJnNndGwtPmxpc3QpOwotCQlrZnJlZShzZ3RsKTsKLQl9Ci0KLQl3aGlsZSAo IWxpc3RfZW1wdHkoJnNndF9pbmZvLT5hY3RpdmVfc2d0cy0+bGlzdCkpIHsKLQkJYXR0YWNobCA9 IGxpc3RfZmlyc3RfZW50cnkoJnNndF9pbmZvLT5hY3RpdmVfYXR0YWNoZWQtPmxpc3QsCi0JCQkJ CSAgIHN0cnVjdCBhdHRhY2htZW50X2xpc3QsIGxpc3QpOwotCi0JCWRtYV9idWZfZGV0YWNoKHNn dF9pbmZvLT5kbWFfYnVmLCBhdHRhY2hsLT5hdHRhY2gpOwotCQlsaXN0X2RlbCgmYXR0YWNobC0+ bGlzdCk7Ci0JCWtmcmVlKGF0dGFjaGwpOwotCX0KLQotCS8qIFN0YXJ0IGNsZWFudXAgb2YgYnVm ZmVyIGluIHJldmVyc2Ugb3JkZXIgdG8gZXhwb3J0aW5nICovCi0Jb3BzLT51bnNoYXJlX3BhZ2Vz KCZzZ3RfaW5mby0+cmVmc19pbmZvLCBzZ3RfaW5mby0+bmVudHMpOwotCi0JLyogdW5tYXAgZG1h LWJ1ZiAqLwotCWRtYV9idWZfdW5tYXBfYXR0YWNobWVudChzZ3RfaW5mby0+YWN0aXZlX2F0dGFj aGVkLT5hdHRhY2gsCi0JCQkJIHNndF9pbmZvLT5hY3RpdmVfc2d0cy0+c2d0LAotCQkJCSBETUFf QklESVJFQ1RJT05BTCk7Ci0KLQkvKiBkZXRhdGNoIGRtYS1idWYgKi8KLQlkbWFfYnVmX2RldGFj aChzZ3RfaW5mby0+ZG1hX2J1Ziwgc2d0X2luZm8tPmFjdGl2ZV9hdHRhY2hlZC0+YXR0YWNoKTsK LQotCS8qIGNsb3NlIGNvbm5lY3Rpb24gdG8gZG1hLWJ1ZiBjb21wbGV0ZWx5ICovCi0JZG1hX2J1 Zl9wdXQoc2d0X2luZm8tPmRtYV9idWYpOwotCXNndF9pbmZvLT5kbWFfYnVmID0gTlVMTDsKLQot CWtmcmVlKHNndF9pbmZvLT5hY3RpdmVfc2d0cyk7Ci0Ja2ZyZWUoc2d0X2luZm8tPmFjdGl2ZV9h dHRhY2hlZCk7Ci0Ja2ZyZWUoc2d0X2luZm8tPnZhX2ttYXBwZWQpOwotCWtmcmVlKHNndF9pbmZv LT52YV92bWFwcGVkKTsKLQotCXJldHVybiAwOwotfQotCi0jZGVmaW5lIFdBSVRfQUZURVJfU1lO Q19SRVEgMAotCi1pbmxpbmUgaW50IGh5cGVyX2RtYWJ1Zl9zeW5jX3JlcXVlc3QoaHlwZXJfZG1h YnVmX2lkX3QgaGlkLCBpbnQgZG1hYnVmX29wcykKLXsKLQlzdHJ1Y3QgaHlwZXJfZG1hYnVmX3Jl cSAqcmVxOwotCXN0cnVjdCBoeXBlcl9kbWFidWZfYmFja2VuZF9vcHMgKm9wcyA9IGh5cGVyX2Rt YWJ1Zl9wcml2YXRlLmJhY2tlbmRfb3BzOwotCWludCBvcGVyYW5kc1s1XTsKLQlpbnQgaTsKLQlp bnQgcmV0OwotCi0Jb3BlcmFuZHNbMF0gPSBoaWQuaWQ7Ci0KLQlmb3IgKGk9MDsgaTwzOyBpKysp Ci0JCW9wZXJhbmRzW2krMV0gPSBoaWQucm5nX2tleVtpXTsKLQotCW9wZXJhbmRzWzRdID0gZG1h YnVmX29wczsKLQotCXJlcSA9IGtjYWxsb2MoMSwgc2l6ZW9mKCpyZXEpLCBHRlBfS0VSTkVMKTsK LQotCWlmICghcmVxKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAot CQkJIk5vIG1lbW9yeSBsZWZ0IHRvIGJlIGFsbG9jYXRlZFxuIik7Ci0JCXJldHVybiAtRU5PTUVN OwotCX0KLQotCWh5cGVyX2RtYWJ1Zl9jcmVhdGVfcmVxdWVzdChyZXEsIEhZUEVSX0RNQUJVRl9P UFNfVE9fU09VUkNFLCAmb3BlcmFuZHNbMF0pOwotCi0JLyogc2VuZCByZXF1ZXN0IGFuZCB3YWl0 IGZvciBhIHJlc3BvbnNlICovCi0JcmV0ID0gb3BzLT5zZW5kX3JlcShIWVBFUl9ETUFCVUZfRE9N X0lEKGhpZCksIHJlcSwgV0FJVF9BRlRFUl9TWU5DX1JFUSk7Ci0KLQlrZnJlZShyZXEpOwotCi0J cmV0dXJuIHJldDsKLX0KLQotc3RhdGljIGludCBoeXBlcl9kbWFidWZfb3BzX2F0dGFjaChzdHJ1 Y3QgZG1hX2J1ZiogZG1hYnVmLCBzdHJ1Y3QgZGV2aWNlKiBkZXYsCi0JCQlzdHJ1Y3QgZG1hX2J1 Zl9hdHRhY2htZW50ICphdHRhY2gpCi17Ci0Jc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9z Z3RfaW5mbyAqc2d0X2luZm87Ci0JaW50IHJldDsKLQotCWlmICghYXR0YWNoLT5kbWFidWYtPnBy aXYpCi0JCXJldHVybiAtRUlOVkFMOwotCi0Jc2d0X2luZm8gPSAoc3RydWN0IGh5cGVyX2RtYWJ1 Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqKWF0dGFjaC0+ZG1hYnVmLT5wcml2OwotCi0JcmV0ID0gaHlw ZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAotCQkJCQlIWVBFUl9ETUFCVUZf T1BTX0FUVEFDSCk7Ci0KLQlpZiAocmV0IDwgMCkgewotCQlkZXZfZXJyKGh5cGVyX2RtYWJ1Zl9w cml2YXRlLmRldmljZSwKLQkJCSJoeXBlcl9kbWFidWY6OiVzIEVycm9yOnNlbmQgZG1hYnVmIHN5 bmMgcmVxdWVzdCBmYWlsZWRcbiIsIF9fZnVuY19fKTsKLQkJcmV0dXJuIHJldDsKLQl9Ci0KLQly ZXR1cm4gMDsKLX0KLQotc3RhdGljIHZvaWQgaHlwZXJfZG1hYnVmX29wc19kZXRhY2goc3RydWN0 IGRtYV9idWYqIGRtYWJ1Ziwgc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNoKQotewot CXN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOwotCWludCBy ZXQ7Ci0KLQlpZiAoIWF0dGFjaC0+ZG1hYnVmLT5wcml2KQotCQlyZXR1cm47Ci0KLQlzZ3RfaW5m byA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopYXR0YWNoLT5kbWFi dWYtPnByaXY7Ci0KLQlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5o aWQsCi0JCQkJCUhZUEVSX0RNQUJVRl9PUFNfREVUQUNIKTsKLQotCWlmIChyZXQgPCAwKSB7Ci0J CWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAotCQkJImh5cGVyX2RtYWJ1Zjo6 JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOwot CX0KLX0KLQotc3RhdGljIHN0cnVjdCBzZ190YWJsZSogaHlwZXJfZG1hYnVmX29wc19tYXAoc3Ry dWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNobWVudCwKLQkJCQkJCWVudW0gZG1hX2RhdGFf ZGlyZWN0aW9uIGRpcikKLXsKLQlzdHJ1Y3Qgc2dfdGFibGUgKnN0OwotCXN0cnVjdCBoeXBlcl9k bWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOwotCXN0cnVjdCBoeXBlcl9kbWFidWZf cGFnZXNfaW5mbyAqcGFnZV9pbmZvOwotCWludCByZXQ7Ci0KLQlpZiAoIWF0dGFjaG1lbnQtPmRt YWJ1Zi0+cHJpdikKLQkJcmV0dXJuIE5VTEw7Ci0KLQlzZ3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJf ZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopYXR0YWNobWVudC0+ZG1hYnVmLT5wcml2OwotCi0J LyogZXh0cmFjdCBwYWdlcyBmcm9tIHNndCAqLwotCXBhZ2VfaW5mbyA9IGh5cGVyX2RtYWJ1Zl9l eHRfcGdzKHNndF9pbmZvLT5zZ3QpOwotCi0JaWYgKCFwYWdlX2luZm8pIHsKLQkJcmV0dXJuIE5V TEw7Ci0JfQotCi0JLyogY3JlYXRlIGEgbmV3IHNnX3RhYmxlIHdpdGggZXh0cmFjdGVkIHBhZ2Vz ICovCi0Jc3QgPSBoeXBlcl9kbWFidWZfY3JlYXRlX3NndChwYWdlX2luZm8tPnBhZ2VzLCBwYWdl X2luZm8tPmZyc3Rfb2ZzdCwKLQkJCQlwYWdlX2luZm8tPmxhc3RfbGVuLCBwYWdlX2luZm8tPm5l bnRzKTsKLQlpZiAoIXN0KQotCQlnb3RvIGVycl9mcmVlX3NnOwotCi0gICAgICAgIGlmICghZG1h X21hcF9zZyhhdHRhY2htZW50LT5kZXYsIHN0LT5zZ2wsIHN0LT5uZW50cywgZGlyKSkgewotICAg ICAgICAgICAgICAgIGdvdG8gZXJyX2ZyZWVfc2c7Ci0gICAgICAgIH0KLQotCXJldCA9IGh5cGVy X2RtYWJ1Zl9zeW5jX3JlcXVlc3Qoc2d0X2luZm8tPmhpZCwKLQkJCQkJSFlQRVJfRE1BQlVGX09Q U19NQVApOwotCi0Ja2ZyZWUocGFnZV9pbmZvLT5wYWdlcyk7Ci0Ja2ZyZWUocGFnZV9pbmZvKTsK LQotCWlmIChyZXQgPCAwKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNl LAotCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZh aWxlZFxuIiwgX19mdW5jX18pOwotCX0KLQotCXJldHVybiBzdDsKLQotZXJyX2ZyZWVfc2c6Ci0J aWYgKHN0KSB7Ci0JCXNnX2ZyZWVfdGFibGUoc3QpOwotCQlrZnJlZShzdCk7Ci0JfQotCi0JcmV0 dXJuIE5VTEw7Ci19Ci0KLXN0YXRpYyB2b2lkIGh5cGVyX2RtYWJ1Zl9vcHNfdW5tYXAoc3RydWN0 IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNobWVudCwKLQkJCQkgICBzdHJ1Y3Qgc2dfdGFibGUg KnNnLAotCQkJCSAgIGVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpcikKLXsKLQlzdHJ1Y3QgaHlw ZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICpzZ3RfaW5mbzsKLQlpbnQgcmV0OwotCi0JaWYg KCFhdHRhY2htZW50LT5kbWFidWYtPnByaXYpCi0JCXJldHVybjsKLQotCXNndF9pbmZvID0gKHN0 cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilhdHRhY2htZW50LT5kbWFidWYt PnByaXY7Ci0KLQlkbWFfdW5tYXBfc2coYXR0YWNobWVudC0+ZGV2LCBzZy0+c2dsLCBzZy0+bmVu dHMsIGRpcik7Ci0KLQlzZ19mcmVlX3RhYmxlKHNnKTsKLQlrZnJlZShzZyk7Ci0KLQlyZXQgPSBo eXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5oaWQsCi0JCQkJCUhZUEVSX0RNQUJV Rl9PUFNfVU5NQVApOwotCi0JaWYgKHJldCA8IDApIHsKLQkJZGV2X2VycihoeXBlcl9kbWFidWZf cHJpdmF0ZS5kZXZpY2UsCi0JCQkiaHlwZXJfZG1hYnVmOjolcyBFcnJvcjpzZW5kIGRtYWJ1ZiBz eW5jIHJlcXVlc3QgZmFpbGVkXG4iLCBfX2Z1bmNfXyk7Ci0JfQotfQotCi1zdGF0aWMgdm9pZCBo eXBlcl9kbWFidWZfb3BzX3JlbGVhc2Uoc3RydWN0IGRtYV9idWYgKmRtYV9idWYpCi17Ci0Jc3Ry dWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0X2luZm87Ci0Jc3RydWN0IGh5 cGVyX2RtYWJ1Zl9iYWNrZW5kX29wcyAqb3BzID0gaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2Vu ZF9vcHM7Ci0JaW50IHJldDsKLQlpbnQgZmluYWxfcmVsZWFzZTsKLQotCWlmICghZG1hX2J1Zi0+ cHJpdikKLQkJcmV0dXJuOwotCi0Jc2d0X2luZm8gPSAoc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBv cnRlZF9zZ3RfaW5mbyAqKWRtYV9idWYtPnByaXY7Ci0KLQlpZiAoIWRtYWJ1Zl9yZWZjb3VudChz Z3RfaW5mby0+ZG1hX2J1ZikpIHsKLQkJc2d0X2luZm8tPmRtYV9idWYgPSBOVUxMOwotCX0KLQot CXNndF9pbmZvLT5udW1faW1wb3J0ZXJzLS07Ci0KLQlpZiAoc2d0X2luZm8tPm51bV9pbXBvcnRl cnMgPT0gMCkgewotCQlvcHMtPnVubWFwX3NoYXJlZF9wYWdlcygmc2d0X2luZm8tPnJlZnNfaW5m bywgc2d0X2luZm8tPm5lbnRzKTsKLQotCQlpZiAoc2d0X2luZm8tPnNndCkgewotCQkJc2dfZnJl ZV90YWJsZShzZ3RfaW5mby0+c2d0KTsKLQkJCWtmcmVlKHNndF9pbmZvLT5zZ3QpOwotCQkJc2d0 X2luZm8tPnNndCA9IE5VTEw7Ci0JCX0KLQl9Ci0KLQlmaW5hbF9yZWxlYXNlID0gc2d0X2luZm8g JiYgIXNndF9pbmZvLT52YWxpZCAmJgotCQkgICAgICAgICFzZ3RfaW5mby0+bnVtX2ltcG9ydGVy czsKLQotCXJldCA9IGh5cGVyX2RtYWJ1Zl9zeW5jX3JlcXVlc3Qoc2d0X2luZm8tPmhpZCwKLQkJ CQkJSFlQRVJfRE1BQlVGX09QU19SRUxFQVNFKTsKLQlpZiAocmV0IDwgMCkgewotCQlkZXZfd2Fy bihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsCi0JCQkgImh5cGVyX2RtYWJ1Zjo6JXMgRXJy b3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOwotCX0KLQot CS8qCi0JICogQ2hlY2sgaWYgYnVmZmVyIGlzIHN0aWxsIHZhbGlkIGFuZCBpZiBub3QgcmVtb3Zl IGl0IGZyb20gaW1wb3J0ZWQgbGlzdC4KLQkgKiBUaGF0IGhhcyB0byBiZSBkb25lIGFmdGVyIHNl bmRpbmcgc3luYyByZXF1ZXN0Ci0JICovCi0JaWYgKGZpbmFsX3JlbGVhc2UpIHsKLQkJaHlwZXJf ZG1hYnVmX3JlbW92ZV9pbXBvcnRlZChzZ3RfaW5mby0+aGlkKTsKLQkJa2ZyZWUoc2d0X2luZm8p OwotCX0KLX0KLQotc3RhdGljIGludCBoeXBlcl9kbWFidWZfb3BzX2JlZ2luX2NwdV9hY2Nlc3Mo c3RydWN0IGRtYV9idWYgKmRtYWJ1ZiwgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyKQotewot CXN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOwotCWludCBy ZXQ7Ci0KLQlpZiAoIWRtYWJ1Zi0+cHJpdikKLQkJcmV0dXJuIC1FSU5WQUw7Ci0KLQlzZ3RfaW5m byA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVmLT5wcml2 OwotCi0JcmV0ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAotCQkJ CQlIWVBFUl9ETUFCVUZfT1BTX0JFR0lOX0NQVV9BQ0NFU1MpOwotCWlmIChyZXQgPCAwKSB7Ci0J CWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAotCQkJImh5cGVyX2RtYWJ1Zjo6 JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOwot CX0KLQotCXJldHVybiByZXQ7Ci19Ci0KLXN0YXRpYyBpbnQgaHlwZXJfZG1hYnVmX29wc19lbmRf Y3B1X2FjY2VzcyhzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCBlbnVtIGRtYV9kYXRhX2RpcmVjdGlv biBkaXIpCi17Ci0Jc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0X2lu Zm87Ci0JaW50IHJldDsKLQotCWlmICghZG1hYnVmLT5wcml2KQotCQlyZXR1cm4gLUVJTlZBTDsK LQotCXNndF9pbmZvID0gKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilk bWFidWYtPnByaXY7Ci0KLQlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZv LT5oaWQsCi0JCQkJCUhZUEVSX0RNQUJVRl9PUFNfRU5EX0NQVV9BQ0NFU1MpOwotCWlmIChyZXQg PCAwKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAotCQkJImh5cGVy X2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19m dW5jX18pOwotCX0KLQotCXJldHVybiAwOwotfQotCi1zdGF0aWMgdm9pZCAqaHlwZXJfZG1hYnVm X29wc19rbWFwX2F0b21pYyhzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCB1bnNpZ25lZCBsb25nIHBn bnVtKQotewotCXN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZv OwotCWludCByZXQ7Ci0KLQlpZiAoIWRtYWJ1Zi0+cHJpdikKLQkJcmV0dXJuIE5VTEw7Ci0KLQlz Z3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVm LT5wcml2OwotCi0JcmV0ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlk LAotCQkJCQlIWVBFUl9ETUFCVUZfT1BTX0tNQVBfQVRPTUlDKTsKLQlpZiAocmV0IDwgMCkgewot CQlkZXZfZXJyKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKLQkJCSJoeXBlcl9kbWFidWY6 OiVzIEVycm9yOnNlbmQgZG1hYnVmIHN5bmMgcmVxdWVzdCBmYWlsZWRcbiIsIF9fZnVuY19fKTsK LQl9Ci0KLQlyZXR1cm4gTlVMTDsgLyogZm9yIG5vdyBOVUxMLi4gbmVlZCB0byByZXR1cm4gdGhl IGFkZHJlc3Mgb2YgbWFwcGVkIHJlZ2lvbiAqLwotfQotCi1zdGF0aWMgdm9pZCBoeXBlcl9kbWFi dWZfb3BzX2t1bm1hcF9hdG9taWMoc3RydWN0IGRtYV9idWYgKmRtYWJ1ZiwgdW5zaWduZWQgbG9u ZyBwZ251bSwgdm9pZCAqdmFkZHIpCi17Ci0Jc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9z Z3RfaW5mbyAqc2d0X2luZm87Ci0JaW50IHJldDsKLQotCWlmICghZG1hYnVmLT5wcml2KQotCQly ZXR1cm47Ci0KLQlzZ3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9p bmZvICopZG1hYnVmLT5wcml2OwotCi0JcmV0ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChz Z3RfaW5mby0+aGlkLAotCQkJCQlIWVBFUl9ETUFCVUZfT1BTX0tVTk1BUF9BVE9NSUMpOwotCWlm IChyZXQgPCAwKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAotCQkJ Imh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxu IiwgX19mdW5jX18pOwotCX0KLX0KLQotc3RhdGljIHZvaWQgKmh5cGVyX2RtYWJ1Zl9vcHNfa21h cChzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCB1bnNpZ25lZCBsb25nIHBnbnVtKQotewotCXN0cnVj dCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOwotCWludCByZXQ7Ci0K LQlpZiAoIWRtYWJ1Zi0+cHJpdikKLQkJcmV0dXJuIE5VTEw7Ci0KLQlzZ3RfaW5mbyA9IChzdHJ1 Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVmLT5wcml2OwotCi0JcmV0 ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAotCQkJCQlIWVBFUl9E TUFCVUZfT1BTX0tNQVApOwotCWlmIChyZXQgPCAwKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVm X3ByaXZhdGUuZGV2aWNlLAotCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYg c3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOwotCX0KLQotCXJldHVybiBOVUxMOyAv KiBmb3Igbm93IE5VTEwuLiBuZWVkIHRvIHJldHVybiB0aGUgYWRkcmVzcyBvZiBtYXBwZWQgcmVn aW9uICovCi19Ci0KLXN0YXRpYyB2b2lkIGh5cGVyX2RtYWJ1Zl9vcHNfa3VubWFwKHN0cnVjdCBk bWFfYnVmICpkbWFidWYsIHVuc2lnbmVkIGxvbmcgcGdudW0sIHZvaWQgKnZhZGRyKQotewotCXN0 cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOwotCWludCByZXQ7 Ci0KLQlpZiAoIWRtYWJ1Zi0+cHJpdikKLQkJcmV0dXJuOwotCi0Jc2d0X2luZm8gPSAoc3RydWN0 IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqKWRtYWJ1Zi0+cHJpdjsKLQotCXJldCA9 IGh5cGVyX2RtYWJ1Zl9zeW5jX3JlcXVlc3Qoc2d0X2luZm8tPmhpZCwKLQkJCQkJSFlQRVJfRE1B QlVGX09QU19LVU5NQVApOwotCWlmIChyZXQgPCAwKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVm X3ByaXZhdGUuZGV2aWNlLAotCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYg c3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOwotCX0KLX0KLQotc3RhdGljIGludCBo eXBlcl9kbWFidWZfb3BzX21tYXAoc3RydWN0IGRtYV9idWYgKmRtYWJ1Ziwgc3RydWN0IHZtX2Fy ZWFfc3RydWN0ICp2bWEpCi17Ci0Jc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5m byAqc2d0X2luZm87Ci0JaW50IHJldDsKLQotCWlmICghZG1hYnVmLT5wcml2KQotCQlyZXR1cm4g LUVJTlZBTDsKLQotCXNndF9pbmZvID0gKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0 X2luZm8gKilkbWFidWYtPnByaXY7Ci0KLQlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0 KHNndF9pbmZvLT5oaWQsCi0JCQkJCUhZUEVSX0RNQUJVRl9PUFNfTU1BUCk7Ci0JaWYgKHJldCA8 IDApIHsKLQkJZGV2X2VycihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsCi0JCQkiaHlwZXJf ZG1hYnVmOjolcyBFcnJvcjpzZW5kIGRtYWJ1ZiBzeW5jIHJlcXVlc3QgZmFpbGVkXG4iLCBfX2Z1 bmNfXyk7Ci0JfQotCi0JcmV0dXJuIHJldDsKLX0KLQotc3RhdGljIHZvaWQgKmh5cGVyX2RtYWJ1 Zl9vcHNfdm1hcChzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmKQotewotCXN0cnVjdCBoeXBlcl9kbWFi dWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOwotCWludCByZXQ7Ci0KLQlpZiAoIWRtYWJ1 Zi0+cHJpdikKLQkJcmV0dXJuIE5VTEw7Ci0KLQlzZ3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1h YnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVmLT5wcml2OwotCi0JcmV0ID0gaHlwZXJfZG1h YnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAotCQkJCQlIWVBFUl9ETUFCVUZfT1BTX1ZN QVApOwotCWlmIChyZXQgPCAwKSB7Ci0JCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2 aWNlLAotCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0 IGZhaWxlZFxuIiwgX19mdW5jX18pOwotCX0KLQotCXJldHVybiBOVUxMOwotfQotCi1zdGF0aWMg dm9pZCBoeXBlcl9kbWFidWZfb3BzX3Z1bm1hcChzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCB2b2lk ICp2YWRkcikKLXsKLQlzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICpzZ3Rf aW5mbzsKLQlpbnQgcmV0OwotCi0JaWYgKCFkbWFidWYtPnByaXYpCi0JCXJldHVybjsKLQotCXNn dF9pbmZvID0gKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilkbWFidWYt PnByaXY7Ci0KLQlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5oaWQs Ci0JCQkJCUhZUEVSX0RNQUJVRl9PUFNfVlVOTUFQKTsKLQlpZiAocmV0IDwgMCkgewotCQlkZXZf ZXJyKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKLQkJCSJoeXBlcl9kbWFidWY6OiVzIEVy cm9yOnNlbmQgZG1hYnVmIHN5bmMgcmVxdWVzdCBmYWlsZWRcbiIsIF9fZnVuY19fKTsKLQl9Ci19 Ci0KLXN0YXRpYyBjb25zdCBzdHJ1Y3QgZG1hX2J1Zl9vcHMgaHlwZXJfZG1hYnVmX29wcyA9IHsK LQkJLmF0dGFjaCA9IGh5cGVyX2RtYWJ1Zl9vcHNfYXR0YWNoLAotCQkuZGV0YWNoID0gaHlwZXJf ZG1hYnVmX29wc19kZXRhY2gsCi0JCS5tYXBfZG1hX2J1ZiA9IGh5cGVyX2RtYWJ1Zl9vcHNfbWFw LAotCQkudW5tYXBfZG1hX2J1ZiA9IGh5cGVyX2RtYWJ1Zl9vcHNfdW5tYXAsCi0JCS5yZWxlYXNl ID0gaHlwZXJfZG1hYnVmX29wc19yZWxlYXNlLAotCQkuYmVnaW5fY3B1X2FjY2VzcyA9ICh2b2lk KiloeXBlcl9kbWFidWZfb3BzX2JlZ2luX2NwdV9hY2Nlc3MsCi0JCS5lbmRfY3B1X2FjY2VzcyA9 ICh2b2lkKiloeXBlcl9kbWFidWZfb3BzX2VuZF9jcHVfYWNjZXNzLAotCQkubWFwX2F0b21pYyA9 IGh5cGVyX2RtYWJ1Zl9vcHNfa21hcF9hdG9taWMsCi0JCS51bm1hcF9hdG9taWMgPSBoeXBlcl9k bWFidWZfb3BzX2t1bm1hcF9hdG9taWMsCi0JCS5tYXAgPSBoeXBlcl9kbWFidWZfb3BzX2ttYXAs Ci0JCS51bm1hcCA9IGh5cGVyX2RtYWJ1Zl9vcHNfa3VubWFwLAotCQkubW1hcCA9IGh5cGVyX2Rt YWJ1Zl9vcHNfbW1hcCwKLQkJLnZtYXAgPSBoeXBlcl9kbWFidWZfb3BzX3ZtYXAsCi0JCS52dW5t YXAgPSBoeXBlcl9kbWFidWZfb3BzX3Z1bm1hcCwKLX07Ci0KLS8qIGV4cG9ydGluZyBkbWFidWYg YXMgZmQgKi8KLWludCBoeXBlcl9kbWFidWZfZXhwb3J0X2ZkKHN0cnVjdCBoeXBlcl9kbWFidWZf aW1wb3J0ZWRfc2d0X2luZm8gKmRpbmZvLCBpbnQgZmxhZ3MpCi17Ci0JaW50IGZkID0gLTE7Ci0K LQkvKiBjYWxsIGh5cGVyX2RtYWJ1Zl9leHBvcnRfZG1hYnVmIGFuZCBjcmVhdGUKLQkgKiBhbmQg YmluZCBhIGhhbmRsZSBmb3IgaXQgdGhlbiByZWxlYXNlCi0JICovCi0JaHlwZXJfZG1hYnVmX2V4 cG9ydF9kbWFfYnVmKGRpbmZvKTsKLQotCWlmIChkaW5mby0+ZG1hX2J1ZikgewotCQlmZCA9IGRt YV9idWZfZmQoZGluZm8tPmRtYV9idWYsIGZsYWdzKTsKLQl9Ci0KLQlyZXR1cm4gZmQ7Ci19Ci0K LXZvaWQgaHlwZXJfZG1hYnVmX2V4cG9ydF9kbWFfYnVmKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1w b3J0ZWRfc2d0X2luZm8gKmRpbmZvKQotewotCURFRklORV9ETUFfQlVGX0VYUE9SVF9JTkZPKGV4 cF9pbmZvKTsKLQotCWV4cF9pbmZvLm9wcyA9ICZoeXBlcl9kbWFidWZfb3BzOwotCi0JLyogbXVs dGlwbGUgb2YgUEFHRV9TSVpFLCBub3QgY29uc2lkZXJpbmcgb2Zmc2V0ICovCi0JZXhwX2luZm8u c2l6ZSA9IGRpbmZvLT5zZ3QtPm5lbnRzICogUEFHRV9TSVpFOwotCWV4cF9pbmZvLmZsYWdzID0g Lyogbm90IHN1cmUgYWJvdXQgZmxhZyAqLzA7Ci0JZXhwX2luZm8ucHJpdiA9IGRpbmZvOwotCi0J ZGluZm8tPmRtYV9idWYgPSBkbWFfYnVmX2V4cG9ydCgmZXhwX2luZm8pOwotfQpkaWZmIC0tZ2l0 IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9pbXAuaCBiL2RyaXZlcnMv eGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfaW1wLmgKZGVsZXRlZCBmaWxlIG1vZGUgMTAw NjQ0CmluZGV4IGVkYTA3NWIzLi4wMDAwMDAwCi0tLSBhL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1 Zi9oeXBlcl9kbWFidWZfaW1wLmgKKysrIC9kZXYvbnVsbApAQCAtMSw0OCArMCwwIEBACi0vKgot ICogQ29weXJpZ2h0IMKpIDIwMTcgSW50ZWwgQ29ycG9yYXRpb24KLSAqCi0gKiBQZXJtaXNzaW9u IGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5p bmcgYQotICogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRp b24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKLSAqIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdp dGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KLSAqIHRoZSBy aWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBz dWJsaWNlbnNlLAotICogYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRv IHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlCi0gKiBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8g ZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgotICoKLSAqIFRoZSBh Ym92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRp bmcgdGhlIG5leHQKLSAqIHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGll cyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUKLSAqIFNvZnR3YXJlLgotICoKLSAqIFRI RSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBL SU5ELCBFWFBSRVNTIE9SCi0gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRP IFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLSAqIEZJVE5FU1MgRk9SIEEgUEFS VElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFMTAot ICogVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xB SU0sIERBTUFHRVMgT1IgT1RIRVIKLSAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04g T0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCi0gKiBGUk9NLCBPVVQgT0Yg T1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERF QUxJTkdTCi0gKiBJTiBUSEUgU09GVFdBUkUuCi0gKgotICovCi0KLSNpZm5kZWYgX19IWVBFUl9E TUFCVUZfSU1QX0hfXwotI2RlZmluZSBfX0hZUEVSX0RNQUJVRl9JTVBfSF9fCi0KLSNpbmNsdWRl IDxsaW51eC9mcy5oPgotI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9zdHJ1Y3QuaCIKLQotLyogZXh0 cmFjdCBwYWdlcyBkaXJlY3RseSBmcm9tIHN0cnVjdCBzZ190YWJsZSAqLwotc3RydWN0IGh5cGVy X2RtYWJ1Zl9wYWdlc19pbmZvICpoeXBlcl9kbWFidWZfZXh0X3BncyhzdHJ1Y3Qgc2dfdGFibGUg KnNndCk7Ci0KLS8qIGNyZWF0ZSBzZ190YWJsZSB3aXRoIGdpdmVuIHBhZ2VzIGFuZCBvdGhlciBw YXJhbWV0ZXJzICovCi1zdHJ1Y3Qgc2dfdGFibGUqIGh5cGVyX2RtYWJ1Zl9jcmVhdGVfc2d0KHN0 cnVjdCBwYWdlICoqcGFnZXMsCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBm cnN0X29mc3QsIGludCBsYXN0X2xlbiwgaW50IG5lbnRzKTsKLQotaW50IGh5cGVyX2RtYWJ1Zl9j bGVhbnVwX3NndF9pbmZvKHN0cnVjdCBoeXBlcl9kbWFidWZfc2d0X2luZm8gKnNndF9pbmZvLCBp bnQgZm9yY2UpOwotCi12b2lkIGh5cGVyX2RtYWJ1Zl9mcmVlX3NndChzdHJ1Y3Qgc2dfdGFibGUg KnNndCk7Ci0KLWludCBoeXBlcl9kbWFidWZfZXhwb3J0X2ZkKHN0cnVjdCBoeXBlcl9kbWFidWZf aW1wb3J0ZWRfc2d0X2luZm8gKmRpbmZvLCBpbnQgZmxhZ3MpOwotCi12b2lkIGh5cGVyX2RtYWJ1 Zl9leHBvcnRfZG1hX2J1ZihzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICpk aW5mbyk7Ci0KLWludCBkbWFidWZfcmVmY291bnQoc3RydWN0IGRtYV9idWYgKmRtYV9idWYpOwot Ci0jZW5kaWYgLyogX19IWVBFUl9ETUFCVUZfSU1QX0hfXyAqLwpkaWZmIC0tZ2l0IGEvZHJpdmVy cy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9pb2N0bC5jIGIvZHJpdmVycy94ZW4vaHlw ZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9pb2N0bC5jCmluZGV4IDlkMDVkNjYuLjI4M2ZlNWEgMTAw NjQ0Ci0tLSBhL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfaW9jdGwuYwor KysgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX2lvY3RsLmMKQEAgLTQx LDcgKzQxLDggQEAKICNpbmNsdWRlICJoeXBlcl9kbWFidWZfaW9jdGwuaCIKICNpbmNsdWRlICJo eXBlcl9kbWFidWZfbGlzdC5oIgogI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9tc2cuaCIKLSNpbmNs dWRlICJoeXBlcl9kbWFidWZfaW1wLmgiCisjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX3NnbF9wcm9j LmgiCisjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX29wcy5oIgogI2luY2x1ZGUgImh5cGVyX2RtYWJ1 Zl9xdWVyeS5oIgogCiBleHRlcm4gc3RydWN0IGh5cGVyX2RtYWJ1Zl9wcml2YXRlIGh5cGVyX2Rt YWJ1Zl9wcml2YXRlOwpAQCAtNjE4LDcgKzYxOSwyOSBAQCBzdGF0aWMgaW50IGh5cGVyX2RtYWJ1 Zl9xdWVyeV9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlscCwgdm9pZCAqZGF0YSkKIAlyZXR1cm4gMDsK IH0KIAotc3RhdGljIGNvbnN0IHN0cnVjdCBoeXBlcl9kbWFidWZfaW9jdGxfZGVzYyBoeXBlcl9k bWFidWZfaW9jdGxzW10gPSB7Cit2b2lkIGh5cGVyX2RtYWJ1Zl9lbWVyZ2VuY3lfcmVsZWFzZShz dHJ1Y3QgaHlwZXJfZG1hYnVmX3NndF9pbmZvKiBzZ3RfaW5mbywKKwkJCQkgICAgdm9pZCAqYXR0 cikKK3sKKwlzdHJ1Y3QgaW9jdGxfaHlwZXJfZG1hYnVmX3VuZXhwb3J0IHVuZXhwb3J0X2F0dHI7 CisJc3RydWN0IGZpbGUgKmZpbHAgPSAoc3RydWN0IGZpbGUqKSBhdHRyOworCisJaWYgKCFmaWxw IHx8ICFzZ3RfaW5mbykKKwkJcmV0dXJuOworCisJaWYgKHNndF9pbmZvLT5maWxwID09IGZpbHAp IHsKKwkJZGV2X2RiZyhoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsCisJCQkiRXhlY3V0aW5n IGVtZXJnZW5jeSByZWxlYXNlIG9mIGJ1ZmZlciB7aWQ6JWQga2V5OiVkICVkICVkfVxuIiwKKwkJ CSBzZ3RfaW5mby0+aGlkLmlkLCBzZ3RfaW5mby0+aGlkLnJuZ19rZXlbMF0sCisJCQkgc2d0X2lu Zm8tPmhpZC5ybmdfa2V5WzFdLCBzZ3RfaW5mby0+aGlkLnJuZ19rZXlbMl0pOworCisJCXVuZXhw b3J0X2F0dHIuaGlkID0gc2d0X2luZm8tPmhpZDsKKwkJdW5leHBvcnRfYXR0ci5kZWxheV9tcyA9 IDA7CisKKwkJaHlwZXJfZG1hYnVmX3VuZXhwb3J0X2lvY3RsKGZpbHAsICZ1bmV4cG9ydF9hdHRy KTsKKwl9Cit9CisKK2NvbnN0IHN0cnVjdCBoeXBlcl9kbWFidWZfaW9jdGxfZGVzYyBoeXBlcl9k bWFidWZfaW9jdGxzW10gPSB7CiAJSFlQRVJfRE1BQlVGX0lPQ1RMX0RFRihJT0NUTF9IWVBFUl9E TUFCVUZfVFhfQ0hfU0VUVVAsIGh5cGVyX2RtYWJ1Zl90eF9jaF9zZXR1cF9pb2N0bCwgMCksCiAJ SFlQRVJfRE1BQlVGX0lPQ1RMX0RFRihJT0NUTF9IWVBFUl9ETUFCVUZfUlhfQ0hfU0VUVVAsIGh5 cGVyX2RtYWJ1Zl9yeF9jaF9zZXR1cF9pb2N0bCwgMCksCiAJSFlQRVJfRE1BQlVGX0lPQ1RMX0RF RihJT0NUTF9IWVBFUl9ETUFCVUZfRVhQT1JUX1JFTU9URSwgaHlwZXJfZG1hYnVmX2V4cG9ydF9y ZW1vdGVfaW9jdGwsIDApLApAQCAtNjI3LDcgKzY1MCw3IEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3Qg aHlwZXJfZG1hYnVmX2lvY3RsX2Rlc2MgaHlwZXJfZG1hYnVmX2lvY3Rsc1tdID0gewogCUhZUEVS X0RNQUJVRl9JT0NUTF9ERUYoSU9DVExfSFlQRVJfRE1BQlVGX1FVRVJZLCBoeXBlcl9kbWFidWZf cXVlcnlfaW9jdGwsIDApLAogfTsKIAotc3RhdGljIGxvbmcgaHlwZXJfZG1hYnVmX2lvY3RsKHN0 cnVjdCBmaWxlICpmaWxwLAorbG9uZyBoeXBlcl9kbWFidWZfaW9jdGwoc3RydWN0IGZpbGUgKmZp bHAsCiAJCQl1bnNpZ25lZCBpbnQgY21kLCB1bnNpZ25lZCBsb25nIHBhcmFtKQogewogCWNvbnN0 IHN0cnVjdCBoeXBlcl9kbWFidWZfaW9jdGxfZGVzYyAqaW9jdGwgPSBOVUxMOwpAQCAtNjcyLDEx MCArNjk1LDMgQEAgc3RhdGljIGxvbmcgaHlwZXJfZG1hYnVmX2lvY3RsKHN0cnVjdCBmaWxlICpm aWxwLAogCiAJcmV0dXJuIHJldDsKIH0KLQotaW50IGh5cGVyX2RtYWJ1Zl9vcGVuKHN0cnVjdCBp bm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxwKQotewotCWludCByZXQgPSAwOwotCi0JLyog RG8gbm90IGFsbG93IGV4Y2x1c2l2ZSBvcGVuICovCi0JaWYgKGZpbHAtPmZfZmxhZ3MgJiBPX0VY Q0wpCi0JCXJldHVybiAtRUJVU1k7Ci0KLQkvKgotCSAqIEluaXRpYWxpemUgYmFja2VuZCBpZiBu ZWVkZWRtLAotCSAqIHVzZSBtdXRleCB0byBwcmV2ZW50IHJhY2UgY29uZGl0aW9ucyB3aGVuCi0J ICogdHdvIHVzZXJzcGFjZSBhcHBzIHdpbGwgb3BlbiBkZXZpY2UgYXQgdGhlIHNhbWUgdGltZQot CSAqLwotCW11dGV4X2xvY2soJmh5cGVyX2RtYWJ1Zl9wcml2YXRlLmxvY2spOwotCi0JaWYgKCFo eXBlcl9kbWFidWZfcHJpdmF0ZS5iYWNrZW5kX2luaXRpYWxpemVkKSB7Ci0JCWh5cGVyX2RtYWJ1 Zl9wcml2YXRlLmRvbWlkID0gaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9vcHMtPmdldF92 bV9pZCgpOwotCi0JCXJldCA9IGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmJhY2tlbmRfb3BzLT5pbml0 X2NvbW1fZW52KCk7Ci0JICAgICAgICBpZiAocmV0IDwgMCkgewotCQkJZGV2X2VycihoeXBlcl9k bWFidWZfcHJpdmF0ZS5kZXZpY2UsCi0JCQkJImZhaWxlZCB0byBpbml0aWFpbGl6ZSBoeXBlcnZp c29yLXNwZWNpZmljIGNvbW0gZW52XG4iKTsKLQkJfSBlbHNlIHsKLQkJCWh5cGVyX2RtYWJ1Zl9w cml2YXRlLmJhY2tlbmRfaW5pdGlhbGl6ZWQgPSB0cnVlOwotCQl9Ci0JfQotCi0JbXV0ZXhfdW5s b2NrKCZoeXBlcl9kbWFidWZfcHJpdmF0ZS5sb2NrKTsKLQotCXJldHVybiByZXQ7Ci19Ci0KLXN0 YXRpYyB2b2lkIGh5cGVyX2RtYWJ1Zl9lbWVyZ2VuY3lfcmVsZWFzZShzdHJ1Y3QgaHlwZXJfZG1h YnVmX3NndF9pbmZvKiBzZ3RfaW5mbywKLQkJCQkJICAgdm9pZCAqYXR0cikKLXsKLQlzdHJ1Y3Qg aW9jdGxfaHlwZXJfZG1hYnVmX3VuZXhwb3J0IHVuZXhwb3J0X2F0dHI7Ci0Jc3RydWN0IGZpbGUg KmZpbHAgPSAoc3RydWN0IGZpbGUqKSBhdHRyOwotCi0JaWYgKCFmaWxwIHx8ICFzZ3RfaW5mbykK LQkJcmV0dXJuOwotCi0JaWYgKHNndF9pbmZvLT5maWxwID09IGZpbHApIHsKLQkJZGV2X2RiZyho eXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsCi0JCQkiRXhlY3V0aW5nIGVtZXJnZW5jeSByZWxl YXNlIG9mIGJ1ZmZlciB7aWQ6JWQga2V5OiVkICVkICVkfVxuIiwKLQkJCSBzZ3RfaW5mby0+aGlk LmlkLCBzZ3RfaW5mby0+aGlkLnJuZ19rZXlbMF0sCi0JCQkgc2d0X2luZm8tPmhpZC5ybmdfa2V5 WzFdLCBzZ3RfaW5mby0+aGlkLnJuZ19rZXlbMl0pOwotCi0JCXVuZXhwb3J0X2F0dHIuaGlkID0g c2d0X2luZm8tPmhpZDsKLQkJdW5leHBvcnRfYXR0ci5kZWxheV9tcyA9IDA7Ci0KLQkJaHlwZXJf ZG1hYnVmX3VuZXhwb3J0X2lvY3RsKGZpbHAsICZ1bmV4cG9ydF9hdHRyKTsKLQl9Ci19Ci0KLWlu dCBoeXBlcl9kbWFidWZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAq ZmlscCkKLXsKLQloeXBlcl9kbWFidWZfZm9yZWFjaF9leHBvcnRlZChoeXBlcl9kbWFidWZfZW1l cmdlbmN5X3JlbGVhc2UsIGZpbHApOwotCi0JcmV0dXJuIDA7Ci19Ci0KLS8qPT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwotc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlv bnMgaHlwZXJfZG1hYnVmX2RyaXZlcl9mb3BzID0KLXsKLSAgIC5vd25lciA9IFRISVNfTU9EVUxF LAotICAgLm9wZW4gPSBoeXBlcl9kbWFidWZfb3BlbiwKLSAgIC5yZWxlYXNlID0gaHlwZXJfZG1h YnVmX3JlbGVhc2UsCi0gICAudW5sb2NrZWRfaW9jdGwgPSBoeXBlcl9kbWFidWZfaW9jdGwsCi19 OwotCi1zdGF0aWMgc3RydWN0IG1pc2NkZXZpY2UgaHlwZXJfZG1hYnVmX21pc2NkZXYgPSB7Ci0J Lm1pbm9yID0gTUlTQ19EWU5BTUlDX01JTk9SLAotCS5uYW1lID0gInhlbi9oeXBlcl9kbWFidWYi LAotCS5mb3BzID0gJmh5cGVyX2RtYWJ1Zl9kcml2ZXJfZm9wcywKLX07Ci0KLXN0YXRpYyBjb25z dCBjaGFyIGRldmljZV9uYW1lW10gPSAiaHlwZXJfZG1hYnVmIjsKLQotLyo9PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PSovCi1pbnQgcmVnaXN0ZXJfZGV2aWNlKHZvaWQpCi17 Ci0JaW50IHJldCA9IDA7Ci0KLQlyZXQgPSBtaXNjX3JlZ2lzdGVyKCZoeXBlcl9kbWFidWZfbWlz Y2Rldik7Ci0KLQlpZiAocmV0KSB7Ci0JCXByaW50ayhLRVJOX0VSUiAiaHlwZXJfZG1hYnVmOiBk cml2ZXIgY2FuJ3QgYmUgcmVnaXN0ZXJlZFxuIik7Ci0JCXJldHVybiByZXQ7Ci0JfQotCi0JaHlw ZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlID0gaHlwZXJfZG1hYnVmX21pc2NkZXYudGhpc19kZXZp Y2U7Ci0KLQkvKiBUT0RPOiBDaGVjayBpZiB0aGVyZSBpcyBhIGRpZmZlcmVudCB3YXkgdG8gaW5p dGlhbGl6ZSBkbWEgbWFzayBuaWNlbHkgKi8KLQlkbWFfY29lcmNlX21hc2tfYW5kX2NvaGVyZW50 KGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwgRE1BX0JJVF9NQVNLKDY0KSk7Ci0KLQlyZXR1 cm4gcmV0OwotfQotCi0vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8K LXZvaWQgdW5yZWdpc3Rlcl9kZXZpY2Uodm9pZCkKLXsKLQlkZXZfaW5mbyhoeXBlcl9kbWFidWZf cHJpdmF0ZS5kZXZpY2UsCi0JCSAiaHlwZXJfZG1hYnVmOiB1bnJlZ2lzdGVyX2RldmljZSgpIGlz IGNhbGxlZFxuIik7Ci0KLQltaXNjX2RlcmVnaXN0ZXIoJmh5cGVyX2RtYWJ1Zl9taXNjZGV2KTsK LX0KZGlmZiAtLWdpdCBhL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfbXNn LmMgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX21zZy5jCmluZGV4IDEy ZWJhZDMuLmM1MTZkZjggMTAwNjQ0Ci0tLSBhL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBl cl9kbWFidWZfbXNnLmMKKysrIGIvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1 Zl9tc2cuYwpAQCAtMzUsNyArMzUsNiBAQAogI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgog I2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9tc2cuaCIKICNpbmNsdWRlICJoeXBlcl9kbWFidWZfZHJ2 LmgiCi0jaW5jbHVkZSAiaHlwZXJfZG1hYnVmX2ltcC5oIgogI2luY2x1ZGUgImh5cGVyX2RtYWJ1 Zl9yZW1vdGVfc3luYy5oIgogI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9saXN0LmgiCiAKZGlmZiAt LWdpdCBhL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfb3BzLmMgYi9kcml2 ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX29wcy5jCm5ldyBmaWxlIG1vZGUgMTAw NjQ0CmluZGV4IDAwMDAwMDAuLjgxY2IwOWYKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL3hl bi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX29wcy5jCkBAIC0wLDAgKzEsNDcxIEBACisvKgor ICogQ29weXJpZ2h0IMKpIDIwMTcgSW50ZWwgQ29ycG9yYXRpb24KKyAqCisgKiBQZXJtaXNzaW9u IGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5p bmcgYQorICogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRp b24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKKyAqIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdp dGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KKyAqIHRoZSBy aWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBz dWJsaWNlbnNlLAorICogYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRv IHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlCisgKiBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8g ZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgorICoKKyAqIFRoZSBh Ym92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRp bmcgdGhlIG5leHQKKyAqIHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGll cyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUKKyAqIFNvZnR3YXJlLgorICoKKyAqIFRI RSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBL SU5ELCBFWFBSRVNTIE9SCisgKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRP IFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKKyAqIEZJVE5FU1MgRk9SIEEgUEFS VElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuICBJTiBOTyBFVkVOVCBTSEFMTAor ICogVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xB SU0sIERBTUFHRVMgT1IgT1RIRVIKKyAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04g T0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HCisgKiBGUk9NLCBPVVQgT0Yg T1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERF QUxJTkdTCisgKiBJTiBUSEUgU09GVFdBUkUuCisgKgorICogQXV0aG9yczoKKyAqICAgIERvbmd3 b24gS2ltIDxkb25nd29uLmtpbUBpbnRlbC5jb20+CisgKiAgICBNYXRldXN6IFBvbHJvbGEgPG1h dGV1c3p4LnBvdHJvbGFAaW50ZWwuY29tPgorICoKKyAqLworCisjaW5jbHVkZSA8bGludXgva2Vy bmVsLmg+CisjaW5jbHVkZSA8bGludXgvZXJybm8uaD4KKyNpbmNsdWRlIDxsaW51eC9mcy5oPgor I2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNs dWRlIDxsaW51eC9kbWEtYnVmLmg+CisjaW5jbHVkZSA8eGVuL2dyYW50X3RhYmxlLmg+CisjaW5j bHVkZSA8YXNtL3hlbi9wYWdlLmg+CisjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX2Rydi5oIgorI2lu Y2x1ZGUgImh5cGVyX2RtYWJ1Zl9zdHJ1Y3QuaCIKKyNpbmNsdWRlICJoeXBlcl9kbWFidWZfb3Bz LmgiCisjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX3NnbF9wcm9jLmgiCisjaW5jbHVkZSAiaHlwZXJf ZG1hYnVmX2lkLmgiCisjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX21zZy5oIgorI2luY2x1ZGUgImh5 cGVyX2RtYWJ1Zl9saXN0LmgiCisKKyNkZWZpbmUgV0FJVF9BRlRFUl9TWU5DX1JFUSAwCisjZGVm aW5lIFJFRlNfUEVSX1BBR0UgKFBBR0VfU0laRS9zaXplb2YoZ3JhbnRfcmVmX3QpKQorCitleHRl cm4gc3RydWN0IGh5cGVyX2RtYWJ1Zl9wcml2YXRlIGh5cGVyX2RtYWJ1Zl9wcml2YXRlOworCitp bmxpbmUgaW50IGh5cGVyX2RtYWJ1Zl9zeW5jX3JlcXVlc3QoaHlwZXJfZG1hYnVmX2lkX3QgaGlk LCBpbnQgZG1hYnVmX29wcykKK3sKKwlzdHJ1Y3QgaHlwZXJfZG1hYnVmX3JlcSAqcmVxOworCXN0 cnVjdCBoeXBlcl9kbWFidWZfYmFja2VuZF9vcHMgKm9wcyA9IGh5cGVyX2RtYWJ1Zl9wcml2YXRl LmJhY2tlbmRfb3BzOworCWludCBvcGVyYW5kc1s1XTsKKwlpbnQgaTsKKwlpbnQgcmV0OworCisJ b3BlcmFuZHNbMF0gPSBoaWQuaWQ7CisKKwlmb3IgKGk9MDsgaTwzOyBpKyspCisJCW9wZXJhbmRz W2krMV0gPSBoaWQucm5nX2tleVtpXTsKKworCW9wZXJhbmRzWzRdID0gZG1hYnVmX29wczsKKwor CXJlcSA9IGtjYWxsb2MoMSwgc2l6ZW9mKCpyZXEpLCBHRlBfS0VSTkVMKTsKKworCWlmICghcmVx KSB7CisJCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJIk5vIG1lbW9y eSBsZWZ0IHRvIGJlIGFsbG9jYXRlZFxuIik7CisJCXJldHVybiAtRU5PTUVNOworCX0KKworCWh5 cGVyX2RtYWJ1Zl9jcmVhdGVfcmVxdWVzdChyZXEsIEhZUEVSX0RNQUJVRl9PUFNfVE9fU09VUkNF LCAmb3BlcmFuZHNbMF0pOworCisJLyogc2VuZCByZXF1ZXN0IGFuZCB3YWl0IGZvciBhIHJlc3Bv bnNlICovCisJcmV0ID0gb3BzLT5zZW5kX3JlcShIWVBFUl9ETUFCVUZfRE9NX0lEKGhpZCksIHJl cSwgV0FJVF9BRlRFUl9TWU5DX1JFUSk7CisKKwlrZnJlZShyZXEpOworCisJcmV0dXJuIHJldDsK K30KKworc3RhdGljIGludCBoeXBlcl9kbWFidWZfb3BzX2F0dGFjaChzdHJ1Y3QgZG1hX2J1Ziog ZG1hYnVmLCBzdHJ1Y3QgZGV2aWNlKiBkZXYsCisJCQlzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50 ICphdHRhY2gpCit7CisJc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0 X2luZm87CisJaW50IHJldDsKKworCWlmICghYXR0YWNoLT5kbWFidWYtPnByaXYpCisJCXJldHVy biAtRUlOVkFMOworCisJc2d0X2luZm8gPSAoc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9z Z3RfaW5mbyAqKWF0dGFjaC0+ZG1hYnVmLT5wcml2OworCisJcmV0ID0gaHlwZXJfZG1hYnVmX3N5 bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAorCQkJCQlIWVBFUl9ETUFCVUZfT1BTX0FUVEFDSCk7 CisKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmlj ZSwKKwkJCSJoeXBlcl9kbWFidWY6OiVzIEVycm9yOnNlbmQgZG1hYnVmIHN5bmMgcmVxdWVzdCBm YWlsZWRcbiIsIF9fZnVuY19fKTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXR1cm4gMDsKK30K Kworc3RhdGljIHZvaWQgaHlwZXJfZG1hYnVmX29wc19kZXRhY2goc3RydWN0IGRtYV9idWYqIGRt YWJ1Ziwgc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNoKQoreworCXN0cnVjdCBoeXBl cl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOworCWludCByZXQ7CisKKwlpZiAo IWF0dGFjaC0+ZG1hYnVmLT5wcml2KQorCQlyZXR1cm47CisKKwlzZ3RfaW5mbyA9IChzdHJ1Y3Qg aHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopYXR0YWNoLT5kbWFidWYtPnByaXY7CisK KwlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5oaWQsCisJCQkJCUhZ UEVSX0RNQUJVRl9PUFNfREVUQUNIKTsKKworCWlmIChyZXQgPCAwKSB7CisJCWRldl9lcnIoaHlw ZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2Vu ZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOworCX0KK30KKworc3Rh dGljIHN0cnVjdCBzZ190YWJsZSogaHlwZXJfZG1hYnVmX29wc19tYXAoc3RydWN0IGRtYV9idWZf YXR0YWNobWVudCAqYXR0YWNobWVudCwKKwkJCQkJCWVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRp cikKK3sKKwlzdHJ1Y3Qgc2dfdGFibGUgKnN0OworCXN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0 ZWRfc2d0X2luZm8gKnNndF9pbmZvOworCXN0cnVjdCBoeXBlcl9kbWFidWZfcGFnZXNfaW5mbyAq cGFnZV9pbmZvOworCWludCByZXQ7CisKKwlpZiAoIWF0dGFjaG1lbnQtPmRtYWJ1Zi0+cHJpdikK KwkJcmV0dXJuIE5VTEw7CisKKwlzZ3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9y dGVkX3NndF9pbmZvICopYXR0YWNobWVudC0+ZG1hYnVmLT5wcml2OworCisJLyogZXh0cmFjdCBw YWdlcyBmcm9tIHNndCAqLworCXBhZ2VfaW5mbyA9IGh5cGVyX2RtYWJ1Zl9leHRfcGdzKHNndF9p bmZvLT5zZ3QpOworCisJaWYgKCFwYWdlX2luZm8pIHsKKwkJcmV0dXJuIE5VTEw7CisJfQorCisJ LyogY3JlYXRlIGEgbmV3IHNnX3RhYmxlIHdpdGggZXh0cmFjdGVkIHBhZ2VzICovCisJc3QgPSBo eXBlcl9kbWFidWZfY3JlYXRlX3NndChwYWdlX2luZm8tPnBhZ2VzLCBwYWdlX2luZm8tPmZyc3Rf b2ZzdCwKKwkJCQlwYWdlX2luZm8tPmxhc3RfbGVuLCBwYWdlX2luZm8tPm5lbnRzKTsKKwlpZiAo IXN0KQorCQlnb3RvIGVycl9mcmVlX3NnOworCisgICAgICAgIGlmICghZG1hX21hcF9zZyhhdHRh Y2htZW50LT5kZXYsIHN0LT5zZ2wsIHN0LT5uZW50cywgZGlyKSkgeworICAgICAgICAgICAgICAg IGdvdG8gZXJyX2ZyZWVfc2c7CisgICAgICAgIH0KKworCXJldCA9IGh5cGVyX2RtYWJ1Zl9zeW5j X3JlcXVlc3Qoc2d0X2luZm8tPmhpZCwKKwkJCQkJSFlQRVJfRE1BQlVGX09QU19NQVApOworCisJ a2ZyZWUocGFnZV9pbmZvLT5wYWdlcyk7CisJa2ZyZWUocGFnZV9pbmZvKTsKKworCWlmIChyZXQg PCAwKSB7CisJCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJImh5cGVy X2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19m dW5jX18pOworCX0KKworCXJldHVybiBzdDsKKworZXJyX2ZyZWVfc2c6CisJaWYgKHN0KSB7CisJ CXNnX2ZyZWVfdGFibGUoc3QpOworCQlrZnJlZShzdCk7CisJfQorCisJcmV0dXJuIE5VTEw7Cit9 CisKK3N0YXRpYyB2b2lkIGh5cGVyX2RtYWJ1Zl9vcHNfdW5tYXAoc3RydWN0IGRtYV9idWZfYXR0 YWNobWVudCAqYXR0YWNobWVudCwKKwkJCQkgICBzdHJ1Y3Qgc2dfdGFibGUgKnNnLAorCQkJCSAg IGVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpcikKK3sKKwlzdHJ1Y3QgaHlwZXJfZG1hYnVmX2lt cG9ydGVkX3NndF9pbmZvICpzZ3RfaW5mbzsKKwlpbnQgcmV0OworCisJaWYgKCFhdHRhY2htZW50 LT5kbWFidWYtPnByaXYpCisJCXJldHVybjsKKworCXNndF9pbmZvID0gKHN0cnVjdCBoeXBlcl9k bWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilhdHRhY2htZW50LT5kbWFidWYtPnByaXY7CisKKwlk bWFfdW5tYXBfc2coYXR0YWNobWVudC0+ZGV2LCBzZy0+c2dsLCBzZy0+bmVudHMsIGRpcik7CisK KwlzZ19mcmVlX3RhYmxlKHNnKTsKKwlrZnJlZShzZyk7CisKKwlyZXQgPSBoeXBlcl9kbWFidWZf c3luY19yZXF1ZXN0KHNndF9pbmZvLT5oaWQsCisJCQkJCUhZUEVSX0RNQUJVRl9PUFNfVU5NQVAp OworCisJaWYgKHJldCA8IDApIHsKKwkJZGV2X2VycihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZp Y2UsCisJCQkiaHlwZXJfZG1hYnVmOjolcyBFcnJvcjpzZW5kIGRtYWJ1ZiBzeW5jIHJlcXVlc3Qg ZmFpbGVkXG4iLCBfX2Z1bmNfXyk7CisJfQorfQorCitzdGF0aWMgdm9pZCBoeXBlcl9kbWFidWZf b3BzX3JlbGVhc2Uoc3RydWN0IGRtYV9idWYgKmRtYV9idWYpCit7CisJc3RydWN0IGh5cGVyX2Rt YWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0X2luZm87CisJc3RydWN0IGh5cGVyX2RtYWJ1Zl9i YWNrZW5kX29wcyAqb3BzID0gaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9vcHM7CisJaW50 IHJldDsKKwlpbnQgZmluYWxfcmVsZWFzZTsKKworCWlmICghZG1hX2J1Zi0+cHJpdikKKwkJcmV0 dXJuOworCisJc2d0X2luZm8gPSAoc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5m byAqKWRtYV9idWYtPnByaXY7CisKKwlpZiAoIWRtYWJ1Zl9yZWZjb3VudChzZ3RfaW5mby0+ZG1h X2J1ZikpIHsKKwkJc2d0X2luZm8tPmRtYV9idWYgPSBOVUxMOworCX0KKworCXNndF9pbmZvLT5u dW1faW1wb3J0ZXJzLS07CisKKwlpZiAoc2d0X2luZm8tPm51bV9pbXBvcnRlcnMgPT0gMCkgewor CQlvcHMtPnVubWFwX3NoYXJlZF9wYWdlcygmc2d0X2luZm8tPnJlZnNfaW5mbywgc2d0X2luZm8t Pm5lbnRzKTsKKworCQlpZiAoc2d0X2luZm8tPnNndCkgeworCQkJc2dfZnJlZV90YWJsZShzZ3Rf aW5mby0+c2d0KTsKKwkJCWtmcmVlKHNndF9pbmZvLT5zZ3QpOworCQkJc2d0X2luZm8tPnNndCA9 IE5VTEw7CisJCX0KKwl9CisKKwlmaW5hbF9yZWxlYXNlID0gc2d0X2luZm8gJiYgIXNndF9pbmZv LT52YWxpZCAmJgorCQkgICAgICAgICFzZ3RfaW5mby0+bnVtX2ltcG9ydGVyczsKKworCXJldCA9 IGh5cGVyX2RtYWJ1Zl9zeW5jX3JlcXVlc3Qoc2d0X2luZm8tPmhpZCwKKwkJCQkJSFlQRVJfRE1B QlVGX09QU19SRUxFQVNFKTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfd2FybihoeXBlcl9kbWFi dWZfcHJpdmF0ZS5kZXZpY2UsCisJCQkgImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFi dWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOworCX0KKworCS8qCisJICogQ2hl Y2sgaWYgYnVmZmVyIGlzIHN0aWxsIHZhbGlkIGFuZCBpZiBub3QgcmVtb3ZlIGl0IGZyb20gaW1w b3J0ZWQgbGlzdC4KKwkgKiBUaGF0IGhhcyB0byBiZSBkb25lIGFmdGVyIHNlbmRpbmcgc3luYyBy ZXF1ZXN0CisJICovCisJaWYgKGZpbmFsX3JlbGVhc2UpIHsKKwkJaHlwZXJfZG1hYnVmX3JlbW92 ZV9pbXBvcnRlZChzZ3RfaW5mby0+aGlkKTsKKwkJa2ZyZWUoc2d0X2luZm8pOworCX0KK30KKwor c3RhdGljIGludCBoeXBlcl9kbWFidWZfb3BzX2JlZ2luX2NwdV9hY2Nlc3Moc3RydWN0IGRtYV9i dWYgKmRtYWJ1ZiwgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyKQoreworCXN0cnVjdCBoeXBl cl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOworCWludCByZXQ7CisKKwlpZiAo IWRtYWJ1Zi0+cHJpdikKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlzZ3RfaW5mbyA9IChzdHJ1Y3Qg aHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVmLT5wcml2OworCisJcmV0ID0g aHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAorCQkJCQlIWVBFUl9ETUFC VUZfT1BTX0JFR0lOX0NQVV9BQ0NFU1MpOworCWlmIChyZXQgPCAwKSB7CisJCWRldl9lcnIoaHlw ZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2Vu ZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOworCX0KKworCXJldHVy biByZXQ7Cit9CisKK3N0YXRpYyBpbnQgaHlwZXJfZG1hYnVmX29wc19lbmRfY3B1X2FjY2Vzcyhz dHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCBlbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIpCit7CisJ c3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0X2luZm87CisJaW50IHJl dDsKKworCWlmICghZG1hYnVmLT5wcml2KQorCQlyZXR1cm4gLUVJTlZBTDsKKworCXNndF9pbmZv ID0gKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilkbWFidWYtPnByaXY7 CisKKwlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5oaWQsCisJCQkJ CUhZUEVSX0RNQUJVRl9PUFNfRU5EX0NQVV9BQ0NFU1MpOworCWlmIChyZXQgPCAwKSB7CisJCWRl dl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJImh5cGVyX2RtYWJ1Zjo6JXMg RXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18pOworCX0K KworCXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCAqaHlwZXJfZG1hYnVmX29wc19rbWFwX2F0 b21pYyhzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCB1bnNpZ25lZCBsb25nIHBnbnVtKQoreworCXN0 cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOworCWludCByZXQ7 CisKKwlpZiAoIWRtYWJ1Zi0+cHJpdikKKwkJcmV0dXJuIE5VTEw7CisKKwlzZ3RfaW5mbyA9IChz dHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVmLT5wcml2OworCisJ cmV0ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAorCQkJCQlIWVBF Ul9ETUFCVUZfT1BTX0tNQVBfQVRPTUlDKTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKGh5 cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJCSJoeXBlcl9kbWFidWY6OiVzIEVycm9yOnNl bmQgZG1hYnVmIHN5bmMgcmVxdWVzdCBmYWlsZWRcbiIsIF9fZnVuY19fKTsKKwl9CisKKwlyZXR1 cm4gTlVMTDsgLyogZm9yIG5vdyBOVUxMLi4gbmVlZCB0byByZXR1cm4gdGhlIGFkZHJlc3Mgb2Yg bWFwcGVkIHJlZ2lvbiAqLworfQorCitzdGF0aWMgdm9pZCBoeXBlcl9kbWFidWZfb3BzX2t1bm1h cF9hdG9taWMoc3RydWN0IGRtYV9idWYgKmRtYWJ1ZiwgdW5zaWduZWQgbG9uZyBwZ251bSwgdm9p ZCAqdmFkZHIpCit7CisJc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0 X2luZm87CisJaW50IHJldDsKKworCWlmICghZG1hYnVmLT5wcml2KQorCQlyZXR1cm47CisKKwlz Z3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVm LT5wcml2OworCisJcmV0ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlk LAorCQkJCQlIWVBFUl9ETUFCVUZfT1BTX0tVTk1BUF9BVE9NSUMpOworCWlmIChyZXQgPCAwKSB7 CisJCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJImh5cGVyX2RtYWJ1 Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwgX19mdW5jX18p OworCX0KK30KKworc3RhdGljIHZvaWQgKmh5cGVyX2RtYWJ1Zl9vcHNfa21hcChzdHJ1Y3QgZG1h X2J1ZiAqZG1hYnVmLCB1bnNpZ25lZCBsb25nIHBnbnVtKQoreworCXN0cnVjdCBoeXBlcl9kbWFi dWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOworCWludCByZXQ7CisKKwlpZiAoIWRtYWJ1 Zi0+cHJpdikKKwkJcmV0dXJuIE5VTEw7CisKKwlzZ3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1h YnVmX2ltcG9ydGVkX3NndF9pbmZvICopZG1hYnVmLT5wcml2OworCisJcmV0ID0gaHlwZXJfZG1h YnVmX3N5bmNfcmVxdWVzdChzZ3RfaW5mby0+aGlkLAorCQkJCQlIWVBFUl9ETUFCVUZfT1BTX0tN QVApOworCWlmIChyZXQgPCAwKSB7CisJCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2 aWNlLAorCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0 IGZhaWxlZFxuIiwgX19mdW5jX18pOworCX0KKworCXJldHVybiBOVUxMOyAvKiBmb3Igbm93IE5V TEwuLiBuZWVkIHRvIHJldHVybiB0aGUgYWRkcmVzcyBvZiBtYXBwZWQgcmVnaW9uICovCit9CisK K3N0YXRpYyB2b2lkIGh5cGVyX2RtYWJ1Zl9vcHNfa3VubWFwKHN0cnVjdCBkbWFfYnVmICpkbWFi dWYsIHVuc2lnbmVkIGxvbmcgcGdudW0sIHZvaWQgKnZhZGRyKQoreworCXN0cnVjdCBoeXBlcl9k bWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKnNndF9pbmZvOworCWludCByZXQ7CisKKwlpZiAoIWRt YWJ1Zi0+cHJpdikKKwkJcmV0dXJuOworCisJc2d0X2luZm8gPSAoc3RydWN0IGh5cGVyX2RtYWJ1 Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqKWRtYWJ1Zi0+cHJpdjsKKworCXJldCA9IGh5cGVyX2RtYWJ1 Zl9zeW5jX3JlcXVlc3Qoc2d0X2luZm8tPmhpZCwKKwkJCQkJSFlQRVJfRE1BQlVGX09QU19LVU5N QVApOworCWlmIChyZXQgPCAwKSB7CisJCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2 aWNlLAorCQkJImh5cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0 IGZhaWxlZFxuIiwgX19mdW5jX18pOworCX0KK30KKworc3RhdGljIGludCBoeXBlcl9kbWFidWZf b3BzX21tYXAoc3RydWN0IGRtYV9idWYgKmRtYWJ1Ziwgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2 bWEpCit7CisJc3RydWN0IGh5cGVyX2RtYWJ1Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqc2d0X2luZm87 CisJaW50IHJldDsKKworCWlmICghZG1hYnVmLT5wcml2KQorCQlyZXR1cm4gLUVJTlZBTDsKKwor CXNndF9pbmZvID0gKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilkbWFi dWYtPnByaXY7CisKKwlyZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5o aWQsCisJCQkJCUhZUEVSX0RNQUJVRl9PUFNfTU1BUCk7CisJaWYgKHJldCA8IDApIHsKKwkJZGV2 X2VycihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsCisJCQkiaHlwZXJfZG1hYnVmOjolcyBF cnJvcjpzZW5kIGRtYWJ1ZiBzeW5jIHJlcXVlc3QgZmFpbGVkXG4iLCBfX2Z1bmNfXyk7CisJfQor CisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIHZvaWQgKmh5cGVyX2RtYWJ1Zl9vcHNfdm1hcChz dHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmKQoreworCXN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRf c2d0X2luZm8gKnNndF9pbmZvOworCWludCByZXQ7CisKKwlpZiAoIWRtYWJ1Zi0+cHJpdikKKwkJ cmV0dXJuIE5VTEw7CisKKwlzZ3RfaW5mbyA9IChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVk X3NndF9pbmZvICopZG1hYnVmLT5wcml2OworCisJcmV0ID0gaHlwZXJfZG1hYnVmX3N5bmNfcmVx dWVzdChzZ3RfaW5mby0+aGlkLAorCQkJCQlIWVBFUl9ETUFCVUZfT1BTX1ZNQVApOworCWlmIChy ZXQgPCAwKSB7CisJCWRldl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJImh5 cGVyX2RtYWJ1Zjo6JXMgRXJyb3I6c2VuZCBkbWFidWYgc3luYyByZXF1ZXN0IGZhaWxlZFxuIiwg X19mdW5jX18pOworCX0KKworCXJldHVybiBOVUxMOworfQorCitzdGF0aWMgdm9pZCBoeXBlcl9k bWFidWZfb3BzX3Z1bm1hcChzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmLCB2b2lkICp2YWRkcikKK3sK KwlzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICpzZ3RfaW5mbzsKKwlpbnQg cmV0OworCisJaWYgKCFkbWFidWYtPnByaXYpCisJCXJldHVybjsKKworCXNndF9pbmZvID0gKHN0 cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2luZm8gKilkbWFidWYtPnByaXY7CisKKwly ZXQgPSBoeXBlcl9kbWFidWZfc3luY19yZXF1ZXN0KHNndF9pbmZvLT5oaWQsCisJCQkJCUhZUEVS X0RNQUJVRl9PUFNfVlVOTUFQKTsKKwlpZiAocmV0IDwgMCkgeworCQlkZXZfZXJyKGh5cGVyX2Rt YWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJCSJoeXBlcl9kbWFidWY6OiVzIEVycm9yOnNlbmQgZG1h YnVmIHN5bmMgcmVxdWVzdCBmYWlsZWRcbiIsIF9fZnVuY19fKTsKKwl9Cit9CisKK3N0YXRpYyBj b25zdCBzdHJ1Y3QgZG1hX2J1Zl9vcHMgaHlwZXJfZG1hYnVmX29wcyA9IHsKKwkJLmF0dGFjaCA9 IGh5cGVyX2RtYWJ1Zl9vcHNfYXR0YWNoLAorCQkuZGV0YWNoID0gaHlwZXJfZG1hYnVmX29wc19k ZXRhY2gsCisJCS5tYXBfZG1hX2J1ZiA9IGh5cGVyX2RtYWJ1Zl9vcHNfbWFwLAorCQkudW5tYXBf ZG1hX2J1ZiA9IGh5cGVyX2RtYWJ1Zl9vcHNfdW5tYXAsCisJCS5yZWxlYXNlID0gaHlwZXJfZG1h YnVmX29wc19yZWxlYXNlLAorCQkuYmVnaW5fY3B1X2FjY2VzcyA9ICh2b2lkKiloeXBlcl9kbWFi dWZfb3BzX2JlZ2luX2NwdV9hY2Nlc3MsCisJCS5lbmRfY3B1X2FjY2VzcyA9ICh2b2lkKiloeXBl cl9kbWFidWZfb3BzX2VuZF9jcHVfYWNjZXNzLAorCQkubWFwX2F0b21pYyA9IGh5cGVyX2RtYWJ1 Zl9vcHNfa21hcF9hdG9taWMsCisJCS51bm1hcF9hdG9taWMgPSBoeXBlcl9kbWFidWZfb3BzX2t1 bm1hcF9hdG9taWMsCisJCS5tYXAgPSBoeXBlcl9kbWFidWZfb3BzX2ttYXAsCisJCS51bm1hcCA9 IGh5cGVyX2RtYWJ1Zl9vcHNfa3VubWFwLAorCQkubW1hcCA9IGh5cGVyX2RtYWJ1Zl9vcHNfbW1h cCwKKwkJLnZtYXAgPSBoeXBlcl9kbWFidWZfb3BzX3ZtYXAsCisJCS52dW5tYXAgPSBoeXBlcl9k bWFidWZfb3BzX3Z1bm1hcCwKK307CisKKy8qIGV4cG9ydGluZyBkbWFidWYgYXMgZmQgKi8KK2lu dCBoeXBlcl9kbWFidWZfZXhwb3J0X2ZkKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0 X2luZm8gKmRpbmZvLCBpbnQgZmxhZ3MpCit7CisJaW50IGZkID0gLTE7CisKKwkvKiBjYWxsIGh5 cGVyX2RtYWJ1Zl9leHBvcnRfZG1hYnVmIGFuZCBjcmVhdGUKKwkgKiBhbmQgYmluZCBhIGhhbmRs ZSBmb3IgaXQgdGhlbiByZWxlYXNlCisJICovCisJaHlwZXJfZG1hYnVmX2V4cG9ydF9kbWFfYnVm KGRpbmZvKTsKKworCWlmIChkaW5mby0+ZG1hX2J1ZikgeworCQlmZCA9IGRtYV9idWZfZmQoZGlu Zm8tPmRtYV9idWYsIGZsYWdzKTsKKwl9CisKKwlyZXR1cm4gZmQ7Cit9CisKK3ZvaWQgaHlwZXJf ZG1hYnVmX2V4cG9ydF9kbWFfYnVmKHN0cnVjdCBoeXBlcl9kbWFidWZfaW1wb3J0ZWRfc2d0X2lu Zm8gKmRpbmZvKQoreworCURFRklORV9ETUFfQlVGX0VYUE9SVF9JTkZPKGV4cF9pbmZvKTsKKwor CWV4cF9pbmZvLm9wcyA9ICZoeXBlcl9kbWFidWZfb3BzOworCisJLyogbXVsdGlwbGUgb2YgUEFH RV9TSVpFLCBub3QgY29uc2lkZXJpbmcgb2Zmc2V0ICovCisJZXhwX2luZm8uc2l6ZSA9IGRpbmZv LT5zZ3QtPm5lbnRzICogUEFHRV9TSVpFOworCWV4cF9pbmZvLmZsYWdzID0gLyogbm90IHN1cmUg YWJvdXQgZmxhZyAqLzA7CisJZXhwX2luZm8ucHJpdiA9IGRpbmZvOworCisJZGluZm8tPmRtYV9i dWYgPSBkbWFfYnVmX2V4cG9ydCgmZXhwX2luZm8pOworfQpkaWZmIC0tZ2l0IGEvZHJpdmVycy94 ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9vcHMuaCBiL2RyaXZlcnMveGVuL2h5cGVyX2Rt YWJ1Zi9oeXBlcl9kbWFidWZfb3BzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw MC4uOGMwNmZjNgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9o eXBlcl9kbWFidWZfb3BzLmgKQEAgLTAsMCArMSwzMiBAQAorLyoKKyAqIENvcHlyaWdodCDCqSAy MDE3IEludGVsIENvcnBvcmF0aW9uCisgKgorICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRl ZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKKyAqIGNvcHkgb2Yg dGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNv ZnR3YXJlIiksCisgKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9u LCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCisgKiB0aGUgcmlnaHRzIHRvIHVzZSwgY29w eSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKKyAqIGFu ZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0 byB3aG9tIHRoZQorICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRv IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKKyAqCisgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5v dGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZSBuZXh0CisgKiBw YXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwg cG9ydGlvbnMgb2YgdGhlCisgKiBTb2Z0d2FyZS4KKyAqCisgKiBUSEUgU09GVFdBUkUgSVMgUFJP VklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgor ICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBP RiBNRVJDSEFOVEFCSUxJVFksCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBB TkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwKKyAqIFRIRSBBVVRIT1JTIE9S IENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9U SEVSCisgKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JU IE9SIE9USEVSV0lTRSwgQVJJU0lORworICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04g V0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUworICogSU4gVEhF IFNPRlRXQVJFLgorICoKKyAqLworCisjaWZuZGVmIF9fSFlQRVJfRE1BQlVGX09QU19IX18KKyNk ZWZpbmUgX19IWVBFUl9ETUFCVUZfT1BTX0hfXworCitpbnQgaHlwZXJfZG1hYnVmX2V4cG9ydF9m ZChzdHJ1Y3QgaHlwZXJfZG1hYnVmX2ltcG9ydGVkX3NndF9pbmZvICpkaW5mbywgaW50IGZsYWdz KTsKKwordm9pZCBoeXBlcl9kbWFidWZfZXhwb3J0X2RtYV9idWYoc3RydWN0IGh5cGVyX2RtYWJ1 Zl9pbXBvcnRlZF9zZ3RfaW5mbyAqZGluZm8pOworCisjZW5kaWYgLyogX19IWVBFUl9ETUFCVUZf SU1QX0hfXyAqLwpkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2Rt YWJ1Zl9yZW1vdGVfc3luYy5jIGIvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1 Zl9yZW1vdGVfc3luYy5jCmluZGV4IGJlMWQzOTUuLjkwMDQ0MDYgMTAwNjQ0Ci0tLSBhL2RyaXZl cnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfcmVtb3RlX3N5bmMuYworKysgYi9kcml2 ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX3JlbW90ZV9zeW5jLmMKQEAgLTM3LDcg KzM3LDcgQEAKICNpbmNsdWRlICJoeXBlcl9kbWFidWZfbXNnLmgiCiAjaW5jbHVkZSAiaHlwZXJf ZG1hYnVmX2lkLmgiCiAjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX21zZy5oIgotI2luY2x1ZGUgImh5 cGVyX2RtYWJ1Zl9pbXAuaCIKKyNpbmNsdWRlICJoeXBlcl9kbWFidWZfc2dsX3Byb2MuaCIKIAog ZXh0ZXJuIHN0cnVjdCBoeXBlcl9kbWFidWZfcHJpdmF0ZSBoeXBlcl9kbWFidWZfcHJpdmF0ZTsK IApkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9zZ2xf cHJvYy5jIGIvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9zZ2xfcHJvYy5j Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMyZDAxM2EKLS0tIC9kZXYvbnVs bAorKysgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX3NnbF9wcm9jLmMK QEAgLTAsMCArMSwyNTggQEAKKy8qCisgKiBDb3B5cmlnaHQgwqkgMjAxNyBJbnRlbCBDb3Jwb3Jh dGlvbgorICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdl LCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCisgKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5k IGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAorICogdG8g ZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhv dXQgbGltaXRhdGlvbgorICogdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2Us IHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCisgKiBhbmQvb3Igc2VsbCBjb3BpZXMg b2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKKyAqIFNv ZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNv bmRpdGlvbnM6CisgKgorICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVy bWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAorICogcGFyYWdyYXBoKSBzaGFsbCBi ZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZQor ICogU29mdHdhcmUuCisgKgorICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJ VEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKKyAqIElNUExJRUQsIElOQ0xV RElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZ LAorICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVO VC4gIElOIE5PIEVWRU5UIFNIQUxMCisgKiBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVS UyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgorICogTElBQklMSVRZ LCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFS SVNJTkcKKyAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJF IE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MKKyAqIElOIFRIRSBTT0ZUV0FSRS4KKyAqCisg KiBBdXRob3JzOgorICogICAgRG9uZ3dvbiBLaW0gPGRvbmd3b24ua2ltQGludGVsLmNvbT4KKyAq ICAgIE1hdGV1c3ogUG9scm9sYSA8bWF0ZXVzengucG90cm9sYUBpbnRlbC5jb20+CisgKgorICov CisKKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KKyNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgor I2luY2x1ZGUgPGxpbnV4L2ZzLmg+CisjaW5jbHVkZSA8bGludXgvc2xhYi5oPgorI2luY2x1ZGUg PGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L2RtYS1idWYuaD4KKyNpbmNsdWRlIDx4 ZW4vZ3JhbnRfdGFibGUuaD4KKyNpbmNsdWRlIDxhc20veGVuL3BhZ2UuaD4KKyNpbmNsdWRlICJo eXBlcl9kbWFidWZfZHJ2LmgiCisjaW5jbHVkZSAiaHlwZXJfZG1hYnVmX3N0cnVjdC5oIgorI2lu Y2x1ZGUgImh5cGVyX2RtYWJ1Zl9zZ2xfcHJvYy5oIgorI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9p ZC5oIgorI2luY2x1ZGUgImh5cGVyX2RtYWJ1Zl9tc2cuaCIKKyNpbmNsdWRlICJoeXBlcl9kbWFi dWZfbGlzdC5oIgorCitleHRlcm4gc3RydWN0IGh5cGVyX2RtYWJ1Zl9wcml2YXRlIGh5cGVyX2Rt YWJ1Zl9wcml2YXRlOworCisjZGVmaW5lIFJFRlNfUEVSX1BBR0UgKFBBR0VfU0laRS9zaXplb2Yo Z3JhbnRfcmVmX3QpKQorCitpbnQgZG1hYnVmX3JlZmNvdW50KHN0cnVjdCBkbWFfYnVmICpkbWFf YnVmKQoreworCWlmICgoZG1hX2J1ZiAhPSBOVUxMKSAmJiAoZG1hX2J1Zi0+ZmlsZSAhPSBOVUxM KSkKKwkJcmV0dXJuIGZpbGVfY291bnQoZG1hX2J1Zi0+ZmlsZSk7CisKKwlyZXR1cm4gLTE7Cit9 CisKKy8qIHJldHVybiB0b3RhbCBudW1iZXIgb2YgcGFnZXMgcmVmZXJlbmNlZCBieSBhIHNndAor ICogZm9yIHByZS1jYWxjdWxhdGlvbiBvZiAjIG9mIHBhZ2VzIGJlaGluZCBhIGdpdmVuIHNndAor ICovCitzdGF0aWMgaW50IGh5cGVyX2RtYWJ1Zl9nZXRfbnVtX3BncyhzdHJ1Y3Qgc2dfdGFibGUg KnNndCkKK3sKKwlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnbDsKKwlpbnQgbGVuZ3RoLCBpOworCS8q IGF0IGxlYXN0IG9uZSBwYWdlICovCisJaW50IG51bV9wYWdlcyA9IDE7CisKKwlzZ2wgPSBzZ3Qt PnNnbDsKKworCWxlbmd0aCA9IHNnbC0+bGVuZ3RoIC0gUEFHRV9TSVpFICsgc2dsLT5vZmZzZXQ7 CisJbnVtX3BhZ2VzICs9ICgobGVuZ3RoICsgUEFHRV9TSVpFIC0gMSkvUEFHRV9TSVpFKTsgLyog cm91bmQtdXAgKi8KKworCWZvciAoaSA9IDE7IGkgPCBzZ3QtPm5lbnRzOyBpKyspIHsKKwkJc2ds ID0gc2dfbmV4dChzZ2wpOworCQludW1fcGFnZXMgKz0gKChzZ2wtPmxlbmd0aCArIFBBR0VfU0la RSAtIDEpIC8gUEFHRV9TSVpFKTsgLyogcm91bmQtdXAgKi8KKwl9CisKKwlyZXR1cm4gbnVtX3Bh Z2VzOworfQorCisvKiBleHRyYWN0IHBhZ2VzIGRpcmVjdGx5IGZyb20gc3RydWN0IHNnX3RhYmxl ICovCitzdHJ1Y3QgaHlwZXJfZG1hYnVmX3BhZ2VzX2luZm8gKmh5cGVyX2RtYWJ1Zl9leHRfcGdz KHN0cnVjdCBzZ190YWJsZSAqc2d0KQoreworCXN0cnVjdCBoeXBlcl9kbWFidWZfcGFnZXNfaW5m byAqcGluZm87CisJaW50IGksIGosIGs7CisJaW50IGxlbmd0aDsKKwlzdHJ1Y3Qgc2NhdHRlcmxp c3QgKnNnbDsKKworCXBpbmZvID0ga21hbGxvYyhzaXplb2YoKnBpbmZvKSwgR0ZQX0tFUk5FTCk7 CisJaWYgKCFwaW5mbykKKwkJcmV0dXJuIE5VTEw7CisKKwlwaW5mby0+cGFnZXMgPSBrbWFsbG9j KHNpemVvZihzdHJ1Y3QgcGFnZSAqKSpoeXBlcl9kbWFidWZfZ2V0X251bV9wZ3Moc2d0KSwgR0ZQ X0tFUk5FTCk7CisJaWYgKCFwaW5mby0+cGFnZXMpCisJCXJldHVybiBOVUxMOworCisJc2dsID0g c2d0LT5zZ2w7CisKKwlwaW5mby0+bmVudHMgPSAxOworCXBpbmZvLT5mcnN0X29mc3QgPSBzZ2wt Pm9mZnNldDsKKwlwaW5mby0+cGFnZXNbMF0gPSBzZ19wYWdlKHNnbCk7CisJbGVuZ3RoID0gc2ds LT5sZW5ndGggLSBQQUdFX1NJWkUgKyBzZ2wtPm9mZnNldDsKKwlpID0gMTsKKworCXdoaWxlIChs ZW5ndGggPiAwKSB7CisJCXBpbmZvLT5wYWdlc1tpXSA9IG50aF9wYWdlKHNnX3BhZ2Uoc2dsKSwg aSk7CisJCWxlbmd0aCAtPSBQQUdFX1NJWkU7CisJCXBpbmZvLT5uZW50cysrOworCQlpKys7CisJ fQorCisJZm9yIChqID0gMTsgaiA8IHNndC0+bmVudHM7IGorKykgeworCQlzZ2wgPSBzZ19uZXh0 KHNnbCk7CisJCXBpbmZvLT5wYWdlc1tpKytdID0gc2dfcGFnZShzZ2wpOworCQlsZW5ndGggPSBz Z2wtPmxlbmd0aCAtIFBBR0VfU0laRTsKKwkJcGluZm8tPm5lbnRzKys7CisJCWsgPSAxOworCisJ CXdoaWxlIChsZW5ndGggPiAwKSB7CisJCQlwaW5mby0+cGFnZXNbaSsrXSA9IG50aF9wYWdlKHNn X3BhZ2Uoc2dsKSwgaysrKTsKKwkJCWxlbmd0aCAtPSBQQUdFX1NJWkU7CisJCQlwaW5mby0+bmVu dHMrKzsKKwkJfQorCX0KKworCS8qCisJICogbGVuZ2h0IGF0IHRoYXQgcG9pbnQgd2lsbCBiZSAw IG9yIG5lZ2F0aXZlLAorCSAqIHNvIHRvIGNhbGN1bGF0ZSBsYXN0IHBhZ2Ugc2l6ZSBqdXN0IGFk ZCBpdCB0byBQQUdFX1NJWkUKKwkgKi8KKwlwaW5mby0+bGFzdF9sZW4gPSBQQUdFX1NJWkUgKyBs ZW5ndGg7CisKKwlyZXR1cm4gcGluZm87Cit9CisKKy8qIGNyZWF0ZSBzZ190YWJsZSB3aXRoIGdp dmVuIHBhZ2VzIGFuZCBvdGhlciBwYXJhbWV0ZXJzICovCitzdHJ1Y3Qgc2dfdGFibGUqIGh5cGVy X2RtYWJ1Zl9jcmVhdGVfc2d0KHN0cnVjdCBwYWdlICoqcGFnZXMsCisJCQkJCSBpbnQgZnJzdF9v ZnN0LCBpbnQgbGFzdF9sZW4sIGludCBuZW50cykKK3sKKwlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsK KwlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnbDsKKwlpbnQgaSwgcmV0OworCisJc2d0ID0ga21hbGxv YyhzaXplb2Yoc3RydWN0IHNnX3RhYmxlKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFzZ3QpIHsKKwkJ cmV0dXJuIE5VTEw7CisJfQorCisJcmV0ID0gc2dfYWxsb2NfdGFibGUoc2d0LCBuZW50cywgR0ZQ X0tFUk5FTCk7CisJaWYgKHJldCkgeworCQlpZiAoc2d0KSB7CisJCQlzZ19mcmVlX3RhYmxlKHNn dCk7CisJCQlrZnJlZShzZ3QpOworCQl9CisKKwkJcmV0dXJuIE5VTEw7CisJfQorCisJc2dsID0g c2d0LT5zZ2w7CisKKwlzZ19zZXRfcGFnZShzZ2wsIHBhZ2VzWzBdLCBQQUdFX1NJWkUtZnJzdF9v ZnN0LCBmcnN0X29mc3QpOworCisJZm9yIChpPTE7IGk8bmVudHMtMTsgaSsrKSB7CisJCXNnbCA9 IHNnX25leHQoc2dsKTsKKwkJc2dfc2V0X3BhZ2Uoc2dsLCBwYWdlc1tpXSwgUEFHRV9TSVpFLCAw KTsKKwl9CisKKwlpZiAobmVudHMgPiAxKSAvKiBtb3JlIHRoYW4gb25lIHBhZ2UgKi8geworCQlz Z2wgPSBzZ19uZXh0KHNnbCk7CisJCXNnX3NldF9wYWdlKHNnbCwgcGFnZXNbaV0sIGxhc3RfbGVu LCAwKTsKKwl9CisKKwlyZXR1cm4gc2d0OworfQorCitpbnQgaHlwZXJfZG1hYnVmX2NsZWFudXBf c2d0X2luZm8oc3RydWN0IGh5cGVyX2RtYWJ1Zl9zZ3RfaW5mbyAqc2d0X2luZm8sIGludCBmb3Jj ZSkKK3sKKwlzdHJ1Y3Qgc2d0X2xpc3QgKnNndGw7CisJc3RydWN0IGF0dGFjaG1lbnRfbGlzdCAq YXR0YWNobDsKKwlzdHJ1Y3Qga21hcF92YWRkcl9saXN0ICp2YV9rbWFwbDsKKwlzdHJ1Y3Qgdm1h cF92YWRkcl9saXN0ICp2YV92bWFwbDsKKwlzdHJ1Y3QgaHlwZXJfZG1hYnVmX2JhY2tlbmRfb3Bz ICpvcHMgPSBoeXBlcl9kbWFidWZfcHJpdmF0ZS5iYWNrZW5kX29wczsKKworCWlmICghc2d0X2lu Zm8pIHsKKwkJZGV2X2VycihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsICJpbnZhbGlkIGh5 cGVyX2RtYWJ1Zl9pZFxuIik7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCS8qIGlmIGZvcmNl ICE9IDEsIHNndF9pbmZvIGNhbiBiZSByZWxlYXNlZCBvbmx5IGlmCisJICogdGhlcmUncyBubyBh Y3Rpdml0eSBvbiBleHBvcnRlZCBkbWEtYnVmIG9uIGltcG9ydGVyCisJICogc2lkZS4KKwkgKi8K KwlpZiAoIWZvcmNlICYmCisJICAgIHNndF9pbmZvLT5pbXBvcnRlcl9leHBvcnRlZCkgeworCQlk ZXZfd2FybihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsICJkbWEtYnVmIGlzIHVzZWQgYnkg aW1wb3J0ZXJcbiIpOworCQlyZXR1cm4gLUVQRVJNOworCX0KKworCS8qIGZvcmNlID09IDEgaXMg bm90IHJlY29tbWVuZGVkICovCisJd2hpbGUgKCFsaXN0X2VtcHR5KCZzZ3RfaW5mby0+dmFfa21h cHBlZC0+bGlzdCkpIHsKKwkJdmFfa21hcGwgPSBsaXN0X2ZpcnN0X2VudHJ5KCZzZ3RfaW5mby0+ dmFfa21hcHBlZC0+bGlzdCwKKwkJCQkJICAgIHN0cnVjdCBrbWFwX3ZhZGRyX2xpc3QsIGxpc3Qp OworCisJCWRtYV9idWZfa3VubWFwKHNndF9pbmZvLT5kbWFfYnVmLCAxLCB2YV9rbWFwbC0+dmFk ZHIpOworCQlsaXN0X2RlbCgmdmFfa21hcGwtPmxpc3QpOworCQlrZnJlZSh2YV9rbWFwbCk7CisJ fQorCisJd2hpbGUgKCFsaXN0X2VtcHR5KCZzZ3RfaW5mby0+dmFfdm1hcHBlZC0+bGlzdCkpIHsK KwkJdmFfdm1hcGwgPSBsaXN0X2ZpcnN0X2VudHJ5KCZzZ3RfaW5mby0+dmFfdm1hcHBlZC0+bGlz dCwKKwkJCQkJICAgIHN0cnVjdCB2bWFwX3ZhZGRyX2xpc3QsIGxpc3QpOworCisJCWRtYV9idWZf dnVubWFwKHNndF9pbmZvLT5kbWFfYnVmLCB2YV92bWFwbC0+dmFkZHIpOworCQlsaXN0X2RlbCgm dmFfdm1hcGwtPmxpc3QpOworCQlrZnJlZSh2YV92bWFwbCk7CisJfQorCisJd2hpbGUgKCFsaXN0 X2VtcHR5KCZzZ3RfaW5mby0+YWN0aXZlX3NndHMtPmxpc3QpKSB7CisJCWF0dGFjaGwgPSBsaXN0 X2ZpcnN0X2VudHJ5KCZzZ3RfaW5mby0+YWN0aXZlX2F0dGFjaGVkLT5saXN0LAorCQkJCQkgICBz dHJ1Y3QgYXR0YWNobWVudF9saXN0LCBsaXN0KTsKKworCQlzZ3RsID0gbGlzdF9maXJzdF9lbnRy eSgmc2d0X2luZm8tPmFjdGl2ZV9zZ3RzLT5saXN0LAorCQkJCQlzdHJ1Y3Qgc2d0X2xpc3QsIGxp c3QpOworCisJCWRtYV9idWZfdW5tYXBfYXR0YWNobWVudChhdHRhY2hsLT5hdHRhY2gsIHNndGwt PnNndCwKKwkJCQkJIERNQV9CSURJUkVDVElPTkFMKTsKKwkJbGlzdF9kZWwoJnNndGwtPmxpc3Qp OworCQlrZnJlZShzZ3RsKTsKKwl9CisKKwl3aGlsZSAoIWxpc3RfZW1wdHkoJnNndF9pbmZvLT5h Y3RpdmVfc2d0cy0+bGlzdCkpIHsKKwkJYXR0YWNobCA9IGxpc3RfZmlyc3RfZW50cnkoJnNndF9p bmZvLT5hY3RpdmVfYXR0YWNoZWQtPmxpc3QsCisJCQkJCSAgIHN0cnVjdCBhdHRhY2htZW50X2xp c3QsIGxpc3QpOworCisJCWRtYV9idWZfZGV0YWNoKHNndF9pbmZvLT5kbWFfYnVmLCBhdHRhY2hs LT5hdHRhY2gpOworCQlsaXN0X2RlbCgmYXR0YWNobC0+bGlzdCk7CisJCWtmcmVlKGF0dGFjaGwp OworCX0KKworCS8qIFN0YXJ0IGNsZWFudXAgb2YgYnVmZmVyIGluIHJldmVyc2Ugb3JkZXIgdG8g ZXhwb3J0aW5nICovCisJb3BzLT51bnNoYXJlX3BhZ2VzKCZzZ3RfaW5mby0+cmVmc19pbmZvLCBz Z3RfaW5mby0+bmVudHMpOworCisJLyogdW5tYXAgZG1hLWJ1ZiAqLworCWRtYV9idWZfdW5tYXBf YXR0YWNobWVudChzZ3RfaW5mby0+YWN0aXZlX2F0dGFjaGVkLT5hdHRhY2gsCisJCQkJIHNndF9p bmZvLT5hY3RpdmVfc2d0cy0+c2d0LAorCQkJCSBETUFfQklESVJFQ1RJT05BTCk7CisKKwkvKiBk ZXRhdGNoIGRtYS1idWYgKi8KKwlkbWFfYnVmX2RldGFjaChzZ3RfaW5mby0+ZG1hX2J1Ziwgc2d0 X2luZm8tPmFjdGl2ZV9hdHRhY2hlZC0+YXR0YWNoKTsKKworCS8qIGNsb3NlIGNvbm5lY3Rpb24g dG8gZG1hLWJ1ZiBjb21wbGV0ZWx5ICovCisJZG1hX2J1Zl9wdXQoc2d0X2luZm8tPmRtYV9idWYp OworCXNndF9pbmZvLT5kbWFfYnVmID0gTlVMTDsKKworCWtmcmVlKHNndF9pbmZvLT5hY3RpdmVf c2d0cyk7CisJa2ZyZWUoc2d0X2luZm8tPmFjdGl2ZV9hdHRhY2hlZCk7CisJa2ZyZWUoc2d0X2lu Zm8tPnZhX2ttYXBwZWQpOworCWtmcmVlKHNndF9pbmZvLT52YV92bWFwcGVkKTsKKworCXJldHVy biAwOworfQpkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1 Zl9zZ2xfcHJvYy5oIGIvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9zZ2xf cHJvYy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIzN2NjZjUKLS0tIC9k ZXYvbnVsbAorKysgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX3NnbF9w cm9jLmgKQEAgLTAsMCArMSw0MSBAQAorLyoKKyAqIENvcHlyaWdodCDCqSAyMDE3IEludGVsIENv cnBvcmF0aW9uCisgKgorICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBj aGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKKyAqIGNvcHkgb2YgdGhpcyBzb2Z0d2Fy ZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksCisg KiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcg d2l0aG91dCBsaW1pdGF0aW9uCisgKiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBt ZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKKyAqIGFuZC9vciBzZWxsIGNv cGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQor ICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dp bmcgY29uZGl0aW9uczoKKyAqCisgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhp cyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZSBuZXh0CisgKiBwYXJhZ3JhcGgpIHNo YWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2Yg dGhlCisgKiBTb2Z0d2FyZS4KKyAqCisgKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElT IiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgorICogSU1QTElFRCwg SU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFC SUxJVFksCisgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklO R0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwKKyAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBI T0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCisgKiBMSUFC SUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lT RSwgQVJJU0lORworICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09G VFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUworICogSU4gVEhFIFNPRlRXQVJFLgor ICoKKyAqLworCisjaWZuZGVmIF9fSFlQRVJfRE1BQlVGX0lNUF9IX18KKyNkZWZpbmUgX19IWVBF Ul9ETUFCVUZfSU1QX0hfXworCitpbnQgZG1hYnVmX3JlZmNvdW50KHN0cnVjdCBkbWFfYnVmICpk bWFfYnVmKTsKKworLyogZXh0cmFjdCBwYWdlcyBkaXJlY3RseSBmcm9tIHN0cnVjdCBzZ190YWJs ZSAqLworc3RydWN0IGh5cGVyX2RtYWJ1Zl9wYWdlc19pbmZvICpoeXBlcl9kbWFidWZfZXh0X3Bn cyhzdHJ1Y3Qgc2dfdGFibGUgKnNndCk7CisKKy8qIGNyZWF0ZSBzZ190YWJsZSB3aXRoIGdpdmVu IHBhZ2VzIGFuZCBvdGhlciBwYXJhbWV0ZXJzICovCitzdHJ1Y3Qgc2dfdGFibGUqIGh5cGVyX2Rt YWJ1Zl9jcmVhdGVfc2d0KHN0cnVjdCBwYWdlICoqcGFnZXMsCisgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIGludCBmcnN0X29mc3QsIGludCBsYXN0X2xlbiwgaW50IG5lbnRzKTsKKwor aW50IGh5cGVyX2RtYWJ1Zl9jbGVhbnVwX3NndF9pbmZvKHN0cnVjdCBoeXBlcl9kbWFidWZfc2d0 X2luZm8gKnNndF9pbmZvLCBpbnQgZm9yY2UpOworCit2b2lkIGh5cGVyX2RtYWJ1Zl9mcmVlX3Nn dChzdHJ1Y3Qgc2dfdGFibGUgKnNndCk7CisKKyNlbmRpZiAvKiBfX0hZUEVSX0RNQUJVRl9JTVBf SF9fICovCi0tIAoyLjcuNAoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QKWGVuLWRldmVsQGxpc3RzLnhlbnByb2pl Y3Qub3JnCmh0dHBzOi8vbGlzdHMueGVucHJvamVjdC5vcmcvbWFpbG1hbi9saXN0aW5mby94ZW4t ZGV2ZWw=