From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.5 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3BD6C433DB for ; Thu, 14 Jan 2021 14:35:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9C6BE23A57 for ; Thu, 14 Jan 2021 14:35:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729181AbhANOe4 (ORCPT ); Thu, 14 Jan 2021 09:34:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37812 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726175AbhANOe4 (ORCPT ); Thu, 14 Jan 2021 09:34:56 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A4915C061575 for ; Thu, 14 Jan 2021 06:34:15 -0800 (PST) Received: from [192.168.0.20] (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5CB492B3; Thu, 14 Jan 2021 15:34:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1610634852; bh=83Ph2rjlgF/e3miikWIqHXd4tEO5toklPl+3r1sDHEc=; h=Reply-To:Subject:To:Cc:References:From:Date:In-Reply-To:From; b=sNP0lSbqDCtn6+7LPUs+L8FDrL40yobi0WX7qeUxP4sNzq8Xm8hH1zeEr0wv1TWKn 8RgXWELDK7kzGZu3lYDSmwTImiBeI2FOIY78ptYqpu3fIjXOWCg8xhgj/3sastrNC3 rmnmrFIZ/igGa0d8aJ6dUS9BKHxjz+NBJtAS8a5Q= Reply-To: kieran.bingham+renesas@ideasonboard.com Subject: Re: [PATCH 2/2] drm/cma-helper: Implement mmap as GEM CMA object functions To: Thomas Zimmermann , maarten.lankhorst@linux.intel.com, mripard@kernel.org, airlied@linux.ie, daniel@ffwll.ch, eric@anholt.net, Linux-Renesas , Laurent Pinchart Cc: dri-devel@lists.freedesktop.org References: <20201123115646.11004-1-tzimmermann@suse.de> <20201123115646.11004-3-tzimmermann@suse.de> From: Kieran Bingham Organization: Ideas on Board Message-ID: Date: Thu, 14 Jan 2021 14:34:09 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-GB Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org Hi Thomas, On 14/01/2021 13:26, Thomas Zimmermann wrote: > Hi Kieran > > Am 14.01.21 um 13:51 schrieb Kieran Bingham: >> Hi Thomas, >> >> On 23/11/2020 11:56, Thomas Zimmermann wrote: >>> The new GEM object function drm_gem_cma_mmap() sets the VMA flags >>> and offset as in the old implementation and immediately maps in the >>> buffer's memory pages. >>> >>> Changing CMA helpers to use the GEM object function allows for the >>> removal of the special implementations for mmap and gem_prime_mmap >>> callbacks. The regular functions drm_gem_mmap() and drm_gem_prime_mmap() >>> are now used. >> >> I've encountered a memory leak regression in our Renesas R-Car DU tests, >> and git bisection has led me to this patch (as commit f5ca8eb6f9). >> >> Running the tests sequentially, while grepping /proc/meminfo for Cma, it >> is evident that CMA memory is not released, until exhausted and the >> allocations fail (seen in [0]) shown by the error report: >> >>>      self.fbs.append(pykms.DumbFramebuffer(self.card, mode.hdisplay, >>> mode.vdisplay, "XR24")) >>> ValueError: DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory >> >> >> Failing tests at f5ca8eb6f9 can be seen at [0], while the tests pass >> successfully [1] on the commit previous to that (bc2532ab7c2): >> >> Reverting f5ca8eb6f9 also produces a successful pass [2] >> >>   [0] https://paste.ubuntu.com/p/VjPGPgswxR/ # Failed at f5ca8eb6f9 >>   [1] https://paste.ubuntu.com/p/78RRp2WpNR/ # Success at bc2532ab7c2 >>   [2] https://paste.ubuntu.com/p/qJKjZZN2pt/ # Success with revert >> >> >> I don't believe we handle mmap specially in the RCar-DU driver, so I >> wonder if this issue has hit anyone else as well? >> >> Any ideas of a repair without a revert ? Or do we just need to submit a >> revert? > > I think we might not be setting the VMA ops and therefore not finalize > the BO correctly. Could you please apply the attched (quick-and-dirty) > patch and try again? Thanks for the quick response. I can confirm the quick-and-dirty patch resolves the issue: https://paste.ubuntu.com/p/sKDp3dNvwV/ You can add a Tested-by: Kieran Bingham if it stays like that, but I suspect there might be a better place to initialise the ops rather than in the mmap call itself. Happy to do further testing as required. -- Regards Kieran > Best regards > Thomas > >> >> I've yet to fully understand the implications of the patch below. >> >> Thanks >> -- >> Regards >> >> Kieran >> >> >> >>> Signed-off-by: Thomas Zimmermann >>> --- >>>   drivers/gpu/drm/drm_file.c           |   3 +- >>>   drivers/gpu/drm/drm_gem_cma_helper.c | 121 +++++++++------------------ >>>   drivers/gpu/drm/pl111/pl111_drv.c    |   2 +- >>>   drivers/gpu/drm/vc4/vc4_bo.c         |   2 +- >>>   include/drm/drm_gem_cma_helper.h     |  10 +-- >>>   5 files changed, 44 insertions(+), 94 deletions(-) >>> >>> diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c >>> index b50380fa80ce..80886d50d0f1 100644 >>> --- a/drivers/gpu/drm/drm_file.c >>> +++ b/drivers/gpu/drm/drm_file.c >>> @@ -113,8 +113,7 @@ bool drm_dev_needs_global_mutex(struct drm_device >>> *dev) >>>    * The memory mapping implementation will vary depending on how the >>> driver >>>    * manages memory. Legacy drivers will use the deprecated >>> drm_legacy_mmap() >>>    * function, modern drivers should use one of the provided >>> memory-manager >>> - * specific implementations. For GEM-based drivers this is >>> drm_gem_mmap(), and >>> - * for drivers which use the CMA GEM helpers it's drm_gem_cma_mmap(). >>> + * specific implementations. For GEM-based drivers this is >>> drm_gem_mmap(). >>>    * >>>    * No other file operations are supported by the DRM userspace API. >>> Overall the >>>    * following is an example &file_operations structure:: >>> diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c >>> b/drivers/gpu/drm/drm_gem_cma_helper.c >>> index 6a4ef335ebc9..7942cf05cd93 100644 >>> --- a/drivers/gpu/drm/drm_gem_cma_helper.c >>> +++ b/drivers/gpu/drm/drm_gem_cma_helper.c >>> @@ -38,6 +38,7 @@ static const struct drm_gem_object_funcs >>> drm_gem_cma_default_funcs = { >>>       .print_info = drm_gem_cma_print_info, >>>       .get_sg_table = drm_gem_cma_get_sg_table, >>>       .vmap = drm_gem_cma_vmap, >>> +    .mmap = drm_gem_cma_mmap, >>>       .vm_ops = &drm_gem_cma_vm_ops, >>>   }; >>>   @@ -277,62 +278,6 @@ const struct vm_operations_struct >>> drm_gem_cma_vm_ops = { >>>   }; >>>   EXPORT_SYMBOL_GPL(drm_gem_cma_vm_ops); >>>   -static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj, >>> -                struct vm_area_struct *vma) >>> -{ >>> -    int ret; >>> - >>> -    /* >>> -     * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and >>> set the >>> -     * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we >>> want to map >>> -     * the whole buffer. >>> -     */ >>> -    vma->vm_flags &= ~VM_PFNMAP; >>> -    vma->vm_pgoff = 0; >>> - >>> -    ret = dma_mmap_wc(cma_obj->base.dev->dev, vma, cma_obj->vaddr, >>> -              cma_obj->paddr, vma->vm_end - vma->vm_start); >>> -    if (ret) >>> -        drm_gem_vm_close(vma); >>> - >>> -    return ret; >>> -} >>> - >>> -/** >>> - * drm_gem_cma_mmap - memory-map a CMA GEM object >>> - * @filp: file object >>> - * @vma: VMA for the area to be mapped >>> - * >>> - * This function implements an augmented version of the GEM DRM file >>> mmap >>> - * operation for CMA objects: In addition to the usual GEM VMA setup it >>> - * immediately faults in the entire object instead of using on-demaind >>> - * faulting. Drivers which employ the CMA helpers should use this >>> function >>> - * as their ->mmap() handler in the DRM device file's file_operations >>> - * structure. >>> - * >>> - * Instead of directly referencing this function, drivers should use >>> the >>> - * DEFINE_DRM_GEM_CMA_FOPS().macro. >>> - * >>> - * Returns: >>> - * 0 on success or a negative error code on failure. >>> - */ >>> -int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) >>> -{ >>> -    struct drm_gem_cma_object *cma_obj; >>> -    struct drm_gem_object *gem_obj; >>> -    int ret; >>> - >>> -    ret = drm_gem_mmap(filp, vma); >>> -    if (ret) >>> -        return ret; >>> - >>> -    gem_obj = vma->vm_private_data; >>> -    cma_obj = to_drm_gem_cma_obj(gem_obj); >>> - >>> -    return drm_gem_cma_mmap_obj(cma_obj, vma); >>> -} >>> -EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); >>> - >>>   #ifndef CONFIG_MMU >>>   /** >>>    * drm_gem_cma_get_unmapped_area - propose address for mapping in >>> noMMU cases >>> @@ -500,33 +445,6 @@ drm_gem_cma_prime_import_sg_table(struct >>> drm_device *dev, >>>   } >>>   EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table); >>>   -/** >>> - * drm_gem_cma_prime_mmap - memory-map an exported CMA GEM object >>> - * @obj: GEM object >>> - * @vma: VMA for the area to be mapped >>> - * >>> - * This function maps a buffer imported via DRM PRIME into a userspace >>> - * process's address space. Drivers that use the CMA helpers should >>> set this >>> - * as their &drm_driver.gem_prime_mmap callback. >>> - * >>> - * Returns: >>> - * 0 on success or a negative error code on failure. >>> - */ >>> -int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, >>> -               struct vm_area_struct *vma) >>> -{ >>> -    struct drm_gem_cma_object *cma_obj; >>> -    int ret; >>> - >>> -    ret = drm_gem_mmap_obj(obj, obj->size, vma); >>> -    if (ret < 0) >>> -        return ret; >>> - >>> -    cma_obj = to_drm_gem_cma_obj(obj); >>> -    return drm_gem_cma_mmap_obj(cma_obj, vma); >>> -} >>> -EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); >>> - >>>   /** >>>    * drm_gem_cma_vmap - map a CMA GEM object into the kernel's virtual >>>    *     address space >>> @@ -553,6 +471,43 @@ int drm_gem_cma_vmap(struct drm_gem_object *obj, >>> struct dma_buf_map *map) >>>   } >>>   EXPORT_SYMBOL_GPL(drm_gem_cma_vmap); >>>   +/** >>> + * drm_gem_cma_mmap - memory-map an exported CMA GEM object >>> + * @obj: GEM object >>> + * @vma: VMA for the area to be mapped >>> + * >>> + * This function maps a buffer into a userspace process's address >>> space. >>> + * In addition to the usual GEM VMA setup it immediately faults in >>> the entire >>> + * object instead of using on-demand faulting. Drivers that use the CMA >>> + * helpers should set this as their &drm_gem_object_funcs.mmap >>> callback. >>> + * >>> + * Returns: >>> + * 0 on success or a negative error code on failure. >>> + */ >>> +int drm_gem_cma_mmap(struct drm_gem_object *obj, struct >>> vm_area_struct *vma) >>> +{ >>> +    struct drm_gem_cma_object *cma_obj; >>> +    int ret; >>> + >>> +    /* >>> +     * Clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and >>> set the >>> +     * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we >>> want to map >>> +     * the whole buffer. >>> +     */ >>> +    vma->vm_pgoff -= drm_vma_node_start(&obj->vma_node); >>> +    vma->vm_flags &= ~VM_PFNMAP; >>> + >>> +    cma_obj = to_drm_gem_cma_obj(obj); >>> + >>> +    ret = dma_mmap_wc(cma_obj->base.dev->dev, vma, cma_obj->vaddr, >>> +              cma_obj->paddr, vma->vm_end - vma->vm_start); >>> +    if (ret) >>> +        drm_gem_vm_close(vma); >>> + >>> +    return ret; >>> +} >>> +EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); >>> + >>>   /** >>>    * drm_gem_cma_prime_import_sg_table_vmap - PRIME import another >>> driver's >>>    *    scatter/gather table and get the virtual address of the buffer >>> diff --git a/drivers/gpu/drm/pl111/pl111_drv.c >>> b/drivers/gpu/drm/pl111/pl111_drv.c >>> index 40e6708fbbe2..e4dcaef6c143 100644 >>> --- a/drivers/gpu/drm/pl111/pl111_drv.c >>> +++ b/drivers/gpu/drm/pl111/pl111_drv.c >>> @@ -228,7 +228,7 @@ static const struct drm_driver pl111_drm_driver = { >>>       .prime_handle_to_fd = drm_gem_prime_handle_to_fd, >>>       .prime_fd_to_handle = drm_gem_prime_fd_to_handle, >>>       .gem_prime_import_sg_table = pl111_gem_import_sg_table, >>> -    .gem_prime_mmap = drm_gem_cma_prime_mmap, >>> +    .gem_prime_mmap = drm_gem_prime_mmap, >>>     #if defined(CONFIG_DEBUG_FS) >>>       .debugfs_init = pl111_debugfs_init, >>> diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c >>> index 813e6cb3f9af..dc316cb79e00 100644 >>> --- a/drivers/gpu/drm/vc4/vc4_bo.c >>> +++ b/drivers/gpu/drm/vc4/vc4_bo.c >>> @@ -782,7 +782,7 @@ int vc4_prime_mmap(struct drm_gem_object *obj, >>> struct vm_area_struct *vma) >>>           return -EINVAL; >>>       } >>>   -    return drm_gem_cma_prime_mmap(obj, vma); >>> +    return drm_gem_prime_mmap(obj, vma); >>>   } >>>     int vc4_prime_vmap(struct drm_gem_object *obj, struct dma_buf_map >>> *map) >>> diff --git a/include/drm/drm_gem_cma_helper.h >>> b/include/drm/drm_gem_cma_helper.h >>> index 4680275ab339..0a9711caa3e8 100644 >>> --- a/include/drm/drm_gem_cma_helper.h >>> +++ b/include/drm/drm_gem_cma_helper.h >>> @@ -59,7 +59,7 @@ struct drm_gem_cma_object { >>>           .poll        = drm_poll,\ >>>           .read        = drm_read,\ >>>           .llseek        = noop_llseek,\ >>> -        .mmap        = drm_gem_cma_mmap,\ >>> +        .mmap        = drm_gem_mmap,\ >>>           DRM_GEM_CMA_UNMAPPED_AREA_FOPS \ >>>       } >>>   @@ -76,9 +76,6 @@ int drm_gem_cma_dumb_create(struct drm_file >>> *file_priv, >>>                   struct drm_device *drm, >>>                   struct drm_mode_create_dumb *args); >>>   -/* set vm_flags and we can change the VM attribute to other one at >>> here */ >>> -int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma); >>> - >>>   /* allocate physical memory */ >>>   struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, >>>                             size_t size); >>> @@ -101,9 +98,8 @@ struct drm_gem_object * >>>   drm_gem_cma_prime_import_sg_table(struct drm_device *dev, >>>                     struct dma_buf_attachment *attach, >>>                     struct sg_table *sgt); >>> -int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, >>> -               struct vm_area_struct *vma); >>>   int drm_gem_cma_vmap(struct drm_gem_object *obj, struct dma_buf_map >>> *map); >>> +int drm_gem_cma_mmap(struct drm_gem_object *obj, struct >>> vm_area_struct *vma); >>>     /** >>>    * DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE - CMA GEM driver operations >>> @@ -123,7 +119,7 @@ int drm_gem_cma_vmap(struct drm_gem_object *obj, >>> struct dma_buf_map *map); >>>       .prime_handle_to_fd    = drm_gem_prime_handle_to_fd, \ >>>       .prime_fd_to_handle    = drm_gem_prime_fd_to_handle, \ >>>       .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, \ >>> -    .gem_prime_mmap        = drm_gem_cma_prime_mmap >>> +    .gem_prime_mmap        = drm_gem_prime_mmap >>>     /** >>>    * DRM_GEM_CMA_DRIVER_OPS - CMA GEM driver operations >>> >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel >> > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.3 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C72CC433E0 for ; Thu, 14 Jan 2021 14:34:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 55C902222D for ; Thu, 14 Jan 2021 14:34:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 55C902222D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A4A356E3FE; Thu, 14 Jan 2021 14:34:16 +0000 (UTC) Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by gabe.freedesktop.org (Postfix) with ESMTPS id DA7FB6E3FE for ; Thu, 14 Jan 2021 14:34:14 +0000 (UTC) Received: from [192.168.0.20] (cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 5CB492B3; Thu, 14 Jan 2021 15:34:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1610634852; bh=83Ph2rjlgF/e3miikWIqHXd4tEO5toklPl+3r1sDHEc=; h=Reply-To:Subject:To:Cc:References:From:Date:In-Reply-To:From; b=sNP0lSbqDCtn6+7LPUs+L8FDrL40yobi0WX7qeUxP4sNzq8Xm8hH1zeEr0wv1TWKn 8RgXWELDK7kzGZu3lYDSmwTImiBeI2FOIY78ptYqpu3fIjXOWCg8xhgj/3sastrNC3 rmnmrFIZ/igGa0d8aJ6dUS9BKHxjz+NBJtAS8a5Q= Subject: Re: [PATCH 2/2] drm/cma-helper: Implement mmap as GEM CMA object functions To: Thomas Zimmermann , maarten.lankhorst@linux.intel.com, mripard@kernel.org, airlied@linux.ie, daniel@ffwll.ch, eric@anholt.net, Linux-Renesas , Laurent Pinchart References: <20201123115646.11004-1-tzimmermann@suse.de> <20201123115646.11004-3-tzimmermann@suse.de> From: Kieran Bingham Organization: Ideas on Board Message-ID: Date: Thu, 14 Jan 2021 14:34:09 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-GB X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: kieran.bingham+renesas@ideasonboard.com Cc: dri-devel@lists.freedesktop.org Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" SGkgVGhvbWFzLAoKT24gMTQvMDEvMjAyMSAxMzoyNiwgVGhvbWFzIFppbW1lcm1hbm4gd3JvdGU6 Cj4gSGkgS2llcmFuCj4gCj4gQW0gMTQuMDEuMjEgdW0gMTM6NTEgc2NocmllYiBLaWVyYW4gQmlu Z2hhbToKPj4gSGkgVGhvbWFzLAo+Pgo+PiBPbiAyMy8xMS8yMDIwIDExOjU2LCBUaG9tYXMgWmlt bWVybWFubiB3cm90ZToKPj4+IFRoZSBuZXcgR0VNIG9iamVjdCBmdW5jdGlvbiBkcm1fZ2VtX2Nt YV9tbWFwKCkgc2V0cyB0aGUgVk1BIGZsYWdzCj4+PiBhbmQgb2Zmc2V0IGFzIGluIHRoZSBvbGQg aW1wbGVtZW50YXRpb24gYW5kIGltbWVkaWF0ZWx5IG1hcHMgaW4gdGhlCj4+PiBidWZmZXIncyBt ZW1vcnkgcGFnZXMuCj4+Pgo+Pj4gQ2hhbmdpbmcgQ01BIGhlbHBlcnMgdG8gdXNlIHRoZSBHRU0g b2JqZWN0IGZ1bmN0aW9uIGFsbG93cyBmb3IgdGhlCj4+PiByZW1vdmFsIG9mIHRoZSBzcGVjaWFs IGltcGxlbWVudGF0aW9ucyBmb3IgbW1hcCBhbmQgZ2VtX3ByaW1lX21tYXAKPj4+IGNhbGxiYWNr cy4gVGhlIHJlZ3VsYXIgZnVuY3Rpb25zIGRybV9nZW1fbW1hcCgpIGFuZCBkcm1fZ2VtX3ByaW1l X21tYXAoKQo+Pj4gYXJlIG5vdyB1c2VkLgo+Pgo+PiBJJ3ZlIGVuY291bnRlcmVkIGEgbWVtb3J5 IGxlYWsgcmVncmVzc2lvbiBpbiBvdXIgUmVuZXNhcyBSLUNhciBEVSB0ZXN0cywKPj4gYW5kIGdp dCBiaXNlY3Rpb24gaGFzIGxlZCBtZSB0byB0aGlzIHBhdGNoIChhcyBjb21taXQgZjVjYThlYjZm OSkuCj4+Cj4+IFJ1bm5pbmcgdGhlIHRlc3RzIHNlcXVlbnRpYWxseSwgd2hpbGUgZ3JlcHBpbmcg L3Byb2MvbWVtaW5mbyBmb3IgQ21hLCBpdAo+PiBpcyBldmlkZW50IHRoYXQgQ01BIG1lbW9yeSBp cyBub3QgcmVsZWFzZWQsIHVudGlsIGV4aGF1c3RlZCBhbmQgdGhlCj4+IGFsbG9jYXRpb25zIGZh aWwgKHNlZW4gaW4gWzBdKSBzaG93biBieSB0aGUgZXJyb3IgcmVwb3J0Ogo+Pgo+Pj4gwqDCoMKg wqAgc2VsZi5mYnMuYXBwZW5kKHB5a21zLkR1bWJGcmFtZWJ1ZmZlcihzZWxmLmNhcmQsIG1vZGUu aGRpc3BsYXksCj4+PiBtb2RlLnZkaXNwbGF5LCAiWFIyNCIpKQo+Pj4gVmFsdWVFcnJvcjogRFJN X0lPQ1RMX01PREVfQ1JFQVRFX0RVTUIgZmFpbGVkOiBDYW5ub3QgYWxsb2NhdGUgbWVtb3J5Cj4+ Cj4+Cj4+IEZhaWxpbmcgdGVzdHMgYXQgZjVjYThlYjZmOSBjYW4gYmUgc2VlbiBhdCBbMF0sIHdo aWxlIHRoZSB0ZXN0cyBwYXNzCj4+IHN1Y2Nlc3NmdWxseSBbMV0gb24gdGhlIGNvbW1pdCBwcmV2 aW91cyB0byB0aGF0IChiYzI1MzJhYjdjMik6Cj4+Cj4+IFJldmVydGluZyBmNWNhOGViNmY5IGFs c28gcHJvZHVjZXMgYSBzdWNjZXNzZnVsIHBhc3MgWzJdCj4+Cj4+IMKgIFswXSBodHRwczovL3Bh c3RlLnVidW50dS5jb20vcC9WalBHUGdzd3hSLyAjIEZhaWxlZCBhdCBmNWNhOGViNmY5Cj4+IMKg IFsxXSBodHRwczovL3Bhc3RlLnVidW50dS5jb20vcC83OFJScDJXcE5SLyAjIFN1Y2Nlc3MgYXQg YmMyNTMyYWI3YzIKPj4gwqAgWzJdIGh0dHBzOi8vcGFzdGUudWJ1bnR1LmNvbS9wL3FKS2paWk4y cHQvICMgU3VjY2VzcyB3aXRoIHJldmVydAo+Pgo+Pgo+PiBJIGRvbid0IGJlbGlldmUgd2UgaGFu ZGxlIG1tYXAgc3BlY2lhbGx5IGluIHRoZSBSQ2FyLURVIGRyaXZlciwgc28gSQo+PiB3b25kZXIg aWYgdGhpcyBpc3N1ZSBoYXMgaGl0IGFueW9uZSBlbHNlIGFzIHdlbGw/Cj4+Cj4+IEFueSBpZGVh cyBvZiBhIHJlcGFpciB3aXRob3V0IGEgcmV2ZXJ0ID8gT3IgZG8gd2UganVzdCBuZWVkIHRvIHN1 Ym1pdCBhCj4+IHJldmVydD8KPiAKPiBJIHRoaW5rIHdlIG1pZ2h0IG5vdCBiZSBzZXR0aW5nIHRo ZSBWTUEgb3BzIGFuZCB0aGVyZWZvcmUgbm90IGZpbmFsaXplCj4gdGhlIEJPIGNvcnJlY3RseS4g Q291bGQgeW91IHBsZWFzZSBhcHBseSB0aGUgYXR0Y2hlZCAocXVpY2stYW5kLWRpcnR5KQo+IHBh dGNoIGFuZCB0cnkgYWdhaW4/CgpUaGFua3MgZm9yIHRoZSBxdWljayByZXNwb25zZS4KCkkgY2Fu IGNvbmZpcm0gdGhlIHF1aWNrLWFuZC1kaXJ0eSBwYXRjaCByZXNvbHZlcyB0aGUgaXNzdWU6CiAg aHR0cHM6Ly9wYXN0ZS51YnVudHUuY29tL3Avc0tEcDNkTnZ3Vi8KCllvdSBjYW4gYWRkIGEKVGVz dGVkLWJ5OiBLaWVyYW4gQmluZ2hhbSA8a2llcmFuLmJpbmdoYW0rcmVuZXNhc0BpZGVhc29uYm9h cmQuY29tPgoKaWYgaXQgc3RheXMgbGlrZSB0aGF0LCBidXQgSSBzdXNwZWN0IHRoZXJlIG1pZ2h0 IGJlIGEgYmV0dGVyIHBsYWNlIHRvCmluaXRpYWxpc2UgdGhlIG9wcyByYXRoZXIgdGhhbiBpbiB0 aGUgbW1hcCBjYWxsIGl0c2VsZi4KCkhhcHB5IHRvIGRvIGZ1cnRoZXIgdGVzdGluZyBhcyByZXF1 aXJlZC4KCi0tClJlZ2FyZHMKCktpZXJhbgoKCj4gQmVzdCByZWdhcmRzCj4gVGhvbWFzCj4gCj4+ Cj4+IEkndmUgeWV0IHRvIGZ1bGx5IHVuZGVyc3RhbmQgdGhlIGltcGxpY2F0aW9ucyBvZiB0aGUg cGF0Y2ggYmVsb3cuCj4+Cj4+IFRoYW5rcwo+PiAtLSAKPj4gUmVnYXJkcwo+Pgo+PiBLaWVyYW4K Pj4KPj4KPj4KPj4+IFNpZ25lZC1vZmYtYnk6IFRob21hcyBaaW1tZXJtYW5uIDx0emltbWVybWFu bkBzdXNlLmRlPgo+Pj4gLS0tCj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vZHJtX2ZpbGUuY8KgwqDC oMKgwqDCoMKgwqDCoMKgIHzCoMKgIDMgKy0KPj4+IMKgIGRyaXZlcnMvZ3B1L2RybS9kcm1fZ2Vt X2NtYV9oZWxwZXIuYyB8IDEyMSArKysrKysrKystLS0tLS0tLS0tLS0tLS0tLS0KPj4+IMKgIGRy aXZlcnMvZ3B1L2RybS9wbDExMS9wbDExMV9kcnYuY8KgwqDCoCB8wqDCoCAyICstCj4+PiDCoCBk cml2ZXJzL2dwdS9kcm0vdmM0L3ZjNF9iby5jwqDCoMKgwqDCoMKgwqDCoCB8wqDCoCAyICstCj4+ PiDCoCBpbmNsdWRlL2RybS9kcm1fZ2VtX2NtYV9oZWxwZXIuaMKgwqDCoMKgIHzCoCAxMCArLS0K Pj4+IMKgIDUgZmlsZXMgY2hhbmdlZCwgNDQgaW5zZXJ0aW9ucygrKSwgOTQgZGVsZXRpb25zKC0p Cj4+Pgo+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9kcm1fZmlsZS5jIGIvZHJpdmVy cy9ncHUvZHJtL2RybV9maWxlLmMKPj4+IGluZGV4IGI1MDM4MGZhODBjZS4uODA4ODZkNTBkMGYx IDEwMDY0NAo+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2RybV9maWxlLmMKPj4+ICsrKyBiL2Ry aXZlcnMvZ3B1L2RybS9kcm1fZmlsZS5jCj4+PiBAQCAtMTEzLDggKzExMyw3IEBAIGJvb2wgZHJt X2Rldl9uZWVkc19nbG9iYWxfbXV0ZXgoc3RydWN0IGRybV9kZXZpY2UKPj4+ICpkZXYpCj4+PiDC oMKgICogVGhlIG1lbW9yeSBtYXBwaW5nIGltcGxlbWVudGF0aW9uIHdpbGwgdmFyeSBkZXBlbmRp bmcgb24gaG93IHRoZQo+Pj4gZHJpdmVyCj4+PiDCoMKgICogbWFuYWdlcyBtZW1vcnkuIExlZ2Fj eSBkcml2ZXJzIHdpbGwgdXNlIHRoZSBkZXByZWNhdGVkCj4+PiBkcm1fbGVnYWN5X21tYXAoKQo+ Pj4gwqDCoCAqIGZ1bmN0aW9uLCBtb2Rlcm4gZHJpdmVycyBzaG91bGQgdXNlIG9uZSBvZiB0aGUg cHJvdmlkZWQKPj4+IG1lbW9yeS1tYW5hZ2VyCj4+PiAtICogc3BlY2lmaWMgaW1wbGVtZW50YXRp b25zLiBGb3IgR0VNLWJhc2VkIGRyaXZlcnMgdGhpcyBpcwo+Pj4gZHJtX2dlbV9tbWFwKCksIGFu ZAo+Pj4gLSAqIGZvciBkcml2ZXJzIHdoaWNoIHVzZSB0aGUgQ01BIEdFTSBoZWxwZXJzIGl0J3Mg ZHJtX2dlbV9jbWFfbW1hcCgpLgo+Pj4gKyAqIHNwZWNpZmljIGltcGxlbWVudGF0aW9ucy4gRm9y IEdFTS1iYXNlZCBkcml2ZXJzIHRoaXMgaXMKPj4+IGRybV9nZW1fbW1hcCgpLgo+Pj4gwqDCoCAq Cj4+PiDCoMKgICogTm8gb3RoZXIgZmlsZSBvcGVyYXRpb25zIGFyZSBzdXBwb3J0ZWQgYnkgdGhl IERSTSB1c2Vyc3BhY2UgQVBJLgo+Pj4gT3ZlcmFsbCB0aGUKPj4+IMKgwqAgKiBmb2xsb3dpbmcg aXMgYW4gZXhhbXBsZSAmZmlsZV9vcGVyYXRpb25zIHN0cnVjdHVyZTo6Cj4+PiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvZHJtL2RybV9nZW1fY21hX2hlbHBlci5jCj4+PiBiL2RyaXZlcnMvZ3B1 L2RybS9kcm1fZ2VtX2NtYV9oZWxwZXIuYwo+Pj4gaW5kZXggNmE0ZWYzMzVlYmM5Li43OTQyY2Yw NWNkOTMgMTAwNjQ0Cj4+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vZHJtX2dlbV9jbWFfaGVscGVy LmMKPj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9kcm1fZ2VtX2NtYV9oZWxwZXIuYwo+Pj4gQEAg LTM4LDYgKzM4LDcgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fZ2VtX29iamVjdF9mdW5jcwo+ Pj4gZHJtX2dlbV9jbWFfZGVmYXVsdF9mdW5jcyA9IHsKPj4+IMKgwqDCoMKgwqAgLnByaW50X2lu Zm8gPSBkcm1fZ2VtX2NtYV9wcmludF9pbmZvLAo+Pj4gwqDCoMKgwqDCoCAuZ2V0X3NnX3RhYmxl ID0gZHJtX2dlbV9jbWFfZ2V0X3NnX3RhYmxlLAo+Pj4gwqDCoMKgwqDCoCAudm1hcCA9IGRybV9n ZW1fY21hX3ZtYXAsCj4+PiArwqDCoMKgIC5tbWFwID0gZHJtX2dlbV9jbWFfbW1hcCwKPj4+IMKg wqDCoMKgwqAgLnZtX29wcyA9ICZkcm1fZ2VtX2NtYV92bV9vcHMsCj4+PiDCoCB9Owo+Pj4gwqAg QEAgLTI3Nyw2MiArMjc4LDYgQEAgY29uc3Qgc3RydWN0IHZtX29wZXJhdGlvbnNfc3RydWN0Cj4+ PiBkcm1fZ2VtX2NtYV92bV9vcHMgPSB7Cj4+PiDCoCB9Owo+Pj4gwqAgRVhQT1JUX1NZTUJPTF9H UEwoZHJtX2dlbV9jbWFfdm1fb3BzKTsKPj4+IMKgIC1zdGF0aWMgaW50IGRybV9nZW1fY21hX21t YXBfb2JqKHN0cnVjdCBkcm1fZ2VtX2NtYV9vYmplY3QgKmNtYV9vYmosCj4+PiAtwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQo+Pj4gLXsK Pj4+IC3CoMKgwqAgaW50IHJldDsKPj4+IC0KPj4+IC3CoMKgwqAgLyoKPj4+IC3CoMKgwqDCoCAq IENsZWFyIHRoZSBWTV9QRk5NQVAgZmxhZyB0aGF0IHdhcyBzZXQgYnkgZHJtX2dlbV9tbWFwKCks IGFuZAo+Pj4gc2V0IHRoZQo+Pj4gLcKgwqDCoMKgICogdm1fcGdvZmYgKHVzZWQgYXMgYSBmYWtl IGJ1ZmZlciBvZmZzZXQgYnkgRFJNKSB0byAwIGFzIHdlCj4+PiB3YW50IHRvIG1hcAo+Pj4gLcKg wqDCoMKgICogdGhlIHdob2xlIGJ1ZmZlci4KPj4+IC3CoMKgwqDCoCAqLwo+Pj4gLcKgwqDCoCB2 bWEtPnZtX2ZsYWdzICY9IH5WTV9QRk5NQVA7Cj4+PiAtwqDCoMKgIHZtYS0+dm1fcGdvZmYgPSAw Owo+Pj4gLQo+Pj4gLcKgwqDCoCByZXQgPSBkbWFfbW1hcF93YyhjbWFfb2JqLT5iYXNlLmRldi0+ ZGV2LCB2bWEsIGNtYV9vYmotPnZhZGRyLAo+Pj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IGNtYV9vYmotPnBhZGRyLCB2bWEtPnZtX2VuZCAtIHZtYS0+dm1fc3RhcnQpOwo+Pj4gLcKgwqDC oCBpZiAocmV0KQo+Pj4gLcKgwqDCoMKgwqDCoMKgIGRybV9nZW1fdm1fY2xvc2Uodm1hKTsKPj4+ IC0KPj4+IC3CoMKgwqAgcmV0dXJuIHJldDsKPj4+IC19Cj4+PiAtCj4+PiAtLyoqCj4+PiAtICog ZHJtX2dlbV9jbWFfbW1hcCAtIG1lbW9yeS1tYXAgYSBDTUEgR0VNIG9iamVjdAo+Pj4gLSAqIEBm aWxwOiBmaWxlIG9iamVjdAo+Pj4gLSAqIEB2bWE6IFZNQSBmb3IgdGhlIGFyZWEgdG8gYmUgbWFw cGVkCj4+PiAtICoKPj4+IC0gKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgYW4gYXVnbWVudGVk IHZlcnNpb24gb2YgdGhlIEdFTSBEUk0gZmlsZQo+Pj4gbW1hcAo+Pj4gLSAqIG9wZXJhdGlvbiBm b3IgQ01BIG9iamVjdHM6IEluIGFkZGl0aW9uIHRvIHRoZSB1c3VhbCBHRU0gVk1BIHNldHVwIGl0 Cj4+PiAtICogaW1tZWRpYXRlbHkgZmF1bHRzIGluIHRoZSBlbnRpcmUgb2JqZWN0IGluc3RlYWQg b2YgdXNpbmcgb24tZGVtYWluZAo+Pj4gLSAqIGZhdWx0aW5nLiBEcml2ZXJzIHdoaWNoIGVtcGxv eSB0aGUgQ01BIGhlbHBlcnMgc2hvdWxkIHVzZSB0aGlzCj4+PiBmdW5jdGlvbgo+Pj4gLSAqIGFz IHRoZWlyIC0+bW1hcCgpIGhhbmRsZXIgaW4gdGhlIERSTSBkZXZpY2UgZmlsZSdzIGZpbGVfb3Bl cmF0aW9ucwo+Pj4gLSAqIHN0cnVjdHVyZS4KPj4+IC0gKgo+Pj4gLSAqIEluc3RlYWQgb2YgZGly ZWN0bHkgcmVmZXJlbmNpbmcgdGhpcyBmdW5jdGlvbiwgZHJpdmVycyBzaG91bGQgdXNlCj4+PiB0 aGUKPj4+IC0gKiBERUZJTkVfRFJNX0dFTV9DTUFfRk9QUygpLm1hY3JvLgo+Pj4gLSAqCj4+PiAt ICogUmV0dXJuczoKPj4+IC0gKiAwIG9uIHN1Y2Nlc3Mgb3IgYSBuZWdhdGl2ZSBlcnJvciBjb2Rl IG9uIGZhaWx1cmUuCj4+PiAtICovCj4+PiAtaW50IGRybV9nZW1fY21hX21tYXAoc3RydWN0IGZp bGUgKmZpbHAsIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqdm1hKQo+Pj4gLXsKPj4+IC3CoMKgwqAg c3RydWN0IGRybV9nZW1fY21hX29iamVjdCAqY21hX29iajsKPj4+IC3CoMKgwqAgc3RydWN0IGRy bV9nZW1fb2JqZWN0ICpnZW1fb2JqOwo+Pj4gLcKgwqDCoCBpbnQgcmV0Owo+Pj4gLQo+Pj4gLcKg wqDCoCByZXQgPSBkcm1fZ2VtX21tYXAoZmlscCwgdm1hKTsKPj4+IC3CoMKgwqAgaWYgKHJldCkK Pj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+Pj4gLQo+Pj4gLcKgwqDCoCBnZW1fb2Jq ID0gdm1hLT52bV9wcml2YXRlX2RhdGE7Cj4+PiAtwqDCoMKgIGNtYV9vYmogPSB0b19kcm1fZ2Vt X2NtYV9vYmooZ2VtX29iaik7Cj4+PiAtCj4+PiAtwqDCoMKgIHJldHVybiBkcm1fZ2VtX2NtYV9t bWFwX29iaihjbWFfb2JqLCB2bWEpOwo+Pj4gLX0KPj4+IC1FWFBPUlRfU1lNQk9MX0dQTChkcm1f Z2VtX2NtYV9tbWFwKTsKPj4+IC0KPj4+IMKgICNpZm5kZWYgQ09ORklHX01NVQo+Pj4gwqAgLyoq Cj4+PiDCoMKgICogZHJtX2dlbV9jbWFfZ2V0X3VubWFwcGVkX2FyZWEgLSBwcm9wb3NlIGFkZHJl c3MgZm9yIG1hcHBpbmcgaW4KPj4+IG5vTU1VIGNhc2VzCj4+PiBAQCAtNTAwLDMzICs0NDUsNiBA QCBkcm1fZ2VtX2NtYV9wcmltZV9pbXBvcnRfc2dfdGFibGUoc3RydWN0Cj4+PiBkcm1fZGV2aWNl ICpkZXYsCj4+PiDCoCB9Cj4+PiDCoCBFWFBPUlRfU1lNQk9MX0dQTChkcm1fZ2VtX2NtYV9wcmlt ZV9pbXBvcnRfc2dfdGFibGUpOwo+Pj4gwqAgLS8qKgo+Pj4gLSAqIGRybV9nZW1fY21hX3ByaW1l X21tYXAgLSBtZW1vcnktbWFwIGFuIGV4cG9ydGVkIENNQSBHRU0gb2JqZWN0Cj4+PiAtICogQG9i ajogR0VNIG9iamVjdAo+Pj4gLSAqIEB2bWE6IFZNQSBmb3IgdGhlIGFyZWEgdG8gYmUgbWFwcGVk Cj4+PiAtICoKPj4+IC0gKiBUaGlzIGZ1bmN0aW9uIG1hcHMgYSBidWZmZXIgaW1wb3J0ZWQgdmlh IERSTSBQUklNRSBpbnRvIGEgdXNlcnNwYWNlCj4+PiAtICogcHJvY2VzcydzIGFkZHJlc3Mgc3Bh Y2UuIERyaXZlcnMgdGhhdCB1c2UgdGhlIENNQSBoZWxwZXJzIHNob3VsZAo+Pj4gc2V0IHRoaXMK Pj4+IC0gKiBhcyB0aGVpciAmZHJtX2RyaXZlci5nZW1fcHJpbWVfbW1hcCBjYWxsYmFjay4KPj4+ IC0gKgo+Pj4gLSAqIFJldHVybnM6Cj4+PiAtICogMCBvbiBzdWNjZXNzIG9yIGEgbmVnYXRpdmUg ZXJyb3IgY29kZSBvbiBmYWlsdXJlLgo+Pj4gLSAqLwo+Pj4gLWludCBkcm1fZ2VtX2NtYV9wcmlt ZV9tbWFwKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqLAo+Pj4gLcKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCj4+PiAtewo+Pj4gLcKgwqDC oCBzdHJ1Y3QgZHJtX2dlbV9jbWFfb2JqZWN0ICpjbWFfb2JqOwo+Pj4gLcKgwqDCoCBpbnQgcmV0 Owo+Pj4gLQo+Pj4gLcKgwqDCoCByZXQgPSBkcm1fZ2VtX21tYXBfb2JqKG9iaiwgb2JqLT5zaXpl LCB2bWEpOwo+Pj4gLcKgwqDCoCBpZiAocmV0IDwgMCkKPj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1 cm4gcmV0Owo+Pj4gLQo+Pj4gLcKgwqDCoCBjbWFfb2JqID0gdG9fZHJtX2dlbV9jbWFfb2JqKG9i aik7Cj4+PiAtwqDCoMKgIHJldHVybiBkcm1fZ2VtX2NtYV9tbWFwX29iaihjbWFfb2JqLCB2bWEp Owo+Pj4gLX0KPj4+IC1FWFBPUlRfU1lNQk9MX0dQTChkcm1fZ2VtX2NtYV9wcmltZV9tbWFwKTsK Pj4+IC0KPj4+IMKgIC8qKgo+Pj4gwqDCoCAqIGRybV9nZW1fY21hX3ZtYXAgLSBtYXAgYSBDTUEg R0VNIG9iamVjdCBpbnRvIHRoZSBrZXJuZWwncyB2aXJ0dWFsCj4+PiDCoMKgICrCoMKgwqDCoCBh ZGRyZXNzIHNwYWNlCj4+PiBAQCAtNTUzLDYgKzQ3MSw0MyBAQCBpbnQgZHJtX2dlbV9jbWFfdm1h cChzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaiwKPj4+IHN0cnVjdCBkbWFfYnVmX21hcCAqbWFw KQo+Pj4gwqAgfQo+Pj4gwqAgRVhQT1JUX1NZTUJPTF9HUEwoZHJtX2dlbV9jbWFfdm1hcCk7Cj4+ PiDCoCArLyoqCj4+PiArICogZHJtX2dlbV9jbWFfbW1hcCAtIG1lbW9yeS1tYXAgYW4gZXhwb3J0 ZWQgQ01BIEdFTSBvYmplY3QKPj4+ICsgKiBAb2JqOiBHRU0gb2JqZWN0Cj4+PiArICogQHZtYTog Vk1BIGZvciB0aGUgYXJlYSB0byBiZSBtYXBwZWQKPj4+ICsgKgo+Pj4gKyAqIFRoaXMgZnVuY3Rp b24gbWFwcyBhIGJ1ZmZlciBpbnRvIGEgdXNlcnNwYWNlIHByb2Nlc3MncyBhZGRyZXNzCj4+PiBz cGFjZS4KPj4+ICsgKiBJbiBhZGRpdGlvbiB0byB0aGUgdXN1YWwgR0VNIFZNQSBzZXR1cCBpdCBp bW1lZGlhdGVseSBmYXVsdHMgaW4KPj4+IHRoZSBlbnRpcmUKPj4+ICsgKiBvYmplY3QgaW5zdGVh ZCBvZiB1c2luZyBvbi1kZW1hbmQgZmF1bHRpbmcuIERyaXZlcnMgdGhhdCB1c2UgdGhlIENNQQo+ Pj4gKyAqIGhlbHBlcnMgc2hvdWxkIHNldCB0aGlzIGFzIHRoZWlyICZkcm1fZ2VtX29iamVjdF9m dW5jcy5tbWFwCj4+PiBjYWxsYmFjay4KPj4+ICsgKgo+Pj4gKyAqIFJldHVybnM6Cj4+PiArICog MCBvbiBzdWNjZXNzIG9yIGEgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgo+Pj4gKyAq Lwo+Pj4gK2ludCBkcm1fZ2VtX2NtYV9tbWFwKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqLCBz dHJ1Y3QKPj4+IHZtX2FyZWFfc3RydWN0ICp2bWEpCj4+PiArewo+Pj4gK8KgwqDCoCBzdHJ1Y3Qg ZHJtX2dlbV9jbWFfb2JqZWN0ICpjbWFfb2JqOwo+Pj4gK8KgwqDCoCBpbnQgcmV0Owo+Pj4gKwo+ Pj4gK8KgwqDCoCAvKgo+Pj4gK8KgwqDCoMKgICogQ2xlYXIgdGhlIFZNX1BGTk1BUCBmbGFnIHRo YXQgd2FzIHNldCBieSBkcm1fZ2VtX21tYXAoKSwgYW5kCj4+PiBzZXQgdGhlCj4+PiArwqDCoMKg wqAgKiB2bV9wZ29mZiAodXNlZCBhcyBhIGZha2UgYnVmZmVyIG9mZnNldCBieSBEUk0pIHRvIDAg YXMgd2UKPj4+IHdhbnQgdG8gbWFwCj4+PiArwqDCoMKgwqAgKiB0aGUgd2hvbGUgYnVmZmVyLgo+ Pj4gK8KgwqDCoMKgICovCj4+PiArwqDCoMKgIHZtYS0+dm1fcGdvZmYgLT0gZHJtX3ZtYV9ub2Rl X3N0YXJ0KCZvYmotPnZtYV9ub2RlKTsKPj4+ICvCoMKgwqAgdm1hLT52bV9mbGFncyAmPSB+Vk1f UEZOTUFQOwo+Pj4gKwo+Pj4gK8KgwqDCoCBjbWFfb2JqID0gdG9fZHJtX2dlbV9jbWFfb2JqKG9i aik7Cj4+PiArCj4+PiArwqDCoMKgIHJldCA9IGRtYV9tbWFwX3djKGNtYV9vYmotPmJhc2UuZGV2 LT5kZXYsIHZtYSwgY21hX29iai0+dmFkZHIsCj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgY21hX29iai0+cGFkZHIsIHZtYS0+dm1fZW5kIC0gdm1hLT52bV9zdGFydCk7Cj4+PiArwqDC oMKgIGlmIChyZXQpCj4+PiArwqDCoMKgwqDCoMKgwqAgZHJtX2dlbV92bV9jbG9zZSh2bWEpOwo+ Pj4gKwo+Pj4gK8KgwqDCoCByZXR1cm4gcmV0Owo+Pj4gK30KPj4+ICtFWFBPUlRfU1lNQk9MX0dQ TChkcm1fZ2VtX2NtYV9tbWFwKTsKPj4+ICsKPj4+IMKgIC8qKgo+Pj4gwqDCoCAqIGRybV9nZW1f Y21hX3ByaW1lX2ltcG9ydF9zZ190YWJsZV92bWFwIC0gUFJJTUUgaW1wb3J0IGFub3RoZXIKPj4+ IGRyaXZlcidzCj4+PiDCoMKgICrCoMKgwqAgc2NhdHRlci9nYXRoZXIgdGFibGUgYW5kIGdldCB0 aGUgdmlydHVhbCBhZGRyZXNzIG9mIHRoZSBidWZmZXIKPj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vcGwxMTEvcGwxMTFfZHJ2LmMKPj4+IGIvZHJpdmVycy9ncHUvZHJtL3BsMTExL3Bs MTExX2Rydi5jCj4+PiBpbmRleCA0MGU2NzA4ZmJiZTIuLmU0ZGNhZWY2YzE0MyAxMDA2NDQKPj4+ IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9wbDExMS9wbDExMV9kcnYuYwo+Pj4gKysrIGIvZHJpdmVy cy9ncHUvZHJtL3BsMTExL3BsMTExX2Rydi5jCj4+PiBAQCAtMjI4LDcgKzIyOCw3IEBAIHN0YXRp YyBjb25zdCBzdHJ1Y3QgZHJtX2RyaXZlciBwbDExMV9kcm1fZHJpdmVyID0gewo+Pj4gwqDCoMKg wqDCoCAucHJpbWVfaGFuZGxlX3RvX2ZkID0gZHJtX2dlbV9wcmltZV9oYW5kbGVfdG9fZmQsCj4+ PiDCoMKgwqDCoMKgIC5wcmltZV9mZF90b19oYW5kbGUgPSBkcm1fZ2VtX3ByaW1lX2ZkX3RvX2hh bmRsZSwKPj4+IMKgwqDCoMKgwqAgLmdlbV9wcmltZV9pbXBvcnRfc2dfdGFibGUgPSBwbDExMV9n ZW1faW1wb3J0X3NnX3RhYmxlLAo+Pj4gLcKgwqDCoCAuZ2VtX3ByaW1lX21tYXAgPSBkcm1fZ2Vt X2NtYV9wcmltZV9tbWFwLAo+Pj4gK8KgwqDCoCAuZ2VtX3ByaW1lX21tYXAgPSBkcm1fZ2VtX3By aW1lX21tYXAsCj4+PiDCoCDCoCAjaWYgZGVmaW5lZChDT05GSUdfREVCVUdfRlMpCj4+PiDCoMKg wqDCoMKgIC5kZWJ1Z2ZzX2luaXQgPSBwbDExMV9kZWJ1Z2ZzX2luaXQsCj4+PiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfYm8uYyBiL2RyaXZlcnMvZ3B1L2RybS92YzQvdmM0 X2JvLmMKPj4+IGluZGV4IDgxM2U2Y2IzZjlhZi4uZGMzMTZjYjc5ZTAwIDEwMDY0NAo+Pj4gLS0t IGEvZHJpdmVycy9ncHUvZHJtL3ZjNC92YzRfYm8uYwo+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJt L3ZjNC92YzRfYm8uYwo+Pj4gQEAgLTc4Miw3ICs3ODIsNyBAQCBpbnQgdmM0X3ByaW1lX21tYXAo c3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmosCj4+PiBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZt YSkKPj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPj4+IMKgwqDCoMKgwqAg fQo+Pj4gwqAgLcKgwqDCoCByZXR1cm4gZHJtX2dlbV9jbWFfcHJpbWVfbW1hcChvYmosIHZtYSk7 Cj4+PiArwqDCoMKgIHJldHVybiBkcm1fZ2VtX3ByaW1lX21tYXAob2JqLCB2bWEpOwo+Pj4gwqAg fQo+Pj4gwqAgwqAgaW50IHZjNF9wcmltZV92bWFwKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2Jq LCBzdHJ1Y3QgZG1hX2J1Zl9tYXAKPj4+ICptYXApCj4+PiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9k cm0vZHJtX2dlbV9jbWFfaGVscGVyLmgKPj4+IGIvaW5jbHVkZS9kcm0vZHJtX2dlbV9jbWFfaGVs cGVyLmgKPj4+IGluZGV4IDQ2ODAyNzVhYjMzOS4uMGE5NzExY2FhM2U4IDEwMDY0NAo+Pj4gLS0t IGEvaW5jbHVkZS9kcm0vZHJtX2dlbV9jbWFfaGVscGVyLmgKPj4+ICsrKyBiL2luY2x1ZGUvZHJt L2RybV9nZW1fY21hX2hlbHBlci5oCj4+PiBAQCAtNTksNyArNTksNyBAQCBzdHJ1Y3QgZHJtX2dl bV9jbWFfb2JqZWN0IHsKPj4+IMKgwqDCoMKgwqDCoMKgwqDCoCAucG9sbMKgwqDCoMKgwqDCoMKg ID0gZHJtX3BvbGwsXAo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIC5yZWFkwqDCoMKgwqDCoMKgwqAg PSBkcm1fcmVhZCxcCj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgLmxsc2Vla8KgwqDCoMKgwqDCoMKg ID0gbm9vcF9sbHNlZWssXAo+Pj4gLcKgwqDCoMKgwqDCoMKgIC5tbWFwwqDCoMKgwqDCoMKgwqAg PSBkcm1fZ2VtX2NtYV9tbWFwLFwKPj4+ICvCoMKgwqDCoMKgwqDCoCAubW1hcMKgwqDCoMKgwqDC oMKgID0gZHJtX2dlbV9tbWFwLFwKPj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBEUk1fR0VNX0NNQV9V Tk1BUFBFRF9BUkVBX0ZPUFMgXAo+Pj4gwqDCoMKgwqDCoCB9Cj4+PiDCoCBAQCAtNzYsOSArNzYs NiBAQCBpbnQgZHJtX2dlbV9jbWFfZHVtYl9jcmVhdGUoc3RydWN0IGRybV9maWxlCj4+PiAqZmls ZV9wcml2LAo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3QgZHJt X2RldmljZSAqZHJtLAo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1 Y3QgZHJtX21vZGVfY3JlYXRlX2R1bWIgKmFyZ3MpOwo+Pj4gwqAgLS8qIHNldCB2bV9mbGFncyBh bmQgd2UgY2FuIGNoYW5nZSB0aGUgVk0gYXR0cmlidXRlIHRvIG90aGVyIG9uZSBhdAo+Pj4gaGVy ZSAqLwo+Pj4gLWludCBkcm1fZ2VtX2NtYV9tbWFwKHN0cnVjdCBmaWxlICpmaWxwLCBzdHJ1Y3Qg dm1fYXJlYV9zdHJ1Y3QgKnZtYSk7Cj4+PiAtCj4+PiDCoCAvKiBhbGxvY2F0ZSBwaHlzaWNhbCBt ZW1vcnkgKi8KPj4+IMKgIHN0cnVjdCBkcm1fZ2VtX2NtYV9vYmplY3QgKmRybV9nZW1fY21hX2Ny ZWF0ZShzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLAo+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHNpemVfdCBzaXplKTsKPj4+IEBAIC0xMDEs OSArOTgsOCBAQCBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKgo+Pj4gwqAgZHJtX2dlbV9jbWFfcHJp bWVfaW1wb3J0X3NnX3RhYmxlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4+PiDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICph dHRhY2gsCj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1Y3Qg c2dfdGFibGUgKnNndCk7Cj4+PiAtaW50IGRybV9nZW1fY21hX3ByaW1lX21tYXAoc3RydWN0IGRy bV9nZW1fb2JqZWN0ICpvYmosCj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzdHJ1 Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSk7Cj4+PiDCoCBpbnQgZHJtX2dlbV9jbWFfdm1hcChzdHJ1 Y3QgZHJtX2dlbV9vYmplY3QgKm9iaiwgc3RydWN0IGRtYV9idWZfbWFwCj4+PiAqbWFwKTsKPj4+ ICtpbnQgZHJtX2dlbV9jbWFfbW1hcChzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaiwgc3RydWN0 Cj4+PiB2bV9hcmVhX3N0cnVjdCAqdm1hKTsKPj4+IMKgIMKgIC8qKgo+Pj4gwqDCoCAqIERSTV9H RU1fQ01BX0RSSVZFUl9PUFNfV0lUSF9EVU1CX0NSRUFURSAtIENNQSBHRU0gZHJpdmVyIG9wZXJh dGlvbnMKPj4+IEBAIC0xMjMsNyArMTE5LDcgQEAgaW50IGRybV9nZW1fY21hX3ZtYXAoc3RydWN0 IGRybV9nZW1fb2JqZWN0ICpvYmosCj4+PiBzdHJ1Y3QgZG1hX2J1Zl9tYXAgKm1hcCk7Cj4+PiDC oMKgwqDCoMKgIC5wcmltZV9oYW5kbGVfdG9fZmTCoMKgwqAgPSBkcm1fZ2VtX3ByaW1lX2hhbmRs ZV90b19mZCwgXAo+Pj4gwqDCoMKgwqDCoCAucHJpbWVfZmRfdG9faGFuZGxlwqDCoMKgID0gZHJt X2dlbV9wcmltZV9mZF90b19oYW5kbGUsIFwKPj4+IMKgwqDCoMKgwqAgLmdlbV9wcmltZV9pbXBv cnRfc2dfdGFibGUgPSBkcm1fZ2VtX2NtYV9wcmltZV9pbXBvcnRfc2dfdGFibGUsIFwKPj4+IC3C oMKgwqAgLmdlbV9wcmltZV9tbWFwwqDCoMKgwqDCoMKgwqAgPSBkcm1fZ2VtX2NtYV9wcmltZV9t bWFwCj4+PiArwqDCoMKgIC5nZW1fcHJpbWVfbW1hcMKgwqDCoMKgwqDCoMKgID0gZHJtX2dlbV9w cmltZV9tbWFwCj4+PiDCoCDCoCAvKioKPj4+IMKgwqAgKiBEUk1fR0VNX0NNQV9EUklWRVJfT1BT IC0gQ01BIEdFTSBkcml2ZXIgb3BlcmF0aW9ucwo+Pj4KPj4KPj4gX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KPj4gZHJpLWRldmVsIG1haWxpbmcgbGlzdAo+ PiBkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCj4+IGh0dHBzOi8vbGlzdHMuZnJlZWRl c2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCj4+Cj4gCgpfX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0 CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3Rv cC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK