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=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 1B0BFC47089 for ; Thu, 27 May 2021 14:47:36 +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 D892160D07 for ; Thu, 27 May 2021 14:47:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D892160D07 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.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 8ABF86F388; Thu, 27 May 2021 14:47:32 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5817C6ED82; Thu, 27 May 2021 14:47:30 +0000 (UTC) IronPort-SDR: AfIe94mhxp6hLQ9EdgwFLB2wpNF4LpJ4oG/SDjgtPq914+SIxhZkJMKPZbDkVosZAHH5jEhhnJ AAlvKWxumpLg== X-IronPort-AV: E=McAfee;i="6200,9189,9996"; a="202515574" X-IronPort-AV: E=Sophos;i="5.82,334,1613462400"; d="scan'208";a="202515574" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 May 2021 07:47:29 -0700 IronPort-SDR: Wb39/iqavLYjX+SaZTYkjBqEhdVlzzuOZjq7Zx2rBGM7/lGVQGxSC49UrhEefXd+uID4mOXgpt lFlQl4Cq2pvQ== X-IronPort-AV: E=Sophos;i="5.82,334,1613462400"; d="scan'208";a="443597873" Received: from ibanaga-mobl.ger.corp.intel.com (HELO thellst-mobl1.intel.com) ([10.249.254.58]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 May 2021 07:47:27 -0700 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [PATCH v5 04/15] drm/i915/ttm Initialize the ttm device and memory managers Date: Thu, 27 May 2021 16:46:59 +0200 Message-Id: <20210527144710.1975553-5-thomas.hellstrom@linux.intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210527144710.1975553-1-thomas.hellstrom@linux.intel.com> References: <20210527144710.1975553-1-thomas.hellstrom@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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: , Cc: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , Matthew Auld Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Temporarily remove the buddy allocator and related selftests and hook up the TTM range manager for i915 regions. Also modify the mock region selftests somewhat to account for a fragmenting manager. Signed-off-by: Thomas Hellström Reviewed-by: Matthew Auld #v2 --- v2: - Fix an error unwind in lmem_get_pages() (Reported by Matthew Auld) - Break out and modify usage of i915_sg_dma_sizes() (Reported by Mattew Auld) - Break out TTM changes to a separate patch (Reported by Christian König) v3: - Fix the same error unwind in mock_region_get_pages() (Reported by Matthew Auld) - Don't rely on new TTM functionality, but create a mock TTM device, (Reported by Christian König) v4: - Use mock_gem_device rather than creating a separate ttm_device per region. --- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/gem/i915_gem_lmem.c | 59 +- .../gpu/drm/i915/gem/i915_gem_object_types.h | 6 +- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 3 +- drivers/gpu/drm/i915/gem/i915_gem_region.c | 120 --- drivers/gpu/drm/i915/gem/i915_gem_region.h | 4 - drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 4 +- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 10 +- drivers/gpu/drm/i915/gem/i915_gem_stolen.h | 9 +- drivers/gpu/drm/i915/gt/intel_gt.c | 2 - drivers/gpu/drm/i915/gt/intel_region_lmem.c | 27 +- drivers/gpu/drm/i915/i915_buddy.c | 435 ---------- drivers/gpu/drm/i915/i915_buddy.h | 131 --- drivers/gpu/drm/i915/i915_drv.c | 8 + drivers/gpu/drm/i915/i915_drv.h | 8 +- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_globals.c | 1 - drivers/gpu/drm/i915/i915_globals.h | 1 - drivers/gpu/drm/i915/i915_scatterlist.c | 70 ++ drivers/gpu/drm/i915/i915_scatterlist.h | 4 + drivers/gpu/drm/i915/intel_memory_region.c | 180 ++-- drivers/gpu/drm/i915/intel_memory_region.h | 44 +- drivers/gpu/drm/i915/intel_region_ttm.c | 220 +++++ drivers/gpu/drm/i915/intel_region_ttm.h | 32 + drivers/gpu/drm/i915/selftests/i915_buddy.c | 789 ------------------ .../drm/i915/selftests/i915_mock_selftests.h | 1 - .../drm/i915/selftests/intel_memory_region.c | 133 +-- .../gpu/drm/i915/selftests/mock_gem_device.c | 10 + drivers/gpu/drm/i915/selftests/mock_region.c | 70 +- 30 files changed, 631 insertions(+), 1754 deletions(-) delete mode 100644 drivers/gpu/drm/i915/i915_buddy.c delete mode 100644 drivers/gpu/drm/i915/i915_buddy.h create mode 100644 drivers/gpu/drm/i915/intel_region_ttm.c create mode 100644 drivers/gpu/drm/i915/intel_region_ttm.h delete mode 100644 drivers/gpu/drm/i915/selftests/i915_buddy.c diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 93f4d059fc89..61ff5c178714 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -27,6 +27,7 @@ config DRM_I915 select SND_HDA_I915 if SND_HDA_CORE select CEC_CORE if CEC_NOTIFIER select VMAP_PFN + select DRM_TTM help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 6947495bf34b..4f22cac1c49b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -50,6 +50,7 @@ i915-y += i915_drv.o \ intel_memory_region.o \ intel_pch.o \ intel_pm.o \ + intel_region_ttm.o \ intel_runtime_pm.o \ intel_sideband.o \ intel_step.o \ @@ -160,7 +161,6 @@ gem-y += \ i915-y += \ $(gem-y) \ i915_active.o \ - i915_buddy.o \ i915_cmd_parser.o \ i915_gem_evict.o \ i915_gem_gtt.o \ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c index f44bdd08f7cb..3b4aa28a076d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c @@ -4,16 +4,71 @@ */ #include "intel_memory_region.h" +#include "intel_region_ttm.h" #include "gem/i915_gem_region.h" #include "gem/i915_gem_lmem.h" #include "i915_drv.h" +static void lmem_put_pages(struct drm_i915_gem_object *obj, + struct sg_table *pages) +{ + intel_region_ttm_node_free(obj->mm.region, obj->mm.st_mm_node); + obj->mm.dirty = false; + sg_free_table(pages); + kfree(pages); +} + +static int lmem_get_pages(struct drm_i915_gem_object *obj) +{ + unsigned int flags; + struct sg_table *pages; + + flags = I915_ALLOC_MIN_PAGE_SIZE; + if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) + flags |= I915_ALLOC_CONTIGUOUS; + + obj->mm.st_mm_node = intel_region_ttm_node_alloc(obj->mm.region, + obj->base.size, + flags); + if (IS_ERR(obj->mm.st_mm_node)) + return PTR_ERR(obj->mm.st_mm_node); + + /* Range manager is always contigous */ + if (obj->mm.region->is_range_manager) + obj->flags |= I915_BO_ALLOC_CONTIGUOUS; + pages = intel_region_ttm_node_to_st(obj->mm.region, obj->mm.st_mm_node); + if (IS_ERR(pages)) { + intel_region_ttm_node_free(obj->mm.region, obj->mm.st_mm_node); + return PTR_ERR(pages); + } + + __i915_gem_object_set_pages(obj, pages, i915_sg_dma_sizes(pages->sgl)); + + if (obj->flags & I915_BO_ALLOC_CPU_CLEAR) { + void __iomem *vaddr = + i915_gem_object_lmem_io_map(obj, 0, obj->base.size); + + if (!vaddr) { + struct sg_table *pages = + __i915_gem_object_unset_pages(obj); + + if (!IS_ERR_OR_NULL(pages)) + lmem_put_pages(obj, pages); + } + + memset_io(vaddr, 0, obj->base.size); + io_mapping_unmap(vaddr); + } + + return 0; +} + const struct drm_i915_gem_object_ops i915_gem_lmem_obj_ops = { .name = "i915_gem_object_lmem", .flags = I915_GEM_OBJECT_HAS_IOMEM, - .get_pages = i915_gem_object_get_pages_buddy, - .put_pages = i915_gem_object_put_pages_buddy, + .get_pages = lmem_get_pages, + .put_pages = lmem_put_pages, .release = i915_gem_object_release_memory_region, }; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 0415f99b6b95..f5b46d11e6e6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -235,10 +235,12 @@ struct drm_i915_gem_object { * Memory region for this object. */ struct intel_memory_region *region; + /** - * List of memory region blocks allocated for this object. + * Memory manager node allocated for this object. */ - struct list_head blocks; + void *st_mm_node; + /** * Element within memory_region->objects or region->purgeable * if the object is marked as DONTNEED. Access is protected by diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 7361971c177d..6444e097016d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -475,7 +475,8 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *obj, might_sleep(); GEM_BUG_ON(n >= obj->base.size >> PAGE_SHIFT); - GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); + if (!i915_gem_object_has_pinned_pages(obj)) + assert_object_held(obj); /* As we iterate forward through the sg, we record each entry in a * radixtree for quick repeated (backwards) lookups. If we have seen diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c index ce8fcfc54079..f25e6646c5b7 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c @@ -8,129 +8,9 @@ #include "i915_drv.h" #include "i915_trace.h" -void -i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj, - struct sg_table *pages) -{ - __intel_memory_region_put_pages_buddy(obj->mm.region, &obj->mm.blocks); - - obj->mm.dirty = false; - sg_free_table(pages); - kfree(pages); -} - -int -i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj) -{ - const u64 max_segment = i915_sg_segment_size(); - struct intel_memory_region *mem = obj->mm.region; - struct list_head *blocks = &obj->mm.blocks; - resource_size_t size = obj->base.size; - resource_size_t prev_end; - struct i915_buddy_block *block; - unsigned int flags; - struct sg_table *st; - struct scatterlist *sg; - unsigned int sg_page_sizes; - int ret; - - st = kmalloc(sizeof(*st), GFP_KERNEL); - if (!st) - return -ENOMEM; - - if (sg_alloc_table(st, size >> PAGE_SHIFT, GFP_KERNEL)) { - kfree(st); - return -ENOMEM; - } - - flags = I915_ALLOC_MIN_PAGE_SIZE; - if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) - flags |= I915_ALLOC_CONTIGUOUS; - - ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks); - if (ret) - goto err_free_sg; - - GEM_BUG_ON(list_empty(blocks)); - - sg = st->sgl; - st->nents = 0; - sg_page_sizes = 0; - prev_end = (resource_size_t)-1; - - list_for_each_entry(block, blocks, link) { - u64 block_size, offset; - - block_size = min_t(u64, size, - i915_buddy_block_size(&mem->mm, block)); - offset = i915_buddy_block_offset(block); - - while (block_size) { - u64 len; - - if (offset != prev_end || sg->length >= max_segment) { - if (st->nents) { - sg_page_sizes |= sg->length; - sg = __sg_next(sg); - } - - sg_dma_address(sg) = mem->region.start + offset; - sg_dma_len(sg) = 0; - sg->length = 0; - st->nents++; - } - - len = min(block_size, max_segment - sg->length); - sg->length += len; - sg_dma_len(sg) += len; - - offset += len; - block_size -= len; - - prev_end = offset; - } - } - - sg_page_sizes |= sg->length; - sg_mark_end(sg); - i915_sg_trim(st); - - /* Intended for kernel internal use only */ - if (obj->flags & I915_BO_ALLOC_CPU_CLEAR) { - struct scatterlist *sg; - unsigned long i; - - for_each_sg(st->sgl, sg, st->nents, i) { - unsigned int length; - void __iomem *vaddr; - dma_addr_t daddr; - - daddr = sg_dma_address(sg); - daddr -= mem->region.start; - length = sg_dma_len(sg); - - vaddr = io_mapping_map_wc(&mem->iomap, daddr, length); - memset64((void __force *)vaddr, 0, length / sizeof(u64)); - io_mapping_unmap(vaddr); - } - - wmb(); - } - - __i915_gem_object_set_pages(obj, st, sg_page_sizes); - - return 0; - -err_free_sg: - sg_free_table(st); - kfree(st); - return ret; -} - void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj, struct intel_memory_region *mem) { - INIT_LIST_HEAD(&obj->mm.blocks); obj->mm.region = intel_memory_region_get(mem); if (obj->base.size <= mem->min_page_size) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.h b/drivers/gpu/drm/i915/gem/i915_gem_region.h index ebddc86d78f7..84fcb3297400 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_region.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_region.h @@ -12,10 +12,6 @@ struct intel_memory_region; struct drm_i915_gem_object; struct sg_table; -int i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj); -void i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj, - struct sg_table *pages); - void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj, struct intel_memory_region *mem); void i915_gem_object_release_memory_region(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index a9bfa66c8da1..5d16c4462fda 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -628,11 +628,13 @@ static const struct intel_memory_region_ops shmem_region_ops = { .init_object = shmem_object_init, }; -struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915) +struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915, + u16 type, u16 instance) { return intel_memory_region_create(i915, 0, totalram_pages() << PAGE_SHIFT, PAGE_SIZE, 0, + type, instance, &shmem_region_ops); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index b5553fc3ac4d..092d7a21de82 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -772,7 +772,8 @@ static const struct intel_memory_region_ops i915_region_stolen_lmem_ops = { }; struct intel_memory_region * -i915_gem_stolen_lmem_setup(struct drm_i915_private *i915) +i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, + u16 instance) { struct intel_uncore *uncore = &i915->uncore; struct pci_dev *pdev = to_pci_dev(i915->drm.dev); @@ -790,6 +791,7 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915) mem = intel_memory_region_create(i915, lmem_base, lmem_size, I915_GTT_PAGE_SIZE_4K, io_start, + type, instance, &i915_region_stolen_lmem_ops); if (IS_ERR(mem)) return mem; @@ -811,14 +813,15 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915) } struct intel_memory_region* -i915_gem_stolen_smem_setup(struct drm_i915_private *i915) +i915_gem_stolen_smem_setup(struct drm_i915_private *i915, u16 type, + u16 instance) { struct intel_memory_region *mem; mem = intel_memory_region_create(i915, intel_graphics_stolen_res.start, resource_size(&intel_graphics_stolen_res), - PAGE_SIZE, 0, + PAGE_SIZE, 0, type, instance, &i915_region_stolen_smem_ops); if (IS_ERR(mem)) return mem; @@ -826,7 +829,6 @@ i915_gem_stolen_smem_setup(struct drm_i915_private *i915) intel_memory_region_set_name(mem, "stolen-system"); mem->private = true; - return mem; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h index 2bec6c367b9c..ccdf7befc571 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.h @@ -21,8 +21,13 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv, u64 end); void i915_gem_stolen_remove_node(struct drm_i915_private *dev_priv, struct drm_mm_node *node); -struct intel_memory_region *i915_gem_stolen_smem_setup(struct drm_i915_private *i915); -struct intel_memory_region *i915_gem_stolen_lmem_setup(struct drm_i915_private *i915); +struct intel_memory_region * +i915_gem_stolen_smem_setup(struct drm_i915_private *i915, u16 type, + u16 instance); +struct intel_memory_region * +i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, + u16 instance); + struct drm_i915_gem_object * i915_gem_object_create_stolen(struct drm_i915_private *dev_priv, resource_size_t size); diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index 8d77dcbad059..3f88ecdee031 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -68,8 +68,6 @@ int intel_gt_probe_lmem(struct intel_gt *gt) id = INTEL_REGION_LMEM; mem->id = id; - mem->type = INTEL_MEMORY_LOCAL; - mem->instance = 0; intel_memory_region_set_name(mem, "local%u", mem->instance); diff --git a/drivers/gpu/drm/i915/gt/intel_region_lmem.c b/drivers/gpu/drm/i915/gt/intel_region_lmem.c index 73fceb0c25fc..f7366b054f8e 100644 --- a/drivers/gpu/drm/i915/gt/intel_region_lmem.c +++ b/drivers/gpu/drm/i915/gt/intel_region_lmem.c @@ -5,6 +5,8 @@ #include "i915_drv.h" #include "intel_memory_region.h" +#include "intel_region_lmem.h" +#include "intel_region_ttm.h" #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" #include "intel_region_lmem.h" @@ -66,9 +68,9 @@ static void release_fake_lmem_bar(struct intel_memory_region *mem) static void region_lmem_release(struct intel_memory_region *mem) { - release_fake_lmem_bar(mem); + intel_region_ttm_fini(mem); io_mapping_fini(&mem->iomap); - intel_memory_region_release_buddy(mem); + release_fake_lmem_bar(mem); } static int @@ -83,12 +85,21 @@ region_lmem_init(struct intel_memory_region *mem) if (!io_mapping_init_wc(&mem->iomap, mem->io_start, - resource_size(&mem->region))) - return -EIO; + resource_size(&mem->region))) { + ret = -EIO; + goto out_no_io; + } - ret = intel_memory_region_init_buddy(mem); + ret = intel_region_ttm_init(mem); if (ret) - io_mapping_fini(&mem->iomap); + goto out_no_buddy; + + return 0; + +out_no_buddy: + io_mapping_fini(&mem->iomap); +out_no_io: + release_fake_lmem_bar(mem); return ret; } @@ -127,6 +138,8 @@ intel_gt_setup_fake_lmem(struct intel_gt *gt) mappable_end, PAGE_SIZE, io_start, + INTEL_MEMORY_LOCAL, + 0, &intel_region_lmem_ops); if (!IS_ERR(mem)) { drm_info(&i915->drm, "Intel graphics fake LMEM: %pR\n", @@ -198,6 +211,8 @@ static struct intel_memory_region *setup_lmem(struct intel_gt *gt) lmem_size, I915_GTT_PAGE_SIZE_4K, io_start, + INTEL_MEMORY_LOCAL, + 0, &intel_region_lmem_ops); if (IS_ERR(mem)) return mem; diff --git a/drivers/gpu/drm/i915/i915_buddy.c b/drivers/gpu/drm/i915/i915_buddy.c deleted file mode 100644 index 3a2f6eecb2fc..000000000000 --- a/drivers/gpu/drm/i915/i915_buddy.c +++ /dev/null @@ -1,435 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2019 Intel Corporation - */ - -#include -#include - -#include "i915_buddy.h" - -#include "i915_gem.h" -#include "i915_globals.h" -#include "i915_utils.h" - -static struct i915_global_block { - struct i915_global base; - struct kmem_cache *slab_blocks; -} global; - -static void i915_global_buddy_shrink(void) -{ - kmem_cache_shrink(global.slab_blocks); -} - -static void i915_global_buddy_exit(void) -{ - kmem_cache_destroy(global.slab_blocks); -} - -static struct i915_global_block global = { { - .shrink = i915_global_buddy_shrink, - .exit = i915_global_buddy_exit, -} }; - -int __init i915_global_buddy_init(void) -{ - global.slab_blocks = KMEM_CACHE(i915_buddy_block, SLAB_HWCACHE_ALIGN); - if (!global.slab_blocks) - return -ENOMEM; - - i915_global_register(&global.base); - return 0; -} - -static struct i915_buddy_block *i915_block_alloc(struct i915_buddy_block *parent, - unsigned int order, - u64 offset) -{ - struct i915_buddy_block *block; - - GEM_BUG_ON(order > I915_BUDDY_MAX_ORDER); - - block = kmem_cache_zalloc(global.slab_blocks, GFP_KERNEL); - if (!block) - return NULL; - - block->header = offset; - block->header |= order; - block->parent = parent; - - GEM_BUG_ON(block->header & I915_BUDDY_HEADER_UNUSED); - return block; -} - -static void i915_block_free(struct i915_buddy_block *block) -{ - kmem_cache_free(global.slab_blocks, block); -} - -static void mark_allocated(struct i915_buddy_block *block) -{ - block->header &= ~I915_BUDDY_HEADER_STATE; - block->header |= I915_BUDDY_ALLOCATED; - - list_del(&block->link); -} - -static void mark_free(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - block->header &= ~I915_BUDDY_HEADER_STATE; - block->header |= I915_BUDDY_FREE; - - list_add(&block->link, - &mm->free_list[i915_buddy_block_order(block)]); -} - -static void mark_split(struct i915_buddy_block *block) -{ - block->header &= ~I915_BUDDY_HEADER_STATE; - block->header |= I915_BUDDY_SPLIT; - - list_del(&block->link); -} - -int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, u64 chunk_size) -{ - unsigned int i; - u64 offset; - - if (size < chunk_size) - return -EINVAL; - - if (chunk_size < PAGE_SIZE) - return -EINVAL; - - if (!is_power_of_2(chunk_size)) - return -EINVAL; - - size = round_down(size, chunk_size); - - mm->size = size; - mm->chunk_size = chunk_size; - mm->max_order = ilog2(size) - ilog2(chunk_size); - - GEM_BUG_ON(mm->max_order > I915_BUDDY_MAX_ORDER); - - mm->free_list = kmalloc_array(mm->max_order + 1, - sizeof(struct list_head), - GFP_KERNEL); - if (!mm->free_list) - return -ENOMEM; - - for (i = 0; i <= mm->max_order; ++i) - INIT_LIST_HEAD(&mm->free_list[i]); - - mm->n_roots = hweight64(size); - - mm->roots = kmalloc_array(mm->n_roots, - sizeof(struct i915_buddy_block *), - GFP_KERNEL); - if (!mm->roots) - goto out_free_list; - - offset = 0; - i = 0; - - /* - * Split into power-of-two blocks, in case we are given a size that is - * not itself a power-of-two. - */ - do { - struct i915_buddy_block *root; - unsigned int order; - u64 root_size; - - root_size = rounddown_pow_of_two(size); - order = ilog2(root_size) - ilog2(chunk_size); - - root = i915_block_alloc(NULL, order, offset); - if (!root) - goto out_free_roots; - - mark_free(mm, root); - - GEM_BUG_ON(i > mm->max_order); - GEM_BUG_ON(i915_buddy_block_size(mm, root) < chunk_size); - - mm->roots[i] = root; - - offset += root_size; - size -= root_size; - i++; - } while (size); - - return 0; - -out_free_roots: - while (i--) - i915_block_free(mm->roots[i]); - kfree(mm->roots); -out_free_list: - kfree(mm->free_list); - return -ENOMEM; -} - -void i915_buddy_fini(struct i915_buddy_mm *mm) -{ - int i; - - for (i = 0; i < mm->n_roots; ++i) { - GEM_WARN_ON(!i915_buddy_block_is_free(mm->roots[i])); - i915_block_free(mm->roots[i]); - } - - kfree(mm->roots); - kfree(mm->free_list); -} - -static int split_block(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - unsigned int block_order = i915_buddy_block_order(block) - 1; - u64 offset = i915_buddy_block_offset(block); - - GEM_BUG_ON(!i915_buddy_block_is_free(block)); - GEM_BUG_ON(!i915_buddy_block_order(block)); - - block->left = i915_block_alloc(block, block_order, offset); - if (!block->left) - return -ENOMEM; - - block->right = i915_block_alloc(block, block_order, - offset + (mm->chunk_size << block_order)); - if (!block->right) { - i915_block_free(block->left); - return -ENOMEM; - } - - mark_free(mm, block->left); - mark_free(mm, block->right); - - mark_split(block); - - return 0; -} - -static struct i915_buddy_block * -get_buddy(struct i915_buddy_block *block) -{ - struct i915_buddy_block *parent; - - parent = block->parent; - if (!parent) - return NULL; - - if (parent->left == block) - return parent->right; - - return parent->left; -} - -static void __i915_buddy_free(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - struct i915_buddy_block *parent; - - while ((parent = block->parent)) { - struct i915_buddy_block *buddy; - - buddy = get_buddy(block); - - if (!i915_buddy_block_is_free(buddy)) - break; - - list_del(&buddy->link); - - i915_block_free(block); - i915_block_free(buddy); - - block = parent; - } - - mark_free(mm, block); -} - -void i915_buddy_free(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - GEM_BUG_ON(!i915_buddy_block_is_allocated(block)); - __i915_buddy_free(mm, block); -} - -void i915_buddy_free_list(struct i915_buddy_mm *mm, struct list_head *objects) -{ - struct i915_buddy_block *block, *on; - - list_for_each_entry_safe(block, on, objects, link) { - i915_buddy_free(mm, block); - cond_resched(); - } - INIT_LIST_HEAD(objects); -} - -/* - * Allocate power-of-two block. The order value here translates to: - * - * 0 = 2^0 * mm->chunk_size - * 1 = 2^1 * mm->chunk_size - * 2 = 2^2 * mm->chunk_size - * ... - */ -struct i915_buddy_block * -i915_buddy_alloc(struct i915_buddy_mm *mm, unsigned int order) -{ - struct i915_buddy_block *block = NULL; - unsigned int i; - int err; - - for (i = order; i <= mm->max_order; ++i) { - block = list_first_entry_or_null(&mm->free_list[i], - struct i915_buddy_block, - link); - if (block) - break; - } - - if (!block) - return ERR_PTR(-ENOSPC); - - GEM_BUG_ON(!i915_buddy_block_is_free(block)); - - while (i != order) { - err = split_block(mm, block); - if (unlikely(err)) - goto out_free; - - /* Go low */ - block = block->left; - i--; - } - - mark_allocated(block); - kmemleak_update_trace(block); - return block; - -out_free: - if (i != order) - __i915_buddy_free(mm, block); - return ERR_PTR(err); -} - -static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2) -{ - return s1 <= e2 && e1 >= s2; -} - -static inline bool contains(u64 s1, u64 e1, u64 s2, u64 e2) -{ - return s1 <= s2 && e1 >= e2; -} - -/* - * Allocate range. Note that it's safe to chain together multiple alloc_ranges - * with the same blocks list. - * - * Intended for pre-allocating portions of the address space, for example to - * reserve a block for the initial framebuffer or similar, hence the expectation - * here is that i915_buddy_alloc() is still the main vehicle for - * allocations, so if that's not the case then the drm_mm range allocator is - * probably a much better fit, and so you should probably go use that instead. - */ -int i915_buddy_alloc_range(struct i915_buddy_mm *mm, - struct list_head *blocks, - u64 start, u64 size) -{ - struct i915_buddy_block *block; - struct i915_buddy_block *buddy; - LIST_HEAD(allocated); - LIST_HEAD(dfs); - u64 end; - int err; - int i; - - if (size < mm->chunk_size) - return -EINVAL; - - if (!IS_ALIGNED(size | start, mm->chunk_size)) - return -EINVAL; - - if (range_overflows(start, size, mm->size)) - return -EINVAL; - - for (i = 0; i < mm->n_roots; ++i) - list_add_tail(&mm->roots[i]->tmp_link, &dfs); - - end = start + size - 1; - - do { - u64 block_start; - u64 block_end; - - block = list_first_entry_or_null(&dfs, - struct i915_buddy_block, - tmp_link); - if (!block) - break; - - list_del(&block->tmp_link); - - block_start = i915_buddy_block_offset(block); - block_end = block_start + i915_buddy_block_size(mm, block) - 1; - - if (!overlaps(start, end, block_start, block_end)) - continue; - - if (i915_buddy_block_is_allocated(block)) { - err = -ENOSPC; - goto err_free; - } - - if (contains(start, end, block_start, block_end)) { - if (!i915_buddy_block_is_free(block)) { - err = -ENOSPC; - goto err_free; - } - - mark_allocated(block); - list_add_tail(&block->link, &allocated); - continue; - } - - if (!i915_buddy_block_is_split(block)) { - err = split_block(mm, block); - if (unlikely(err)) - goto err_undo; - } - - list_add(&block->right->tmp_link, &dfs); - list_add(&block->left->tmp_link, &dfs); - } while (1); - - list_splice_tail(&allocated, blocks); - return 0; - -err_undo: - /* - * We really don't want to leave around a bunch of split blocks, since - * bigger is better, so make sure we merge everything back before we - * free the allocated blocks. - */ - buddy = get_buddy(block); - if (buddy && - (i915_buddy_block_is_free(block) && - i915_buddy_block_is_free(buddy))) - __i915_buddy_free(mm, block); - -err_free: - i915_buddy_free_list(mm, &allocated); - return err; -} - -#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) -#include "selftests/i915_buddy.c" -#endif diff --git a/drivers/gpu/drm/i915/i915_buddy.h b/drivers/gpu/drm/i915/i915_buddy.h deleted file mode 100644 index 9ce5200f4001..000000000000 --- a/drivers/gpu/drm/i915/i915_buddy.h +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2019 Intel Corporation - */ - -#ifndef __I915_BUDDY_H__ -#define __I915_BUDDY_H__ - -#include -#include - -struct i915_buddy_block { -#define I915_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12) -#define I915_BUDDY_HEADER_STATE GENMASK_ULL(11, 10) -#define I915_BUDDY_ALLOCATED (1 << 10) -#define I915_BUDDY_FREE (2 << 10) -#define I915_BUDDY_SPLIT (3 << 10) -/* Free to be used, if needed in the future */ -#define I915_BUDDY_HEADER_UNUSED GENMASK_ULL(9, 6) -#define I915_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0) - u64 header; - - struct i915_buddy_block *left; - struct i915_buddy_block *right; - struct i915_buddy_block *parent; - - void *private; /* owned by creator */ - - /* - * While the block is allocated by the user through i915_buddy_alloc*, - * the user has ownership of the link, for example to maintain within - * a list, if so desired. As soon as the block is freed with - * i915_buddy_free* ownership is given back to the mm. - */ - struct list_head link; - struct list_head tmp_link; -}; - -/* Order-zero must be at least PAGE_SIZE */ -#define I915_BUDDY_MAX_ORDER (63 - PAGE_SHIFT) - -/* - * Binary Buddy System. - * - * Locking should be handled by the user, a simple mutex around - * i915_buddy_alloc* and i915_buddy_free* should suffice. - */ -struct i915_buddy_mm { - /* Maintain a free list for each order. */ - struct list_head *free_list; - - /* - * Maintain explicit binary tree(s) to track the allocation of the - * address space. This gives us a simple way of finding a buddy block - * and performing the potentially recursive merge step when freeing a - * block. Nodes are either allocated or free, in which case they will - * also exist on the respective free list. - */ - struct i915_buddy_block **roots; - - /* - * Anything from here is public, and remains static for the lifetime of - * the mm. Everything above is considered do-not-touch. - */ - unsigned int n_roots; - unsigned int max_order; - - /* Must be at least PAGE_SIZE */ - u64 chunk_size; - u64 size; -}; - -static inline u64 -i915_buddy_block_offset(struct i915_buddy_block *block) -{ - return block->header & I915_BUDDY_HEADER_OFFSET; -} - -static inline unsigned int -i915_buddy_block_order(struct i915_buddy_block *block) -{ - return block->header & I915_BUDDY_HEADER_ORDER; -} - -static inline unsigned int -i915_buddy_block_state(struct i915_buddy_block *block) -{ - return block->header & I915_BUDDY_HEADER_STATE; -} - -static inline bool -i915_buddy_block_is_allocated(struct i915_buddy_block *block) -{ - return i915_buddy_block_state(block) == I915_BUDDY_ALLOCATED; -} - -static inline bool -i915_buddy_block_is_free(struct i915_buddy_block *block) -{ - return i915_buddy_block_state(block) == I915_BUDDY_FREE; -} - -static inline bool -i915_buddy_block_is_split(struct i915_buddy_block *block) -{ - return i915_buddy_block_state(block) == I915_BUDDY_SPLIT; -} - -static inline u64 -i915_buddy_block_size(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - return mm->chunk_size << i915_buddy_block_order(block); -} - -int i915_buddy_init(struct i915_buddy_mm *mm, u64 size, u64 chunk_size); - -void i915_buddy_fini(struct i915_buddy_mm *mm); - -struct i915_buddy_block * -i915_buddy_alloc(struct i915_buddy_mm *mm, unsigned int order); - -int i915_buddy_alloc_range(struct i915_buddy_mm *mm, - struct list_head *blocks, - u64 start, u64 size); - -void i915_buddy_free(struct i915_buddy_mm *mm, struct i915_buddy_block *block); - -void i915_buddy_free_list(struct i915_buddy_mm *mm, struct list_head *objects); - -#endif diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d82a99e128cf..30c349137be2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -84,6 +84,7 @@ #include "intel_gvt.h" #include "intel_memory_region.h" #include "intel_pm.h" +#include "intel_region_ttm.h" #include "intel_sideband.h" #include "vlv_suspend.h" @@ -335,6 +336,10 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) if (ret < 0) goto err_workqueues; + ret = intel_region_ttm_device_init(dev_priv); + if (ret) + goto err_ttm; + intel_wopcm_init_early(&dev_priv->wopcm); intel_gt_init_early(&dev_priv->gt, dev_priv); @@ -359,6 +364,8 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) err_gem: i915_gem_cleanup_early(dev_priv); intel_gt_driver_late_release(&dev_priv->gt); + intel_region_ttm_device_fini(dev_priv); +err_ttm: vlv_suspend_cleanup(dev_priv); err_workqueues: i915_workqueues_cleanup(dev_priv); @@ -376,6 +383,7 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) intel_power_domains_cleanup(dev_priv); i915_gem_cleanup_early(dev_priv); intel_gt_driver_late_release(&dev_priv->gt); + intel_region_ttm_device_fini(dev_priv); vlv_suspend_cleanup(dev_priv); i915_workqueues_cleanup(dev_priv); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0f6d27da69ac..524aaeb0e842 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -59,6 +59,7 @@ #include #include #include +#include #include "i915_params.h" #include "i915_reg.h" @@ -778,6 +779,7 @@ struct intel_cdclk_config { struct i915_selftest_stash { atomic_t counter; + struct ida mock_region_instances; }; struct drm_i915_private { @@ -1170,6 +1172,9 @@ struct drm_i915_private { /* Mutex to protect the above hdcp component related values. */ struct mutex hdcp_comp_mutex; + /* The TTM device structure. */ + struct ttm_device bdev; + I915_SELFTEST_DECLARE(struct i915_selftest_stash selftest;) /* @@ -1763,7 +1768,8 @@ void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv); void i915_gem_init_early(struct drm_i915_private *dev_priv); void i915_gem_cleanup_early(struct drm_i915_private *dev_priv); -struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915); +struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915, + u16 type, u16 instance); static inline void i915_gem_drain_freed_objects(struct drm_i915_private *i915) { diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cffd7f4f87dc..0993d706f067 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1108,6 +1108,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv) } i915_gem_drain_freed_objects(dev_priv); + return ret; } diff --git a/drivers/gpu/drm/i915/i915_globals.c b/drivers/gpu/drm/i915/i915_globals.c index 3aa213684293..77f1911c463b 100644 --- a/drivers/gpu/drm/i915/i915_globals.c +++ b/drivers/gpu/drm/i915/i915_globals.c @@ -87,7 +87,6 @@ static void __i915_globals_cleanup(void) static __initconst int (* const initfn[])(void) = { i915_global_active_init, - i915_global_buddy_init, i915_global_context_init, i915_global_gem_context_init, i915_global_objects_init, diff --git a/drivers/gpu/drm/i915/i915_globals.h b/drivers/gpu/drm/i915/i915_globals.h index b2f5cd9b9b1a..2d199f411a4a 100644 --- a/drivers/gpu/drm/i915/i915_globals.h +++ b/drivers/gpu/drm/i915/i915_globals.h @@ -27,7 +27,6 @@ void i915_globals_exit(void); /* constructors */ int i915_global_active_init(void); -int i915_global_buddy_init(void); int i915_global_context_init(void); int i915_global_gem_context_init(void); int i915_global_objects_init(void); diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c index cc6b3846a8c7..69e9e6c3135e 100644 --- a/drivers/gpu/drm/i915/i915_scatterlist.c +++ b/drivers/gpu/drm/i915/i915_scatterlist.c @@ -6,6 +6,10 @@ #include "i915_scatterlist.h" +#include + +#include + bool i915_sg_trim(struct sg_table *orig_st) { struct sg_table new_st; @@ -34,6 +38,72 @@ bool i915_sg_trim(struct sg_table *orig_st) return true; } +/** + * i915_sg_from_mm_node - Create an sg_table from a struct drm_mm_node + * @node: The drm_mm_node. + * @region_start: An offset to add to the dma addresses of the sg list. + * + * Create a struct sg_table, initializing it from a struct drm_mm_node, + * taking a maximum segment length into account, splitting into segments + * if necessary. + * + * Return: A pointer to a kmalloced struct sg_table on success, negative + * error code cast to an error pointer on failure. + */ +struct sg_table *i915_sg_from_mm_node(const struct drm_mm_node *node, + u64 region_start) +{ + const u64 max_segment = SZ_1G; /* Do we have a limit on this? */ + u64 segment_pages = max_segment >> PAGE_SHIFT; + u64 block_size, offset, prev_end; + struct sg_table *st; + struct scatterlist *sg; + + st = kmalloc(sizeof(*st), GFP_KERNEL); + if (!st) + return ERR_PTR(-ENOMEM); + + if (sg_alloc_table(st, DIV_ROUND_UP(node->size, segment_pages), + GFP_KERNEL)) { + kfree(st); + return ERR_PTR(-ENOMEM); + } + + sg = st->sgl; + st->nents = 0; + prev_end = (resource_size_t)-1; + block_size = node->size << PAGE_SHIFT; + offset = node->start << PAGE_SHIFT; + + while (block_size) { + u64 len; + + if (offset != prev_end || sg->length >= max_segment) { + if (st->nents) + sg = __sg_next(sg); + + sg_dma_address(sg) = region_start + offset; + sg_dma_len(sg) = 0; + sg->length = 0; + st->nents++; + } + + len = min(block_size, max_segment - sg->length); + sg->length += len; + sg_dma_len(sg) += len; + + offset += len; + block_size -= len; + + prev_end = offset; + } + + sg_mark_end(sg); + i915_sg_trim(st); + + return st; +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/scatterlist.c" #endif diff --git a/drivers/gpu/drm/i915/i915_scatterlist.h b/drivers/gpu/drm/i915/i915_scatterlist.h index b96baad66a3a..5acca45ea981 100644 --- a/drivers/gpu/drm/i915/i915_scatterlist.h +++ b/drivers/gpu/drm/i915/i915_scatterlist.h @@ -13,6 +13,8 @@ #include "i915_gem.h" +struct drm_mm_node; + /* * Optimised SGL iterator for GEM objects */ @@ -141,4 +143,6 @@ static inline unsigned int i915_sg_segment_size(void) bool i915_sg_trim(struct sg_table *orig_st); +struct sg_table *i915_sg_from_mm_node(const struct drm_mm_node *node, + u64 region_start); #endif diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index d98e8b81d322..4092cc987679 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -28,6 +28,11 @@ static const struct { }, }; +struct intel_region_reserve { + struct list_head link; + void *node; +}; + struct intel_memory_region * intel_memory_region_lookup(struct drm_i915_private *i915, u16 class, u16 instance) @@ -58,146 +63,61 @@ intel_memory_region_by_type(struct drm_i915_private *i915, return NULL; } -static u64 -intel_memory_region_free_pages(struct intel_memory_region *mem, - struct list_head *blocks) +/** + * intel_memory_region_unreserve - Unreserve all previously reserved + * ranges + * @mem: The region containing the reserved ranges. + */ +void intel_memory_region_unreserve(struct intel_memory_region *mem) { - struct i915_buddy_block *block, *on; - u64 size = 0; + struct intel_region_reserve *reserve, *next; - list_for_each_entry_safe(block, on, blocks, link) { - size += i915_buddy_block_size(&mem->mm, block); - i915_buddy_free(&mem->mm, block); - } - INIT_LIST_HEAD(blocks); + if (!mem->priv_ops || !mem->priv_ops->free) + return; - return size; -} - -void -__intel_memory_region_put_pages_buddy(struct intel_memory_region *mem, - struct list_head *blocks) -{ mutex_lock(&mem->mm_lock); - mem->avail += intel_memory_region_free_pages(mem, blocks); - mutex_unlock(&mem->mm_lock); -} - -void -__intel_memory_region_put_block_buddy(struct i915_buddy_block *block) -{ - struct list_head blocks; - - INIT_LIST_HEAD(&blocks); - list_add(&block->link, &blocks); - __intel_memory_region_put_pages_buddy(block->private, &blocks); -} - -int -__intel_memory_region_get_pages_buddy(struct intel_memory_region *mem, - resource_size_t size, - unsigned int flags, - struct list_head *blocks) -{ - unsigned int min_order = 0; - unsigned long n_pages; - - GEM_BUG_ON(!IS_ALIGNED(size, mem->mm.chunk_size)); - GEM_BUG_ON(!list_empty(blocks)); - - if (flags & I915_ALLOC_MIN_PAGE_SIZE) { - min_order = ilog2(mem->min_page_size) - - ilog2(mem->mm.chunk_size); - } - - if (flags & I915_ALLOC_CONTIGUOUS) { - size = roundup_pow_of_two(size); - min_order = ilog2(size) - ilog2(mem->mm.chunk_size); + list_for_each_entry_safe(reserve, next, &mem->reserved, link) { + list_del(&reserve->link); + mem->priv_ops->free(mem, reserve->node); + kfree(reserve); } - - if (size > mem->mm.size) - return -E2BIG; - - n_pages = size >> ilog2(mem->mm.chunk_size); - - mutex_lock(&mem->mm_lock); - - do { - struct i915_buddy_block *block; - unsigned int order; - - order = fls(n_pages) - 1; - GEM_BUG_ON(order > mem->mm.max_order); - GEM_BUG_ON(order < min_order); - - do { - block = i915_buddy_alloc(&mem->mm, order); - if (!IS_ERR(block)) - break; - - if (order-- == min_order) - goto err_free_blocks; - } while (1); - - n_pages -= BIT(order); - - block->private = mem; - list_add_tail(&block->link, blocks); - - if (!n_pages) - break; - } while (1); - - mem->avail -= size; mutex_unlock(&mem->mm_lock); - return 0; - -err_free_blocks: - intel_memory_region_free_pages(mem, blocks); - mutex_unlock(&mem->mm_lock); - return -ENXIO; } -struct i915_buddy_block * -__intel_memory_region_get_block_buddy(struct intel_memory_region *mem, - resource_size_t size, - unsigned int flags) +/** + * intel_memory_region_reserve - Reserve a memory range + * @mem: The region for which we want to reserve a range. + * @offset: Start of the range to reserve. + * @size: The size of the range to reserve. + * + * Return: 0 on success, negative error code on failure. + */ +int intel_memory_region_reserve(struct intel_memory_region *mem, + resource_size_t offset, + resource_size_t size) { - struct i915_buddy_block *block; - LIST_HEAD(blocks); int ret; + struct intel_region_reserve *reserve; - ret = __intel_memory_region_get_pages_buddy(mem, size, flags, &blocks); - if (ret) - return ERR_PTR(ret); + if (!mem->priv_ops || !mem->priv_ops->reserve) + return -EINVAL; - block = list_first_entry(&blocks, typeof(*block), link); - list_del_init(&block->link); - return block; -} + reserve = kzalloc(sizeof(*reserve), GFP_KERNEL); + if (!reserve) + return -ENOMEM; -int intel_memory_region_init_buddy(struct intel_memory_region *mem) -{ - return i915_buddy_init(&mem->mm, resource_size(&mem->region), - PAGE_SIZE); -} - -void intel_memory_region_release_buddy(struct intel_memory_region *mem) -{ - i915_buddy_free_list(&mem->mm, &mem->reserved); - i915_buddy_fini(&mem->mm); -} - -int intel_memory_region_reserve(struct intel_memory_region *mem, - u64 offset, u64 size) -{ - int ret; + reserve->node = mem->priv_ops->reserve(mem, offset, size); + if (IS_ERR(reserve->node)) { + ret = PTR_ERR(reserve->node); + kfree(reserve); + return ret; + } mutex_lock(&mem->mm_lock); - ret = i915_buddy_alloc_range(&mem->mm, &mem->reserved, offset, size); + list_add_tail(&reserve->link, &mem->reserved); mutex_unlock(&mem->mm_lock); - return ret; + return 0; } struct intel_memory_region * @@ -206,6 +126,8 @@ intel_memory_region_create(struct drm_i915_private *i915, resource_size_t size, resource_size_t min_page_size, resource_size_t io_start, + u16 type, + u16 instance, const struct intel_memory_region_ops *ops) { struct intel_memory_region *mem; @@ -222,6 +144,8 @@ intel_memory_region_create(struct drm_i915_private *i915, mem->ops = ops; mem->total = size; mem->avail = mem->total; + mem->type = type; + mem->instance = instance; mutex_init(&mem->objects.lock); INIT_LIST_HEAD(&mem->objects.list); @@ -259,6 +183,7 @@ static void __intel_memory_region_destroy(struct kref *kref) struct intel_memory_region *mem = container_of(kref, typeof(*mem), kref); + intel_memory_region_unreserve(mem); if (mem->ops->release) mem->ops->release(mem); @@ -296,15 +221,15 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915) instance = intel_region_map[i].instance; switch (type) { case INTEL_MEMORY_SYSTEM: - mem = i915_gem_shmem_setup(i915); + mem = i915_gem_shmem_setup(i915, type, instance); break; case INTEL_MEMORY_STOLEN_LOCAL: - mem = i915_gem_stolen_lmem_setup(i915); + mem = i915_gem_stolen_lmem_setup(i915, type, instance); if (!IS_ERR(mem)) i915->mm.stolen_region = mem; break; case INTEL_MEMORY_STOLEN_SYSTEM: - mem = i915_gem_stolen_smem_setup(i915); + mem = i915_gem_stolen_smem_setup(i915, type, instance); if (!IS_ERR(mem)) i915->mm.stolen_region = mem; break; @@ -321,9 +246,6 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915) } mem->id = i; - mem->type = type; - mem->instance = instance; - i915->mm.regions[i] = mem; } diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h index d24ce5a0b30b..e69cde13daf2 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.h +++ b/drivers/gpu/drm/i915/intel_memory_region.h @@ -13,8 +13,6 @@ #include #include -#include "i915_buddy.h" - struct drm_i915_private; struct drm_i915_gem_object; struct intel_memory_region; @@ -25,6 +23,7 @@ enum intel_memory_type { INTEL_MEMORY_LOCAL = I915_MEMORY_CLASS_DEVICE, INTEL_MEMORY_STOLEN_SYSTEM, INTEL_MEMORY_STOLEN_LOCAL, + INTEL_MEMORY_MOCK, }; enum intel_region_id { @@ -59,10 +58,19 @@ struct intel_memory_region_ops { unsigned int flags); }; +struct intel_memory_region_private_ops { + void *(*reserve)(struct intel_memory_region *mem, + resource_size_t offset, + resource_size_t size); + void (*free)(struct intel_memory_region *mem, + void *node); +}; + struct intel_memory_region { struct drm_i915_private *i915; const struct intel_memory_region_ops *ops; + const struct intel_memory_region_private_ops *priv_ops; struct io_mapping iomap; struct resource region; @@ -70,7 +78,6 @@ struct intel_memory_region { /* For fake LMEM */ struct drm_mm_node fake_mappable; - struct i915_buddy_mm mm; struct mutex mm_lock; struct kref kref; @@ -95,36 +102,26 @@ struct intel_memory_region { struct list_head list; struct list_head purgeable; } objects; + + size_t chunk_size; + unsigned int max_order; + bool is_range_manager; + + void *region_private; }; struct intel_memory_region * intel_memory_region_lookup(struct drm_i915_private *i915, u16 class, u16 instance); -int intel_memory_region_init_buddy(struct intel_memory_region *mem); -void intel_memory_region_release_buddy(struct intel_memory_region *mem); - -int __intel_memory_region_get_pages_buddy(struct intel_memory_region *mem, - resource_size_t size, - unsigned int flags, - struct list_head *blocks); -struct i915_buddy_block * -__intel_memory_region_get_block_buddy(struct intel_memory_region *mem, - resource_size_t size, - unsigned int flags); -void __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem, - struct list_head *blocks); -void __intel_memory_region_put_block_buddy(struct i915_buddy_block *block); - -int intel_memory_region_reserve(struct intel_memory_region *mem, - u64 offset, u64 size); - struct intel_memory_region * intel_memory_region_create(struct drm_i915_private *i915, resource_size_t start, resource_size_t size, resource_size_t min_page_size, resource_size_t io_start, + u16 type, + u16 instance, const struct intel_memory_region_ops *ops); struct intel_memory_region * @@ -141,4 +138,9 @@ __printf(2, 3) void intel_memory_region_set_name(struct intel_memory_region *mem, const char *fmt, ...); +void intel_memory_region_unreserve(struct intel_memory_region *mem); + +int intel_memory_region_reserve(struct intel_memory_region *mem, + resource_size_t offset, + resource_size_t size); #endif diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c b/drivers/gpu/drm/i915/intel_region_ttm.c new file mode 100644 index 000000000000..c8ac118c21f6 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_region_ttm.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2021 Intel Corporation + */ +#include +#include + +#include "i915_drv.h" +#include "i915_scatterlist.h" + +#include "intel_region_ttm.h" + +/** + * DOC: TTM support structure + * + * The code in this file deals with setting up memory managers for TTM + * LMEM and MOCK regions and converting the output from + * the managers to struct sg_table, Basically providing the mapping from + * i915 GEM regions to TTM memory types and resource managers. + */ + +/* A Zero-initialized driver for now. We don't have a TTM backend yet. */ +static struct ttm_device_funcs i915_ttm_bo_driver; + +/** + * intel_region_ttm_device_init - Initialize a TTM device + * @dev_priv: Pointer to an i915 device private structure. + * + * Return: 0 on success, negative error code on failure. + */ +int intel_region_ttm_device_init(struct drm_i915_private *dev_priv) +{ + struct drm_device *drm = &dev_priv->drm; + + return ttm_device_init(&dev_priv->bdev, &i915_ttm_bo_driver, + drm->dev, drm->anon_inode->i_mapping, + drm->vma_offset_manager, false, false); +} + +/** + * intel_region_ttm_device_fini - Finalize a TTM device + * @dev_priv: Pointer to an i915 device private structure. + */ +void intel_region_ttm_device_fini(struct drm_i915_private *dev_priv) +{ + ttm_device_fini(&dev_priv->bdev); +} + +/* + * Map the i915 memory regions to TTM memory types. We use the + * driver-private types for now, reserving TTM_PL_VRAM for stolen + * memory and TTM_PL_TT for GGTT use if decided to implement this. + */ +static int intel_region_to_ttm_type(struct intel_memory_region *mem) +{ + int type; + + GEM_BUG_ON(mem->type != INTEL_MEMORY_LOCAL && + mem->type != INTEL_MEMORY_MOCK); + + type = mem->instance + TTM_PL_PRIV; + GEM_BUG_ON(type >= TTM_NUM_MEM_TYPES); + + return type; +} + +static void *intel_region_ttm_node_reserve(struct intel_memory_region *mem, + resource_size_t offset, + resource_size_t size) +{ + struct ttm_resource_manager *man = mem->region_private; + struct ttm_place place = {}; + struct ttm_resource res = {}; + struct ttm_buffer_object mock_bo = {}; + int ret; + + /* + * Having to use a mock_bo is unfortunate but stems from some + * drivers having private managers that insist to know what the + * allocate memory is intended for, using it to send private + * data to the manager. Also recently the bo has been used to send + * alignment info to the manager. Assume that apart from the latter, + * none of the managers we use will ever access the buffer object + * members, hoping we can pass the alignment info in the + * struct ttm_place in the future. + */ + + place.fpfn = offset >> PAGE_SHIFT; + place.lpfn = place.fpfn + (size >> PAGE_SHIFT); + res.num_pages = size >> PAGE_SHIFT; + ret = man->func->alloc(man, &mock_bo, &place, &res); + if (ret == -ENOSPC) + ret = -ENXIO; + + return ret ? ERR_PTR(ret) : res.mm_node; +} + +/** + * intel_region_ttm_node_free - Free a node allocated from a resource manager + * @mem: The region the node was allocated from. + * @node: The opaque node representing an allocation. + */ +void intel_region_ttm_node_free(struct intel_memory_region *mem, + void *node) +{ + struct ttm_resource_manager *man = mem->region_private; + struct ttm_resource res = {}; + + res.mm_node = node; + man->func->free(man, &res); +} + +static const struct intel_memory_region_private_ops priv_ops = { + .reserve = intel_region_ttm_node_reserve, + .free = intel_region_ttm_node_free, +}; + +int intel_region_ttm_init(struct intel_memory_region *mem) +{ + struct ttm_device *bdev = &mem->i915->bdev; + int mem_type = intel_region_to_ttm_type(mem); + int ret; + + ret = ttm_range_man_init(bdev, mem_type, false, + resource_size(&mem->region) >> PAGE_SHIFT); + if (ret) + return ret; + + mem->chunk_size = PAGE_SIZE; + mem->max_order = + get_order(rounddown_pow_of_two(resource_size(&mem->region))); + mem->is_range_manager = true; + mem->priv_ops = &priv_ops; + mem->region_private = ttm_manager_type(bdev, mem_type); + + return 0; +} + +/** + * intel_region_ttm_fini - Finalize a TTM region. + * @mem: The memory region + * + * This functions takes down the TTM resource manager associated with the + * memory region, and if it was registered with the TTM device, + * removes that registration. + */ +void intel_region_ttm_fini(struct intel_memory_region *mem) +{ + int ret; + + ret = ttm_range_man_fini(&mem->i915->bdev, + intel_region_to_ttm_type(mem)); + GEM_WARN_ON(ret); + mem->region_private = NULL; +} + +/** + * intel_region_ttm_node_to_st - Convert an opaque TTM resource manager node + * to an sg_table. + * @mem: The memory region. + * @node: The resource manager node obtained from the TTM resource manager. + * + * The gem backends typically use sg-tables for operations on the underlying + * io_memory. So provide a way for the backends to translate the + * nodes they are handed from TTM to sg-tables. + * + * Return: A malloced sg_table on success, an error pointer on failure. + */ +struct sg_table *intel_region_ttm_node_to_st(struct intel_memory_region *mem, + void *node) +{ + return i915_sg_from_mm_node(node, mem->region.start); +} + +/** + * intel_region_ttm_node_alloc - Allocate memory resources from a region + * @mem: The memory region, + * @size: The requested size in bytes + * @flags: Allocation flags + * + * This functionality is provided only for callers that need to allocate + * memory from standalone TTM range managers, without the TTM eviction + * functionality. Don't use if you are not completely sure that's the + * case. The returned opaque node can be converted to an sg_table using + * intel_region_ttm_node_to_st(), and can be freed using + * intel_region_ttm_node_free(). + * + * Return: A valid pointer on success, an error pointer on failure. + */ +void *intel_region_ttm_node_alloc(struct intel_memory_region *mem, + resource_size_t size, + unsigned int flags) +{ + struct ttm_resource_manager *man = mem->region_private; + struct ttm_place place = {}; + struct ttm_resource res = {}; + struct ttm_buffer_object mock_bo = {}; + int ret; + + /* + * We ignore the flags for now since we're using the range + * manager and contigous and min page size would be fulfilled + * by default if size is min page size aligned. + */ + res.num_pages = size >> PAGE_SHIFT; + + if (mem->is_range_manager) { + if (size >= SZ_1G) + mock_bo.page_alignment = SZ_1G >> PAGE_SHIFT; + else if (size >= SZ_2M) + mock_bo.page_alignment = SZ_2M >> PAGE_SHIFT; + else if (size >= SZ_64K) + mock_bo.page_alignment = SZ_64K >> PAGE_SHIFT; + } + + ret = man->func->alloc(man, &mock_bo, &place, &res); + if (ret == -ENOSPC) + ret = -ENXIO; + return ret ? ERR_PTR(ret) : res.mm_node; +} diff --git a/drivers/gpu/drm/i915/intel_region_ttm.h b/drivers/gpu/drm/i915/intel_region_ttm.h new file mode 100644 index 000000000000..1c82c6c3429d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_region_ttm.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2021 Intel Corporation + */ +#ifndef _INTEL_REGION_TTM_H_ +#define _INTEL_REGION_TTM_H_ + +#include + +#include "i915_selftest.h" + +struct drm_i915_private; +struct intel_memory_region; + +int intel_region_ttm_device_init(struct drm_i915_private *dev_priv); + +void intel_region_ttm_device_fini(struct drm_i915_private *dev_priv); + +int intel_region_ttm_init(struct intel_memory_region *mem); + +void intel_region_ttm_fini(struct intel_memory_region *mem); + +struct sg_table *intel_region_ttm_node_to_st(struct intel_memory_region *mem, + void *node); + +void *intel_region_ttm_node_alloc(struct intel_memory_region *mem, + resource_size_t size, + unsigned int flags); + +void intel_region_ttm_node_free(struct intel_memory_region *mem, + void *node); +#endif /* _INTEL_REGION_TTM_H_ */ diff --git a/drivers/gpu/drm/i915/selftests/i915_buddy.c b/drivers/gpu/drm/i915/selftests/i915_buddy.c deleted file mode 100644 index f0f5c4df8dbc..000000000000 --- a/drivers/gpu/drm/i915/selftests/i915_buddy.c +++ /dev/null @@ -1,789 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2019 Intel Corporation - */ - -#include - -#include "../i915_selftest.h" -#include "i915_random.h" - -static void __igt_dump_block(struct i915_buddy_mm *mm, - struct i915_buddy_block *block, - bool buddy) -{ - pr_err("block info: header=%llx, state=%u, order=%d, offset=%llx size=%llx root=%s buddy=%s\n", - block->header, - i915_buddy_block_state(block), - i915_buddy_block_order(block), - i915_buddy_block_offset(block), - i915_buddy_block_size(mm, block), - yesno(!block->parent), - yesno(buddy)); -} - -static void igt_dump_block(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - struct i915_buddy_block *buddy; - - __igt_dump_block(mm, block, false); - - buddy = get_buddy(block); - if (buddy) - __igt_dump_block(mm, buddy, true); -} - -static int igt_check_block(struct i915_buddy_mm *mm, - struct i915_buddy_block *block) -{ - struct i915_buddy_block *buddy; - unsigned int block_state; - u64 block_size; - u64 offset; - int err = 0; - - block_state = i915_buddy_block_state(block); - - if (block_state != I915_BUDDY_ALLOCATED && - block_state != I915_BUDDY_FREE && - block_state != I915_BUDDY_SPLIT) { - pr_err("block state mismatch\n"); - err = -EINVAL; - } - - block_size = i915_buddy_block_size(mm, block); - offset = i915_buddy_block_offset(block); - - if (block_size < mm->chunk_size) { - pr_err("block size smaller than min size\n"); - err = -EINVAL; - } - - if (!is_power_of_2(block_size)) { - pr_err("block size not power of two\n"); - err = -EINVAL; - } - - if (!IS_ALIGNED(block_size, mm->chunk_size)) { - pr_err("block size not aligned to min size\n"); - err = -EINVAL; - } - - if (!IS_ALIGNED(offset, mm->chunk_size)) { - pr_err("block offset not aligned to min size\n"); - err = -EINVAL; - } - - if (!IS_ALIGNED(offset, block_size)) { - pr_err("block offset not aligned to block size\n"); - err = -EINVAL; - } - - buddy = get_buddy(block); - - if (!buddy && block->parent) { - pr_err("buddy has gone fishing\n"); - err = -EINVAL; - } - - if (buddy) { - if (i915_buddy_block_offset(buddy) != (offset ^ block_size)) { - pr_err("buddy has wrong offset\n"); - err = -EINVAL; - } - - if (i915_buddy_block_size(mm, buddy) != block_size) { - pr_err("buddy size mismatch\n"); - err = -EINVAL; - } - - if (i915_buddy_block_state(buddy) == block_state && - block_state == I915_BUDDY_FREE) { - pr_err("block and its buddy are free\n"); - err = -EINVAL; - } - } - - return err; -} - -static int igt_check_blocks(struct i915_buddy_mm *mm, - struct list_head *blocks, - u64 expected_size, - bool is_contiguous) -{ - struct i915_buddy_block *block; - struct i915_buddy_block *prev; - u64 total; - int err = 0; - - block = NULL; - prev = NULL; - total = 0; - - list_for_each_entry(block, blocks, link) { - err = igt_check_block(mm, block); - - if (!i915_buddy_block_is_allocated(block)) { - pr_err("block not allocated\n"), - err = -EINVAL; - } - - if (is_contiguous && prev) { - u64 prev_block_size; - u64 prev_offset; - u64 offset; - - prev_offset = i915_buddy_block_offset(prev); - prev_block_size = i915_buddy_block_size(mm, prev); - offset = i915_buddy_block_offset(block); - - if (offset != (prev_offset + prev_block_size)) { - pr_err("block offset mismatch\n"); - err = -EINVAL; - } - } - - if (err) - break; - - total += i915_buddy_block_size(mm, block); - prev = block; - } - - if (!err) { - if (total != expected_size) { - pr_err("size mismatch, expected=%llx, found=%llx\n", - expected_size, total); - err = -EINVAL; - } - return err; - } - - if (prev) { - pr_err("prev block, dump:\n"); - igt_dump_block(mm, prev); - } - - if (block) { - pr_err("bad block, dump:\n"); - igt_dump_block(mm, block); - } - - return err; -} - -static int igt_check_mm(struct i915_buddy_mm *mm) -{ - struct i915_buddy_block *root; - struct i915_buddy_block *prev; - unsigned int i; - u64 total; - int err = 0; - - if (!mm->n_roots) { - pr_err("n_roots is zero\n"); - return -EINVAL; - } - - if (mm->n_roots != hweight64(mm->size)) { - pr_err("n_roots mismatch, n_roots=%u, expected=%lu\n", - mm->n_roots, hweight64(mm->size)); - return -EINVAL; - } - - root = NULL; - prev = NULL; - total = 0; - - for (i = 0; i < mm->n_roots; ++i) { - struct i915_buddy_block *block; - unsigned int order; - - root = mm->roots[i]; - if (!root) { - pr_err("root(%u) is NULL\n", i); - err = -EINVAL; - break; - } - - err = igt_check_block(mm, root); - - if (!i915_buddy_block_is_free(root)) { - pr_err("root not free\n"); - err = -EINVAL; - } - - order = i915_buddy_block_order(root); - - if (!i) { - if (order != mm->max_order) { - pr_err("max order root missing\n"); - err = -EINVAL; - } - } - - if (prev) { - u64 prev_block_size; - u64 prev_offset; - u64 offset; - - prev_offset = i915_buddy_block_offset(prev); - prev_block_size = i915_buddy_block_size(mm, prev); - offset = i915_buddy_block_offset(root); - - if (offset != (prev_offset + prev_block_size)) { - pr_err("root offset mismatch\n"); - err = -EINVAL; - } - } - - block = list_first_entry_or_null(&mm->free_list[order], - struct i915_buddy_block, - link); - if (block != root) { - pr_err("root mismatch at order=%u\n", order); - err = -EINVAL; - } - - if (err) - break; - - prev = root; - total += i915_buddy_block_size(mm, root); - } - - if (!err) { - if (total != mm->size) { - pr_err("expected mm size=%llx, found=%llx\n", mm->size, - total); - err = -EINVAL; - } - return err; - } - - if (prev) { - pr_err("prev root(%u), dump:\n", i - 1); - igt_dump_block(mm, prev); - } - - if (root) { - pr_err("bad root(%u), dump:\n", i); - igt_dump_block(mm, root); - } - - return err; -} - -static void igt_mm_config(u64 *size, u64 *chunk_size) -{ - I915_RND_STATE(prng); - u32 s, ms; - - /* Nothing fancy, just try to get an interesting bit pattern */ - - prandom_seed_state(&prng, i915_selftest.random_seed); - - /* Let size be a random number of pages up to 8 GB (2M pages) */ - s = 1 + i915_prandom_u32_max_state((BIT(33 - 12)) - 1, &prng); - /* Let the chunk size be a random power of 2 less than size */ - ms = BIT(i915_prandom_u32_max_state(ilog2(s), &prng)); - /* Round size down to the chunk size */ - s &= -ms; - - /* Convert from pages to bytes */ - *chunk_size = (u64)ms << 12; - *size = (u64)s << 12; -} - -static int igt_buddy_alloc_smoke(void *arg) -{ - struct i915_buddy_mm mm; - IGT_TIMEOUT(end_time); - I915_RND_STATE(prng); - u64 chunk_size; - u64 mm_size; - int *order; - int err, i; - - igt_mm_config(&mm_size, &chunk_size); - - pr_info("buddy_init with size=%llx, chunk_size=%llx\n", mm_size, chunk_size); - - err = i915_buddy_init(&mm, mm_size, chunk_size); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - - order = i915_random_order(mm.max_order + 1, &prng); - if (!order) - goto out_fini; - - for (i = 0; i <= mm.max_order; ++i) { - struct i915_buddy_block *block; - int max_order = order[i]; - bool timeout = false; - LIST_HEAD(blocks); - int order; - u64 total; - - err = igt_check_mm(&mm); - if (err) { - pr_err("pre-mm check failed, abort\n"); - break; - } - - pr_info("filling from max_order=%u\n", max_order); - - order = max_order; - total = 0; - - do { -retry: - block = i915_buddy_alloc(&mm, order); - if (IS_ERR(block)) { - err = PTR_ERR(block); - if (err == -ENOMEM) { - pr_info("buddy_alloc hit -ENOMEM with order=%d\n", - order); - } else { - if (order--) { - err = 0; - goto retry; - } - - pr_err("buddy_alloc with order=%d failed(%d)\n", - order, err); - } - - break; - } - - list_add_tail(&block->link, &blocks); - - if (i915_buddy_block_order(block) != order) { - pr_err("buddy_alloc order mismatch\n"); - err = -EINVAL; - break; - } - - total += i915_buddy_block_size(&mm, block); - - if (__igt_timeout(end_time, NULL)) { - timeout = true; - break; - } - } while (total < mm.size); - - if (!err) - err = igt_check_blocks(&mm, &blocks, total, false); - - i915_buddy_free_list(&mm, &blocks); - - if (!err) { - err = igt_check_mm(&mm); - if (err) - pr_err("post-mm check failed\n"); - } - - if (err || timeout) - break; - - cond_resched(); - } - - if (err == -ENOMEM) - err = 0; - - kfree(order); -out_fini: - i915_buddy_fini(&mm); - - return err; -} - -static int igt_buddy_alloc_pessimistic(void *arg) -{ - const unsigned int max_order = 16; - struct i915_buddy_block *block, *bn; - struct i915_buddy_mm mm; - unsigned int order; - LIST_HEAD(blocks); - int err; - - /* - * Create a pot-sized mm, then allocate one of each possible - * order within. This should leave the mm with exactly one - * page left. - */ - - err = i915_buddy_init(&mm, PAGE_SIZE << max_order, PAGE_SIZE); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - GEM_BUG_ON(mm.max_order != max_order); - - for (order = 0; order < max_order; order++) { - block = i915_buddy_alloc(&mm, order); - if (IS_ERR(block)) { - pr_info("buddy_alloc hit -ENOMEM with order=%d\n", - order); - err = PTR_ERR(block); - goto err; - } - - list_add_tail(&block->link, &blocks); - } - - /* And now the last remaining block available */ - block = i915_buddy_alloc(&mm, 0); - if (IS_ERR(block)) { - pr_info("buddy_alloc hit -ENOMEM on final alloc\n"); - err = PTR_ERR(block); - goto err; - } - list_add_tail(&block->link, &blocks); - - /* Should be completely full! */ - for (order = max_order; order--; ) { - block = i915_buddy_alloc(&mm, order); - if (!IS_ERR(block)) { - pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!", - order); - list_add_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - } - - block = list_last_entry(&blocks, typeof(*block), link); - list_del(&block->link); - i915_buddy_free(&mm, block); - - /* As we free in increasing size, we make available larger blocks */ - order = 1; - list_for_each_entry_safe(block, bn, &blocks, link) { - list_del(&block->link); - i915_buddy_free(&mm, block); - - block = i915_buddy_alloc(&mm, order); - if (IS_ERR(block)) { - pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n", - order); - err = PTR_ERR(block); - goto err; - } - i915_buddy_free(&mm, block); - order++; - } - - /* To confirm, now the whole mm should be available */ - block = i915_buddy_alloc(&mm, max_order); - if (IS_ERR(block)) { - pr_info("buddy_alloc (realloc) hit -ENOMEM with order=%d\n", - max_order); - err = PTR_ERR(block); - goto err; - } - i915_buddy_free(&mm, block); - -err: - i915_buddy_free_list(&mm, &blocks); - i915_buddy_fini(&mm); - return err; -} - -static int igt_buddy_alloc_optimistic(void *arg) -{ - const int max_order = 16; - struct i915_buddy_block *block; - struct i915_buddy_mm mm; - LIST_HEAD(blocks); - int order; - int err; - - /* - * Create a mm with one block of each order available, and - * try to allocate them all. - */ - - err = i915_buddy_init(&mm, - PAGE_SIZE * ((1 << (max_order + 1)) - 1), - PAGE_SIZE); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - GEM_BUG_ON(mm.max_order != max_order); - - for (order = 0; order <= max_order; order++) { - block = i915_buddy_alloc(&mm, order); - if (IS_ERR(block)) { - pr_info("buddy_alloc hit -ENOMEM with order=%d\n", - order); - err = PTR_ERR(block); - goto err; - } - - list_add_tail(&block->link, &blocks); - } - - /* Should be completely full! */ - block = i915_buddy_alloc(&mm, 0); - if (!IS_ERR(block)) { - pr_info("buddy_alloc unexpectedly succeeded, it should be full!"); - list_add_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - -err: - i915_buddy_free_list(&mm, &blocks); - i915_buddy_fini(&mm); - return err; -} - -static int igt_buddy_alloc_pathological(void *arg) -{ - const int max_order = 16; - struct i915_buddy_block *block; - struct i915_buddy_mm mm; - LIST_HEAD(blocks); - LIST_HEAD(holes); - int order, top; - int err; - - /* - * Create a pot-sized mm, then allocate one of each possible - * order within. This should leave the mm with exactly one - * page left. Free the largest block, then whittle down again. - * Eventually we will have a fully 50% fragmented mm. - */ - - err = i915_buddy_init(&mm, PAGE_SIZE << max_order, PAGE_SIZE); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - GEM_BUG_ON(mm.max_order != max_order); - - for (top = max_order; top; top--) { - /* Make room by freeing the largest allocated block */ - block = list_first_entry_or_null(&blocks, typeof(*block), link); - if (block) { - list_del(&block->link); - i915_buddy_free(&mm, block); - } - - for (order = top; order--; ) { - block = i915_buddy_alloc(&mm, order); - if (IS_ERR(block)) { - pr_info("buddy_alloc hit -ENOMEM with order=%d, top=%d\n", - order, top); - err = PTR_ERR(block); - goto err; - } - list_add_tail(&block->link, &blocks); - } - - /* There should be one final page for this sub-allocation */ - block = i915_buddy_alloc(&mm, 0); - if (IS_ERR(block)) { - pr_info("buddy_alloc hit -ENOMEM for hole\n"); - err = PTR_ERR(block); - goto err; - } - list_add_tail(&block->link, &holes); - - block = i915_buddy_alloc(&mm, top); - if (!IS_ERR(block)) { - pr_info("buddy_alloc unexpectedly succeeded at top-order %d/%d, it should be full!", - top, max_order); - list_add_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - } - - i915_buddy_free_list(&mm, &holes); - - /* Nothing larger than blocks of chunk_size now available */ - for (order = 1; order <= max_order; order++) { - block = i915_buddy_alloc(&mm, order); - if (!IS_ERR(block)) { - pr_info("buddy_alloc unexpectedly succeeded at order %d, it should be full!", - order); - list_add_tail(&block->link, &blocks); - err = -EINVAL; - goto err; - } - } - -err: - list_splice_tail(&holes, &blocks); - i915_buddy_free_list(&mm, &blocks); - i915_buddy_fini(&mm); - return err; -} - -static int igt_buddy_alloc_range(void *arg) -{ - struct i915_buddy_mm mm; - unsigned long page_num; - LIST_HEAD(blocks); - u64 chunk_size; - u64 offset; - u64 size; - u64 rem; - int err; - - igt_mm_config(&size, &chunk_size); - - pr_info("buddy_init with size=%llx, chunk_size=%llx\n", size, chunk_size); - - err = i915_buddy_init(&mm, size, chunk_size); - if (err) { - pr_err("buddy_init failed(%d)\n", err); - return err; - } - - err = igt_check_mm(&mm); - if (err) { - pr_err("pre-mm check failed, abort, abort, abort!\n"); - goto err_fini; - } - - rem = mm.size; - offset = 0; - - for_each_prime_number_from(page_num, 1, ULONG_MAX - 1) { - struct i915_buddy_block *block; - LIST_HEAD(tmp); - - size = min(page_num * mm.chunk_size, rem); - - err = i915_buddy_alloc_range(&mm, &tmp, offset, size); - if (err) { - if (err == -ENOMEM) { - pr_info("alloc_range hit -ENOMEM with size=%llx\n", - size); - } else { - pr_err("alloc_range with offset=%llx, size=%llx failed(%d)\n", - offset, size, err); - } - - break; - } - - block = list_first_entry_or_null(&tmp, - struct i915_buddy_block, - link); - if (!block) { - pr_err("alloc_range has no blocks\n"); - err = -EINVAL; - break; - } - - if (i915_buddy_block_offset(block) != offset) { - pr_err("alloc_range start offset mismatch, found=%llx, expected=%llx\n", - i915_buddy_block_offset(block), offset); - err = -EINVAL; - } - - if (!err) - err = igt_check_blocks(&mm, &tmp, size, true); - - list_splice_tail(&tmp, &blocks); - - if (err) - break; - - offset += size; - - rem -= size; - if (!rem) - break; - - cond_resched(); - } - - if (err == -ENOMEM) - err = 0; - - i915_buddy_free_list(&mm, &blocks); - - if (!err) { - err = igt_check_mm(&mm); - if (err) - pr_err("post-mm check failed\n"); - } - -err_fini: - i915_buddy_fini(&mm); - - return err; -} - -static int igt_buddy_alloc_limit(void *arg) -{ - struct i915_buddy_block *block; - struct i915_buddy_mm mm; - const u64 size = U64_MAX; - int err; - - err = i915_buddy_init(&mm, size, PAGE_SIZE); - if (err) - return err; - - if (mm.max_order != I915_BUDDY_MAX_ORDER) { - pr_err("mm.max_order(%d) != %d\n", - mm.max_order, I915_BUDDY_MAX_ORDER); - err = -EINVAL; - goto out_fini; - } - - block = i915_buddy_alloc(&mm, mm.max_order); - if (IS_ERR(block)) { - err = PTR_ERR(block); - goto out_fini; - } - - if (i915_buddy_block_order(block) != mm.max_order) { - pr_err("block order(%d) != %d\n", - i915_buddy_block_order(block), mm.max_order); - err = -EINVAL; - goto out_free; - } - - if (i915_buddy_block_size(&mm, block) != - BIT_ULL(mm.max_order) * PAGE_SIZE) { - pr_err("block size(%llu) != %llu\n", - i915_buddy_block_size(&mm, block), - BIT_ULL(mm.max_order) * PAGE_SIZE); - err = -EINVAL; - goto out_free; - } - -out_free: - i915_buddy_free(&mm, block); -out_fini: - i915_buddy_fini(&mm); - return err; -} - -int i915_buddy_mock_selftests(void) -{ - static const struct i915_subtest tests[] = { - SUBTEST(igt_buddy_alloc_pessimistic), - SUBTEST(igt_buddy_alloc_optimistic), - SUBTEST(igt_buddy_alloc_pathological), - SUBTEST(igt_buddy_alloc_smoke), - SUBTEST(igt_buddy_alloc_range), - SUBTEST(igt_buddy_alloc_limit), - }; - - return i915_subtests(tests, NULL); -} diff --git a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h index 3db34d3eea58..34e5caf38093 100644 --- a/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_mock_selftests.h @@ -33,5 +33,4 @@ selftest(evict, i915_gem_evict_mock_selftests) selftest(gtt, i915_gem_gtt_mock_selftests) selftest(hugepages, i915_gem_huge_page_mock_selftests) selftest(contexts, i915_gem_context_mock_selftests) -selftest(buddy, i915_buddy_mock_selftests) selftest(memory_region, intel_memory_region_mock_selftests) diff --git a/drivers/gpu/drm/i915/selftests/intel_memory_region.c b/drivers/gpu/drm/i915/selftests/intel_memory_region.c index f85fd8cbfbf5..c85d516b85cd 100644 --- a/drivers/gpu/drm/i915/selftests/intel_memory_region.c +++ b/drivers/gpu/drm/i915/selftests/intel_memory_region.c @@ -57,9 +57,10 @@ static int igt_mock_fill(void *arg) LIST_HEAD(objects); int err = 0; - page_size = mem->mm.chunk_size; - max_pages = div64_u64(total, page_size); + page_size = mem->chunk_size; rem = total; +retry: + max_pages = div64_u64(rem, page_size); for_each_prime_number_from(page_num, 1, max_pages) { resource_size_t size = page_num * page_size; @@ -85,6 +86,11 @@ static int igt_mock_fill(void *arg) err = 0; if (err == -ENXIO) { if (page_num * page_size <= rem) { + if (mem->is_range_manager && max_pages > 1) { + max_pages >>= 1; + goto retry; + } + pr_err("%s failed, space still left in region\n", __func__); err = -EINVAL; @@ -199,12 +205,18 @@ static int igt_mock_reserve(void *arg) do { u32 size = i915_prandom_u32_max_state(cur_avail, &prng); +retry: size = max_t(u32, round_up(size, PAGE_SIZE), PAGE_SIZE); obj = igt_object_create(mem, &objects, size, 0); if (IS_ERR(obj)) { - if (PTR_ERR(obj) == -ENXIO) + if (PTR_ERR(obj) == -ENXIO) { + if (mem->is_range_manager && + size > mem->chunk_size) { + size >>= 1; + goto retry; + } break; - + } err = PTR_ERR(obj); goto out_close; } @@ -220,7 +232,7 @@ static int igt_mock_reserve(void *arg) out_close: kfree(order); close_objects(mem, &objects); - i915_buddy_free_list(&mem->mm, &mem->reserved); + intel_memory_region_unreserve(mem); return err; } @@ -240,7 +252,7 @@ static int igt_mock_contiguous(void *arg) total = resource_size(&mem->region); /* Min size */ - obj = igt_object_create(mem, &objects, mem->mm.chunk_size, + obj = igt_object_create(mem, &objects, mem->chunk_size, I915_BO_ALLOC_CONTIGUOUS); if (IS_ERR(obj)) return PTR_ERR(obj); @@ -321,14 +333,16 @@ static int igt_mock_contiguous(void *arg) min = target; target = total >> 1; - /* Make sure we can still allocate all the fragmented space */ - obj = igt_object_create(mem, &objects, target, 0); - if (IS_ERR(obj)) { - err = PTR_ERR(obj); - goto err_close_objects; - } + if (!mem->is_range_manager) { + /* Make sure we can still allocate all the fragmented space */ + obj = igt_object_create(mem, &objects, target, 0); + if (IS_ERR(obj)) { + err = PTR_ERR(obj); + goto err_close_objects; + } - igt_object_release(obj); + igt_object_release(obj); + } /* * Even though we have enough free space, we don't have a big enough @@ -348,7 +362,7 @@ static int igt_mock_contiguous(void *arg) } target >>= 1; - } while (target >= mem->mm.chunk_size); + } while (target >= mem->chunk_size); err_close_objects: list_splice_tail(&holes, &objects); @@ -368,7 +382,7 @@ static int igt_mock_splintered_region(void *arg) /* * Sanity check we can still allocate everything even if the - * mm.max_order != mm.size. i.e our starting address space size is not a + * max_order != mm.size. i.e our starting address space size is not a * power-of-two. */ @@ -377,17 +391,10 @@ static int igt_mock_splintered_region(void *arg) if (IS_ERR(mem)) return PTR_ERR(mem); - if (mem->mm.size != size) { - pr_err("%s size mismatch(%llu != %llu)\n", - __func__, mem->mm.size, size); - err = -EINVAL; - goto out_put; - } - expected_order = get_order(rounddown_pow_of_two(size)); - if (mem->mm.max_order != expected_order) { + if (mem->max_order != expected_order) { pr_err("%s order mismatch(%u != %u)\n", - __func__, mem->mm.max_order, expected_order); + __func__, mem->max_order, expected_order); err = -EINVAL; goto out_put; } @@ -408,12 +415,15 @@ static int igt_mock_splintered_region(void *arg) * sure that does indeed hold true. */ - obj = igt_object_create(mem, &objects, size, I915_BO_ALLOC_CONTIGUOUS); - if (!IS_ERR(obj)) { - pr_err("%s too large contiguous allocation was not rejected\n", - __func__); - err = -EINVAL; - goto out_close; + if (!mem->is_range_manager) { + obj = igt_object_create(mem, &objects, size, + I915_BO_ALLOC_CONTIGUOUS); + if (!IS_ERR(obj)) { + pr_err("%s too large contiguous allocation was not rejected\n", + __func__); + err = -EINVAL; + goto out_close; + } } obj = igt_object_create(mem, &objects, rounddown_pow_of_two(size), @@ -432,68 +442,6 @@ static int igt_mock_splintered_region(void *arg) return err; } -#ifndef SZ_8G -#define SZ_8G BIT_ULL(33) -#endif - -static int igt_mock_max_segment(void *arg) -{ - const unsigned int max_segment = i915_sg_segment_size(); - struct intel_memory_region *mem = arg; - struct drm_i915_private *i915 = mem->i915; - struct drm_i915_gem_object *obj; - struct i915_buddy_block *block; - struct scatterlist *sg; - LIST_HEAD(objects); - u64 size; - int err = 0; - - /* - * While we may create very large contiguous blocks, we may need - * to break those down for consumption elsewhere. In particular, - * dma-mapping with scatterlist elements have an implicit limit of - * UINT_MAX on each element. - */ - - size = SZ_8G; - mem = mock_region_create(i915, 0, size, PAGE_SIZE, 0); - if (IS_ERR(mem)) - return PTR_ERR(mem); - - obj = igt_object_create(mem, &objects, size, 0); - if (IS_ERR(obj)) { - err = PTR_ERR(obj); - goto out_put; - } - - size = 0; - list_for_each_entry(block, &obj->mm.blocks, link) { - if (i915_buddy_block_size(&mem->mm, block) > size) - size = i915_buddy_block_size(&mem->mm, block); - } - if (size < max_segment) { - pr_err("%s: Failed to create a huge contiguous block [> %u], largest block %lld\n", - __func__, max_segment, size); - err = -EINVAL; - goto out_close; - } - - for (sg = obj->mm.pages->sgl; sg; sg = sg_next(sg)) { - if (sg->length > max_segment) { - pr_err("%s: Created an oversized scatterlist entry, %u > %u\n", - __func__, sg->length, max_segment); - err = -EINVAL; - goto out_close; - } - } - -out_close: - close_objects(mem, &objects); -out_put: - intel_memory_region_put(mem); - return err; -} - static int igt_gpu_write_dw(struct intel_context *ce, struct i915_vma *vma, u32 dword, @@ -1098,7 +1046,6 @@ int intel_memory_region_mock_selftests(void) SUBTEST(igt_mock_fill), SUBTEST(igt_mock_contiguous), SUBTEST(igt_mock_splintered_region), - SUBTEST(igt_mock_max_segment), }; struct intel_memory_region *mem; struct drm_i915_private *i915; diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index cf40004bc92a..d189c4bd4bef 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -32,6 +32,7 @@ #include "gt/intel_gt_requests.h" #include "gt/mock_engine.h" #include "intel_memory_region.h" +#include "intel_region_ttm.h" #include "mock_request.h" #include "mock_gem_device.h" @@ -70,6 +71,7 @@ static void mock_device_release(struct drm_device *dev) mock_fini_ggtt(&i915->ggtt); destroy_workqueue(i915->wq); + intel_region_ttm_device_fini(i915); intel_gt_driver_late_release(&i915->gt); intel_memory_regions_driver_release(i915); @@ -116,6 +118,7 @@ struct drm_i915_private *mock_gem_device(void) #endif struct drm_i915_private *i915; struct pci_dev *pdev; + int ret; pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); if (!pdev) @@ -178,6 +181,10 @@ struct drm_i915_private *mock_gem_device(void) atomic_inc(&i915->gt.wakeref.count); /* disable; no hw support */ i915->gt.awake = -ENODEV; + ret = intel_region_ttm_device_init(i915); + if (ret) + goto err_ttm; + i915->wq = alloc_ordered_workqueue("mock", 0); if (!i915->wq) goto err_drv; @@ -201,6 +208,7 @@ struct drm_i915_private *mock_gem_device(void) intel_engines_driver_register(i915); i915->do_release = true; + ida_init(&i915->selftest.mock_region_instances); return i915; @@ -209,6 +217,8 @@ struct drm_i915_private *mock_gem_device(void) err_unlock: destroy_workqueue(i915->wq); err_drv: + intel_region_ttm_device_fini(i915); +err_ttm: intel_gt_driver_late_release(&i915->gt); intel_memory_regions_driver_release(i915); drm_mode_config_cleanup(&i915->drm); diff --git a/drivers/gpu/drm/i915/selftests/mock_region.c b/drivers/gpu/drm/i915/selftests/mock_region.c index 5d2d010a1e22..eafc5a04975c 100644 --- a/drivers/gpu/drm/i915/selftests/mock_region.c +++ b/drivers/gpu/drm/i915/selftests/mock_region.c @@ -1,17 +1,56 @@ // SPDX-License-Identifier: MIT /* - * Copyright © 2019 Intel Corporation + * Copyright © 2019-2021 Intel Corporation */ +#include + +#include + #include "gem/i915_gem_region.h" #include "intel_memory_region.h" +#include "intel_region_ttm.h" #include "mock_region.h" +static void mock_region_put_pages(struct drm_i915_gem_object *obj, + struct sg_table *pages) +{ + intel_region_ttm_node_free(obj->mm.region, obj->mm.st_mm_node); + sg_free_table(pages); + kfree(pages); +} + +static int mock_region_get_pages(struct drm_i915_gem_object *obj) +{ + unsigned int flags; + struct sg_table *pages; + + flags = I915_ALLOC_MIN_PAGE_SIZE; + if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) + flags |= I915_ALLOC_CONTIGUOUS; + + obj->mm.st_mm_node = intel_region_ttm_node_alloc(obj->mm.region, + obj->base.size, + flags); + if (IS_ERR(obj->mm.st_mm_node)) + return PTR_ERR(obj->mm.st_mm_node); + + pages = intel_region_ttm_node_to_st(obj->mm.region, obj->mm.st_mm_node); + if (IS_ERR(pages)) { + intel_region_ttm_node_free(obj->mm.region, obj->mm.st_mm_node); + return PTR_ERR(pages); + } + + __i915_gem_object_set_pages(obj, pages, i915_sg_dma_sizes(pages->sgl)); + + return 0; +} + static const struct drm_i915_gem_object_ops mock_region_obj_ops = { .name = "mock-region", - .get_pages = i915_gem_object_get_pages_buddy, - .put_pages = i915_gem_object_put_pages_buddy, + .get_pages = mock_region_get_pages, + .put_pages = mock_region_put_pages, .release = i915_gem_object_release_memory_region, }; @@ -23,7 +62,7 @@ static int mock_object_init(struct intel_memory_region *mem, static struct lock_class_key lock_class; struct drm_i915_private *i915 = mem->i915; - if (size > mem->mm.size) + if (size > resource_size(&mem->region)) return -E2BIG; drm_gem_private_object_init(&i915->drm, &obj->base, size); @@ -38,9 +77,18 @@ static int mock_object_init(struct intel_memory_region *mem, return 0; } +static void mock_region_fini(struct intel_memory_region *mem) +{ + struct drm_i915_private *i915 = mem->i915; + int instance = mem->instance; + + intel_region_ttm_fini(mem); + ida_free(&i915->selftest.mock_region_instances, instance); +} + static const struct intel_memory_region_ops mock_region_ops = { - .init = intel_memory_region_init_buddy, - .release = intel_memory_region_release_buddy, + .init = intel_region_ttm_init, + .release = mock_region_fini, .init_object = mock_object_init, }; @@ -51,6 +99,14 @@ mock_region_create(struct drm_i915_private *i915, resource_size_t min_page_size, resource_size_t io_start) { + int instance = ida_alloc_max(&i915->selftest.mock_region_instances, + TTM_NUM_MEM_TYPES - TTM_PL_PRIV - 1, + GFP_KERNEL); + + if (instance < 0) + return ERR_PTR(instance); + return intel_memory_region_create(i915, start, size, min_page_size, - io_start, &mock_region_ops); + io_start, INTEL_MEMORY_MOCK, instance, + &mock_region_ops); } -- 2.31.1 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=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 E31ECC4708B for ; Thu, 27 May 2021 14:47:38 +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 9110660D07 for ; Thu, 27 May 2021 14:47:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9110660D07 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E6E2A6F3C9; Thu, 27 May 2021 14:47:34 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5817C6ED82; Thu, 27 May 2021 14:47:30 +0000 (UTC) IronPort-SDR: AfIe94mhxp6hLQ9EdgwFLB2wpNF4LpJ4oG/SDjgtPq914+SIxhZkJMKPZbDkVosZAHH5jEhhnJ AAlvKWxumpLg== X-IronPort-AV: E=McAfee;i="6200,9189,9996"; a="202515574" X-IronPort-AV: E=Sophos;i="5.82,334,1613462400"; d="scan'208";a="202515574" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 May 2021 07:47:29 -0700 IronPort-SDR: Wb39/iqavLYjX+SaZTYkjBqEhdVlzzuOZjq7Zx2rBGM7/lGVQGxSC49UrhEefXd+uID4mOXgpt lFlQl4Cq2pvQ== X-IronPort-AV: E=Sophos;i="5.82,334,1613462400"; d="scan'208";a="443597873" Received: from ibanaga-mobl.ger.corp.intel.com (HELO thellst-mobl1.intel.com) ([10.249.254.58]) by orsmga008-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 May 2021 07:47:27 -0700 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Date: Thu, 27 May 2021 16:46:59 +0200 Message-Id: <20210527144710.1975553-5-thomas.hellstrom@linux.intel.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210527144710.1975553-1-thomas.hellstrom@linux.intel.com> References: <20210527144710.1975553-1-thomas.hellstrom@linux.intel.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v5 04/15] drm/i915/ttm Initialize the ttm device and memory managers X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , Matthew Auld Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" VGVtcG9yYXJpbHkgcmVtb3ZlIHRoZSBidWRkeSBhbGxvY2F0b3IgYW5kIHJlbGF0ZWQgc2VsZnRl c3RzCmFuZCBob29rIHVwIHRoZSBUVE0gcmFuZ2UgbWFuYWdlciBmb3IgaTkxNSByZWdpb25zLgoK QWxzbyBtb2RpZnkgdGhlIG1vY2sgcmVnaW9uIHNlbGZ0ZXN0cyBzb21ld2hhdCB0byBhY2NvdW50 IGZvciBhCmZyYWdtZW50aW5nIG1hbmFnZXIuCgpTaWduZWQtb2ZmLWJ5OiBUaG9tYXMgSGVsbHN0 csO2bSA8dGhvbWFzLmhlbGxzdHJvbUBsaW51eC5pbnRlbC5jb20+ClJldmlld2VkLWJ5OiBNYXR0 aGV3IEF1bGQgPG1hdHRoZXcuYXVsZEBpbnRlbC5jb20+ICN2MgotLS0KdjI6Ci0gRml4IGFuIGVy cm9yIHVud2luZCBpbiBsbWVtX2dldF9wYWdlcygpIChSZXBvcnRlZCBieSBNYXR0aGV3IEF1bGQp Ci0gQnJlYWsgb3V0IGFuZCBtb2RpZnkgdXNhZ2Ugb2YgaTkxNV9zZ19kbWFfc2l6ZXMoKSAoUmVw b3J0ZWQgYnkgTWF0dGV3IEF1bGQpCi0gQnJlYWsgb3V0IFRUTSBjaGFuZ2VzIHRvIGEgc2VwYXJh dGUgcGF0Y2ggKFJlcG9ydGVkIGJ5IENocmlzdGlhbiBLw7ZuaWcpCnYzOgotIEZpeCB0aGUgc2Ft ZSBlcnJvciB1bndpbmQgaW4gbW9ja19yZWdpb25fZ2V0X3BhZ2VzKCkKKFJlcG9ydGVkIGJ5IE1h dHRoZXcgQXVsZCkKLSBEb24ndCByZWx5IG9uIG5ldyBUVE0gZnVuY3Rpb25hbGl0eSwgYnV0IGNy ZWF0ZSBhIG1vY2sgVFRNIGRldmljZSwKKFJlcG9ydGVkIGJ5IENocmlzdGlhbiBLw7ZuaWcpCnY0 OgotIFVzZSBtb2NrX2dlbV9kZXZpY2UgcmF0aGVyIHRoYW4gY3JlYXRpbmcgYSBzZXBhcmF0ZSB0 dG1fZGV2aWNlIHBlcgogIHJlZ2lvbi4KLS0tCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9LY29uZmln ICAgICAgICAgICAgICAgICAgfCAgIDEgKwogZHJpdmVycy9ncHUvZHJtL2k5MTUvTWFrZWZpbGUg ICAgICAgICAgICAgICAgIHwgICAyICstCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9n ZW1fbG1lbS5jICAgICAgfCAgNTkgKy0KIC4uLi9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX29i amVjdF90eXBlcy5oICB8ICAgNiArLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2Vt X3BhZ2VzLmMgICAgIHwgICAzICstCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1f cmVnaW9uLmMgICAgfCAxMjAgLS0tCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1f cmVnaW9uLmggICAgfCAgIDQgLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3No bWVtLmMgICAgIHwgICA0ICstCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1fc3Rv bGVuLmMgICAgfCAgMTAgKy0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9zdG9s ZW4uaCAgICB8ICAgOSArLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfZ3QuYyAgICAg ICAgICAgIHwgICAyIC0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX3JlZ2lvbl9sbWVt LmMgICB8ICAyNyArLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9idWRkeS5jICAgICAgICAg ICAgIHwgNDM1IC0tLS0tLS0tLS0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfYnVkZHkuaCAg ICAgICAgICAgICB8IDEzMSAtLS0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfZHJ2LmMgICAg ICAgICAgICAgICB8ICAgOCArCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2Rydi5oICAgICAg ICAgICAgICAgfCAgIDggKy0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfZ2VtLmMgICAgICAg ICAgICAgICB8ICAgMSArCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2dsb2JhbHMuYyAgICAg ICAgICAgfCAgIDEgLQogZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9nbG9iYWxzLmggICAgICAg ICAgIHwgICAxIC0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfc2NhdHRlcmxpc3QuYyAgICAg ICB8ICA3MCArKwogZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9zY2F0dGVybGlzdC5oICAgICAg IHwgICA0ICsKIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX21lbW9yeV9yZWdpb24uYyAgICB8 IDE4MCArKy0tCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9tZW1vcnlfcmVnaW9uLmggICAg fCAgNDQgKy0KIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX3JlZ2lvbl90dG0uYyAgICAgICB8 IDIyMCArKysrKwogZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfcmVnaW9uX3R0bS5oICAgICAg IHwgIDMyICsKIGRyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9pOTE1X2J1ZGR5LmMgICB8 IDc4OSAtLS0tLS0tLS0tLS0tLS0tLS0KIC4uLi9kcm0vaTkxNS9zZWxmdGVzdHMvaTkxNV9tb2Nr X3NlbGZ0ZXN0cy5oICB8ICAgMSAtCiAuLi4vZHJtL2k5MTUvc2VsZnRlc3RzL2ludGVsX21lbW9y eV9yZWdpb24uYyAgfCAxMzMgKy0tCiAuLi4vZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9tb2NrX2dl bV9kZXZpY2UuYyAgfCAgMTAgKwogZHJpdmVycy9ncHUvZHJtL2k5MTUvc2VsZnRlc3RzL21vY2tf cmVnaW9uLmMgIHwgIDcwICstCiAzMCBmaWxlcyBjaGFuZ2VkLCA2MzEgaW5zZXJ0aW9ucygrKSwg MTc1NCBkZWxldGlvbnMoLSkKIGRlbGV0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkx NS9pOTE1X2J1ZGR5LmMKIGRlbGV0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkxNS9p OTE1X2J1ZGR5LmgKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRl bF9yZWdpb25fdHRtLmMKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkxNS9p bnRlbF9yZWdpb25fdHRtLmgKIGRlbGV0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkx NS9zZWxmdGVzdHMvaTkxNV9idWRkeS5jCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5 MTUvS2NvbmZpZyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L0tjb25maWcKaW5kZXggOTNmNGQwNTlm Yzg5Li42MWZmNWMxNzg3MTQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L0tjb25m aWcKKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvS2NvbmZpZwpAQCAtMjcsNiArMjcsNyBAQCBj b25maWcgRFJNX0k5MTUKIAlzZWxlY3QgU05EX0hEQV9JOTE1IGlmIFNORF9IREFfQ09SRQogCXNl bGVjdCBDRUNfQ09SRSBpZiBDRUNfTk9USUZJRVIKIAlzZWxlY3QgVk1BUF9QRk4KKwlzZWxlY3Qg RFJNX1RUTQogCWhlbHAKIAkgIENob29zZSB0aGlzIG9wdGlvbiBpZiB5b3UgaGF2ZSBhIHN5c3Rl bSB0aGF0IGhhcyAiSW50ZWwgR3JhcGhpY3MKIAkgIE1lZGlhIEFjY2VsZXJhdG9yIiBvciAiSEQg R3JhcGhpY3MiIGludGVncmF0ZWQgZ3JhcGhpY3MsCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9k cm0vaTkxNS9NYWtlZmlsZSBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L01ha2VmaWxlCmluZGV4IDY5 NDc0OTViZjM0Yi4uNGYyMmNhYzFjNDliIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkx NS9NYWtlZmlsZQorKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9NYWtlZmlsZQpAQCAtNTAsNiAr NTAsNyBAQCBpOTE1LXkgKz0gaTkxNV9kcnYubyBcCiAJICBpbnRlbF9tZW1vcnlfcmVnaW9uLm8g XAogCSAgaW50ZWxfcGNoLm8gXAogCSAgaW50ZWxfcG0ubyBcCisJICBpbnRlbF9yZWdpb25fdHRt Lm8gXAogCSAgaW50ZWxfcnVudGltZV9wbS5vIFwKIAkgIGludGVsX3NpZGViYW5kLm8gXAogCSAg aW50ZWxfc3RlcC5vIFwKQEAgLTE2MCw3ICsxNjEsNiBAQCBnZW0teSArPSBcCiBpOTE1LXkgKz0g XAogCSAgJChnZW0teSkgXAogCSAgaTkxNV9hY3RpdmUubyBcCi0JICBpOTE1X2J1ZGR5Lm8gXAog CSAgaTkxNV9jbWRfcGFyc2VyLm8gXAogCSAgaTkxNV9nZW1fZXZpY3QubyBcCiAJICBpOTE1X2dl bV9ndHQubyBcCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1f bG1lbS5jIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX2xtZW0uYwppbmRleCBm NDRiZGQwOGY3Y2IuLjNiNGFhMjhhMDc2ZCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5 MTUvZ2VtL2k5MTVfZ2VtX2xtZW0uYworKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkx NV9nZW1fbG1lbS5jCkBAIC00LDE2ICs0LDcxIEBACiAgKi8KIAogI2luY2x1ZGUgImludGVsX21l bW9yeV9yZWdpb24uaCIKKyNpbmNsdWRlICJpbnRlbF9yZWdpb25fdHRtLmgiCiAjaW5jbHVkZSAi Z2VtL2k5MTVfZ2VtX3JlZ2lvbi5oIgogI2luY2x1ZGUgImdlbS9pOTE1X2dlbV9sbWVtLmgiCiAj aW5jbHVkZSAiaTkxNV9kcnYuaCIKIAorc3RhdGljIHZvaWQgbG1lbV9wdXRfcGFnZXMoc3RydWN0 IGRybV9pOTE1X2dlbV9vYmplY3QgKm9iaiwKKwkJCSAgIHN0cnVjdCBzZ190YWJsZSAqcGFnZXMp Cit7CisJaW50ZWxfcmVnaW9uX3R0bV9ub2RlX2ZyZWUob2JqLT5tbS5yZWdpb24sIG9iai0+bW0u c3RfbW1fbm9kZSk7CisJb2JqLT5tbS5kaXJ0eSA9IGZhbHNlOworCXNnX2ZyZWVfdGFibGUocGFn ZXMpOworCWtmcmVlKHBhZ2VzKTsKK30KKworc3RhdGljIGludCBsbWVtX2dldF9wYWdlcyhzdHJ1 Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCAqb2JqKQoreworCXVuc2lnbmVkIGludCBmbGFnczsKKwlz dHJ1Y3Qgc2dfdGFibGUgKnBhZ2VzOworCisJZmxhZ3MgPSBJOTE1X0FMTE9DX01JTl9QQUdFX1NJ WkU7CisJaWYgKG9iai0+ZmxhZ3MgJiBJOTE1X0JPX0FMTE9DX0NPTlRJR1VPVVMpCisJCWZsYWdz IHw9IEk5MTVfQUxMT0NfQ09OVElHVU9VUzsKKworCW9iai0+bW0uc3RfbW1fbm9kZSA9IGludGVs X3JlZ2lvbl90dG1fbm9kZV9hbGxvYyhvYmotPm1tLnJlZ2lvbiwKKwkJCQkJCQkgb2JqLT5iYXNl LnNpemUsCisJCQkJCQkJIGZsYWdzKTsKKwlpZiAoSVNfRVJSKG9iai0+bW0uc3RfbW1fbm9kZSkp CisJCXJldHVybiBQVFJfRVJSKG9iai0+bW0uc3RfbW1fbm9kZSk7CisKKwkvKiBSYW5nZSBtYW5h Z2VyIGlzIGFsd2F5cyBjb250aWdvdXMgKi8KKwlpZiAob2JqLT5tbS5yZWdpb24tPmlzX3Jhbmdl X21hbmFnZXIpCisJCW9iai0+ZmxhZ3MgfD0gSTkxNV9CT19BTExPQ19DT05USUdVT1VTOworCXBh Z2VzID0gaW50ZWxfcmVnaW9uX3R0bV9ub2RlX3RvX3N0KG9iai0+bW0ucmVnaW9uLCBvYmotPm1t LnN0X21tX25vZGUpOworCWlmIChJU19FUlIocGFnZXMpKSB7CisJCWludGVsX3JlZ2lvbl90dG1f bm9kZV9mcmVlKG9iai0+bW0ucmVnaW9uLCBvYmotPm1tLnN0X21tX25vZGUpOworCQlyZXR1cm4g UFRSX0VSUihwYWdlcyk7CisJfQorCisJX19pOTE1X2dlbV9vYmplY3Rfc2V0X3BhZ2VzKG9iaiwg cGFnZXMsIGk5MTVfc2dfZG1hX3NpemVzKHBhZ2VzLT5zZ2wpKTsKKworCWlmIChvYmotPmZsYWdz ICYgSTkxNV9CT19BTExPQ19DUFVfQ0xFQVIpIHsKKwkJdm9pZCBfX2lvbWVtICp2YWRkciA9CisJ CQlpOTE1X2dlbV9vYmplY3RfbG1lbV9pb19tYXAob2JqLCAwLCBvYmotPmJhc2Uuc2l6ZSk7CisK KwkJaWYgKCF2YWRkcikgeworCQkJc3RydWN0IHNnX3RhYmxlICpwYWdlcyA9CisJCQkJX19pOTE1 X2dlbV9vYmplY3RfdW5zZXRfcGFnZXMob2JqKTsKKworCQkJaWYgKCFJU19FUlJfT1JfTlVMTChw YWdlcykpCisJCQkJbG1lbV9wdXRfcGFnZXMob2JqLCBwYWdlcyk7CisJCX0KKworCQltZW1zZXRf aW8odmFkZHIsIDAsIG9iai0+YmFzZS5zaXplKTsKKwkJaW9fbWFwcGluZ191bm1hcCh2YWRkcik7 CisJfQorCisJcmV0dXJuIDA7Cit9CisKIGNvbnN0IHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0 X29wcyBpOTE1X2dlbV9sbWVtX29ial9vcHMgPSB7CiAJLm5hbWUgPSAiaTkxNV9nZW1fb2JqZWN0 X2xtZW0iLAogCS5mbGFncyA9IEk5MTVfR0VNX09CSkVDVF9IQVNfSU9NRU0sCiAKLQkuZ2V0X3Bh Z2VzID0gaTkxNV9nZW1fb2JqZWN0X2dldF9wYWdlc19idWRkeSwKLQkucHV0X3BhZ2VzID0gaTkx NV9nZW1fb2JqZWN0X3B1dF9wYWdlc19idWRkeSwKKwkuZ2V0X3BhZ2VzID0gbG1lbV9nZXRfcGFn ZXMsCisJLnB1dF9wYWdlcyA9IGxtZW1fcHV0X3BhZ2VzLAogCS5yZWxlYXNlID0gaTkxNV9nZW1f b2JqZWN0X3JlbGVhc2VfbWVtb3J5X3JlZ2lvbiwKIH07CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMv Z3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9vYmplY3RfdHlwZXMuaCBiL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2dlbS9pOTE1X2dlbV9vYmplY3RfdHlwZXMuaAppbmRleCAwNDE1Zjk5YjZiOTUuLmY1 YjQ2ZDExZTZlNiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2Vt X29iamVjdF90eXBlcy5oCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9v YmplY3RfdHlwZXMuaApAQCAtMjM1LDEwICsyMzUsMTIgQEAgc3RydWN0IGRybV9pOTE1X2dlbV9v YmplY3QgewogCQkgKiBNZW1vcnkgcmVnaW9uIGZvciB0aGlzIG9iamVjdC4KIAkJICovCiAJCXN0 cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICpyZWdpb247CisKIAkJLyoqCi0JCSAqIExpc3Qgb2Yg bWVtb3J5IHJlZ2lvbiBibG9ja3MgYWxsb2NhdGVkIGZvciB0aGlzIG9iamVjdC4KKwkJICogTWVt b3J5IG1hbmFnZXIgbm9kZSBhbGxvY2F0ZWQgZm9yIHRoaXMgb2JqZWN0LgogCQkgKi8KLQkJc3Ry dWN0IGxpc3RfaGVhZCBibG9ja3M7CisJCXZvaWQgKnN0X21tX25vZGU7CisKIAkJLyoqCiAJCSAq IEVsZW1lbnQgd2l0aGluIG1lbW9yeV9yZWdpb24tPm9iamVjdHMgb3IgcmVnaW9uLT5wdXJnZWFi bGUKIAkJICogaWYgdGhlIG9iamVjdCBpcyBtYXJrZWQgYXMgRE9OVE5FRUQuIEFjY2VzcyBpcyBw cm90ZWN0ZWQgYnkKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dl bV9wYWdlcy5jIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3BhZ2VzLmMKaW5k ZXggNzM2MTk3MWMxNzdkLi42NDQ0ZTA5NzAxNmQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2dlbS9pOTE1X2dlbV9wYWdlcy5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dl bS9pOTE1X2dlbV9wYWdlcy5jCkBAIC00NzUsNyArNDc1LDggQEAgX19pOTE1X2dlbV9vYmplY3Rf Z2V0X3NnKHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmosCiAKIAltaWdodF9zbGVlcCgp OwogCUdFTV9CVUdfT04obiA+PSBvYmotPmJhc2Uuc2l6ZSA+PiBQQUdFX1NISUZUKTsKLQlHRU1f QlVHX09OKCFpOTE1X2dlbV9vYmplY3RfaGFzX3Bpbm5lZF9wYWdlcyhvYmopKTsKKwlpZiAoIWk5 MTVfZ2VtX29iamVjdF9oYXNfcGlubmVkX3BhZ2VzKG9iaikpCisJCWFzc2VydF9vYmplY3RfaGVs ZChvYmopOwogCiAJLyogQXMgd2UgaXRlcmF0ZSBmb3J3YXJkIHRocm91Z2ggdGhlIHNnLCB3ZSBy ZWNvcmQgZWFjaCBlbnRyeSBpbiBhCiAJICogcmFkaXh0cmVlIGZvciBxdWljayByZXBlYXRlZCAo YmFja3dhcmRzKSBsb29rdXBzLiBJZiB3ZSBoYXZlIHNlZW4KZGlmZiAtLWdpdCBhL2RyaXZlcnMv Z3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9yZWdpb24uYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1 L2dlbS9pOTE1X2dlbV9yZWdpb24uYwppbmRleCBjZThmY2ZjNTQwNzkuLmYyNWU2NjQ2YzViNyAx MDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3JlZ2lvbi5jCisr KyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9yZWdpb24uYwpAQCAtOCwxMjkg KzgsOSBAQAogI2luY2x1ZGUgImk5MTVfZHJ2LmgiCiAjaW5jbHVkZSAiaTkxNV90cmFjZS5oIgog Ci12b2lkCi1pOTE1X2dlbV9vYmplY3RfcHV0X3BhZ2VzX2J1ZGR5KHN0cnVjdCBkcm1faTkxNV9n ZW1fb2JqZWN0ICpvYmosCi0JCQkJc3RydWN0IHNnX3RhYmxlICpwYWdlcykKLXsKLQlfX2ludGVs X21lbW9yeV9yZWdpb25fcHV0X3BhZ2VzX2J1ZGR5KG9iai0+bW0ucmVnaW9uLCAmb2JqLT5tbS5i bG9ja3MpOwotCi0Jb2JqLT5tbS5kaXJ0eSA9IGZhbHNlOwotCXNnX2ZyZWVfdGFibGUocGFnZXMp OwotCWtmcmVlKHBhZ2VzKTsKLX0KLQotaW50Ci1pOTE1X2dlbV9vYmplY3RfZ2V0X3BhZ2VzX2J1 ZGR5KHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmopCi17Ci0JY29uc3QgdTY0IG1heF9z ZWdtZW50ID0gaTkxNV9zZ19zZWdtZW50X3NpemUoKTsKLQlzdHJ1Y3QgaW50ZWxfbWVtb3J5X3Jl Z2lvbiAqbWVtID0gb2JqLT5tbS5yZWdpb247Ci0Jc3RydWN0IGxpc3RfaGVhZCAqYmxvY2tzID0g Jm9iai0+bW0uYmxvY2tzOwotCXJlc291cmNlX3NpemVfdCBzaXplID0gb2JqLT5iYXNlLnNpemU7 Ci0JcmVzb3VyY2Vfc2l6ZV90IHByZXZfZW5kOwotCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpi bG9jazsKLQl1bnNpZ25lZCBpbnQgZmxhZ3M7Ci0Jc3RydWN0IHNnX3RhYmxlICpzdDsKLQlzdHJ1 Y3Qgc2NhdHRlcmxpc3QgKnNnOwotCXVuc2lnbmVkIGludCBzZ19wYWdlX3NpemVzOwotCWludCBy ZXQ7Ci0KLQlzdCA9IGttYWxsb2Moc2l6ZW9mKCpzdCksIEdGUF9LRVJORUwpOwotCWlmICghc3Qp Ci0JCXJldHVybiAtRU5PTUVNOwotCi0JaWYgKHNnX2FsbG9jX3RhYmxlKHN0LCBzaXplID4+IFBB R0VfU0hJRlQsIEdGUF9LRVJORUwpKSB7Ci0JCWtmcmVlKHN0KTsKLQkJcmV0dXJuIC1FTk9NRU07 Ci0JfQotCi0JZmxhZ3MgPSBJOTE1X0FMTE9DX01JTl9QQUdFX1NJWkU7Ci0JaWYgKG9iai0+Zmxh Z3MgJiBJOTE1X0JPX0FMTE9DX0NPTlRJR1VPVVMpCi0JCWZsYWdzIHw9IEk5MTVfQUxMT0NfQ09O VElHVU9VUzsKLQotCXJldCA9IF9faW50ZWxfbWVtb3J5X3JlZ2lvbl9nZXRfcGFnZXNfYnVkZHko bWVtLCBzaXplLCBmbGFncywgYmxvY2tzKTsKLQlpZiAocmV0KQotCQlnb3RvIGVycl9mcmVlX3Nn OwotCi0JR0VNX0JVR19PTihsaXN0X2VtcHR5KGJsb2NrcykpOwotCi0Jc2cgPSBzdC0+c2dsOwot CXN0LT5uZW50cyA9IDA7Ci0Jc2dfcGFnZV9zaXplcyA9IDA7Ci0JcHJldl9lbmQgPSAocmVzb3Vy Y2Vfc2l6ZV90KS0xOwotCi0JbGlzdF9mb3JfZWFjaF9lbnRyeShibG9jaywgYmxvY2tzLCBsaW5r KSB7Ci0JCXU2NCBibG9ja19zaXplLCBvZmZzZXQ7Ci0KLQkJYmxvY2tfc2l6ZSA9IG1pbl90KHU2 NCwgc2l6ZSwKLQkJCQkgICBpOTE1X2J1ZGR5X2Jsb2NrX3NpemUoJm1lbS0+bW0sIGJsb2NrKSk7 Ci0JCW9mZnNldCA9IGk5MTVfYnVkZHlfYmxvY2tfb2Zmc2V0KGJsb2NrKTsKLQotCQl3aGlsZSAo YmxvY2tfc2l6ZSkgewotCQkJdTY0IGxlbjsKLQotCQkJaWYgKG9mZnNldCAhPSBwcmV2X2VuZCB8 fCBzZy0+bGVuZ3RoID49IG1heF9zZWdtZW50KSB7Ci0JCQkJaWYgKHN0LT5uZW50cykgewotCQkJ CQlzZ19wYWdlX3NpemVzIHw9IHNnLT5sZW5ndGg7Ci0JCQkJCXNnID0gX19zZ19uZXh0KHNnKTsK LQkJCQl9Ci0KLQkJCQlzZ19kbWFfYWRkcmVzcyhzZykgPSBtZW0tPnJlZ2lvbi5zdGFydCArIG9m ZnNldDsKLQkJCQlzZ19kbWFfbGVuKHNnKSA9IDA7Ci0JCQkJc2ctPmxlbmd0aCA9IDA7Ci0JCQkJ c3QtPm5lbnRzKys7Ci0JCQl9Ci0KLQkJCWxlbiA9IG1pbihibG9ja19zaXplLCBtYXhfc2VnbWVu dCAtIHNnLT5sZW5ndGgpOwotCQkJc2ctPmxlbmd0aCArPSBsZW47Ci0JCQlzZ19kbWFfbGVuKHNn KSArPSBsZW47Ci0KLQkJCW9mZnNldCArPSBsZW47Ci0JCQlibG9ja19zaXplIC09IGxlbjsKLQot CQkJcHJldl9lbmQgPSBvZmZzZXQ7Ci0JCX0KLQl9Ci0KLQlzZ19wYWdlX3NpemVzIHw9IHNnLT5s ZW5ndGg7Ci0Jc2dfbWFya19lbmQoc2cpOwotCWk5MTVfc2dfdHJpbShzdCk7Ci0KLQkvKiBJbnRl bmRlZCBmb3Iga2VybmVsIGludGVybmFsIHVzZSBvbmx5ICovCi0JaWYgKG9iai0+ZmxhZ3MgJiBJ OTE1X0JPX0FMTE9DX0NQVV9DTEVBUikgewotCQlzdHJ1Y3Qgc2NhdHRlcmxpc3QgKnNnOwotCQl1 bnNpZ25lZCBsb25nIGk7Ci0KLQkJZm9yX2VhY2hfc2coc3QtPnNnbCwgc2csIHN0LT5uZW50cywg aSkgewotCQkJdW5zaWduZWQgaW50IGxlbmd0aDsKLQkJCXZvaWQgX19pb21lbSAqdmFkZHI7Ci0J CQlkbWFfYWRkcl90IGRhZGRyOwotCi0JCQlkYWRkciA9IHNnX2RtYV9hZGRyZXNzKHNnKTsKLQkJ CWRhZGRyIC09IG1lbS0+cmVnaW9uLnN0YXJ0OwotCQkJbGVuZ3RoID0gc2dfZG1hX2xlbihzZyk7 Ci0KLQkJCXZhZGRyID0gaW9fbWFwcGluZ19tYXBfd2MoJm1lbS0+aW9tYXAsIGRhZGRyLCBsZW5n dGgpOwotCQkJbWVtc2V0NjQoKHZvaWQgX19mb3JjZSAqKXZhZGRyLCAwLCBsZW5ndGggLyBzaXpl b2YodTY0KSk7Ci0JCQlpb19tYXBwaW5nX3VubWFwKHZhZGRyKTsKLQkJfQotCi0JCXdtYigpOwot CX0KLQotCV9faTkxNV9nZW1fb2JqZWN0X3NldF9wYWdlcyhvYmosIHN0LCBzZ19wYWdlX3NpemVz KTsKLQotCXJldHVybiAwOwotCi1lcnJfZnJlZV9zZzoKLQlzZ19mcmVlX3RhYmxlKHN0KTsKLQlr ZnJlZShzdCk7Ci0JcmV0dXJuIHJldDsKLX0KLQogdm9pZCBpOTE1X2dlbV9vYmplY3RfaW5pdF9t ZW1vcnlfcmVnaW9uKHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmosCiAJCQkJCXN0cnVj dCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0pCiB7Ci0JSU5JVF9MSVNUX0hFQUQoJm9iai0+bW0u YmxvY2tzKTsKIAlvYmotPm1tLnJlZ2lvbiA9IGludGVsX21lbW9yeV9yZWdpb25fZ2V0KG1lbSk7 CiAKIAlpZiAob2JqLT5iYXNlLnNpemUgPD0gbWVtLT5taW5fcGFnZV9zaXplKQpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3JlZ2lvbi5oIGIvZHJpdmVycy9n cHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3JlZ2lvbi5oCmluZGV4IGViZGRjODZkNzhmNy4uODRm Y2IzMjk3NDAwIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkxNV9nZW1f cmVnaW9uLmgKKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3JlZ2lvbi5o CkBAIC0xMiwxMCArMTIsNiBAQCBzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbjsKIHN0cnVjdCBk cm1faTkxNV9nZW1fb2JqZWN0Owogc3RydWN0IHNnX3RhYmxlOwogCi1pbnQgaTkxNV9nZW1fb2Jq ZWN0X2dldF9wYWdlc19idWRkeShzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCAqb2JqKTsKLXZv aWQgaTkxNV9nZW1fb2JqZWN0X3B1dF9wYWdlc19idWRkeShzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29i amVjdCAqb2JqLAotCQkJCSAgICAgc3RydWN0IHNnX3RhYmxlICpwYWdlcyk7Ci0KIHZvaWQgaTkx NV9nZW1fb2JqZWN0X2luaXRfbWVtb3J5X3JlZ2lvbihzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVj dCAqb2JqLAogCQkJCQlzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtKTsKIHZvaWQgaTkx NV9nZW1fb2JqZWN0X3JlbGVhc2VfbWVtb3J5X3JlZ2lvbihzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29i amVjdCAqb2JqKTsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dl bV9zaG1lbS5jIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3NobWVtLmMKaW5k ZXggYTliZmE2NmM4ZGExLi41ZDE2YzQ0NjJmZGEgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2dlbS9pOTE1X2dlbV9zaG1lbS5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dl bS9pOTE1X2dlbV9zaG1lbS5jCkBAIC02MjgsMTEgKzYyOCwxMyBAQCBzdGF0aWMgY29uc3Qgc3Ry dWN0IGludGVsX21lbW9yeV9yZWdpb25fb3BzIHNobWVtX3JlZ2lvbl9vcHMgPSB7CiAJLmluaXRf b2JqZWN0ID0gc2htZW1fb2JqZWN0X2luaXQsCiB9OwogCi1zdHJ1Y3QgaW50ZWxfbWVtb3J5X3Jl Z2lvbiAqaTkxNV9nZW1fc2htZW1fc2V0dXAoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUp CitzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqaTkxNV9nZW1fc2htZW1fc2V0dXAoc3RydWN0 IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUsCisJCQkJCQkgdTE2IHR5cGUsIHUxNiBpbnN0YW5jZSkK IHsKIAlyZXR1cm4gaW50ZWxfbWVtb3J5X3JlZ2lvbl9jcmVhdGUoaTkxNSwgMCwKIAkJCQkJICB0 b3RhbHJhbV9wYWdlcygpIDw8IFBBR0VfU0hJRlQsCiAJCQkJCSAgUEFHRV9TSVpFLCAwLAorCQkJ CQkgIHR5cGUsIGluc3RhbmNlLAogCQkJCQkgICZzaG1lbV9yZWdpb25fb3BzKTsKIH0KIApkaWZm IC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3N0b2xlbi5jIGIvZHJp dmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3N0b2xlbi5jCmluZGV4IGI1NTUzZmMzYWM0 ZC4uMDkyZDdhMjFkZTgyIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9nZW0vaTkx NV9nZW1fc3RvbGVuLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3N0 b2xlbi5jCkBAIC03NzIsNyArNzcyLDggQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBpbnRlbF9tZW1v cnlfcmVnaW9uX29wcyBpOTE1X3JlZ2lvbl9zdG9sZW5fbG1lbV9vcHMgPSB7CiB9OwogCiBzdHJ1 Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqCi1pOTE1X2dlbV9zdG9sZW5fbG1lbV9zZXR1cChzdHJ1 Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqaTkxNSkKK2k5MTVfZ2VtX3N0b2xlbl9sbWVtX3NldHVwKHN0 cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1LCB1MTYgdHlwZSwKKwkJCSAgIHUxNiBpbnN0YW5j ZSkKIHsKIAlzdHJ1Y3QgaW50ZWxfdW5jb3JlICp1bmNvcmUgPSAmaTkxNS0+dW5jb3JlOwogCXN0 cnVjdCBwY2lfZGV2ICpwZGV2ID0gdG9fcGNpX2RldihpOTE1LT5kcm0uZGV2KTsKQEAgLTc5MCw2 ICs3OTEsNyBAQCBpOTE1X2dlbV9zdG9sZW5fbG1lbV9zZXR1cChzdHJ1Y3QgZHJtX2k5MTVfcHJp dmF0ZSAqaTkxNSkKIAogCW1lbSA9IGludGVsX21lbW9yeV9yZWdpb25fY3JlYXRlKGk5MTUsIGxt ZW1fYmFzZSwgbG1lbV9zaXplLAogCQkJCQkgSTkxNV9HVFRfUEFHRV9TSVpFXzRLLCBpb19zdGFy dCwKKwkJCQkJIHR5cGUsIGluc3RhbmNlLAogCQkJCQkgJmk5MTVfcmVnaW9uX3N0b2xlbl9sbWVt X29wcyk7CiAJaWYgKElTX0VSUihtZW0pKQogCQlyZXR1cm4gbWVtOwpAQCAtODExLDE0ICs4MTMs MTUgQEAgaTkxNV9nZW1fc3RvbGVuX2xtZW1fc2V0dXAoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUg Kmk5MTUpCiB9CiAKIHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uKgotaTkxNV9nZW1fc3RvbGVu X3NtZW1fc2V0dXAoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUpCitpOTE1X2dlbV9zdG9s ZW5fc21lbV9zZXR1cChzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqaTkxNSwgdTE2IHR5cGUsCisJ CQkgICB1MTYgaW5zdGFuY2UpCiB7CiAJc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbTsK IAogCW1lbSA9IGludGVsX21lbW9yeV9yZWdpb25fY3JlYXRlKGk5MTUsCiAJCQkJCSBpbnRlbF9n cmFwaGljc19zdG9sZW5fcmVzLnN0YXJ0LAogCQkJCQkgcmVzb3VyY2Vfc2l6ZSgmaW50ZWxfZ3Jh cGhpY3Nfc3RvbGVuX3JlcyksCi0JCQkJCSBQQUdFX1NJWkUsIDAsCisJCQkJCSBQQUdFX1NJWkUs IDAsIHR5cGUsIGluc3RhbmNlLAogCQkJCQkgJmk5MTVfcmVnaW9uX3N0b2xlbl9zbWVtX29wcyk7 CiAJaWYgKElTX0VSUihtZW0pKQogCQlyZXR1cm4gbWVtOwpAQCAtODI2LDcgKzgyOSw2IEBAIGk5 MTVfZ2VtX3N0b2xlbl9zbWVtX3NldHVwKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1KQog CWludGVsX21lbW9yeV9yZWdpb25fc2V0X25hbWUobWVtLCAic3RvbGVuLXN5c3RlbSIpOwogCiAJ bWVtLT5wcml2YXRlID0gdHJ1ZTsKLQogCXJldHVybiBtZW07CiB9CiAKZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9zdG9sZW4uaCBiL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2dlbS9pOTE1X2dlbV9zdG9sZW4uaAppbmRleCAyYmVjNmMzNjdiOWMuLmNjZGY3YmVm YzU3MSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ2VtL2k5MTVfZ2VtX3N0b2xl bi5oCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2dlbS9pOTE1X2dlbV9zdG9sZW4uaApAQCAt MjEsOCArMjEsMTMgQEAgaW50IGk5MTVfZ2VtX3N0b2xlbl9pbnNlcnRfbm9kZV9pbl9yYW5nZShz dHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYsCiAJCQkJCSB1NjQgZW5kKTsKIHZvaWQg aTkxNV9nZW1fc3RvbGVuX3JlbW92ZV9ub2RlKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZf cHJpdiwKIAkJCQkgc3RydWN0IGRybV9tbV9ub2RlICpub2RlKTsKLXN0cnVjdCBpbnRlbF9tZW1v cnlfcmVnaW9uICppOTE1X2dlbV9zdG9sZW5fc21lbV9zZXR1cChzdHJ1Y3QgZHJtX2k5MTVfcHJp dmF0ZSAqaTkxNSk7Ci1zdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqaTkxNV9nZW1fc3RvbGVu X2xtZW1fc2V0dXAoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUpOworc3RydWN0IGludGVs X21lbW9yeV9yZWdpb24gKgoraTkxNV9nZW1fc3RvbGVuX3NtZW1fc2V0dXAoc3RydWN0IGRybV9p OTE1X3ByaXZhdGUgKmk5MTUsIHUxNiB0eXBlLAorCQkJICAgdTE2IGluc3RhbmNlKTsKK3N0cnVj dCBpbnRlbF9tZW1vcnlfcmVnaW9uICoKK2k5MTVfZ2VtX3N0b2xlbl9sbWVtX3NldHVwKHN0cnVj dCBkcm1faTkxNV9wcml2YXRlICppOTE1LCB1MTYgdHlwZSwKKwkJCSAgIHUxNiBpbnN0YW5jZSk7 CisKIHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICoKIGk5MTVfZ2VtX29iamVjdF9jcmVhdGVf c3RvbGVuKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdiwKIAkJCSAgICAgIHJlc291 cmNlX3NpemVfdCBzaXplKTsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2lu dGVsX2d0LmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9ndC5jCmluZGV4IDhkNzdk Y2JhZDA1OS4uM2Y4OGVjZGVlMDMxIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9n dC9pbnRlbF9ndC5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d0L2ludGVsX2d0LmMKQEAg LTY4LDggKzY4LDYgQEAgaW50IGludGVsX2d0X3Byb2JlX2xtZW0oc3RydWN0IGludGVsX2d0ICpn dCkKIAlpZCA9IElOVEVMX1JFR0lPTl9MTUVNOwogCiAJbWVtLT5pZCA9IGlkOwotCW1lbS0+dHlw ZSA9IElOVEVMX01FTU9SWV9MT0NBTDsKLQltZW0tPmluc3RhbmNlID0gMDsKIAogCWludGVsX21l bW9yeV9yZWdpb25fc2V0X25hbWUobWVtLCAibG9jYWwldSIsIG1lbS0+aW5zdGFuY2UpOwogCmRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9yZWdpb25fbG1lbS5jIGIv ZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3QvaW50ZWxfcmVnaW9uX2xtZW0uYwppbmRleCA3M2ZjZWIw YzI1ZmMuLmY3MzY2YjA1NGY4ZSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Qv aW50ZWxfcmVnaW9uX2xtZW0uYworKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndC9pbnRlbF9y ZWdpb25fbG1lbS5jCkBAIC01LDYgKzUsOCBAQAogCiAjaW5jbHVkZSAiaTkxNV9kcnYuaCIKICNp bmNsdWRlICJpbnRlbF9tZW1vcnlfcmVnaW9uLmgiCisjaW5jbHVkZSAiaW50ZWxfcmVnaW9uX2xt ZW0uaCIKKyNpbmNsdWRlICJpbnRlbF9yZWdpb25fdHRtLmgiCiAjaW5jbHVkZSAiZ2VtL2k5MTVf Z2VtX2xtZW0uaCIKICNpbmNsdWRlICJnZW0vaTkxNV9nZW1fcmVnaW9uLmgiCiAjaW5jbHVkZSAi aW50ZWxfcmVnaW9uX2xtZW0uaCIKQEAgLTY2LDkgKzY4LDkgQEAgc3RhdGljIHZvaWQgcmVsZWFz ZV9mYWtlX2xtZW1fYmFyKHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0pCiBzdGF0aWMg dm9pZAogcmVnaW9uX2xtZW1fcmVsZWFzZShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVt KQogewotCXJlbGVhc2VfZmFrZV9sbWVtX2JhcihtZW0pOworCWludGVsX3JlZ2lvbl90dG1fZmlu aShtZW0pOwogCWlvX21hcHBpbmdfZmluaSgmbWVtLT5pb21hcCk7Ci0JaW50ZWxfbWVtb3J5X3Jl Z2lvbl9yZWxlYXNlX2J1ZGR5KG1lbSk7CisJcmVsZWFzZV9mYWtlX2xtZW1fYmFyKG1lbSk7CiB9 CiAKIHN0YXRpYyBpbnQKQEAgLTgzLDEyICs4NSwyMSBAQCByZWdpb25fbG1lbV9pbml0KHN0cnVj dCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0pCiAKIAlpZiAoIWlvX21hcHBpbmdfaW5pdF93Yygm bWVtLT5pb21hcCwKIAkJCQltZW0tPmlvX3N0YXJ0LAotCQkJCXJlc291cmNlX3NpemUoJm1lbS0+ cmVnaW9uKSkpCi0JCXJldHVybiAtRUlPOworCQkJCXJlc291cmNlX3NpemUoJm1lbS0+cmVnaW9u KSkpIHsKKwkJcmV0ID0gLUVJTzsKKwkJZ290byBvdXRfbm9faW87CisJfQogCi0JcmV0ID0gaW50 ZWxfbWVtb3J5X3JlZ2lvbl9pbml0X2J1ZGR5KG1lbSk7CisJcmV0ID0gaW50ZWxfcmVnaW9uX3R0 bV9pbml0KG1lbSk7CiAJaWYgKHJldCkKLQkJaW9fbWFwcGluZ19maW5pKCZtZW0tPmlvbWFwKTsK KwkJZ290byBvdXRfbm9fYnVkZHk7CisKKwlyZXR1cm4gMDsKKworb3V0X25vX2J1ZGR5OgorCWlv X21hcHBpbmdfZmluaSgmbWVtLT5pb21hcCk7CitvdXRfbm9faW86CisJcmVsZWFzZV9mYWtlX2xt ZW1fYmFyKG1lbSk7CiAKIAlyZXR1cm4gcmV0OwogfQpAQCAtMTI3LDYgKzEzOCw4IEBAIGludGVs X2d0X3NldHVwX2Zha2VfbG1lbShzdHJ1Y3QgaW50ZWxfZ3QgKmd0KQogCQkJCQkgbWFwcGFibGVf ZW5kLAogCQkJCQkgUEFHRV9TSVpFLAogCQkJCQkgaW9fc3RhcnQsCisJCQkJCSBJTlRFTF9NRU1P UllfTE9DQUwsCisJCQkJCSAwLAogCQkJCQkgJmludGVsX3JlZ2lvbl9sbWVtX29wcyk7CiAJaWYg KCFJU19FUlIobWVtKSkgewogCQlkcm1faW5mbygmaTkxNS0+ZHJtLCAiSW50ZWwgZ3JhcGhpY3Mg ZmFrZSBMTUVNOiAlcFJcbiIsCkBAIC0xOTgsNiArMjExLDggQEAgc3RhdGljIHN0cnVjdCBpbnRl bF9tZW1vcnlfcmVnaW9uICpzZXR1cF9sbWVtKHN0cnVjdCBpbnRlbF9ndCAqZ3QpCiAJCQkJCSBs bWVtX3NpemUsCiAJCQkJCSBJOTE1X0dUVF9QQUdFX1NJWkVfNEssCiAJCQkJCSBpb19zdGFydCwK KwkJCQkJIElOVEVMX01FTU9SWV9MT0NBTCwKKwkJCQkJIDAsCiAJCQkJCSAmaW50ZWxfcmVnaW9u X2xtZW1fb3BzKTsKIAlpZiAoSVNfRVJSKG1lbSkpCiAJCXJldHVybiBtZW07CmRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2J1ZGR5LmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkx NS9pOTE1X2J1ZGR5LmMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNhMmY2ZWVjYjJm Yy4uMDAwMDAwMDAwMDAwCi0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfYnVkZHkuYwor KysgL2Rldi9udWxsCkBAIC0xLDQzNSArMCwwIEBACi0vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmll cjogTUlUCi0vKgotICogQ29weXJpZ2h0IMKpIDIwMTkgSW50ZWwgQ29ycG9yYXRpb24KLSAqLwot Ci0jaW5jbHVkZSA8bGludXgva21lbWxlYWsuaD4KLSNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Ci0K LSNpbmNsdWRlICJpOTE1X2J1ZGR5LmgiCi0KLSNpbmNsdWRlICJpOTE1X2dlbS5oIgotI2luY2x1 ZGUgImk5MTVfZ2xvYmFscy5oIgotI2luY2x1ZGUgImk5MTVfdXRpbHMuaCIKLQotc3RhdGljIHN0 cnVjdCBpOTE1X2dsb2JhbF9ibG9jayB7Ci0Jc3RydWN0IGk5MTVfZ2xvYmFsIGJhc2U7Ci0Jc3Ry dWN0IGttZW1fY2FjaGUgKnNsYWJfYmxvY2tzOwotfSBnbG9iYWw7Ci0KLXN0YXRpYyB2b2lkIGk5 MTVfZ2xvYmFsX2J1ZGR5X3Nocmluayh2b2lkKQotewotCWttZW1fY2FjaGVfc2hyaW5rKGdsb2Jh bC5zbGFiX2Jsb2Nrcyk7Ci19Ci0KLXN0YXRpYyB2b2lkIGk5MTVfZ2xvYmFsX2J1ZGR5X2V4aXQo dm9pZCkKLXsKLQlrbWVtX2NhY2hlX2Rlc3Ryb3koZ2xvYmFsLnNsYWJfYmxvY2tzKTsKLX0KLQot c3RhdGljIHN0cnVjdCBpOTE1X2dsb2JhbF9ibG9jayBnbG9iYWwgPSB7IHsKLQkuc2hyaW5rID0g aTkxNV9nbG9iYWxfYnVkZHlfc2hyaW5rLAotCS5leGl0ID0gaTkxNV9nbG9iYWxfYnVkZHlfZXhp dCwKLX0gfTsKLQotaW50IF9faW5pdCBpOTE1X2dsb2JhbF9idWRkeV9pbml0KHZvaWQpCi17Ci0J Z2xvYmFsLnNsYWJfYmxvY2tzID0gS01FTV9DQUNIRShpOTE1X2J1ZGR5X2Jsb2NrLCBTTEFCX0hX Q0FDSEVfQUxJR04pOwotCWlmICghZ2xvYmFsLnNsYWJfYmxvY2tzKQotCQlyZXR1cm4gLUVOT01F TTsKLQotCWk5MTVfZ2xvYmFsX3JlZ2lzdGVyKCZnbG9iYWwuYmFzZSk7Ci0JcmV0dXJuIDA7Ci19 Ci0KLXN0YXRpYyBzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqaTkxNV9ibG9ja19hbGxvYyhzdHJ1 Y3QgaTkxNV9idWRkeV9ibG9jayAqcGFyZW50LAotCQkJCQkJIHVuc2lnbmVkIGludCBvcmRlciwK LQkJCQkJCSB1NjQgb2Zmc2V0KQotewotCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jazsK LQotCUdFTV9CVUdfT04ob3JkZXIgPiBJOTE1X0JVRERZX01BWF9PUkRFUik7Ci0KLQlibG9jayA9 IGttZW1fY2FjaGVfemFsbG9jKGdsb2JhbC5zbGFiX2Jsb2NrcywgR0ZQX0tFUk5FTCk7Ci0JaWYg KCFibG9jaykKLQkJcmV0dXJuIE5VTEw7Ci0KLQlibG9jay0+aGVhZGVyID0gb2Zmc2V0OwotCWJs b2NrLT5oZWFkZXIgfD0gb3JkZXI7Ci0JYmxvY2stPnBhcmVudCA9IHBhcmVudDsKLQotCUdFTV9C VUdfT04oYmxvY2stPmhlYWRlciAmIEk5MTVfQlVERFlfSEVBREVSX1VOVVNFRCk7Ci0JcmV0dXJu IGJsb2NrOwotfQotCi1zdGF0aWMgdm9pZCBpOTE1X2Jsb2NrX2ZyZWUoc3RydWN0IGk5MTVfYnVk ZHlfYmxvY2sgKmJsb2NrKQotewotCWttZW1fY2FjaGVfZnJlZShnbG9iYWwuc2xhYl9ibG9ja3Ms IGJsb2NrKTsKLX0KLQotc3RhdGljIHZvaWQgbWFya19hbGxvY2F0ZWQoc3RydWN0IGk5MTVfYnVk ZHlfYmxvY2sgKmJsb2NrKQotewotCWJsb2NrLT5oZWFkZXIgJj0gfkk5MTVfQlVERFlfSEVBREVS X1NUQVRFOwotCWJsb2NrLT5oZWFkZXIgfD0gSTkxNV9CVUREWV9BTExPQ0FURUQ7Ci0KLQlsaXN0 X2RlbCgmYmxvY2stPmxpbmspOwotfQotCi1zdGF0aWMgdm9pZCBtYXJrX2ZyZWUoc3RydWN0IGk5 MTVfYnVkZHlfbW0gKm1tLAotCQkgICAgICBzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqYmxvY2sp Ci17Ci0JYmxvY2stPmhlYWRlciAmPSB+STkxNV9CVUREWV9IRUFERVJfU1RBVEU7Ci0JYmxvY2st PmhlYWRlciB8PSBJOTE1X0JVRERZX0ZSRUU7Ci0KLQlsaXN0X2FkZCgmYmxvY2stPmxpbmssCi0J CSAmbW0tPmZyZWVfbGlzdFtpOTE1X2J1ZGR5X2Jsb2NrX29yZGVyKGJsb2NrKV0pOwotfQotCi1z dGF0aWMgdm9pZCBtYXJrX3NwbGl0KHN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jaykKLXsK LQlibG9jay0+aGVhZGVyICY9IH5JOTE1X0JVRERZX0hFQURFUl9TVEFURTsKLQlibG9jay0+aGVh ZGVyIHw9IEk5MTVfQlVERFlfU1BMSVQ7Ci0KLQlsaXN0X2RlbCgmYmxvY2stPmxpbmspOwotfQot Ci1pbnQgaTkxNV9idWRkeV9pbml0KHN0cnVjdCBpOTE1X2J1ZGR5X21tICptbSwgdTY0IHNpemUs IHU2NCBjaHVua19zaXplKQotewotCXVuc2lnbmVkIGludCBpOwotCXU2NCBvZmZzZXQ7Ci0KLQlp ZiAoc2l6ZSA8IGNodW5rX3NpemUpCi0JCXJldHVybiAtRUlOVkFMOwotCi0JaWYgKGNodW5rX3Np emUgPCBQQUdFX1NJWkUpCi0JCXJldHVybiAtRUlOVkFMOwotCi0JaWYgKCFpc19wb3dlcl9vZl8y KGNodW5rX3NpemUpKQotCQlyZXR1cm4gLUVJTlZBTDsKLQotCXNpemUgPSByb3VuZF9kb3duKHNp emUsIGNodW5rX3NpemUpOwotCi0JbW0tPnNpemUgPSBzaXplOwotCW1tLT5jaHVua19zaXplID0g Y2h1bmtfc2l6ZTsKLQltbS0+bWF4X29yZGVyID0gaWxvZzIoc2l6ZSkgLSBpbG9nMihjaHVua19z aXplKTsKLQotCUdFTV9CVUdfT04obW0tPm1heF9vcmRlciA+IEk5MTVfQlVERFlfTUFYX09SREVS KTsKLQotCW1tLT5mcmVlX2xpc3QgPSBrbWFsbG9jX2FycmF5KG1tLT5tYXhfb3JkZXIgKyAxLAot CQkJCSAgICAgIHNpemVvZihzdHJ1Y3QgbGlzdF9oZWFkKSwKLQkJCQkgICAgICBHRlBfS0VSTkVM KTsKLQlpZiAoIW1tLT5mcmVlX2xpc3QpCi0JCXJldHVybiAtRU5PTUVNOwotCi0JZm9yIChpID0g MDsgaSA8PSBtbS0+bWF4X29yZGVyOyArK2kpCi0JCUlOSVRfTElTVF9IRUFEKCZtbS0+ZnJlZV9s aXN0W2ldKTsKLQotCW1tLT5uX3Jvb3RzID0gaHdlaWdodDY0KHNpemUpOwotCi0JbW0tPnJvb3Rz ID0ga21hbGxvY19hcnJheShtbS0+bl9yb290cywKLQkJCQkgIHNpemVvZihzdHJ1Y3QgaTkxNV9i dWRkeV9ibG9jayAqKSwKLQkJCQkgIEdGUF9LRVJORUwpOwotCWlmICghbW0tPnJvb3RzKQotCQln b3RvIG91dF9mcmVlX2xpc3Q7Ci0KLQlvZmZzZXQgPSAwOwotCWkgPSAwOwotCi0JLyoKLQkgKiBT cGxpdCBpbnRvIHBvd2VyLW9mLXR3byBibG9ja3MsIGluIGNhc2Ugd2UgYXJlIGdpdmVuIGEgc2l6 ZSB0aGF0IGlzCi0JICogbm90IGl0c2VsZiBhIHBvd2VyLW9mLXR3by4KLQkgKi8KLQlkbyB7Ci0J CXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpyb290OwotCQl1bnNpZ25lZCBpbnQgb3JkZXI7Ci0J CXU2NCByb290X3NpemU7Ci0KLQkJcm9vdF9zaXplID0gcm91bmRkb3duX3Bvd19vZl90d28oc2l6 ZSk7Ci0JCW9yZGVyID0gaWxvZzIocm9vdF9zaXplKSAtIGlsb2cyKGNodW5rX3NpemUpOwotCi0J CXJvb3QgPSBpOTE1X2Jsb2NrX2FsbG9jKE5VTEwsIG9yZGVyLCBvZmZzZXQpOwotCQlpZiAoIXJv b3QpCi0JCQlnb3RvIG91dF9mcmVlX3Jvb3RzOwotCi0JCW1hcmtfZnJlZShtbSwgcm9vdCk7Ci0K LQkJR0VNX0JVR19PTihpID4gbW0tPm1heF9vcmRlcik7Ci0JCUdFTV9CVUdfT04oaTkxNV9idWRk eV9ibG9ja19zaXplKG1tLCByb290KSA8IGNodW5rX3NpemUpOwotCi0JCW1tLT5yb290c1tpXSA9 IHJvb3Q7Ci0KLQkJb2Zmc2V0ICs9IHJvb3Rfc2l6ZTsKLQkJc2l6ZSAtPSByb290X3NpemU7Ci0J CWkrKzsKLQl9IHdoaWxlIChzaXplKTsKLQotCXJldHVybiAwOwotCi1vdXRfZnJlZV9yb290czoK LQl3aGlsZSAoaS0tKQotCQlpOTE1X2Jsb2NrX2ZyZWUobW0tPnJvb3RzW2ldKTsKLQlrZnJlZSht bS0+cm9vdHMpOwotb3V0X2ZyZWVfbGlzdDoKLQlrZnJlZShtbS0+ZnJlZV9saXN0KTsKLQlyZXR1 cm4gLUVOT01FTTsKLX0KLQotdm9pZCBpOTE1X2J1ZGR5X2Zpbmkoc3RydWN0IGk5MTVfYnVkZHlf bW0gKm1tKQotewotCWludCBpOwotCi0JZm9yIChpID0gMDsgaSA8IG1tLT5uX3Jvb3RzOyArK2kp IHsKLQkJR0VNX1dBUk5fT04oIWk5MTVfYnVkZHlfYmxvY2tfaXNfZnJlZShtbS0+cm9vdHNbaV0p KTsKLQkJaTkxNV9ibG9ja19mcmVlKG1tLT5yb290c1tpXSk7Ci0JfQotCi0Ja2ZyZWUobW0tPnJv b3RzKTsKLQlrZnJlZShtbS0+ZnJlZV9saXN0KTsKLX0KLQotc3RhdGljIGludCBzcGxpdF9ibG9j ayhzdHJ1Y3QgaTkxNV9idWRkeV9tbSAqbW0sCi0JCSAgICAgICBzdHJ1Y3QgaTkxNV9idWRkeV9i bG9jayAqYmxvY2spCi17Ci0JdW5zaWduZWQgaW50IGJsb2NrX29yZGVyID0gaTkxNV9idWRkeV9i bG9ja19vcmRlcihibG9jaykgLSAxOwotCXU2NCBvZmZzZXQgPSBpOTE1X2J1ZGR5X2Jsb2NrX29m ZnNldChibG9jayk7Ci0KLQlHRU1fQlVHX09OKCFpOTE1X2J1ZGR5X2Jsb2NrX2lzX2ZyZWUoYmxv Y2spKTsKLQlHRU1fQlVHX09OKCFpOTE1X2J1ZGR5X2Jsb2NrX29yZGVyKGJsb2NrKSk7Ci0KLQli bG9jay0+bGVmdCA9IGk5MTVfYmxvY2tfYWxsb2MoYmxvY2ssIGJsb2NrX29yZGVyLCBvZmZzZXQp OwotCWlmICghYmxvY2stPmxlZnQpCi0JCXJldHVybiAtRU5PTUVNOwotCi0JYmxvY2stPnJpZ2h0 ID0gaTkxNV9ibG9ja19hbGxvYyhibG9jaywgYmxvY2tfb3JkZXIsCi0JCQkJCW9mZnNldCArICht bS0+Y2h1bmtfc2l6ZSA8PCBibG9ja19vcmRlcikpOwotCWlmICghYmxvY2stPnJpZ2h0KSB7Ci0J CWk5MTVfYmxvY2tfZnJlZShibG9jay0+bGVmdCk7Ci0JCXJldHVybiAtRU5PTUVNOwotCX0KLQot CW1hcmtfZnJlZShtbSwgYmxvY2stPmxlZnQpOwotCW1hcmtfZnJlZShtbSwgYmxvY2stPnJpZ2h0 KTsKLQotCW1hcmtfc3BsaXQoYmxvY2spOwotCi0JcmV0dXJuIDA7Ci19Ci0KLXN0YXRpYyBzdHJ1 Y3QgaTkxNV9idWRkeV9ibG9jayAqCi1nZXRfYnVkZHkoc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sg KmJsb2NrKQotewotCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpwYXJlbnQ7Ci0KLQlwYXJlbnQg PSBibG9jay0+cGFyZW50OwotCWlmICghcGFyZW50KQotCQlyZXR1cm4gTlVMTDsKLQotCWlmIChw YXJlbnQtPmxlZnQgPT0gYmxvY2spCi0JCXJldHVybiBwYXJlbnQtPnJpZ2h0OwotCi0JcmV0dXJu IHBhcmVudC0+bGVmdDsKLX0KLQotc3RhdGljIHZvaWQgX19pOTE1X2J1ZGR5X2ZyZWUoc3RydWN0 IGk5MTVfYnVkZHlfbW0gKm1tLAotCQkJICAgICAgc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKmJs b2NrKQotewotCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpwYXJlbnQ7Ci0KLQl3aGlsZSAoKHBh cmVudCA9IGJsb2NrLT5wYXJlbnQpKSB7Ci0JCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpidWRk eTsKLQotCQlidWRkeSA9IGdldF9idWRkeShibG9jayk7Ci0KLQkJaWYgKCFpOTE1X2J1ZGR5X2Js b2NrX2lzX2ZyZWUoYnVkZHkpKQotCQkJYnJlYWs7Ci0KLQkJbGlzdF9kZWwoJmJ1ZGR5LT5saW5r KTsKLQotCQlpOTE1X2Jsb2NrX2ZyZWUoYmxvY2spOwotCQlpOTE1X2Jsb2NrX2ZyZWUoYnVkZHkp OwotCi0JCWJsb2NrID0gcGFyZW50OwotCX0KLQotCW1hcmtfZnJlZShtbSwgYmxvY2spOwotfQot Ci12b2lkIGk5MTVfYnVkZHlfZnJlZShzdHJ1Y3QgaTkxNV9idWRkeV9tbSAqbW0sCi0JCSAgICAg c3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrKQotewotCUdFTV9CVUdfT04oIWk5MTVfYnVk ZHlfYmxvY2tfaXNfYWxsb2NhdGVkKGJsb2NrKSk7Ci0JX19pOTE1X2J1ZGR5X2ZyZWUobW0sIGJs b2NrKTsKLX0KLQotdm9pZCBpOTE1X2J1ZGR5X2ZyZWVfbGlzdChzdHJ1Y3QgaTkxNV9idWRkeV9t bSAqbW0sIHN0cnVjdCBsaXN0X2hlYWQgKm9iamVjdHMpCi17Ci0Jc3RydWN0IGk5MTVfYnVkZHlf YmxvY2sgKmJsb2NrLCAqb247Ci0KLQlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYmxvY2ssIG9u LCBvYmplY3RzLCBsaW5rKSB7Ci0JCWk5MTVfYnVkZHlfZnJlZShtbSwgYmxvY2spOwotCQljb25k X3Jlc2NoZWQoKTsKLQl9Ci0JSU5JVF9MSVNUX0hFQUQob2JqZWN0cyk7Ci19Ci0KLS8qCi0gKiBB bGxvY2F0ZSBwb3dlci1vZi10d28gYmxvY2suIFRoZSBvcmRlciB2YWx1ZSBoZXJlIHRyYW5zbGF0 ZXMgdG86Ci0gKgotICogICAwID0gMl4wICogbW0tPmNodW5rX3NpemUKLSAqICAgMSA9IDJeMSAq IG1tLT5jaHVua19zaXplCi0gKiAgIDIgPSAyXjIgKiBtbS0+Y2h1bmtfc2l6ZQotICogICAuLi4K LSAqLwotc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKgotaTkxNV9idWRkeV9hbGxvYyhzdHJ1Y3Qg aTkxNV9idWRkeV9tbSAqbW0sIHVuc2lnbmVkIGludCBvcmRlcikKLXsKLQlzdHJ1Y3QgaTkxNV9i dWRkeV9ibG9jayAqYmxvY2sgPSBOVUxMOwotCXVuc2lnbmVkIGludCBpOwotCWludCBlcnI7Ci0K LQlmb3IgKGkgPSBvcmRlcjsgaSA8PSBtbS0+bWF4X29yZGVyOyArK2kpIHsKLQkJYmxvY2sgPSBs aXN0X2ZpcnN0X2VudHJ5X29yX251bGwoJm1tLT5mcmVlX2xpc3RbaV0sCi0JCQkJCQkgc3RydWN0 IGk5MTVfYnVkZHlfYmxvY2ssCi0JCQkJCQkgbGluayk7Ci0JCWlmIChibG9jaykKLQkJCWJyZWFr OwotCX0KLQotCWlmICghYmxvY2spCi0JCXJldHVybiBFUlJfUFRSKC1FTk9TUEMpOwotCi0JR0VN X0JVR19PTighaTkxNV9idWRkeV9ibG9ja19pc19mcmVlKGJsb2NrKSk7Ci0KLQl3aGlsZSAoaSAh PSBvcmRlcikgewotCQllcnIgPSBzcGxpdF9ibG9jayhtbSwgYmxvY2spOwotCQlpZiAodW5saWtl bHkoZXJyKSkKLQkJCWdvdG8gb3V0X2ZyZWU7Ci0KLQkJLyogR28gbG93ICovCi0JCWJsb2NrID0g YmxvY2stPmxlZnQ7Ci0JCWktLTsKLQl9Ci0KLQltYXJrX2FsbG9jYXRlZChibG9jayk7Ci0Ja21l bWxlYWtfdXBkYXRlX3RyYWNlKGJsb2NrKTsKLQlyZXR1cm4gYmxvY2s7Ci0KLW91dF9mcmVlOgot CWlmIChpICE9IG9yZGVyKQotCQlfX2k5MTVfYnVkZHlfZnJlZShtbSwgYmxvY2spOwotCXJldHVy biBFUlJfUFRSKGVycik7Ci19Ci0KLXN0YXRpYyBpbmxpbmUgYm9vbCBvdmVybGFwcyh1NjQgczEs IHU2NCBlMSwgdTY0IHMyLCB1NjQgZTIpCi17Ci0JcmV0dXJuIHMxIDw9IGUyICYmIGUxID49IHMy OwotfQotCi1zdGF0aWMgaW5saW5lIGJvb2wgY29udGFpbnModTY0IHMxLCB1NjQgZTEsIHU2NCBz MiwgdTY0IGUyKQotewotCXJldHVybiBzMSA8PSBzMiAmJiBlMSA+PSBlMjsKLX0KLQotLyoKLSAq IEFsbG9jYXRlIHJhbmdlLiBOb3RlIHRoYXQgaXQncyBzYWZlIHRvIGNoYWluIHRvZ2V0aGVyIG11 bHRpcGxlIGFsbG9jX3JhbmdlcwotICogd2l0aCB0aGUgc2FtZSBibG9ja3MgbGlzdC4KLSAqCi0g KiBJbnRlbmRlZCBmb3IgcHJlLWFsbG9jYXRpbmcgcG9ydGlvbnMgb2YgdGhlIGFkZHJlc3Mgc3Bh Y2UsIGZvciBleGFtcGxlIHRvCi0gKiByZXNlcnZlIGEgYmxvY2sgZm9yIHRoZSBpbml0aWFsIGZy YW1lYnVmZmVyIG9yIHNpbWlsYXIsIGhlbmNlIHRoZSBleHBlY3RhdGlvbgotICogaGVyZSBpcyB0 aGF0IGk5MTVfYnVkZHlfYWxsb2MoKSBpcyBzdGlsbCB0aGUgbWFpbiB2ZWhpY2xlIGZvcgotICog YWxsb2NhdGlvbnMsIHNvIGlmIHRoYXQncyBub3QgdGhlIGNhc2UgdGhlbiB0aGUgZHJtX21tIHJh bmdlIGFsbG9jYXRvciBpcwotICogcHJvYmFibHkgYSBtdWNoIGJldHRlciBmaXQsIGFuZCBzbyB5 b3Ugc2hvdWxkIHByb2JhYmx5IGdvIHVzZSB0aGF0IGluc3RlYWQuCi0gKi8KLWludCBpOTE1X2J1 ZGR5X2FsbG9jX3JhbmdlKHN0cnVjdCBpOTE1X2J1ZGR5X21tICptbSwKLQkJCSAgIHN0cnVjdCBs aXN0X2hlYWQgKmJsb2NrcywKLQkJCSAgIHU2NCBzdGFydCwgdTY0IHNpemUpCi17Ci0Jc3RydWN0 IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrOwotCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpidWRk eTsKLQlMSVNUX0hFQUQoYWxsb2NhdGVkKTsKLQlMSVNUX0hFQUQoZGZzKTsKLQl1NjQgZW5kOwot CWludCBlcnI7Ci0JaW50IGk7Ci0KLQlpZiAoc2l6ZSA8IG1tLT5jaHVua19zaXplKQotCQlyZXR1 cm4gLUVJTlZBTDsKLQotCWlmICghSVNfQUxJR05FRChzaXplIHwgc3RhcnQsIG1tLT5jaHVua19z aXplKSkKLQkJcmV0dXJuIC1FSU5WQUw7Ci0KLQlpZiAocmFuZ2Vfb3ZlcmZsb3dzKHN0YXJ0LCBz aXplLCBtbS0+c2l6ZSkpCi0JCXJldHVybiAtRUlOVkFMOwotCi0JZm9yIChpID0gMDsgaSA8IG1t LT5uX3Jvb3RzOyArK2kpCi0JCWxpc3RfYWRkX3RhaWwoJm1tLT5yb290c1tpXS0+dG1wX2xpbmss ICZkZnMpOwotCi0JZW5kID0gc3RhcnQgKyBzaXplIC0gMTsKLQotCWRvIHsKLQkJdTY0IGJsb2Nr X3N0YXJ0OwotCQl1NjQgYmxvY2tfZW5kOwotCi0JCWJsb2NrID0gbGlzdF9maXJzdF9lbnRyeV9v cl9udWxsKCZkZnMsCi0JCQkJCQkgc3RydWN0IGk5MTVfYnVkZHlfYmxvY2ssCi0JCQkJCQkgdG1w X2xpbmspOwotCQlpZiAoIWJsb2NrKQotCQkJYnJlYWs7Ci0KLQkJbGlzdF9kZWwoJmJsb2NrLT50 bXBfbGluayk7Ci0KLQkJYmxvY2tfc3RhcnQgPSBpOTE1X2J1ZGR5X2Jsb2NrX29mZnNldChibG9j ayk7Ci0JCWJsb2NrX2VuZCA9IGJsb2NrX3N0YXJ0ICsgaTkxNV9idWRkeV9ibG9ja19zaXplKG1t LCBibG9jaykgLSAxOwotCi0JCWlmICghb3ZlcmxhcHMoc3RhcnQsIGVuZCwgYmxvY2tfc3RhcnQs IGJsb2NrX2VuZCkpCi0JCQljb250aW51ZTsKLQotCQlpZiAoaTkxNV9idWRkeV9ibG9ja19pc19h bGxvY2F0ZWQoYmxvY2spKSB7Ci0JCQllcnIgPSAtRU5PU1BDOwotCQkJZ290byBlcnJfZnJlZTsK LQkJfQotCi0JCWlmIChjb250YWlucyhzdGFydCwgZW5kLCBibG9ja19zdGFydCwgYmxvY2tfZW5k KSkgewotCQkJaWYgKCFpOTE1X2J1ZGR5X2Jsb2NrX2lzX2ZyZWUoYmxvY2spKSB7Ci0JCQkJZXJy ID0gLUVOT1NQQzsKLQkJCQlnb3RvIGVycl9mcmVlOwotCQkJfQotCi0JCQltYXJrX2FsbG9jYXRl ZChibG9jayk7Ci0JCQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGluaywgJmFsbG9jYXRlZCk7Ci0J CQljb250aW51ZTsKLQkJfQotCi0JCWlmICghaTkxNV9idWRkeV9ibG9ja19pc19zcGxpdChibG9j aykpIHsKLQkJCWVyciA9IHNwbGl0X2Jsb2NrKG1tLCBibG9jayk7Ci0JCQlpZiAodW5saWtlbHko ZXJyKSkKLQkJCQlnb3RvIGVycl91bmRvOwotCQl9Ci0KLQkJbGlzdF9hZGQoJmJsb2NrLT5yaWdo dC0+dG1wX2xpbmssICZkZnMpOwotCQlsaXN0X2FkZCgmYmxvY2stPmxlZnQtPnRtcF9saW5rLCAm ZGZzKTsKLQl9IHdoaWxlICgxKTsKLQotCWxpc3Rfc3BsaWNlX3RhaWwoJmFsbG9jYXRlZCwgYmxv Y2tzKTsKLQlyZXR1cm4gMDsKLQotZXJyX3VuZG86Ci0JLyoKLQkgKiBXZSByZWFsbHkgZG9uJ3Qg d2FudCB0byBsZWF2ZSBhcm91bmQgYSBidW5jaCBvZiBzcGxpdCBibG9ja3MsIHNpbmNlCi0JICog YmlnZ2VyIGlzIGJldHRlciwgc28gbWFrZSBzdXJlIHdlIG1lcmdlIGV2ZXJ5dGhpbmcgYmFjayBi ZWZvcmUgd2UKLQkgKiBmcmVlIHRoZSBhbGxvY2F0ZWQgYmxvY2tzLgotCSAqLwotCWJ1ZGR5ID0g Z2V0X2J1ZGR5KGJsb2NrKTsKLQlpZiAoYnVkZHkgJiYKLQkgICAgKGk5MTVfYnVkZHlfYmxvY2tf aXNfZnJlZShibG9jaykgJiYKLQkgICAgIGk5MTVfYnVkZHlfYmxvY2tfaXNfZnJlZShidWRkeSkp KQotCQlfX2k5MTVfYnVkZHlfZnJlZShtbSwgYmxvY2spOwotCi1lcnJfZnJlZToKLQlpOTE1X2J1 ZGR5X2ZyZWVfbGlzdChtbSwgJmFsbG9jYXRlZCk7Ci0JcmV0dXJuIGVycjsKLX0KLQotI2lmIElT X0VOQUJMRUQoQ09ORklHX0RSTV9JOTE1X1NFTEZURVNUKQotI2luY2x1ZGUgInNlbGZ0ZXN0cy9p OTE1X2J1ZGR5LmMiCi0jZW5kaWYKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5 MTVfYnVkZHkuaCBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfYnVkZHkuaApkZWxldGVkIGZp bGUgbW9kZSAxMDA2NDQKaW5kZXggOWNlNTIwMGY0MDAxLi4wMDAwMDAwMDAwMDAKLS0tIGEvZHJp dmVycy9ncHUvZHJtL2k5MTUvaTkxNV9idWRkeS5oCisrKyAvZGV2L251bGwKQEAgLTEsMTMxICsw LDAgQEAKLS8qIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNSVQgKi8KLS8qCi0gKiBDb3B5cmln aHQgwqkgMjAxOSBJbnRlbCBDb3Jwb3JhdGlvbgotICovCi0KLSNpZm5kZWYgX19JOTE1X0JVRERZ X0hfXwotI2RlZmluZSBfX0k5MTVfQlVERFlfSF9fCi0KLSNpbmNsdWRlIDxsaW51eC9iaXRvcHMu aD4KLSNpbmNsdWRlIDxsaW51eC9saXN0Lmg+Ci0KLXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrIHsK LSNkZWZpbmUgSTkxNV9CVUREWV9IRUFERVJfT0ZGU0VUIEdFTk1BU0tfVUxMKDYzLCAxMikKLSNk ZWZpbmUgSTkxNV9CVUREWV9IRUFERVJfU1RBVEUgIEdFTk1BU0tfVUxMKDExLCAxMCkKLSNkZWZp bmUgICBJOTE1X0JVRERZX0FMTE9DQVRFRAkgICAoMSA8PCAxMCkKLSNkZWZpbmUgICBJOTE1X0JV RERZX0ZSRUUJICAgKDIgPDwgMTApCi0jZGVmaW5lICAgSTkxNV9CVUREWV9TUExJVAkgICAoMyA8 PCAxMCkKLS8qIEZyZWUgdG8gYmUgdXNlZCwgaWYgbmVlZGVkIGluIHRoZSBmdXR1cmUgKi8KLSNk ZWZpbmUgSTkxNV9CVUREWV9IRUFERVJfVU5VU0VEIEdFTk1BU0tfVUxMKDksIDYpCi0jZGVmaW5l IEk5MTVfQlVERFlfSEVBREVSX09SREVSICBHRU5NQVNLX1VMTCg1LCAwKQotCXU2NCBoZWFkZXI7 Ci0KLQlzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqbGVmdDsKLQlzdHJ1Y3QgaTkxNV9idWRkeV9i bG9jayAqcmlnaHQ7Ci0Jc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKnBhcmVudDsKLQotCXZvaWQg KnByaXZhdGU7IC8qIG93bmVkIGJ5IGNyZWF0b3IgKi8KLQotCS8qCi0JICogV2hpbGUgdGhlIGJs b2NrIGlzIGFsbG9jYXRlZCBieSB0aGUgdXNlciB0aHJvdWdoIGk5MTVfYnVkZHlfYWxsb2MqLAot CSAqIHRoZSB1c2VyIGhhcyBvd25lcnNoaXAgb2YgdGhlIGxpbmssIGZvciBleGFtcGxlIHRvIG1h aW50YWluIHdpdGhpbgotCSAqIGEgbGlzdCwgaWYgc28gZGVzaXJlZC4gQXMgc29vbiBhcyB0aGUg YmxvY2sgaXMgZnJlZWQgd2l0aAotCSAqIGk5MTVfYnVkZHlfZnJlZSogb3duZXJzaGlwIGlzIGdp dmVuIGJhY2sgdG8gdGhlIG1tLgotCSAqLwotCXN0cnVjdCBsaXN0X2hlYWQgbGluazsKLQlzdHJ1 Y3QgbGlzdF9oZWFkIHRtcF9saW5rOwotfTsKLQotLyogT3JkZXItemVybyBtdXN0IGJlIGF0IGxl YXN0IFBBR0VfU0laRSAqLwotI2RlZmluZSBJOTE1X0JVRERZX01BWF9PUkRFUiAoNjMgLSBQQUdF X1NISUZUKQotCi0vKgotICogQmluYXJ5IEJ1ZGR5IFN5c3RlbS4KLSAqCi0gKiBMb2NraW5nIHNo b3VsZCBiZSBoYW5kbGVkIGJ5IHRoZSB1c2VyLCBhIHNpbXBsZSBtdXRleCBhcm91bmQKLSAqIGk5 MTVfYnVkZHlfYWxsb2MqIGFuZCBpOTE1X2J1ZGR5X2ZyZWUqIHNob3VsZCBzdWZmaWNlLgotICov Ci1zdHJ1Y3QgaTkxNV9idWRkeV9tbSB7Ci0JLyogTWFpbnRhaW4gYSBmcmVlIGxpc3QgZm9yIGVh Y2ggb3JkZXIuICovCi0Jc3RydWN0IGxpc3RfaGVhZCAqZnJlZV9saXN0OwotCi0JLyoKLQkgKiBN YWludGFpbiBleHBsaWNpdCBiaW5hcnkgdHJlZShzKSB0byB0cmFjayB0aGUgYWxsb2NhdGlvbiBv ZiB0aGUKLQkgKiBhZGRyZXNzIHNwYWNlLiBUaGlzIGdpdmVzIHVzIGEgc2ltcGxlIHdheSBvZiBm aW5kaW5nIGEgYnVkZHkgYmxvY2sKLQkgKiBhbmQgcGVyZm9ybWluZyB0aGUgcG90ZW50aWFsbHkg cmVjdXJzaXZlIG1lcmdlIHN0ZXAgd2hlbiBmcmVlaW5nIGEKLQkgKiBibG9jay4gIE5vZGVzIGFy ZSBlaXRoZXIgYWxsb2NhdGVkIG9yIGZyZWUsIGluIHdoaWNoIGNhc2UgdGhleSB3aWxsCi0JICog YWxzbyBleGlzdCBvbiB0aGUgcmVzcGVjdGl2ZSBmcmVlIGxpc3QuCi0JICovCi0Jc3RydWN0IGk5 MTVfYnVkZHlfYmxvY2sgKipyb290czsKLQotCS8qCi0JICogQW55dGhpbmcgZnJvbSBoZXJlIGlz IHB1YmxpYywgYW5kIHJlbWFpbnMgc3RhdGljIGZvciB0aGUgbGlmZXRpbWUgb2YKLQkgKiB0aGUg bW0uIEV2ZXJ5dGhpbmcgYWJvdmUgaXMgY29uc2lkZXJlZCBkby1ub3QtdG91Y2guCi0JICovCi0J dW5zaWduZWQgaW50IG5fcm9vdHM7Ci0JdW5zaWduZWQgaW50IG1heF9vcmRlcjsKLQotCS8qIE11 c3QgYmUgYXQgbGVhc3QgUEFHRV9TSVpFICovCi0JdTY0IGNodW5rX3NpemU7Ci0JdTY0IHNpemU7 Ci19OwotCi1zdGF0aWMgaW5saW5lIHU2NAotaTkxNV9idWRkeV9ibG9ja19vZmZzZXQoc3RydWN0 IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrKQotewotCXJldHVybiBibG9jay0+aGVhZGVyICYgSTkx NV9CVUREWV9IRUFERVJfT0ZGU0VUOwotfQotCi1zdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludAot aTkxNV9idWRkeV9ibG9ja19vcmRlcihzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqYmxvY2spCi17 Ci0JcmV0dXJuIGJsb2NrLT5oZWFkZXIgJiBJOTE1X0JVRERZX0hFQURFUl9PUkRFUjsKLX0KLQot c3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQKLWk5MTVfYnVkZHlfYmxvY2tfc3RhdGUoc3RydWN0 IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrKQotewotCXJldHVybiBibG9jay0+aGVhZGVyICYgSTkx NV9CVUREWV9IRUFERVJfU1RBVEU7Ci19Ci0KLXN0YXRpYyBpbmxpbmUgYm9vbAotaTkxNV9idWRk eV9ibG9ja19pc19hbGxvY2F0ZWQoc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrKQotewot CXJldHVybiBpOTE1X2J1ZGR5X2Jsb2NrX3N0YXRlKGJsb2NrKSA9PSBJOTE1X0JVRERZX0FMTE9D QVRFRDsKLX0KLQotc3RhdGljIGlubGluZSBib29sCi1pOTE1X2J1ZGR5X2Jsb2NrX2lzX2ZyZWUo c3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrKQotewotCXJldHVybiBpOTE1X2J1ZGR5X2Js b2NrX3N0YXRlKGJsb2NrKSA9PSBJOTE1X0JVRERZX0ZSRUU7Ci19Ci0KLXN0YXRpYyBpbmxpbmUg Ym9vbAotaTkxNV9idWRkeV9ibG9ja19pc19zcGxpdChzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAq YmxvY2spCi17Ci0JcmV0dXJuIGk5MTVfYnVkZHlfYmxvY2tfc3RhdGUoYmxvY2spID09IEk5MTVf QlVERFlfU1BMSVQ7Ci19Ci0KLXN0YXRpYyBpbmxpbmUgdTY0Ci1pOTE1X2J1ZGR5X2Jsb2NrX3Np emUoc3RydWN0IGk5MTVfYnVkZHlfbW0gKm1tLAotCQkgICAgICBzdHJ1Y3QgaTkxNV9idWRkeV9i bG9jayAqYmxvY2spCi17Ci0JcmV0dXJuIG1tLT5jaHVua19zaXplIDw8IGk5MTVfYnVkZHlfYmxv Y2tfb3JkZXIoYmxvY2spOwotfQotCi1pbnQgaTkxNV9idWRkeV9pbml0KHN0cnVjdCBpOTE1X2J1 ZGR5X21tICptbSwgdTY0IHNpemUsIHU2NCBjaHVua19zaXplKTsKLQotdm9pZCBpOTE1X2J1ZGR5 X2Zpbmkoc3RydWN0IGk5MTVfYnVkZHlfbW0gKm1tKTsKLQotc3RydWN0IGk5MTVfYnVkZHlfYmxv Y2sgKgotaTkxNV9idWRkeV9hbGxvYyhzdHJ1Y3QgaTkxNV9idWRkeV9tbSAqbW0sIHVuc2lnbmVk IGludCBvcmRlcik7Ci0KLWludCBpOTE1X2J1ZGR5X2FsbG9jX3JhbmdlKHN0cnVjdCBpOTE1X2J1 ZGR5X21tICptbSwKLQkJCSAgIHN0cnVjdCBsaXN0X2hlYWQgKmJsb2NrcywKLQkJCSAgIHU2NCBz dGFydCwgdTY0IHNpemUpOwotCi12b2lkIGk5MTVfYnVkZHlfZnJlZShzdHJ1Y3QgaTkxNV9idWRk eV9tbSAqbW0sIHN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jayk7Ci0KLXZvaWQgaTkxNV9i dWRkeV9mcmVlX2xpc3Qoc3RydWN0IGk5MTVfYnVkZHlfbW0gKm1tLCBzdHJ1Y3QgbGlzdF9oZWFk ICpvYmplY3RzKTsKLQotI2VuZGlmCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9p OTE1X2Rydi5jIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9kcnYuYwppbmRleCBkODJhOTll MTI4Y2YuLjMwYzM0OTEzN2JlMiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkx NV9kcnYuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2Rydi5jCkBAIC04NCw2ICs4 NCw3IEBACiAjaW5jbHVkZSAiaW50ZWxfZ3Z0LmgiCiAjaW5jbHVkZSAiaW50ZWxfbWVtb3J5X3Jl Z2lvbi5oIgogI2luY2x1ZGUgImludGVsX3BtLmgiCisjaW5jbHVkZSAiaW50ZWxfcmVnaW9uX3R0 bS5oIgogI2luY2x1ZGUgImludGVsX3NpZGViYW5kLmgiCiAjaW5jbHVkZSAidmx2X3N1c3BlbmQu aCIKIApAQCAtMzM1LDYgKzMzNiwxMCBAQCBzdGF0aWMgaW50IGk5MTVfZHJpdmVyX2Vhcmx5X3By b2JlKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdikKIAlpZiAocmV0IDwgMCkKIAkJ Z290byBlcnJfd29ya3F1ZXVlczsKIAorCXJldCA9IGludGVsX3JlZ2lvbl90dG1fZGV2aWNlX2lu aXQoZGV2X3ByaXYpOworCWlmIChyZXQpCisJCWdvdG8gZXJyX3R0bTsKKwogCWludGVsX3dvcGNt X2luaXRfZWFybHkoJmRldl9wcml2LT53b3BjbSk7CiAKIAlpbnRlbF9ndF9pbml0X2Vhcmx5KCZk ZXZfcHJpdi0+Z3QsIGRldl9wcml2KTsKQEAgLTM1OSw2ICszNjQsOCBAQCBzdGF0aWMgaW50IGk5 MTVfZHJpdmVyX2Vhcmx5X3Byb2JlKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdikK IGVycl9nZW06CiAJaTkxNV9nZW1fY2xlYW51cF9lYXJseShkZXZfcHJpdik7CiAJaW50ZWxfZ3Rf ZHJpdmVyX2xhdGVfcmVsZWFzZSgmZGV2X3ByaXYtPmd0KTsKKwlpbnRlbF9yZWdpb25fdHRtX2Rl dmljZV9maW5pKGRldl9wcml2KTsKK2Vycl90dG06CiAJdmx2X3N1c3BlbmRfY2xlYW51cChkZXZf cHJpdik7CiBlcnJfd29ya3F1ZXVlczoKIAlpOTE1X3dvcmtxdWV1ZXNfY2xlYW51cChkZXZfcHJp dik7CkBAIC0zNzYsNiArMzgzLDcgQEAgc3RhdGljIHZvaWQgaTkxNV9kcml2ZXJfbGF0ZV9yZWxl YXNlKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdikKIAlpbnRlbF9wb3dlcl9kb21h aW5zX2NsZWFudXAoZGV2X3ByaXYpOwogCWk5MTVfZ2VtX2NsZWFudXBfZWFybHkoZGV2X3ByaXYp OwogCWludGVsX2d0X2RyaXZlcl9sYXRlX3JlbGVhc2UoJmRldl9wcml2LT5ndCk7CisJaW50ZWxf cmVnaW9uX3R0bV9kZXZpY2VfZmluaShkZXZfcHJpdik7CiAJdmx2X3N1c3BlbmRfY2xlYW51cChk ZXZfcHJpdik7CiAJaTkxNV93b3JrcXVldWVzX2NsZWFudXAoZGV2X3ByaXYpOwogCmRpZmYgLS1n aXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2Rydi5oIGIvZHJpdmVycy9ncHUvZHJtL2k5 MTUvaTkxNV9kcnYuaAppbmRleCAwZjZkMjdkYTY5YWMuLjUyNGFhZWIwZTg0MiAxMDA2NDQKLS0t IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9kcnYuaAorKysgYi9kcml2ZXJzL2dwdS9kcm0v aTkxNS9pOTE1X2Rydi5oCkBAIC01OSw2ICs1OSw3IEBACiAjaW5jbHVkZSA8ZHJtL2RybV9hdG9t aWMuaD4KICNpbmNsdWRlIDxkcm0vZHJtX2Nvbm5lY3Rvci5oPgogI2luY2x1ZGUgPGRybS9pOTE1 X21laV9oZGNwX2ludGVyZmFjZS5oPgorI2luY2x1ZGUgPGRybS90dG0vdHRtX2RldmljZS5oPgog CiAjaW5jbHVkZSAiaTkxNV9wYXJhbXMuaCIKICNpbmNsdWRlICJpOTE1X3JlZy5oIgpAQCAtNzc4 LDYgKzc3OSw3IEBAIHN0cnVjdCBpbnRlbF9jZGNsa19jb25maWcgewogCiBzdHJ1Y3QgaTkxNV9z ZWxmdGVzdF9zdGFzaCB7CiAJYXRvbWljX3QgY291bnRlcjsKKwlzdHJ1Y3QgaWRhIG1vY2tfcmVn aW9uX2luc3RhbmNlczsKIH07CiAKIHN0cnVjdCBkcm1faTkxNV9wcml2YXRlIHsKQEAgLTExNzAs NiArMTE3Miw5IEBAIHN0cnVjdCBkcm1faTkxNV9wcml2YXRlIHsKIAkvKiBNdXRleCB0byBwcm90 ZWN0IHRoZSBhYm92ZSBoZGNwIGNvbXBvbmVudCByZWxhdGVkIHZhbHVlcy4gKi8KIAlzdHJ1Y3Qg bXV0ZXggaGRjcF9jb21wX211dGV4OwogCisJLyogVGhlIFRUTSBkZXZpY2Ugc3RydWN0dXJlLiAq LworCXN0cnVjdCB0dG1fZGV2aWNlIGJkZXY7CisKIAlJOTE1X1NFTEZURVNUX0RFQ0xBUkUoc3Ry dWN0IGk5MTVfc2VsZnRlc3Rfc3Rhc2ggc2VsZnRlc3Q7KQogCiAJLyoKQEAgLTE3NjMsNyArMTc2 OCw4IEBAIHZvaWQgaTkxNV9nZW1fY2xlYW51cF91c2VycHRyKHN0cnVjdCBkcm1faTkxNV9wcml2 YXRlICpkZXZfcHJpdik7CiB2b2lkIGk5MTVfZ2VtX2luaXRfZWFybHkoc3RydWN0IGRybV9pOTE1 X3ByaXZhdGUgKmRldl9wcml2KTsKIHZvaWQgaTkxNV9nZW1fY2xlYW51cF9lYXJseShzdHJ1Y3Qg ZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYpOwogCi1zdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lv biAqaTkxNV9nZW1fc2htZW1fc2V0dXAoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUpOwor c3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKmk5MTVfZ2VtX3NobWVtX3NldHVwKHN0cnVjdCBk cm1faTkxNV9wcml2YXRlICppOTE1LAorCQkJCQkJIHUxNiB0eXBlLCB1MTYgaW5zdGFuY2UpOwog CiBzdGF0aWMgaW5saW5lIHZvaWQgaTkxNV9nZW1fZHJhaW5fZnJlZWRfb2JqZWN0cyhzdHJ1Y3Qg ZHJtX2k5MTVfcHJpdmF0ZSAqaTkxNSkKIHsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9p OTE1L2k5MTVfZ2VtLmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2dlbS5jCmluZGV4IGNm ZmQ3ZjRmODdkYy4uMDk5M2Q3MDZmMDY3IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkx NS9pOTE1X2dlbS5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfZ2VtLmMKQEAgLTEx MDgsNiArMTEwOCw3IEBAIGludCBpOTE1X2dlbV9pbml0KHN0cnVjdCBkcm1faTkxNV9wcml2YXRl ICpkZXZfcHJpdikKIAl9CiAKIAlpOTE1X2dlbV9kcmFpbl9mcmVlZF9vYmplY3RzKGRldl9wcml2 KTsKKwogCXJldHVybiByZXQ7CiB9CiAKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1 L2k5MTVfZ2xvYmFscy5jIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9nbG9iYWxzLmMKaW5k ZXggM2FhMjEzNjg0MjkzLi43N2YxOTExYzQ2M2IgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2k5MTVfZ2xvYmFscy5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfZ2xv YmFscy5jCkBAIC04Nyw3ICs4Nyw2IEBAIHN0YXRpYyB2b2lkIF9faTkxNV9nbG9iYWxzX2NsZWFu dXAodm9pZCkKIAogc3RhdGljIF9faW5pdGNvbnN0IGludCAoKiBjb25zdCBpbml0Zm5bXSkodm9p ZCkgPSB7CiAJaTkxNV9nbG9iYWxfYWN0aXZlX2luaXQsCi0JaTkxNV9nbG9iYWxfYnVkZHlfaW5p dCwKIAlpOTE1X2dsb2JhbF9jb250ZXh0X2luaXQsCiAJaTkxNV9nbG9iYWxfZ2VtX2NvbnRleHRf aW5pdCwKIAlpOTE1X2dsb2JhbF9vYmplY3RzX2luaXQsCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dw dS9kcm0vaTkxNS9pOTE1X2dsb2JhbHMuaCBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfZ2xv YmFscy5oCmluZGV4IGIyZjVjZDliOWIxYS4uMmQxOTlmNDExYTRhIDEwMDY0NAotLS0gYS9kcml2 ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2dsb2JhbHMuaAorKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkx NS9pOTE1X2dsb2JhbHMuaApAQCAtMjcsNyArMjcsNiBAQCB2b2lkIGk5MTVfZ2xvYmFsc19leGl0 KHZvaWQpOwogCiAvKiBjb25zdHJ1Y3RvcnMgKi8KIGludCBpOTE1X2dsb2JhbF9hY3RpdmVfaW5p dCh2b2lkKTsKLWludCBpOTE1X2dsb2JhbF9idWRkeV9pbml0KHZvaWQpOwogaW50IGk5MTVfZ2xv YmFsX2NvbnRleHRfaW5pdCh2b2lkKTsKIGludCBpOTE1X2dsb2JhbF9nZW1fY29udGV4dF9pbml0 KHZvaWQpOwogaW50IGk5MTVfZ2xvYmFsX29iamVjdHNfaW5pdCh2b2lkKTsKZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfc2NhdHRlcmxpc3QuYyBiL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2k5MTVfc2NhdHRlcmxpc3QuYwppbmRleCBjYzZiMzg0NmE4YzcuLjY5ZTllNmMzMTM1 ZSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9zY2F0dGVybGlzdC5jCisr KyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfc2NhdHRlcmxpc3QuYwpAQCAtNiw2ICs2LDEw IEBACiAKICNpbmNsdWRlICJpOTE1X3NjYXR0ZXJsaXN0LmgiCiAKKyNpbmNsdWRlIDxkcm0vZHJt X21tLmg+CisKKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CisKIGJvb2wgaTkxNV9zZ190cmltKHN0 cnVjdCBzZ190YWJsZSAqb3JpZ19zdCkKIHsKIAlzdHJ1Y3Qgc2dfdGFibGUgbmV3X3N0OwpAQCAt MzQsNiArMzgsNzIgQEAgYm9vbCBpOTE1X3NnX3RyaW0oc3RydWN0IHNnX3RhYmxlICpvcmlnX3N0 KQogCXJldHVybiB0cnVlOwogfQogCisvKioKKyAqIGk5MTVfc2dfZnJvbV9tbV9ub2RlIC0gQ3Jl YXRlIGFuIHNnX3RhYmxlIGZyb20gYSBzdHJ1Y3QgZHJtX21tX25vZGUKKyAqIEBub2RlOiBUaGUg ZHJtX21tX25vZGUuCisgKiBAcmVnaW9uX3N0YXJ0OiBBbiBvZmZzZXQgdG8gYWRkIHRvIHRoZSBk bWEgYWRkcmVzc2VzIG9mIHRoZSBzZyBsaXN0LgorICoKKyAqIENyZWF0ZSBhIHN0cnVjdCBzZ190 YWJsZSwgaW5pdGlhbGl6aW5nIGl0IGZyb20gYSBzdHJ1Y3QgZHJtX21tX25vZGUsCisgKiB0YWtp bmcgYSBtYXhpbXVtIHNlZ21lbnQgbGVuZ3RoIGludG8gYWNjb3VudCwgc3BsaXR0aW5nIGludG8g c2VnbWVudHMKKyAqIGlmIG5lY2Vzc2FyeS4KKyAqCisgKiBSZXR1cm46IEEgcG9pbnRlciB0byBh IGttYWxsb2NlZCBzdHJ1Y3Qgc2dfdGFibGUgb24gc3VjY2VzcywgbmVnYXRpdmUKKyAqIGVycm9y IGNvZGUgY2FzdCB0byBhbiBlcnJvciBwb2ludGVyIG9uIGZhaWx1cmUuCisgKi8KK3N0cnVjdCBz Z190YWJsZSAqaTkxNV9zZ19mcm9tX21tX25vZGUoY29uc3Qgc3RydWN0IGRybV9tbV9ub2RlICpu b2RlLAorCQkJCSAgICAgIHU2NCByZWdpb25fc3RhcnQpCit7CisJY29uc3QgdTY0IG1heF9zZWdt ZW50ID0gU1pfMUc7IC8qIERvIHdlIGhhdmUgYSBsaW1pdCBvbiB0aGlzPyAqLworCXU2NCBzZWdt ZW50X3BhZ2VzID0gbWF4X3NlZ21lbnQgPj4gUEFHRV9TSElGVDsKKwl1NjQgYmxvY2tfc2l6ZSwg b2Zmc2V0LCBwcmV2X2VuZDsKKwlzdHJ1Y3Qgc2dfdGFibGUgKnN0OworCXN0cnVjdCBzY2F0dGVy bGlzdCAqc2c7CisKKwlzdCA9IGttYWxsb2Moc2l6ZW9mKCpzdCksIEdGUF9LRVJORUwpOworCWlm ICghc3QpCisJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOworCisJaWYgKHNnX2FsbG9jX3RhYmxl KHN0LCBESVZfUk9VTkRfVVAobm9kZS0+c2l6ZSwgc2VnbWVudF9wYWdlcyksCisJCQkgICBHRlBf S0VSTkVMKSkgeworCQlrZnJlZShzdCk7CisJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOworCX0K KworCXNnID0gc3QtPnNnbDsKKwlzdC0+bmVudHMgPSAwOworCXByZXZfZW5kID0gKHJlc291cmNl X3NpemVfdCktMTsKKwlibG9ja19zaXplID0gbm9kZS0+c2l6ZSA8PCBQQUdFX1NISUZUOworCW9m ZnNldCA9IG5vZGUtPnN0YXJ0IDw8IFBBR0VfU0hJRlQ7CisKKwl3aGlsZSAoYmxvY2tfc2l6ZSkg eworCQl1NjQgbGVuOworCisJCWlmIChvZmZzZXQgIT0gcHJldl9lbmQgfHwgc2ctPmxlbmd0aCA+ PSBtYXhfc2VnbWVudCkgeworCQkJaWYgKHN0LT5uZW50cykKKwkJCQlzZyA9IF9fc2dfbmV4dChz Zyk7CisKKwkJCXNnX2RtYV9hZGRyZXNzKHNnKSA9IHJlZ2lvbl9zdGFydCArIG9mZnNldDsKKwkJ CXNnX2RtYV9sZW4oc2cpID0gMDsKKwkJCXNnLT5sZW5ndGggPSAwOworCQkJc3QtPm5lbnRzKys7 CisJCX0KKworCQlsZW4gPSBtaW4oYmxvY2tfc2l6ZSwgbWF4X3NlZ21lbnQgLSBzZy0+bGVuZ3Ro KTsKKwkJc2ctPmxlbmd0aCArPSBsZW47CisJCXNnX2RtYV9sZW4oc2cpICs9IGxlbjsKKworCQlv ZmZzZXQgKz0gbGVuOworCQlibG9ja19zaXplIC09IGxlbjsKKworCQlwcmV2X2VuZCA9IG9mZnNl dDsKKwl9CisKKwlzZ19tYXJrX2VuZChzZyk7CisJaTkxNV9zZ190cmltKHN0KTsKKworCXJldHVy biBzdDsKK30KKwogI2lmIElTX0VOQUJMRUQoQ09ORklHX0RSTV9JOTE1X1NFTEZURVNUKQogI2lu Y2x1ZGUgInNlbGZ0ZXN0cy9zY2F0dGVybGlzdC5jIgogI2VuZGlmCmRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X3NjYXR0ZXJsaXN0LmggYi9kcml2ZXJzL2dwdS9kcm0vaTkx NS9pOTE1X3NjYXR0ZXJsaXN0LmgKaW5kZXggYjk2YmFhZDY2YTNhLi41YWNjYTQ1ZWE5ODEgMTAw NjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfc2NhdHRlcmxpc3QuaAorKysgYi9k cml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X3NjYXR0ZXJsaXN0LmgKQEAgLTEzLDYgKzEzLDggQEAK IAogI2luY2x1ZGUgImk5MTVfZ2VtLmgiCiAKK3N0cnVjdCBkcm1fbW1fbm9kZTsKKwogLyoKICAq IE9wdGltaXNlZCBTR0wgaXRlcmF0b3IgZm9yIEdFTSBvYmplY3RzCiAgKi8KQEAgLTE0MSw0ICsx NDMsNiBAQCBzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludCBpOTE1X3NnX3NlZ21lbnRfc2l6ZSh2 b2lkKQogCiBib29sIGk5MTVfc2dfdHJpbShzdHJ1Y3Qgc2dfdGFibGUgKm9yaWdfc3QpOwogCitz dHJ1Y3Qgc2dfdGFibGUgKmk5MTVfc2dfZnJvbV9tbV9ub2RlKGNvbnN0IHN0cnVjdCBkcm1fbW1f bm9kZSAqbm9kZSwKKwkJCQkgICAgICB1NjQgcmVnaW9uX3N0YXJ0KTsKICNlbmRpZgpkaWZmIC0t Z2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfbWVtb3J5X3JlZ2lvbi5jIGIvZHJpdmVy cy9ncHUvZHJtL2k5MTUvaW50ZWxfbWVtb3J5X3JlZ2lvbi5jCmluZGV4IGQ5OGU4YjgxZDMyMi4u NDA5MmNjOTg3Njc5IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9tZW1v cnlfcmVnaW9uLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfbWVtb3J5X3JlZ2lv bi5jCkBAIC0yOCw2ICsyOCwxMSBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHsKIAl9LAogfTsKIAor c3RydWN0IGludGVsX3JlZ2lvbl9yZXNlcnZlIHsKKwlzdHJ1Y3QgbGlzdF9oZWFkIGxpbms7CisJ dm9pZCAqbm9kZTsKK307CisKIHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICoKIGludGVsX21l bW9yeV9yZWdpb25fbG9va3VwKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1LAogCQkJICAg dTE2IGNsYXNzLCB1MTYgaW5zdGFuY2UpCkBAIC01OCwxNDYgKzYzLDYxIEBAIGludGVsX21lbW9y eV9yZWdpb25fYnlfdHlwZShzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqaTkxNSwKIAlyZXR1cm4g TlVMTDsKIH0KIAotc3RhdGljIHU2NAotaW50ZWxfbWVtb3J5X3JlZ2lvbl9mcmVlX3BhZ2VzKHN0 cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCi0JCQkgICAgICAgc3RydWN0IGxpc3RfaGVh ZCAqYmxvY2tzKQorLyoqCisgKiBpbnRlbF9tZW1vcnlfcmVnaW9uX3VucmVzZXJ2ZSAtIFVucmVz ZXJ2ZSBhbGwgcHJldmlvdXNseSByZXNlcnZlZAorICogcmFuZ2VzCisgKiBAbWVtOiBUaGUgcmVn aW9uIGNvbnRhaW5pbmcgdGhlIHJlc2VydmVkIHJhbmdlcy4KKyAqLwordm9pZCBpbnRlbF9tZW1v cnlfcmVnaW9uX3VucmVzZXJ2ZShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtKQogewot CXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jaywgKm9uOwotCXU2NCBzaXplID0gMDsKKwlz dHJ1Y3QgaW50ZWxfcmVnaW9uX3Jlc2VydmUgKnJlc2VydmUsICpuZXh0OwogCi0JbGlzdF9mb3Jf ZWFjaF9lbnRyeV9zYWZlKGJsb2NrLCBvbiwgYmxvY2tzLCBsaW5rKSB7Ci0JCXNpemUgKz0gaTkx NV9idWRkeV9ibG9ja19zaXplKCZtZW0tPm1tLCBibG9jayk7Ci0JCWk5MTVfYnVkZHlfZnJlZSgm bWVtLT5tbSwgYmxvY2spOwotCX0KLQlJTklUX0xJU1RfSEVBRChibG9ja3MpOworCWlmICghbWVt LT5wcml2X29wcyB8fCAhbWVtLT5wcml2X29wcy0+ZnJlZSkKKwkJcmV0dXJuOwogCi0JcmV0dXJu IHNpemU7Ci19Ci0KLXZvaWQKLV9faW50ZWxfbWVtb3J5X3JlZ2lvbl9wdXRfcGFnZXNfYnVkZHko c3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbSwKLQkJCQkgICAgICBzdHJ1Y3QgbGlzdF9o ZWFkICpibG9ja3MpCi17CiAJbXV0ZXhfbG9jaygmbWVtLT5tbV9sb2NrKTsKLQltZW0tPmF2YWls ICs9IGludGVsX21lbW9yeV9yZWdpb25fZnJlZV9wYWdlcyhtZW0sIGJsb2Nrcyk7Ci0JbXV0ZXhf dW5sb2NrKCZtZW0tPm1tX2xvY2spOwotfQotCi12b2lkCi1fX2ludGVsX21lbW9yeV9yZWdpb25f cHV0X2Jsb2NrX2J1ZGR5KHN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jaykKLXsKLQlzdHJ1 Y3QgbGlzdF9oZWFkIGJsb2NrczsKLQotCUlOSVRfTElTVF9IRUFEKCZibG9ja3MpOwotCWxpc3Rf YWRkKCZibG9jay0+bGluaywgJmJsb2Nrcyk7Ci0JX19pbnRlbF9tZW1vcnlfcmVnaW9uX3B1dF9w YWdlc19idWRkeShibG9jay0+cHJpdmF0ZSwgJmJsb2Nrcyk7Ci19Ci0KLWludAotX19pbnRlbF9t ZW1vcnlfcmVnaW9uX2dldF9wYWdlc19idWRkeShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAq bWVtLAotCQkJCSAgICAgIHJlc291cmNlX3NpemVfdCBzaXplLAotCQkJCSAgICAgIHVuc2lnbmVk IGludCBmbGFncywKLQkJCQkgICAgICBzdHJ1Y3QgbGlzdF9oZWFkICpibG9ja3MpCi17Ci0JdW5z aWduZWQgaW50IG1pbl9vcmRlciA9IDA7Ci0JdW5zaWduZWQgbG9uZyBuX3BhZ2VzOwotCi0JR0VN X0JVR19PTighSVNfQUxJR05FRChzaXplLCBtZW0tPm1tLmNodW5rX3NpemUpKTsKLQlHRU1fQlVH X09OKCFsaXN0X2VtcHR5KGJsb2NrcykpOwotCi0JaWYgKGZsYWdzICYgSTkxNV9BTExPQ19NSU5f UEFHRV9TSVpFKSB7Ci0JCW1pbl9vcmRlciA9IGlsb2cyKG1lbS0+bWluX3BhZ2Vfc2l6ZSkgLQot CQkJICAgIGlsb2cyKG1lbS0+bW0uY2h1bmtfc2l6ZSk7Ci0JfQotCi0JaWYgKGZsYWdzICYgSTkx NV9BTExPQ19DT05USUdVT1VTKSB7Ci0JCXNpemUgPSByb3VuZHVwX3Bvd19vZl90d28oc2l6ZSk7 Ci0JCW1pbl9vcmRlciA9IGlsb2cyKHNpemUpIC0gaWxvZzIobWVtLT5tbS5jaHVua19zaXplKTsK KwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUocmVzZXJ2ZSwgbmV4dCwgJm1lbS0+cmVzZXJ2ZWQs IGxpbmspIHsKKwkJbGlzdF9kZWwoJnJlc2VydmUtPmxpbmspOworCQltZW0tPnByaXZfb3BzLT5m cmVlKG1lbSwgcmVzZXJ2ZS0+bm9kZSk7CisJCWtmcmVlKHJlc2VydmUpOwogCX0KLQotCWlmIChz aXplID4gbWVtLT5tbS5zaXplKQotCQlyZXR1cm4gLUUyQklHOwotCi0Jbl9wYWdlcyA9IHNpemUg Pj4gaWxvZzIobWVtLT5tbS5jaHVua19zaXplKTsKLQotCW11dGV4X2xvY2soJm1lbS0+bW1fbG9j ayk7Ci0KLQlkbyB7Ci0JCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jazsKLQkJdW5zaWdu ZWQgaW50IG9yZGVyOwotCi0JCW9yZGVyID0gZmxzKG5fcGFnZXMpIC0gMTsKLQkJR0VNX0JVR19P TihvcmRlciA+IG1lbS0+bW0ubWF4X29yZGVyKTsKLQkJR0VNX0JVR19PTihvcmRlciA8IG1pbl9v cmRlcik7Ci0KLQkJZG8gewotCQkJYmxvY2sgPSBpOTE1X2J1ZGR5X2FsbG9jKCZtZW0tPm1tLCBv cmRlcik7Ci0JCQlpZiAoIUlTX0VSUihibG9jaykpCi0JCQkJYnJlYWs7Ci0KLQkJCWlmIChvcmRl ci0tID09IG1pbl9vcmRlcikKLQkJCQlnb3RvIGVycl9mcmVlX2Jsb2NrczsKLQkJfSB3aGlsZSAo MSk7Ci0KLQkJbl9wYWdlcyAtPSBCSVQob3JkZXIpOwotCi0JCWJsb2NrLT5wcml2YXRlID0gbWVt OwotCQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGluaywgYmxvY2tzKTsKLQotCQlpZiAoIW5fcGFn ZXMpCi0JCQlicmVhazsKLQl9IHdoaWxlICgxKTsKLQotCW1lbS0+YXZhaWwgLT0gc2l6ZTsKIAlt dXRleF91bmxvY2soJm1lbS0+bW1fbG9jayk7Ci0JcmV0dXJuIDA7Ci0KLWVycl9mcmVlX2Jsb2Nr czoKLQlpbnRlbF9tZW1vcnlfcmVnaW9uX2ZyZWVfcGFnZXMobWVtLCBibG9ja3MpOwotCW11dGV4 X3VubG9jaygmbWVtLT5tbV9sb2NrKTsKLQlyZXR1cm4gLUVOWElPOwogfQogCi1zdHJ1Y3QgaTkx NV9idWRkeV9ibG9jayAqCi1fX2ludGVsX21lbW9yeV9yZWdpb25fZ2V0X2Jsb2NrX2J1ZGR5KHN0 cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCi0JCQkJICAgICAgcmVzb3VyY2Vfc2l6ZV90 IHNpemUsCi0JCQkJICAgICAgdW5zaWduZWQgaW50IGZsYWdzKQorLyoqCisgKiBpbnRlbF9tZW1v cnlfcmVnaW9uX3Jlc2VydmUgLSBSZXNlcnZlIGEgbWVtb3J5IHJhbmdlCisgKiBAbWVtOiBUaGUg cmVnaW9uIGZvciB3aGljaCB3ZSB3YW50IHRvIHJlc2VydmUgYSByYW5nZS4KKyAqIEBvZmZzZXQ6 IFN0YXJ0IG9mIHRoZSByYW5nZSB0byByZXNlcnZlLgorICogQHNpemU6IFRoZSBzaXplIG9mIHRo ZSByYW5nZSB0byByZXNlcnZlLgorICoKKyAqIFJldHVybjogMCBvbiBzdWNjZXNzLCBuZWdhdGl2 ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCisgKi8KK2ludCBpbnRlbF9tZW1vcnlfcmVnaW9uX3Jl c2VydmUoc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbSwKKwkJCQlyZXNvdXJjZV9zaXpl X3Qgb2Zmc2V0LAorCQkJCXJlc291cmNlX3NpemVfdCBzaXplKQogewotCXN0cnVjdCBpOTE1X2J1 ZGR5X2Jsb2NrICpibG9jazsKLQlMSVNUX0hFQUQoYmxvY2tzKTsKIAlpbnQgcmV0OworCXN0cnVj dCBpbnRlbF9yZWdpb25fcmVzZXJ2ZSAqcmVzZXJ2ZTsKIAotCXJldCA9IF9faW50ZWxfbWVtb3J5 X3JlZ2lvbl9nZXRfcGFnZXNfYnVkZHkobWVtLCBzaXplLCBmbGFncywgJmJsb2Nrcyk7Ci0JaWYg KHJldCkKLQkJcmV0dXJuIEVSUl9QVFIocmV0KTsKKwlpZiAoIW1lbS0+cHJpdl9vcHMgfHwgIW1l bS0+cHJpdl9vcHMtPnJlc2VydmUpCisJCXJldHVybiAtRUlOVkFMOwogCi0JYmxvY2sgPSBsaXN0 X2ZpcnN0X2VudHJ5KCZibG9ja3MsIHR5cGVvZigqYmxvY2spLCBsaW5rKTsKLQlsaXN0X2RlbF9p bml0KCZibG9jay0+bGluayk7Ci0JcmV0dXJuIGJsb2NrOwotfQorCXJlc2VydmUgPSBremFsbG9j KHNpemVvZigqcmVzZXJ2ZSksIEdGUF9LRVJORUwpOworCWlmICghcmVzZXJ2ZSkKKwkJcmV0dXJu IC1FTk9NRU07CiAKLWludCBpbnRlbF9tZW1vcnlfcmVnaW9uX2luaXRfYnVkZHkoc3RydWN0IGlu dGVsX21lbW9yeV9yZWdpb24gKm1lbSkKLXsKLQlyZXR1cm4gaTkxNV9idWRkeV9pbml0KCZtZW0t Pm1tLCByZXNvdXJjZV9zaXplKCZtZW0tPnJlZ2lvbiksCi0JCQkgICAgICAgUEFHRV9TSVpFKTsK LX0KLQotdm9pZCBpbnRlbF9tZW1vcnlfcmVnaW9uX3JlbGVhc2VfYnVkZHkoc3RydWN0IGludGVs X21lbW9yeV9yZWdpb24gKm1lbSkKLXsKLQlpOTE1X2J1ZGR5X2ZyZWVfbGlzdCgmbWVtLT5tbSwg Jm1lbS0+cmVzZXJ2ZWQpOwotCWk5MTVfYnVkZHlfZmluaSgmbWVtLT5tbSk7Ci19Ci0KLWludCBp bnRlbF9tZW1vcnlfcmVnaW9uX3Jlc2VydmUoc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1l bSwKLQkJCQl1NjQgb2Zmc2V0LCB1NjQgc2l6ZSkKLXsKLQlpbnQgcmV0OworCXJlc2VydmUtPm5v ZGUgPSBtZW0tPnByaXZfb3BzLT5yZXNlcnZlKG1lbSwgb2Zmc2V0LCBzaXplKTsKKwlpZiAoSVNf RVJSKHJlc2VydmUtPm5vZGUpKSB7CisJCXJldCA9IFBUUl9FUlIocmVzZXJ2ZS0+bm9kZSk7CisJ CWtmcmVlKHJlc2VydmUpOworCQlyZXR1cm4gcmV0OworCX0KIAogCW11dGV4X2xvY2soJm1lbS0+ bW1fbG9jayk7Ci0JcmV0ID0gaTkxNV9idWRkeV9hbGxvY19yYW5nZSgmbWVtLT5tbSwgJm1lbS0+ cmVzZXJ2ZWQsIG9mZnNldCwgc2l6ZSk7CisJbGlzdF9hZGRfdGFpbCgmcmVzZXJ2ZS0+bGluaywg Jm1lbS0+cmVzZXJ2ZWQpOwogCW11dGV4X3VubG9jaygmbWVtLT5tbV9sb2NrKTsKIAotCXJldHVy biByZXQ7CisJcmV0dXJuIDA7CiB9CiAKIHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICoKQEAg LTIwNiw2ICsxMjYsOCBAQCBpbnRlbF9tZW1vcnlfcmVnaW9uX2NyZWF0ZShzdHJ1Y3QgZHJtX2k5 MTVfcHJpdmF0ZSAqaTkxNSwKIAkJCSAgIHJlc291cmNlX3NpemVfdCBzaXplLAogCQkJICAgcmVz b3VyY2Vfc2l6ZV90IG1pbl9wYWdlX3NpemUsCiAJCQkgICByZXNvdXJjZV9zaXplX3QgaW9fc3Rh cnQsCisJCQkgICB1MTYgdHlwZSwKKwkJCSAgIHUxNiBpbnN0YW5jZSwKIAkJCSAgIGNvbnN0IHN0 cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uX29wcyAqb3BzKQogewogCXN0cnVjdCBpbnRlbF9tZW1v cnlfcmVnaW9uICptZW07CkBAIC0yMjIsNiArMTQ0LDggQEAgaW50ZWxfbWVtb3J5X3JlZ2lvbl9j cmVhdGUoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmk5MTUsCiAJbWVtLT5vcHMgPSBvcHM7CiAJ bWVtLT50b3RhbCA9IHNpemU7CiAJbWVtLT5hdmFpbCA9IG1lbS0+dG90YWw7CisJbWVtLT50eXBl ID0gdHlwZTsKKwltZW0tPmluc3RhbmNlID0gaW5zdGFuY2U7CiAKIAltdXRleF9pbml0KCZtZW0t Pm9iamVjdHMubG9jayk7CiAJSU5JVF9MSVNUX0hFQUQoJm1lbS0+b2JqZWN0cy5saXN0KTsKQEAg LTI1OSw2ICsxODMsNyBAQCBzdGF0aWMgdm9pZCBfX2ludGVsX21lbW9yeV9yZWdpb25fZGVzdHJv eShzdHJ1Y3Qga3JlZiAqa3JlZikKIAlzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtID0K IAkJY29udGFpbmVyX29mKGtyZWYsIHR5cGVvZigqbWVtKSwga3JlZik7CiAKKwlpbnRlbF9tZW1v cnlfcmVnaW9uX3VucmVzZXJ2ZShtZW0pOwogCWlmIChtZW0tPm9wcy0+cmVsZWFzZSkKIAkJbWVt LT5vcHMtPnJlbGVhc2UobWVtKTsKIApAQCAtMjk2LDE1ICsyMjEsMTUgQEAgaW50IGludGVsX21l bW9yeV9yZWdpb25zX2h3X3Byb2JlKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1KQogCQlp bnN0YW5jZSA9IGludGVsX3JlZ2lvbl9tYXBbaV0uaW5zdGFuY2U7CiAJCXN3aXRjaCAodHlwZSkg ewogCQljYXNlIElOVEVMX01FTU9SWV9TWVNURU06Ci0JCQltZW0gPSBpOTE1X2dlbV9zaG1lbV9z ZXR1cChpOTE1KTsKKwkJCW1lbSA9IGk5MTVfZ2VtX3NobWVtX3NldHVwKGk5MTUsIHR5cGUsIGlu c3RhbmNlKTsKIAkJCWJyZWFrOwogCQljYXNlIElOVEVMX01FTU9SWV9TVE9MRU5fTE9DQUw6Ci0J CQltZW0gPSBpOTE1X2dlbV9zdG9sZW5fbG1lbV9zZXR1cChpOTE1KTsKKwkJCW1lbSA9IGk5MTVf Z2VtX3N0b2xlbl9sbWVtX3NldHVwKGk5MTUsIHR5cGUsIGluc3RhbmNlKTsKIAkJCWlmICghSVNf RVJSKG1lbSkpCiAJCQkJaTkxNS0+bW0uc3RvbGVuX3JlZ2lvbiA9IG1lbTsKIAkJCWJyZWFrOwog CQljYXNlIElOVEVMX01FTU9SWV9TVE9MRU5fU1lTVEVNOgotCQkJbWVtID0gaTkxNV9nZW1fc3Rv bGVuX3NtZW1fc2V0dXAoaTkxNSk7CisJCQltZW0gPSBpOTE1X2dlbV9zdG9sZW5fc21lbV9zZXR1 cChpOTE1LCB0eXBlLCBpbnN0YW5jZSk7CiAJCQlpZiAoIUlTX0VSUihtZW0pKQogCQkJCWk5MTUt Pm1tLnN0b2xlbl9yZWdpb24gPSBtZW07CiAJCQlicmVhazsKQEAgLTMyMSw5ICsyNDYsNiBAQCBp bnQgaW50ZWxfbWVtb3J5X3JlZ2lvbnNfaHdfcHJvYmUoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUg Kmk5MTUpCiAJCX0KIAogCQltZW0tPmlkID0gaTsKLQkJbWVtLT50eXBlID0gdHlwZTsKLQkJbWVt LT5pbnN0YW5jZSA9IGluc3RhbmNlOwotCiAJCWk5MTUtPm1tLnJlZ2lvbnNbaV0gPSBtZW07CiAJ fQogCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9tZW1vcnlfcmVnaW9u LmggYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9tZW1vcnlfcmVnaW9uLmgKaW5kZXggZDI0 Y2U1YTBiMzBiLi5lNjljZGUxM2RhZjIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1 L2ludGVsX21lbW9yeV9yZWdpb24uaAorKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9t ZW1vcnlfcmVnaW9uLmgKQEAgLTEzLDggKzEzLDYgQEAKICNpbmNsdWRlIDxkcm0vZHJtX21tLmg+ CiAjaW5jbHVkZSA8ZHJtL2k5MTVfZHJtLmg+CiAKLSNpbmNsdWRlICJpOTE1X2J1ZGR5LmgiCi0K IHN0cnVjdCBkcm1faTkxNV9wcml2YXRlOwogc3RydWN0IGRybV9pOTE1X2dlbV9vYmplY3Q7CiBz dHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbjsKQEAgLTI1LDYgKzIzLDcgQEAgZW51bSBpbnRlbF9t ZW1vcnlfdHlwZSB7CiAJSU5URUxfTUVNT1JZX0xPQ0FMID0gSTkxNV9NRU1PUllfQ0xBU1NfREVW SUNFLAogCUlOVEVMX01FTU9SWV9TVE9MRU5fU1lTVEVNLAogCUlOVEVMX01FTU9SWV9TVE9MRU5f TE9DQUwsCisJSU5URUxfTUVNT1JZX01PQ0ssCiB9OwogCiBlbnVtIGludGVsX3JlZ2lvbl9pZCB7 CkBAIC01OSwxMCArNTgsMTkgQEAgc3RydWN0IGludGVsX21lbW9yeV9yZWdpb25fb3BzIHsKIAkJ CSAgIHVuc2lnbmVkIGludCBmbGFncyk7CiB9OwogCitzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lv bl9wcml2YXRlX29wcyB7CisJdm9pZCAqKCpyZXNlcnZlKShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3Jl Z2lvbiAqbWVtLAorCQkJIHJlc291cmNlX3NpemVfdCBvZmZzZXQsCisJCQkgcmVzb3VyY2Vfc2l6 ZV90IHNpemUpOworCXZvaWQgKCpmcmVlKShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVt LAorCQkgICAgIHZvaWQgKm5vZGUpOworfTsKKwogc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24g ewogCXN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1OwogCiAJY29uc3Qgc3RydWN0IGludGVs X21lbW9yeV9yZWdpb25fb3BzICpvcHM7CisJY29uc3Qgc3RydWN0IGludGVsX21lbW9yeV9yZWdp b25fcHJpdmF0ZV9vcHMgKnByaXZfb3BzOwogCiAJc3RydWN0IGlvX21hcHBpbmcgaW9tYXA7CiAJ c3RydWN0IHJlc291cmNlIHJlZ2lvbjsKQEAgLTcwLDcgKzc4LDYgQEAgc3RydWN0IGludGVsX21l bW9yeV9yZWdpb24gewogCS8qIEZvciBmYWtlIExNRU0gKi8KIAlzdHJ1Y3QgZHJtX21tX25vZGUg ZmFrZV9tYXBwYWJsZTsKIAotCXN0cnVjdCBpOTE1X2J1ZGR5X21tIG1tOwogCXN0cnVjdCBtdXRl eCBtbV9sb2NrOwogCiAJc3RydWN0IGtyZWYga3JlZjsKQEAgLTk1LDM2ICsxMDIsMjYgQEAgc3Ry dWN0IGludGVsX21lbW9yeV9yZWdpb24gewogCQlzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7CiAJCXN0 cnVjdCBsaXN0X2hlYWQgcHVyZ2VhYmxlOwogCX0gb2JqZWN0czsKKworCXNpemVfdCBjaHVua19z aXplOworCXVuc2lnbmVkIGludCBtYXhfb3JkZXI7CisJYm9vbCBpc19yYW5nZV9tYW5hZ2VyOwor CisJdm9pZCAqcmVnaW9uX3ByaXZhdGU7CiB9OwogCiBzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lv biAqCiBpbnRlbF9tZW1vcnlfcmVnaW9uX2xvb2t1cChzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAq aTkxNSwKIAkJCSAgIHUxNiBjbGFzcywgdTE2IGluc3RhbmNlKTsKIAotaW50IGludGVsX21lbW9y eV9yZWdpb25faW5pdF9idWRkeShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtKTsKLXZv aWQgaW50ZWxfbWVtb3J5X3JlZ2lvbl9yZWxlYXNlX2J1ZGR5KHN0cnVjdCBpbnRlbF9tZW1vcnlf cmVnaW9uICptZW0pOwotCi1pbnQgX19pbnRlbF9tZW1vcnlfcmVnaW9uX2dldF9wYWdlc19idWRk eShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtLAotCQkJCQkgIHJlc291cmNlX3NpemVf dCBzaXplLAotCQkJCQkgIHVuc2lnbmVkIGludCBmbGFncywKLQkJCQkJICBzdHJ1Y3QgbGlzdF9o ZWFkICpibG9ja3MpOwotc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKgotX19pbnRlbF9tZW1vcnlf cmVnaW9uX2dldF9ibG9ja19idWRkeShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtLAot CQkJCSAgICAgIHJlc291cmNlX3NpemVfdCBzaXplLAotCQkJCSAgICAgIHVuc2lnbmVkIGludCBm bGFncyk7Ci12b2lkIF9faW50ZWxfbWVtb3J5X3JlZ2lvbl9wdXRfcGFnZXNfYnVkZHkoc3RydWN0 IGludGVsX21lbW9yeV9yZWdpb24gKm1lbSwKLQkJCQkJICAgc3RydWN0IGxpc3RfaGVhZCAqYmxv Y2tzKTsKLXZvaWQgX19pbnRlbF9tZW1vcnlfcmVnaW9uX3B1dF9ibG9ja19idWRkeShzdHJ1Y3Qg aTkxNV9idWRkeV9ibG9jayAqYmxvY2spOwotCi1pbnQgaW50ZWxfbWVtb3J5X3JlZ2lvbl9yZXNl cnZlKHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCi0JCQkJdTY0IG9mZnNldCwgdTY0 IHNpemUpOwotCiBzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqCiBpbnRlbF9tZW1vcnlfcmVn aW9uX2NyZWF0ZShzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqaTkxNSwKIAkJCSAgIHJlc291cmNl X3NpemVfdCBzdGFydCwKIAkJCSAgIHJlc291cmNlX3NpemVfdCBzaXplLAogCQkJICAgcmVzb3Vy Y2Vfc2l6ZV90IG1pbl9wYWdlX3NpemUsCiAJCQkgICByZXNvdXJjZV9zaXplX3QgaW9fc3RhcnQs CisJCQkgICB1MTYgdHlwZSwKKwkJCSAgIHUxNiBpbnN0YW5jZSwKIAkJCSAgIGNvbnN0IHN0cnVj dCBpbnRlbF9tZW1vcnlfcmVnaW9uX29wcyAqb3BzKTsKIAogc3RydWN0IGludGVsX21lbW9yeV9y ZWdpb24gKgpAQCAtMTQxLDQgKzEzOCw5IEBAIF9fcHJpbnRmKDIsIDMpIHZvaWQKIGludGVsX21l bW9yeV9yZWdpb25fc2V0X25hbWUoc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbSwKIAkJ CSAgICAgY29uc3QgY2hhciAqZm10LCAuLi4pOwogCit2b2lkIGludGVsX21lbW9yeV9yZWdpb25f dW5yZXNlcnZlKHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0pOworCitpbnQgaW50ZWxf bWVtb3J5X3JlZ2lvbl9yZXNlcnZlKHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCisJ CQkJcmVzb3VyY2Vfc2l6ZV90IG9mZnNldCwKKwkJCQlyZXNvdXJjZV9zaXplX3Qgc2l6ZSk7CiAj ZW5kaWYKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX3JlZ2lvbl90dG0u YyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX3JlZ2lvbl90dG0uYwpuZXcgZmlsZSBtb2Rl IDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLmM4YWMxMThjMjFmNgotLS0gL2Rldi9udWxsCisr KyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX3JlZ2lvbl90dG0uYwpAQCAtMCwwICsxLDIy MCBAQAorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1JVAorLyoKKyAqIENvcHlyaWdodCDC qSAyMDIxIEludGVsIENvcnBvcmF0aW9uCisgKi8KKyNpbmNsdWRlIDxkcm0vdHRtL3R0bV9ib19k cml2ZXIuaD4KKyNpbmNsdWRlIDxkcm0vdHRtL3R0bV9kZXZpY2UuaD4KKworI2luY2x1ZGUgImk5 MTVfZHJ2LmgiCisjaW5jbHVkZSAiaTkxNV9zY2F0dGVybGlzdC5oIgorCisjaW5jbHVkZSAiaW50 ZWxfcmVnaW9uX3R0bS5oIgorCisvKioKKyAqIERPQzogVFRNIHN1cHBvcnQgc3RydWN0dXJlCisg KgorICogVGhlIGNvZGUgaW4gdGhpcyBmaWxlIGRlYWxzIHdpdGggc2V0dGluZyB1cCBtZW1vcnkg bWFuYWdlcnMgZm9yIFRUTQorICogTE1FTSBhbmQgTU9DSyByZWdpb25zIGFuZCBjb252ZXJ0aW5n IHRoZSBvdXRwdXQgZnJvbQorICogdGhlIG1hbmFnZXJzIHRvIHN0cnVjdCBzZ190YWJsZSwgQmFz aWNhbGx5IHByb3ZpZGluZyB0aGUgbWFwcGluZyBmcm9tCisgKiBpOTE1IEdFTSByZWdpb25zIHRv IFRUTSBtZW1vcnkgdHlwZXMgYW5kIHJlc291cmNlIG1hbmFnZXJzLgorICovCisKKy8qIEEgWmVy by1pbml0aWFsaXplZCBkcml2ZXIgZm9yIG5vdy4gV2UgZG9uJ3QgaGF2ZSBhIFRUTSBiYWNrZW5k IHlldC4gKi8KK3N0YXRpYyBzdHJ1Y3QgdHRtX2RldmljZV9mdW5jcyBpOTE1X3R0bV9ib19kcml2 ZXI7CisKKy8qKgorICogaW50ZWxfcmVnaW9uX3R0bV9kZXZpY2VfaW5pdCAtIEluaXRpYWxpemUg YSBUVE0gZGV2aWNlCisgKiBAZGV2X3ByaXY6IFBvaW50ZXIgdG8gYW4gaTkxNSBkZXZpY2UgcHJp dmF0ZSBzdHJ1Y3R1cmUuCisgKgorICogUmV0dXJuOiAwIG9uIHN1Y2Nlc3MsIG5lZ2F0aXZlIGVy cm9yIGNvZGUgb24gZmFpbHVyZS4KKyAqLworaW50IGludGVsX3JlZ2lvbl90dG1fZGV2aWNlX2lu aXQoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmRldl9wcml2KQoreworCXN0cnVjdCBkcm1fZGV2 aWNlICpkcm0gPSAmZGV2X3ByaXYtPmRybTsKKworCXJldHVybiB0dG1fZGV2aWNlX2luaXQoJmRl dl9wcml2LT5iZGV2LCAmaTkxNV90dG1fYm9fZHJpdmVyLAorCQkJICAgICAgIGRybS0+ZGV2LCBk cm0tPmFub25faW5vZGUtPmlfbWFwcGluZywKKwkJCSAgICAgICBkcm0tPnZtYV9vZmZzZXRfbWFu YWdlciwgZmFsc2UsIGZhbHNlKTsKK30KKworLyoqCisgKiBpbnRlbF9yZWdpb25fdHRtX2Rldmlj ZV9maW5pIC0gRmluYWxpemUgYSBUVE0gZGV2aWNlCisgKiBAZGV2X3ByaXY6IFBvaW50ZXIgdG8g YW4gaTkxNSBkZXZpY2UgcHJpdmF0ZSBzdHJ1Y3R1cmUuCisgKi8KK3ZvaWQgaW50ZWxfcmVnaW9u X3R0bV9kZXZpY2VfZmluaShzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYpCit7CisJ dHRtX2RldmljZV9maW5pKCZkZXZfcHJpdi0+YmRldik7Cit9CisKKy8qCisgKiBNYXAgdGhlIGk5 MTUgbWVtb3J5IHJlZ2lvbnMgdG8gVFRNIG1lbW9yeSB0eXBlcy4gV2UgdXNlIHRoZQorICogZHJp dmVyLXByaXZhdGUgdHlwZXMgZm9yIG5vdywgcmVzZXJ2aW5nIFRUTV9QTF9WUkFNIGZvciBzdG9s ZW4KKyAqIG1lbW9yeSBhbmQgVFRNX1BMX1RUIGZvciBHR1RUIHVzZSBpZiBkZWNpZGVkIHRvIGlt cGxlbWVudCB0aGlzLgorICovCitzdGF0aWMgaW50IGludGVsX3JlZ2lvbl90b190dG1fdHlwZShz dHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtKQoreworCWludCB0eXBlOworCisJR0VNX0JV R19PTihtZW0tPnR5cGUgIT0gSU5URUxfTUVNT1JZX0xPQ0FMICYmCisJCSAgIG1lbS0+dHlwZSAh PSBJTlRFTF9NRU1PUllfTU9DSyk7CisKKwl0eXBlID0gbWVtLT5pbnN0YW5jZSArIFRUTV9QTF9Q UklWOworCUdFTV9CVUdfT04odHlwZSA+PSBUVE1fTlVNX01FTV9UWVBFUyk7CisKKwlyZXR1cm4g dHlwZTsKK30KKworc3RhdGljIHZvaWQgKmludGVsX3JlZ2lvbl90dG1fbm9kZV9yZXNlcnZlKHN0 cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCisJCQkJCSAgIHJlc291cmNlX3NpemVfdCBv ZmZzZXQsCisJCQkJCSAgIHJlc291cmNlX3NpemVfdCBzaXplKQoreworCXN0cnVjdCB0dG1fcmVz b3VyY2VfbWFuYWdlciAqbWFuID0gbWVtLT5yZWdpb25fcHJpdmF0ZTsKKwlzdHJ1Y3QgdHRtX3Bs YWNlIHBsYWNlID0ge307CisJc3RydWN0IHR0bV9yZXNvdXJjZSByZXMgPSB7fTsKKwlzdHJ1Y3Qg dHRtX2J1ZmZlcl9vYmplY3QgbW9ja19ibyA9IHt9OworCWludCByZXQ7CisKKwkvKgorCSAqIEhh dmluZyB0byB1c2UgYSBtb2NrX2JvIGlzIHVuZm9ydHVuYXRlIGJ1dCBzdGVtcyBmcm9tIHNvbWUK KwkgKiBkcml2ZXJzIGhhdmluZyBwcml2YXRlIG1hbmFnZXJzIHRoYXQgaW5zaXN0IHRvIGtub3cg d2hhdCB0aGUKKwkgKiBhbGxvY2F0ZSBtZW1vcnkgaXMgaW50ZW5kZWQgZm9yLCB1c2luZyBpdCB0 byBzZW5kIHByaXZhdGUKKwkgKiBkYXRhIHRvIHRoZSBtYW5hZ2VyLiBBbHNvIHJlY2VudGx5IHRo ZSBibyBoYXMgYmVlbiB1c2VkIHRvIHNlbmQKKwkgKiBhbGlnbm1lbnQgaW5mbyB0byB0aGUgbWFu YWdlci4gQXNzdW1lIHRoYXQgYXBhcnQgZnJvbSB0aGUgbGF0dGVyLAorCSAqIG5vbmUgb2YgdGhl IG1hbmFnZXJzIHdlIHVzZSB3aWxsIGV2ZXIgYWNjZXNzIHRoZSBidWZmZXIgb2JqZWN0CisJICog bWVtYmVycywgaG9waW5nIHdlIGNhbiBwYXNzIHRoZSBhbGlnbm1lbnQgaW5mbyBpbiB0aGUKKwkg KiBzdHJ1Y3QgdHRtX3BsYWNlIGluIHRoZSBmdXR1cmUuCisJICovCisKKwlwbGFjZS5mcGZuID0g b2Zmc2V0ID4+IFBBR0VfU0hJRlQ7CisJcGxhY2UubHBmbiA9IHBsYWNlLmZwZm4gKyAoc2l6ZSA+ PiBQQUdFX1NISUZUKTsKKwlyZXMubnVtX3BhZ2VzID0gc2l6ZSA+PiBQQUdFX1NISUZUOworCXJl dCA9IG1hbi0+ZnVuYy0+YWxsb2MobWFuLCAmbW9ja19ibywgJnBsYWNlLCAmcmVzKTsKKwlpZiAo cmV0ID09IC1FTk9TUEMpCisJCXJldCA9IC1FTlhJTzsKKworCXJldHVybiByZXQgPyBFUlJfUFRS KHJldCkgOiByZXMubW1fbm9kZTsKK30KKworLyoqCisgKiBpbnRlbF9yZWdpb25fdHRtX25vZGVf ZnJlZSAtIEZyZWUgYSBub2RlIGFsbG9jYXRlZCBmcm9tIGEgcmVzb3VyY2UgbWFuYWdlcgorICog QG1lbTogVGhlIHJlZ2lvbiB0aGUgbm9kZSB3YXMgYWxsb2NhdGVkIGZyb20uCisgKiBAbm9kZTog VGhlIG9wYXF1ZSBub2RlIHJlcHJlc2VudGluZyBhbiBhbGxvY2F0aW9uLgorICovCit2b2lkIGlu dGVsX3JlZ2lvbl90dG1fbm9kZV9mcmVlKHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0s CisJCQkJdm9pZCAqbm9kZSkKK3sKKwlzdHJ1Y3QgdHRtX3Jlc291cmNlX21hbmFnZXIgKm1hbiA9 IG1lbS0+cmVnaW9uX3ByaXZhdGU7CisJc3RydWN0IHR0bV9yZXNvdXJjZSByZXMgPSB7fTsKKwor CXJlcy5tbV9ub2RlID0gbm9kZTsKKwltYW4tPmZ1bmMtPmZyZWUobWFuLCAmcmVzKTsKK30KKwor c3RhdGljIGNvbnN0IHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uX3ByaXZhdGVfb3BzIHByaXZf b3BzID0geworCS5yZXNlcnZlID0gaW50ZWxfcmVnaW9uX3R0bV9ub2RlX3Jlc2VydmUsCisJLmZy ZWUgPSBpbnRlbF9yZWdpb25fdHRtX25vZGVfZnJlZSwKK307CisKK2ludCBpbnRlbF9yZWdpb25f dHRtX2luaXQoc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbSkKK3sKKwlzdHJ1Y3QgdHRt X2RldmljZSAqYmRldiA9ICZtZW0tPmk5MTUtPmJkZXY7CisJaW50IG1lbV90eXBlID0gaW50ZWxf cmVnaW9uX3RvX3R0bV90eXBlKG1lbSk7CisJaW50IHJldDsKKworCXJldCA9IHR0bV9yYW5nZV9t YW5faW5pdChiZGV2LCBtZW1fdHlwZSwgZmFsc2UsCisJCQkJIHJlc291cmNlX3NpemUoJm1lbS0+ cmVnaW9uKSA+PiBQQUdFX1NISUZUKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJbWVt LT5jaHVua19zaXplID0gUEFHRV9TSVpFOworCW1lbS0+bWF4X29yZGVyID0KKwkJZ2V0X29yZGVy KHJvdW5kZG93bl9wb3dfb2ZfdHdvKHJlc291cmNlX3NpemUoJm1lbS0+cmVnaW9uKSkpOworCW1l bS0+aXNfcmFuZ2VfbWFuYWdlciA9IHRydWU7CisJbWVtLT5wcml2X29wcyA9ICZwcml2X29wczsK KwltZW0tPnJlZ2lvbl9wcml2YXRlID0gdHRtX21hbmFnZXJfdHlwZShiZGV2LCBtZW1fdHlwZSk7 CisKKwlyZXR1cm4gMDsKK30KKworLyoqCisgKiBpbnRlbF9yZWdpb25fdHRtX2ZpbmkgLSBGaW5h bGl6ZSBhIFRUTSByZWdpb24uCisgKiBAbWVtOiBUaGUgbWVtb3J5IHJlZ2lvbgorICoKKyAqIFRo aXMgZnVuY3Rpb25zIHRha2VzIGRvd24gdGhlIFRUTSByZXNvdXJjZSBtYW5hZ2VyIGFzc29jaWF0 ZWQgd2l0aCB0aGUKKyAqIG1lbW9yeSByZWdpb24sIGFuZCBpZiBpdCB3YXMgcmVnaXN0ZXJlZCB3 aXRoIHRoZSBUVE0gZGV2aWNlLAorICogcmVtb3ZlcyB0aGF0IHJlZ2lzdHJhdGlvbi4KKyAqLwor dm9pZCBpbnRlbF9yZWdpb25fdHRtX2Zpbmkoc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1l bSkKK3sKKwlpbnQgcmV0OworCisJcmV0ID0gdHRtX3JhbmdlX21hbl9maW5pKCZtZW0tPmk5MTUt PmJkZXYsCisJCQkJIGludGVsX3JlZ2lvbl90b190dG1fdHlwZShtZW0pKTsKKwlHRU1fV0FSTl9P TihyZXQpOworCW1lbS0+cmVnaW9uX3ByaXZhdGUgPSBOVUxMOworfQorCisvKioKKyAqIGludGVs X3JlZ2lvbl90dG1fbm9kZV90b19zdCAtIENvbnZlcnQgYW4gb3BhcXVlIFRUTSByZXNvdXJjZSBt YW5hZ2VyIG5vZGUKKyAqIHRvIGFuIHNnX3RhYmxlLgorICogQG1lbTogVGhlIG1lbW9yeSByZWdp b24uCisgKiBAbm9kZTogVGhlIHJlc291cmNlIG1hbmFnZXIgbm9kZSBvYnRhaW5lZCBmcm9tIHRo ZSBUVE0gcmVzb3VyY2UgbWFuYWdlci4KKyAqCisgKiBUaGUgZ2VtIGJhY2tlbmRzIHR5cGljYWxs eSB1c2Ugc2ctdGFibGVzIGZvciBvcGVyYXRpb25zIG9uIHRoZSB1bmRlcmx5aW5nCisgKiBpb19t ZW1vcnkuIFNvIHByb3ZpZGUgYSB3YXkgZm9yIHRoZSBiYWNrZW5kcyB0byB0cmFuc2xhdGUgdGhl CisgKiBub2RlcyB0aGV5IGFyZSBoYW5kZWQgZnJvbSBUVE0gdG8gc2ctdGFibGVzLgorICoKKyAq IFJldHVybjogQSBtYWxsb2NlZCBzZ190YWJsZSBvbiBzdWNjZXNzLCBhbiBlcnJvciBwb2ludGVy IG9uIGZhaWx1cmUuCisgKi8KK3N0cnVjdCBzZ190YWJsZSAqaW50ZWxfcmVnaW9uX3R0bV9ub2Rl X3RvX3N0KHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCisJCQkJCSAgICAgdm9pZCAq bm9kZSkKK3sKKwlyZXR1cm4gaTkxNV9zZ19mcm9tX21tX25vZGUobm9kZSwgbWVtLT5yZWdpb24u c3RhcnQpOworfQorCisvKioKKyAqIGludGVsX3JlZ2lvbl90dG1fbm9kZV9hbGxvYyAtIEFsbG9j YXRlIG1lbW9yeSByZXNvdXJjZXMgZnJvbSBhIHJlZ2lvbgorICogQG1lbTogVGhlIG1lbW9yeSBy ZWdpb24sCisgKiBAc2l6ZTogVGhlIHJlcXVlc3RlZCBzaXplIGluIGJ5dGVzCisgKiBAZmxhZ3M6 IEFsbG9jYXRpb24gZmxhZ3MKKyAqCisgKiBUaGlzIGZ1bmN0aW9uYWxpdHkgaXMgcHJvdmlkZWQg b25seSBmb3IgY2FsbGVycyB0aGF0IG5lZWQgdG8gYWxsb2NhdGUKKyAqIG1lbW9yeSBmcm9tIHN0 YW5kYWxvbmUgVFRNIHJhbmdlIG1hbmFnZXJzLCB3aXRob3V0IHRoZSBUVE0gZXZpY3Rpb24KKyAq IGZ1bmN0aW9uYWxpdHkuIERvbid0IHVzZSBpZiB5b3UgYXJlIG5vdCBjb21wbGV0ZWx5IHN1cmUg dGhhdCdzIHRoZQorICogY2FzZS4gVGhlIHJldHVybmVkIG9wYXF1ZSBub2RlIGNhbiBiZSBjb252 ZXJ0ZWQgdG8gYW4gc2dfdGFibGUgdXNpbmcKKyAqIGludGVsX3JlZ2lvbl90dG1fbm9kZV90b19z dCgpLCBhbmQgY2FuIGJlIGZyZWVkIHVzaW5nCisgKiBpbnRlbF9yZWdpb25fdHRtX25vZGVfZnJl ZSgpLgorICoKKyAqIFJldHVybjogQSB2YWxpZCBwb2ludGVyIG9uIHN1Y2Nlc3MsIGFuIGVycm9y IHBvaW50ZXIgb24gZmFpbHVyZS4KKyAqLwordm9pZCAqaW50ZWxfcmVnaW9uX3R0bV9ub2RlX2Fs bG9jKHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCisJCQkJICByZXNvdXJjZV9zaXpl X3Qgc2l6ZSwKKwkJCQkgIHVuc2lnbmVkIGludCBmbGFncykKK3sKKwlzdHJ1Y3QgdHRtX3Jlc291 cmNlX21hbmFnZXIgKm1hbiA9IG1lbS0+cmVnaW9uX3ByaXZhdGU7CisJc3RydWN0IHR0bV9wbGFj ZSBwbGFjZSA9IHt9OworCXN0cnVjdCB0dG1fcmVzb3VyY2UgcmVzID0ge307CisJc3RydWN0IHR0 bV9idWZmZXJfb2JqZWN0IG1vY2tfYm8gPSB7fTsKKwlpbnQgcmV0OworCisJLyoKKwkgKiBXZSBp Z25vcmUgdGhlIGZsYWdzIGZvciBub3cgc2luY2Ugd2UncmUgdXNpbmcgdGhlIHJhbmdlCisJICog bWFuYWdlciBhbmQgY29udGlnb3VzIGFuZCBtaW4gcGFnZSBzaXplIHdvdWxkIGJlIGZ1bGZpbGxl ZAorCSAqIGJ5IGRlZmF1bHQgaWYgc2l6ZSBpcyBtaW4gcGFnZSBzaXplIGFsaWduZWQuCisJICov CisJcmVzLm51bV9wYWdlcyA9IHNpemUgPj4gUEFHRV9TSElGVDsKKworCWlmIChtZW0tPmlzX3Jh bmdlX21hbmFnZXIpIHsKKwkJaWYgKHNpemUgPj0gU1pfMUcpCisJCQltb2NrX2JvLnBhZ2VfYWxp Z25tZW50ID0gU1pfMUcgPj4gUEFHRV9TSElGVDsKKwkJZWxzZSBpZiAoc2l6ZSA+PSBTWl8yTSkK KwkJCW1vY2tfYm8ucGFnZV9hbGlnbm1lbnQgPSBTWl8yTSA+PiBQQUdFX1NISUZUOworCQllbHNl IGlmIChzaXplID49IFNaXzY0SykKKwkJCW1vY2tfYm8ucGFnZV9hbGlnbm1lbnQgPSBTWl82NEsg Pj4gUEFHRV9TSElGVDsKKwl9CisKKwlyZXQgPSBtYW4tPmZ1bmMtPmFsbG9jKG1hbiwgJm1vY2tf Ym8sICZwbGFjZSwgJnJlcyk7CisJaWYgKHJldCA9PSAtRU5PU1BDKQorCQlyZXQgPSAtRU5YSU87 CisJcmV0dXJuIHJldCA/IEVSUl9QVFIocmV0KSA6IHJlcy5tbV9ub2RlOworfQpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfcmVnaW9uX3R0bS5oIGIvZHJpdmVycy9ncHUv ZHJtL2k5MTUvaW50ZWxfcmVnaW9uX3R0bS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAw MDAwMDAwMDAwMC4uMWM4MmM2YzM0MjlkCi0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9ncHUv ZHJtL2k5MTUvaW50ZWxfcmVnaW9uX3R0bS5oCkBAIC0wLDAgKzEsMzIgQEAKKy8qIFNQRFgtTGlj ZW5zZS1JZGVudGlmaWVyOiBNSVQgKi8KKy8qCisgKiBDb3B5cmlnaHQgwqkgMjAyMSBJbnRlbCBD b3Jwb3JhdGlvbgorICovCisjaWZuZGVmIF9JTlRFTF9SRUdJT05fVFRNX0hfCisjZGVmaW5lIF9J TlRFTF9SRUdJT05fVFRNX0hfCisKKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgorCisjaW5jbHVk ZSAiaTkxNV9zZWxmdGVzdC5oIgorCitzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZTsKK3N0cnVjdCBp bnRlbF9tZW1vcnlfcmVnaW9uOworCitpbnQgaW50ZWxfcmVnaW9uX3R0bV9kZXZpY2VfaW5pdChz dHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYpOworCit2b2lkIGludGVsX3JlZ2lvbl90 dG1fZGV2aWNlX2Zpbmkoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmRldl9wcml2KTsKKworaW50 IGludGVsX3JlZ2lvbl90dG1faW5pdChzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtKTsK Kwordm9pZCBpbnRlbF9yZWdpb25fdHRtX2Zpbmkoc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24g Km1lbSk7CisKK3N0cnVjdCBzZ190YWJsZSAqaW50ZWxfcmVnaW9uX3R0bV9ub2RlX3RvX3N0KHN0 cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCisJCQkJCSAgICAgdm9pZCAqbm9kZSk7CisK K3ZvaWQgKmludGVsX3JlZ2lvbl90dG1fbm9kZV9hbGxvYyhzdHJ1Y3QgaW50ZWxfbWVtb3J5X3Jl Z2lvbiAqbWVtLAorCQkJCSAgcmVzb3VyY2Vfc2l6ZV90IHNpemUsCisJCQkJICB1bnNpZ25lZCBp bnQgZmxhZ3MpOworCit2b2lkIGludGVsX3JlZ2lvbl90dG1fbm9kZV9mcmVlKHN0cnVjdCBpbnRl bF9tZW1vcnlfcmVnaW9uICptZW0sCisJCQkJdm9pZCAqbm9kZSk7CisjZW5kaWYgLyogX0lOVEVM X1JFR0lPTl9UVE1fSF8gKi8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0 ZXN0cy9pOTE1X2J1ZGR5LmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9zZWxmdGVzdHMvaTkxNV9i dWRkeS5jCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmMGY1YzRkZjhkYmMuLjAwMDAw MDAwMDAwMAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9zZWxmdGVzdHMvaTkxNV9idWRkeS5j CisrKyAvZGV2L251bGwKQEAgLTEsNzg5ICswLDAgQEAKLS8vIFNQRFgtTGljZW5zZS1JZGVudGlm aWVyOiBNSVQKLS8qCi0gKiBDb3B5cmlnaHQgwqkgMjAxOSBJbnRlbCBDb3Jwb3JhdGlvbgotICov Ci0KLSNpbmNsdWRlIDxsaW51eC9wcmltZV9udW1iZXJzLmg+Ci0KLSNpbmNsdWRlICIuLi9pOTE1 X3NlbGZ0ZXN0LmgiCi0jaW5jbHVkZSAiaTkxNV9yYW5kb20uaCIKLQotc3RhdGljIHZvaWQgX19p Z3RfZHVtcF9ibG9jayhzdHJ1Y3QgaTkxNV9idWRkeV9tbSAqbW0sCi0JCQkgICAgIHN0cnVjdCBp OTE1X2J1ZGR5X2Jsb2NrICpibG9jaywKLQkJCSAgICAgYm9vbCBidWRkeSkKLXsKLQlwcl9lcnIo ImJsb2NrIGluZm86IGhlYWRlcj0lbGx4LCBzdGF0ZT0ldSwgb3JkZXI9JWQsIG9mZnNldD0lbGx4 IHNpemU9JWxseCByb290PSVzIGJ1ZGR5PSVzXG4iLAotCSAgICAgICBibG9jay0+aGVhZGVyLAot CSAgICAgICBpOTE1X2J1ZGR5X2Jsb2NrX3N0YXRlKGJsb2NrKSwKLQkgICAgICAgaTkxNV9idWRk eV9ibG9ja19vcmRlcihibG9jayksCi0JICAgICAgIGk5MTVfYnVkZHlfYmxvY2tfb2Zmc2V0KGJs b2NrKSwKLQkgICAgICAgaTkxNV9idWRkeV9ibG9ja19zaXplKG1tLCBibG9jayksCi0JICAgICAg IHllc25vKCFibG9jay0+cGFyZW50KSwKLQkgICAgICAgeWVzbm8oYnVkZHkpKTsKLX0KLQotc3Rh dGljIHZvaWQgaWd0X2R1bXBfYmxvY2soc3RydWN0IGk5MTVfYnVkZHlfbW0gKm1tLAotCQkJICAg c3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrKQotewotCXN0cnVjdCBpOTE1X2J1ZGR5X2Js b2NrICpidWRkeTsKLQotCV9faWd0X2R1bXBfYmxvY2sobW0sIGJsb2NrLCBmYWxzZSk7Ci0KLQli dWRkeSA9IGdldF9idWRkeShibG9jayk7Ci0JaWYgKGJ1ZGR5KQotCQlfX2lndF9kdW1wX2Jsb2Nr KG1tLCBidWRkeSwgdHJ1ZSk7Ci19Ci0KLXN0YXRpYyBpbnQgaWd0X2NoZWNrX2Jsb2NrKHN0cnVj dCBpOTE1X2J1ZGR5X21tICptbSwKLQkJCSAgIHN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9j aykKLXsKLQlzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqYnVkZHk7Ci0JdW5zaWduZWQgaW50IGJs b2NrX3N0YXRlOwotCXU2NCBibG9ja19zaXplOwotCXU2NCBvZmZzZXQ7Ci0JaW50IGVyciA9IDA7 Ci0KLQlibG9ja19zdGF0ZSA9IGk5MTVfYnVkZHlfYmxvY2tfc3RhdGUoYmxvY2spOwotCi0JaWYg KGJsb2NrX3N0YXRlICE9IEk5MTVfQlVERFlfQUxMT0NBVEVEICYmCi0JICAgIGJsb2NrX3N0YXRl ICE9IEk5MTVfQlVERFlfRlJFRSAmJgotCSAgICBibG9ja19zdGF0ZSAhPSBJOTE1X0JVRERZX1NQ TElUKSB7Ci0JCXByX2VycigiYmxvY2sgc3RhdGUgbWlzbWF0Y2hcbiIpOwotCQllcnIgPSAtRUlO VkFMOwotCX0KLQotCWJsb2NrX3NpemUgPSBpOTE1X2J1ZGR5X2Jsb2NrX3NpemUobW0sIGJsb2Nr KTsKLQlvZmZzZXQgPSBpOTE1X2J1ZGR5X2Jsb2NrX29mZnNldChibG9jayk7Ci0KLQlpZiAoYmxv Y2tfc2l6ZSA8IG1tLT5jaHVua19zaXplKSB7Ci0JCXByX2VycigiYmxvY2sgc2l6ZSBzbWFsbGVy IHRoYW4gbWluIHNpemVcbiIpOwotCQllcnIgPSAtRUlOVkFMOwotCX0KLQotCWlmICghaXNfcG93 ZXJfb2ZfMihibG9ja19zaXplKSkgewotCQlwcl9lcnIoImJsb2NrIHNpemUgbm90IHBvd2VyIG9m IHR3b1xuIik7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JfQotCi0JaWYgKCFJU19BTElHTkVEKGJsb2Nr X3NpemUsIG1tLT5jaHVua19zaXplKSkgewotCQlwcl9lcnIoImJsb2NrIHNpemUgbm90IGFsaWdu ZWQgdG8gbWluIHNpemVcbiIpOwotCQllcnIgPSAtRUlOVkFMOwotCX0KLQotCWlmICghSVNfQUxJ R05FRChvZmZzZXQsIG1tLT5jaHVua19zaXplKSkgewotCQlwcl9lcnIoImJsb2NrIG9mZnNldCBu b3QgYWxpZ25lZCB0byBtaW4gc2l6ZVxuIik7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JfQotCi0JaWYg KCFJU19BTElHTkVEKG9mZnNldCwgYmxvY2tfc2l6ZSkpIHsKLQkJcHJfZXJyKCJibG9jayBvZmZz ZXQgbm90IGFsaWduZWQgdG8gYmxvY2sgc2l6ZVxuIik7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JfQot Ci0JYnVkZHkgPSBnZXRfYnVkZHkoYmxvY2spOwotCi0JaWYgKCFidWRkeSAmJiBibG9jay0+cGFy ZW50KSB7Ci0JCXByX2VycigiYnVkZHkgaGFzIGdvbmUgZmlzaGluZ1xuIik7Ci0JCWVyciA9IC1F SU5WQUw7Ci0JfQotCi0JaWYgKGJ1ZGR5KSB7Ci0JCWlmIChpOTE1X2J1ZGR5X2Jsb2NrX29mZnNl dChidWRkeSkgIT0gKG9mZnNldCBeIGJsb2NrX3NpemUpKSB7Ci0JCQlwcl9lcnIoImJ1ZGR5IGhh cyB3cm9uZyBvZmZzZXRcbiIpOwotCQkJZXJyID0gLUVJTlZBTDsKLQkJfQotCi0JCWlmIChpOTE1 X2J1ZGR5X2Jsb2NrX3NpemUobW0sIGJ1ZGR5KSAhPSBibG9ja19zaXplKSB7Ci0JCQlwcl9lcnIo ImJ1ZGR5IHNpemUgbWlzbWF0Y2hcbiIpOwotCQkJZXJyID0gLUVJTlZBTDsKLQkJfQotCi0JCWlm IChpOTE1X2J1ZGR5X2Jsb2NrX3N0YXRlKGJ1ZGR5KSA9PSBibG9ja19zdGF0ZSAmJgotCQkgICAg YmxvY2tfc3RhdGUgPT0gSTkxNV9CVUREWV9GUkVFKSB7Ci0JCQlwcl9lcnIoImJsb2NrIGFuZCBp dHMgYnVkZHkgYXJlIGZyZWVcbiIpOwotCQkJZXJyID0gLUVJTlZBTDsKLQkJfQotCX0KLQotCXJl dHVybiBlcnI7Ci19Ci0KLXN0YXRpYyBpbnQgaWd0X2NoZWNrX2Jsb2NrcyhzdHJ1Y3QgaTkxNV9i dWRkeV9tbSAqbW0sCi0JCQkgICAgc3RydWN0IGxpc3RfaGVhZCAqYmxvY2tzLAotCQkJICAgIHU2 NCBleHBlY3RlZF9zaXplLAotCQkJICAgIGJvb2wgaXNfY29udGlndW91cykKLXsKLQlzdHJ1Y3Qg aTkxNV9idWRkeV9ibG9jayAqYmxvY2s7Ci0Jc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKnByZXY7 Ci0JdTY0IHRvdGFsOwotCWludCBlcnIgPSAwOwotCi0JYmxvY2sgPSBOVUxMOwotCXByZXYgPSBO VUxMOwotCXRvdGFsID0gMDsKLQotCWxpc3RfZm9yX2VhY2hfZW50cnkoYmxvY2ssIGJsb2Nrcywg bGluaykgewotCQllcnIgPSBpZ3RfY2hlY2tfYmxvY2sobW0sIGJsb2NrKTsKLQotCQlpZiAoIWk5 MTVfYnVkZHlfYmxvY2tfaXNfYWxsb2NhdGVkKGJsb2NrKSkgewotCQkJcHJfZXJyKCJibG9jayBu b3QgYWxsb2NhdGVkXG4iKSwKLQkJCWVyciA9IC1FSU5WQUw7Ci0JCX0KLQotCQlpZiAoaXNfY29u dGlndW91cyAmJiBwcmV2KSB7Ci0JCQl1NjQgcHJldl9ibG9ja19zaXplOwotCQkJdTY0IHByZXZf b2Zmc2V0OwotCQkJdTY0IG9mZnNldDsKLQotCQkJcHJldl9vZmZzZXQgPSBpOTE1X2J1ZGR5X2Js b2NrX29mZnNldChwcmV2KTsKLQkJCXByZXZfYmxvY2tfc2l6ZSA9IGk5MTVfYnVkZHlfYmxvY2tf c2l6ZShtbSwgcHJldik7Ci0JCQlvZmZzZXQgPSBpOTE1X2J1ZGR5X2Jsb2NrX29mZnNldChibG9j ayk7Ci0KLQkJCWlmIChvZmZzZXQgIT0gKHByZXZfb2Zmc2V0ICsgcHJldl9ibG9ja19zaXplKSkg ewotCQkJCXByX2VycigiYmxvY2sgb2Zmc2V0IG1pc21hdGNoXG4iKTsKLQkJCQllcnIgPSAtRUlO VkFMOwotCQkJfQotCQl9Ci0KLQkJaWYgKGVycikKLQkJCWJyZWFrOwotCi0JCXRvdGFsICs9IGk5 MTVfYnVkZHlfYmxvY2tfc2l6ZShtbSwgYmxvY2spOwotCQlwcmV2ID0gYmxvY2s7Ci0JfQotCi0J aWYgKCFlcnIpIHsKLQkJaWYgKHRvdGFsICE9IGV4cGVjdGVkX3NpemUpIHsKLQkJCXByX2Vycigi c2l6ZSBtaXNtYXRjaCwgZXhwZWN0ZWQ9JWxseCwgZm91bmQ9JWxseFxuIiwKLQkJCSAgICAgICBl eHBlY3RlZF9zaXplLCB0b3RhbCk7Ci0JCQllcnIgPSAtRUlOVkFMOwotCQl9Ci0JCXJldHVybiBl cnI7Ci0JfQotCi0JaWYgKHByZXYpIHsKLQkJcHJfZXJyKCJwcmV2IGJsb2NrLCBkdW1wOlxuIik7 Ci0JCWlndF9kdW1wX2Jsb2NrKG1tLCBwcmV2KTsKLQl9Ci0KLQlpZiAoYmxvY2spIHsKLQkJcHJf ZXJyKCJiYWQgYmxvY2ssIGR1bXA6XG4iKTsKLQkJaWd0X2R1bXBfYmxvY2sobW0sIGJsb2NrKTsK LQl9Ci0KLQlyZXR1cm4gZXJyOwotfQotCi1zdGF0aWMgaW50IGlndF9jaGVja19tbShzdHJ1Y3Qg aTkxNV9idWRkeV9tbSAqbW0pCi17Ci0Jc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKnJvb3Q7Ci0J c3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKnByZXY7Ci0JdW5zaWduZWQgaW50IGk7Ci0JdTY0IHRv dGFsOwotCWludCBlcnIgPSAwOwotCi0JaWYgKCFtbS0+bl9yb290cykgewotCQlwcl9lcnIoIm5f cm9vdHMgaXMgemVyb1xuIik7Ci0JCXJldHVybiAtRUlOVkFMOwotCX0KLQotCWlmIChtbS0+bl9y b290cyAhPSBod2VpZ2h0NjQobW0tPnNpemUpKSB7Ci0JCXByX2Vycigibl9yb290cyBtaXNtYXRj aCwgbl9yb290cz0ldSwgZXhwZWN0ZWQ9JWx1XG4iLAotCQkgICAgICAgbW0tPm5fcm9vdHMsIGh3 ZWlnaHQ2NChtbS0+c2l6ZSkpOwotCQlyZXR1cm4gLUVJTlZBTDsKLQl9Ci0KLQlyb290ID0gTlVM TDsKLQlwcmV2ID0gTlVMTDsKLQl0b3RhbCA9IDA7Ci0KLQlmb3IgKGkgPSAwOyBpIDwgbW0tPm5f cm9vdHM7ICsraSkgewotCQlzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqYmxvY2s7Ci0JCXVuc2ln bmVkIGludCBvcmRlcjsKLQotCQlyb290ID0gbW0tPnJvb3RzW2ldOwotCQlpZiAoIXJvb3QpIHsK LQkJCXByX2Vycigicm9vdCgldSkgaXMgTlVMTFxuIiwgaSk7Ci0JCQllcnIgPSAtRUlOVkFMOwot CQkJYnJlYWs7Ci0JCX0KLQotCQllcnIgPSBpZ3RfY2hlY2tfYmxvY2sobW0sIHJvb3QpOwotCi0J CWlmICghaTkxNV9idWRkeV9ibG9ja19pc19mcmVlKHJvb3QpKSB7Ci0JCQlwcl9lcnIoInJvb3Qg bm90IGZyZWVcbiIpOwotCQkJZXJyID0gLUVJTlZBTDsKLQkJfQotCi0JCW9yZGVyID0gaTkxNV9i dWRkeV9ibG9ja19vcmRlcihyb290KTsKLQotCQlpZiAoIWkpIHsKLQkJCWlmIChvcmRlciAhPSBt bS0+bWF4X29yZGVyKSB7Ci0JCQkJcHJfZXJyKCJtYXggb3JkZXIgcm9vdCBtaXNzaW5nXG4iKTsK LQkJCQllcnIgPSAtRUlOVkFMOwotCQkJfQotCQl9Ci0KLQkJaWYgKHByZXYpIHsKLQkJCXU2NCBw cmV2X2Jsb2NrX3NpemU7Ci0JCQl1NjQgcHJldl9vZmZzZXQ7Ci0JCQl1NjQgb2Zmc2V0OwotCi0J CQlwcmV2X29mZnNldCA9IGk5MTVfYnVkZHlfYmxvY2tfb2Zmc2V0KHByZXYpOwotCQkJcHJldl9i bG9ja19zaXplID0gaTkxNV9idWRkeV9ibG9ja19zaXplKG1tLCBwcmV2KTsKLQkJCW9mZnNldCA9 IGk5MTVfYnVkZHlfYmxvY2tfb2Zmc2V0KHJvb3QpOwotCi0JCQlpZiAob2Zmc2V0ICE9IChwcmV2 X29mZnNldCArIHByZXZfYmxvY2tfc2l6ZSkpIHsKLQkJCQlwcl9lcnIoInJvb3Qgb2Zmc2V0IG1p c21hdGNoXG4iKTsKLQkJCQllcnIgPSAtRUlOVkFMOwotCQkJfQotCQl9Ci0KLQkJYmxvY2sgPSBs aXN0X2ZpcnN0X2VudHJ5X29yX251bGwoJm1tLT5mcmVlX2xpc3Rbb3JkZXJdLAotCQkJCQkJIHN0 cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrLAotCQkJCQkJIGxpbmspOwotCQlpZiAoYmxvY2sgIT0gcm9v dCkgewotCQkJcHJfZXJyKCJyb290IG1pc21hdGNoIGF0IG9yZGVyPSV1XG4iLCBvcmRlcik7Ci0J CQllcnIgPSAtRUlOVkFMOwotCQl9Ci0KLQkJaWYgKGVycikKLQkJCWJyZWFrOwotCi0JCXByZXYg PSByb290OwotCQl0b3RhbCArPSBpOTE1X2J1ZGR5X2Jsb2NrX3NpemUobW0sIHJvb3QpOwotCX0K LQotCWlmICghZXJyKSB7Ci0JCWlmICh0b3RhbCAhPSBtbS0+c2l6ZSkgewotCQkJcHJfZXJyKCJl eHBlY3RlZCBtbSBzaXplPSVsbHgsIGZvdW5kPSVsbHhcbiIsIG1tLT5zaXplLAotCQkJICAgICAg IHRvdGFsKTsKLQkJCWVyciA9IC1FSU5WQUw7Ci0JCX0KLQkJcmV0dXJuIGVycjsKLQl9Ci0KLQlp ZiAocHJldikgewotCQlwcl9lcnIoInByZXYgcm9vdCgldSksIGR1bXA6XG4iLCBpIC0gMSk7Ci0J CWlndF9kdW1wX2Jsb2NrKG1tLCBwcmV2KTsKLQl9Ci0KLQlpZiAocm9vdCkgewotCQlwcl9lcnIo ImJhZCByb290KCV1KSwgZHVtcDpcbiIsIGkpOwotCQlpZ3RfZHVtcF9ibG9jayhtbSwgcm9vdCk7 Ci0JfQotCi0JcmV0dXJuIGVycjsKLX0KLQotc3RhdGljIHZvaWQgaWd0X21tX2NvbmZpZyh1NjQg KnNpemUsIHU2NCAqY2h1bmtfc2l6ZSkKLXsKLQlJOTE1X1JORF9TVEFURShwcm5nKTsKLQl1MzIg cywgbXM7Ci0KLQkvKiBOb3RoaW5nIGZhbmN5LCBqdXN0IHRyeSB0byBnZXQgYW4gaW50ZXJlc3Rp bmcgYml0IHBhdHRlcm4gKi8KLQotCXByYW5kb21fc2VlZF9zdGF0ZSgmcHJuZywgaTkxNV9zZWxm dGVzdC5yYW5kb21fc2VlZCk7Ci0KLQkvKiBMZXQgc2l6ZSBiZSBhIHJhbmRvbSBudW1iZXIgb2Yg cGFnZXMgdXAgdG8gOCBHQiAoMk0gcGFnZXMpICovCi0JcyA9IDEgKyBpOTE1X3ByYW5kb21fdTMy X21heF9zdGF0ZSgoQklUKDMzIC0gMTIpKSAtIDEsICZwcm5nKTsKLQkvKiBMZXQgdGhlIGNodW5r IHNpemUgYmUgYSByYW5kb20gcG93ZXIgb2YgMiBsZXNzIHRoYW4gc2l6ZSAqLwotCW1zID0gQklU KGk5MTVfcHJhbmRvbV91MzJfbWF4X3N0YXRlKGlsb2cyKHMpLCAmcHJuZykpOwotCS8qIFJvdW5k IHNpemUgZG93biB0byB0aGUgY2h1bmsgc2l6ZSAqLwotCXMgJj0gLW1zOwotCi0JLyogQ29udmVy dCBmcm9tIHBhZ2VzIHRvIGJ5dGVzICovCi0JKmNodW5rX3NpemUgPSAodTY0KW1zIDw8IDEyOwot CSpzaXplID0gKHU2NClzIDw8IDEyOwotfQotCi1zdGF0aWMgaW50IGlndF9idWRkeV9hbGxvY19z bW9rZSh2b2lkICphcmcpCi17Ci0Jc3RydWN0IGk5MTVfYnVkZHlfbW0gbW07Ci0JSUdUX1RJTUVP VVQoZW5kX3RpbWUpOwotCUk5MTVfUk5EX1NUQVRFKHBybmcpOwotCXU2NCBjaHVua19zaXplOwot CXU2NCBtbV9zaXplOwotCWludCAqb3JkZXI7Ci0JaW50IGVyciwgaTsKLQotCWlndF9tbV9jb25m aWcoJm1tX3NpemUsICZjaHVua19zaXplKTsKLQotCXByX2luZm8oImJ1ZGR5X2luaXQgd2l0aCBz aXplPSVsbHgsIGNodW5rX3NpemU9JWxseFxuIiwgbW1fc2l6ZSwgY2h1bmtfc2l6ZSk7Ci0KLQll cnIgPSBpOTE1X2J1ZGR5X2luaXQoJm1tLCBtbV9zaXplLCBjaHVua19zaXplKTsKLQlpZiAoZXJy KSB7Ci0JCXByX2VycigiYnVkZHlfaW5pdCBmYWlsZWQoJWQpXG4iLCBlcnIpOwotCQlyZXR1cm4g ZXJyOwotCX0KLQotCW9yZGVyID0gaTkxNV9yYW5kb21fb3JkZXIobW0ubWF4X29yZGVyICsgMSwg JnBybmcpOwotCWlmICghb3JkZXIpCi0JCWdvdG8gb3V0X2Zpbmk7Ci0KLQlmb3IgKGkgPSAwOyBp IDw9IG1tLm1heF9vcmRlcjsgKytpKSB7Ci0JCXN0cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9j azsKLQkJaW50IG1heF9vcmRlciA9IG9yZGVyW2ldOwotCQlib29sIHRpbWVvdXQgPSBmYWxzZTsK LQkJTElTVF9IRUFEKGJsb2Nrcyk7Ci0JCWludCBvcmRlcjsKLQkJdTY0IHRvdGFsOwotCi0JCWVy ciA9IGlndF9jaGVja19tbSgmbW0pOwotCQlpZiAoZXJyKSB7Ci0JCQlwcl9lcnIoInByZS1tbSBj aGVjayBmYWlsZWQsIGFib3J0XG4iKTsKLQkJCWJyZWFrOwotCQl9Ci0KLQkJcHJfaW5mbygiZmls bGluZyBmcm9tIG1heF9vcmRlcj0ldVxuIiwgbWF4X29yZGVyKTsKLQotCQlvcmRlciA9IG1heF9v cmRlcjsKLQkJdG90YWwgPSAwOwotCi0JCWRvIHsKLXJldHJ5OgotCQkJYmxvY2sgPSBpOTE1X2J1 ZGR5X2FsbG9jKCZtbSwgb3JkZXIpOwotCQkJaWYgKElTX0VSUihibG9jaykpIHsKLQkJCQllcnIg PSBQVFJfRVJSKGJsb2NrKTsKLQkJCQlpZiAoZXJyID09IC1FTk9NRU0pIHsKLQkJCQkJcHJfaW5m bygiYnVkZHlfYWxsb2MgaGl0IC1FTk9NRU0gd2l0aCBvcmRlcj0lZFxuIiwKLQkJCQkJCW9yZGVy KTsKLQkJCQl9IGVsc2UgewotCQkJCQlpZiAob3JkZXItLSkgewotCQkJCQkJZXJyID0gMDsKLQkJ CQkJCWdvdG8gcmV0cnk7Ci0JCQkJCX0KLQotCQkJCQlwcl9lcnIoImJ1ZGR5X2FsbG9jIHdpdGgg b3JkZXI9JWQgZmFpbGVkKCVkKVxuIiwKLQkJCQkJICAgICAgIG9yZGVyLCBlcnIpOwotCQkJCX0K LQotCQkJCWJyZWFrOwotCQkJfQotCi0JCQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGluaywgJmJs b2Nrcyk7Ci0KLQkJCWlmIChpOTE1X2J1ZGR5X2Jsb2NrX29yZGVyKGJsb2NrKSAhPSBvcmRlcikg ewotCQkJCXByX2VycigiYnVkZHlfYWxsb2Mgb3JkZXIgbWlzbWF0Y2hcbiIpOwotCQkJCWVyciA9 IC1FSU5WQUw7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0KLQkJCXRvdGFsICs9IGk5MTVfYnVkZHlfYmxv Y2tfc2l6ZSgmbW0sIGJsb2NrKTsKLQotCQkJaWYgKF9faWd0X3RpbWVvdXQoZW5kX3RpbWUsIE5V TEwpKSB7Ci0JCQkJdGltZW91dCA9IHRydWU7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCX0gd2hpbGUg KHRvdGFsIDwgbW0uc2l6ZSk7Ci0KLQkJaWYgKCFlcnIpCi0JCQllcnIgPSBpZ3RfY2hlY2tfYmxv Y2tzKCZtbSwgJmJsb2NrcywgdG90YWwsIGZhbHNlKTsKLQotCQlpOTE1X2J1ZGR5X2ZyZWVfbGlz dCgmbW0sICZibG9ja3MpOwotCi0JCWlmICghZXJyKSB7Ci0JCQllcnIgPSBpZ3RfY2hlY2tfbW0o Jm1tKTsKLQkJCWlmIChlcnIpCi0JCQkJcHJfZXJyKCJwb3N0LW1tIGNoZWNrIGZhaWxlZFxuIik7 Ci0JCX0KLQotCQlpZiAoZXJyIHx8IHRpbWVvdXQpCi0JCQlicmVhazsKLQotCQljb25kX3Jlc2No ZWQoKTsKLQl9Ci0KLQlpZiAoZXJyID09IC1FTk9NRU0pCi0JCWVyciA9IDA7Ci0KLQlrZnJlZShv cmRlcik7Ci1vdXRfZmluaToKLQlpOTE1X2J1ZGR5X2ZpbmkoJm1tKTsKLQotCXJldHVybiBlcnI7 Ci19Ci0KLXN0YXRpYyBpbnQgaWd0X2J1ZGR5X2FsbG9jX3Blc3NpbWlzdGljKHZvaWQgKmFyZykK LXsKLQljb25zdCB1bnNpZ25lZCBpbnQgbWF4X29yZGVyID0gMTY7Ci0Jc3RydWN0IGk5MTVfYnVk ZHlfYmxvY2sgKmJsb2NrLCAqYm47Ci0Jc3RydWN0IGk5MTVfYnVkZHlfbW0gbW07Ci0JdW5zaWdu ZWQgaW50IG9yZGVyOwotCUxJU1RfSEVBRChibG9ja3MpOwotCWludCBlcnI7Ci0KLQkvKgotCSAq IENyZWF0ZSBhIHBvdC1zaXplZCBtbSwgdGhlbiBhbGxvY2F0ZSBvbmUgb2YgZWFjaCBwb3NzaWJs ZQotCSAqIG9yZGVyIHdpdGhpbi4gVGhpcyBzaG91bGQgbGVhdmUgdGhlIG1tIHdpdGggZXhhY3Rs eSBvbmUKLQkgKiBwYWdlIGxlZnQuCi0JICovCi0KLQllcnIgPSBpOTE1X2J1ZGR5X2luaXQoJm1t LCBQQUdFX1NJWkUgPDwgbWF4X29yZGVyLCBQQUdFX1NJWkUpOwotCWlmIChlcnIpIHsKLQkJcHJf ZXJyKCJidWRkeV9pbml0IGZhaWxlZCglZClcbiIsIGVycik7Ci0JCXJldHVybiBlcnI7Ci0JfQot CUdFTV9CVUdfT04obW0ubWF4X29yZGVyICE9IG1heF9vcmRlcik7Ci0KLQlmb3IgKG9yZGVyID0g MDsgb3JkZXIgPCBtYXhfb3JkZXI7IG9yZGVyKyspIHsKLQkJYmxvY2sgPSBpOTE1X2J1ZGR5X2Fs bG9jKCZtbSwgb3JkZXIpOwotCQlpZiAoSVNfRVJSKGJsb2NrKSkgewotCQkJcHJfaW5mbygiYnVk ZHlfYWxsb2MgaGl0IC1FTk9NRU0gd2l0aCBvcmRlcj0lZFxuIiwKLQkJCQlvcmRlcik7Ci0JCQll cnIgPSBQVFJfRVJSKGJsb2NrKTsKLQkJCWdvdG8gZXJyOwotCQl9Ci0KLQkJbGlzdF9hZGRfdGFp bCgmYmxvY2stPmxpbmssICZibG9ja3MpOwotCX0KLQotCS8qIEFuZCBub3cgdGhlIGxhc3QgcmVt YWluaW5nIGJsb2NrIGF2YWlsYWJsZSAqLwotCWJsb2NrID0gaTkxNV9idWRkeV9hbGxvYygmbW0s IDApOwotCWlmIChJU19FUlIoYmxvY2spKSB7Ci0JCXByX2luZm8oImJ1ZGR5X2FsbG9jIGhpdCAt RU5PTUVNIG9uIGZpbmFsIGFsbG9jXG4iKTsKLQkJZXJyID0gUFRSX0VSUihibG9jayk7Ci0JCWdv dG8gZXJyOwotCX0KLQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGluaywgJmJsb2Nrcyk7Ci0KLQkv KiBTaG91bGQgYmUgY29tcGxldGVseSBmdWxsISAqLwotCWZvciAob3JkZXIgPSBtYXhfb3JkZXI7 IG9yZGVyLS07ICkgewotCQlibG9jayA9IGk5MTVfYnVkZHlfYWxsb2MoJm1tLCBvcmRlcik7Ci0J CWlmICghSVNfRVJSKGJsb2NrKSkgewotCQkJcHJfaW5mbygiYnVkZHlfYWxsb2MgdW5leHBlY3Rl ZGx5IHN1Y2NlZWRlZCBhdCBvcmRlciAlZCwgaXQgc2hvdWxkIGJlIGZ1bGwhIiwKLQkJCQlvcmRl cik7Ci0JCQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGluaywgJmJsb2Nrcyk7Ci0JCQllcnIgPSAt RUlOVkFMOwotCQkJZ290byBlcnI7Ci0JCX0KLQl9Ci0KLQlibG9jayA9IGxpc3RfbGFzdF9lbnRy eSgmYmxvY2tzLCB0eXBlb2YoKmJsb2NrKSwgbGluayk7Ci0JbGlzdF9kZWwoJmJsb2NrLT5saW5r KTsKLQlpOTE1X2J1ZGR5X2ZyZWUoJm1tLCBibG9jayk7Ci0KLQkvKiBBcyB3ZSBmcmVlIGluIGlu Y3JlYXNpbmcgc2l6ZSwgd2UgbWFrZSBhdmFpbGFibGUgbGFyZ2VyIGJsb2NrcyAqLwotCW9yZGVy ID0gMTsKLQlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYmxvY2ssIGJuLCAmYmxvY2tzLCBsaW5r KSB7Ci0JCWxpc3RfZGVsKCZibG9jay0+bGluayk7Ci0JCWk5MTVfYnVkZHlfZnJlZSgmbW0sIGJs b2NrKTsKLQotCQlibG9jayA9IGk5MTVfYnVkZHlfYWxsb2MoJm1tLCBvcmRlcik7Ci0JCWlmIChJ U19FUlIoYmxvY2spKSB7Ci0JCQlwcl9pbmZvKCJidWRkeV9hbGxvYyAocmVhbGxvYykgaGl0IC1F Tk9NRU0gd2l0aCBvcmRlcj0lZFxuIiwKLQkJCQlvcmRlcik7Ci0JCQllcnIgPSBQVFJfRVJSKGJs b2NrKTsKLQkJCWdvdG8gZXJyOwotCQl9Ci0JCWk5MTVfYnVkZHlfZnJlZSgmbW0sIGJsb2NrKTsK LQkJb3JkZXIrKzsKLQl9Ci0KLQkvKiBUbyBjb25maXJtLCBub3cgdGhlIHdob2xlIG1tIHNob3Vs ZCBiZSBhdmFpbGFibGUgKi8KLQlibG9jayA9IGk5MTVfYnVkZHlfYWxsb2MoJm1tLCBtYXhfb3Jk ZXIpOwotCWlmIChJU19FUlIoYmxvY2spKSB7Ci0JCXByX2luZm8oImJ1ZGR5X2FsbG9jIChyZWFs bG9jKSBoaXQgLUVOT01FTSB3aXRoIG9yZGVyPSVkXG4iLAotCQkJbWF4X29yZGVyKTsKLQkJZXJy ID0gUFRSX0VSUihibG9jayk7Ci0JCWdvdG8gZXJyOwotCX0KLQlpOTE1X2J1ZGR5X2ZyZWUoJm1t LCBibG9jayk7Ci0KLWVycjoKLQlpOTE1X2J1ZGR5X2ZyZWVfbGlzdCgmbW0sICZibG9ja3MpOwot CWk5MTVfYnVkZHlfZmluaSgmbW0pOwotCXJldHVybiBlcnI7Ci19Ci0KLXN0YXRpYyBpbnQgaWd0 X2J1ZGR5X2FsbG9jX29wdGltaXN0aWModm9pZCAqYXJnKQotewotCWNvbnN0IGludCBtYXhfb3Jk ZXIgPSAxNjsKLQlzdHJ1Y3QgaTkxNV9idWRkeV9ibG9jayAqYmxvY2s7Ci0Jc3RydWN0IGk5MTVf YnVkZHlfbW0gbW07Ci0JTElTVF9IRUFEKGJsb2Nrcyk7Ci0JaW50IG9yZGVyOwotCWludCBlcnI7 Ci0KLQkvKgotCSAqIENyZWF0ZSBhIG1tIHdpdGggb25lIGJsb2NrIG9mIGVhY2ggb3JkZXIgYXZh aWxhYmxlLCBhbmQKLQkgKiB0cnkgdG8gYWxsb2NhdGUgdGhlbSBhbGwuCi0JICovCi0KLQllcnIg PSBpOTE1X2J1ZGR5X2luaXQoJm1tLAotCQkJICAgICAgUEFHRV9TSVpFICogKCgxIDw8IChtYXhf b3JkZXIgKyAxKSkgLSAxKSwKLQkJCSAgICAgIFBBR0VfU0laRSk7Ci0JaWYgKGVycikgewotCQlw cl9lcnIoImJ1ZGR5X2luaXQgZmFpbGVkKCVkKVxuIiwgZXJyKTsKLQkJcmV0dXJuIGVycjsKLQl9 Ci0JR0VNX0JVR19PTihtbS5tYXhfb3JkZXIgIT0gbWF4X29yZGVyKTsKLQotCWZvciAob3JkZXIg PSAwOyBvcmRlciA8PSBtYXhfb3JkZXI7IG9yZGVyKyspIHsKLQkJYmxvY2sgPSBpOTE1X2J1ZGR5 X2FsbG9jKCZtbSwgb3JkZXIpOwotCQlpZiAoSVNfRVJSKGJsb2NrKSkgewotCQkJcHJfaW5mbygi YnVkZHlfYWxsb2MgaGl0IC1FTk9NRU0gd2l0aCBvcmRlcj0lZFxuIiwKLQkJCQlvcmRlcik7Ci0J CQllcnIgPSBQVFJfRVJSKGJsb2NrKTsKLQkJCWdvdG8gZXJyOwotCQl9Ci0KLQkJbGlzdF9hZGRf dGFpbCgmYmxvY2stPmxpbmssICZibG9ja3MpOwotCX0KLQotCS8qIFNob3VsZCBiZSBjb21wbGV0 ZWx5IGZ1bGwhICovCi0JYmxvY2sgPSBpOTE1X2J1ZGR5X2FsbG9jKCZtbSwgMCk7Ci0JaWYgKCFJ U19FUlIoYmxvY2spKSB7Ci0JCXByX2luZm8oImJ1ZGR5X2FsbG9jIHVuZXhwZWN0ZWRseSBzdWNj ZWVkZWQsIGl0IHNob3VsZCBiZSBmdWxsISIpOwotCQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGlu aywgJmJsb2Nrcyk7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JCWdvdG8gZXJyOwotCX0KLQotZXJyOgot CWk5MTVfYnVkZHlfZnJlZV9saXN0KCZtbSwgJmJsb2Nrcyk7Ci0JaTkxNV9idWRkeV9maW5pKCZt bSk7Ci0JcmV0dXJuIGVycjsKLX0KLQotc3RhdGljIGludCBpZ3RfYnVkZHlfYWxsb2NfcGF0aG9s b2dpY2FsKHZvaWQgKmFyZykKLXsKLQljb25zdCBpbnQgbWF4X29yZGVyID0gMTY7Ci0Jc3RydWN0 IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrOwotCXN0cnVjdCBpOTE1X2J1ZGR5X21tIG1tOwotCUxJ U1RfSEVBRChibG9ja3MpOwotCUxJU1RfSEVBRChob2xlcyk7Ci0JaW50IG9yZGVyLCB0b3A7Ci0J aW50IGVycjsKLQotCS8qCi0JICogQ3JlYXRlIGEgcG90LXNpemVkIG1tLCB0aGVuIGFsbG9jYXRl IG9uZSBvZiBlYWNoIHBvc3NpYmxlCi0JICogb3JkZXIgd2l0aGluLiBUaGlzIHNob3VsZCBsZWF2 ZSB0aGUgbW0gd2l0aCBleGFjdGx5IG9uZQotCSAqIHBhZ2UgbGVmdC4gRnJlZSB0aGUgbGFyZ2Vz dCBibG9jaywgdGhlbiB3aGl0dGxlIGRvd24gYWdhaW4uCi0JICogRXZlbnR1YWxseSB3ZSB3aWxs IGhhdmUgYSBmdWxseSA1MCUgZnJhZ21lbnRlZCBtbS4KLQkgKi8KLQotCWVyciA9IGk5MTVfYnVk ZHlfaW5pdCgmbW0sIFBBR0VfU0laRSA8PCBtYXhfb3JkZXIsIFBBR0VfU0laRSk7Ci0JaWYgKGVy cikgewotCQlwcl9lcnIoImJ1ZGR5X2luaXQgZmFpbGVkKCVkKVxuIiwgZXJyKTsKLQkJcmV0dXJu IGVycjsKLQl9Ci0JR0VNX0JVR19PTihtbS5tYXhfb3JkZXIgIT0gbWF4X29yZGVyKTsKLQotCWZv ciAodG9wID0gbWF4X29yZGVyOyB0b3A7IHRvcC0tKSB7Ci0JCS8qIE1ha2Ugcm9vbSBieSBmcmVl aW5nIHRoZSBsYXJnZXN0IGFsbG9jYXRlZCBibG9jayAqLwotCQlibG9jayA9IGxpc3RfZmlyc3Rf ZW50cnlfb3JfbnVsbCgmYmxvY2tzLCB0eXBlb2YoKmJsb2NrKSwgbGluayk7Ci0JCWlmIChibG9j aykgewotCQkJbGlzdF9kZWwoJmJsb2NrLT5saW5rKTsKLQkJCWk5MTVfYnVkZHlfZnJlZSgmbW0s IGJsb2NrKTsKLQkJfQotCi0JCWZvciAob3JkZXIgPSB0b3A7IG9yZGVyLS07ICkgewotCQkJYmxv Y2sgPSBpOTE1X2J1ZGR5X2FsbG9jKCZtbSwgb3JkZXIpOwotCQkJaWYgKElTX0VSUihibG9jaykp IHsKLQkJCQlwcl9pbmZvKCJidWRkeV9hbGxvYyBoaXQgLUVOT01FTSB3aXRoIG9yZGVyPSVkLCB0 b3A9JWRcbiIsCi0JCQkJCW9yZGVyLCB0b3ApOwotCQkJCWVyciA9IFBUUl9FUlIoYmxvY2spOwot CQkJCWdvdG8gZXJyOwotCQkJfQotCQkJbGlzdF9hZGRfdGFpbCgmYmxvY2stPmxpbmssICZibG9j a3MpOwotCQl9Ci0KLQkJLyogVGhlcmUgc2hvdWxkIGJlIG9uZSBmaW5hbCBwYWdlIGZvciB0aGlz IHN1Yi1hbGxvY2F0aW9uICovCi0JCWJsb2NrID0gaTkxNV9idWRkeV9hbGxvYygmbW0sIDApOwot CQlpZiAoSVNfRVJSKGJsb2NrKSkgewotCQkJcHJfaW5mbygiYnVkZHlfYWxsb2MgaGl0IC1FTk9N RU0gZm9yIGhvbGVcbiIpOwotCQkJZXJyID0gUFRSX0VSUihibG9jayk7Ci0JCQlnb3RvIGVycjsK LQkJfQotCQlsaXN0X2FkZF90YWlsKCZibG9jay0+bGluaywgJmhvbGVzKTsKLQotCQlibG9jayA9 IGk5MTVfYnVkZHlfYWxsb2MoJm1tLCB0b3ApOwotCQlpZiAoIUlTX0VSUihibG9jaykpIHsKLQkJ CXByX2luZm8oImJ1ZGR5X2FsbG9jIHVuZXhwZWN0ZWRseSBzdWNjZWVkZWQgYXQgdG9wLW9yZGVy ICVkLyVkLCBpdCBzaG91bGQgYmUgZnVsbCEiLAotCQkJCXRvcCwgbWF4X29yZGVyKTsKLQkJCWxp c3RfYWRkX3RhaWwoJmJsb2NrLT5saW5rLCAmYmxvY2tzKTsKLQkJCWVyciA9IC1FSU5WQUw7Ci0J CQlnb3RvIGVycjsKLQkJfQotCX0KLQotCWk5MTVfYnVkZHlfZnJlZV9saXN0KCZtbSwgJmhvbGVz KTsKLQotCS8qIE5vdGhpbmcgbGFyZ2VyIHRoYW4gYmxvY2tzIG9mIGNodW5rX3NpemUgbm93IGF2 YWlsYWJsZSAqLwotCWZvciAob3JkZXIgPSAxOyBvcmRlciA8PSBtYXhfb3JkZXI7IG9yZGVyKysp IHsKLQkJYmxvY2sgPSBpOTE1X2J1ZGR5X2FsbG9jKCZtbSwgb3JkZXIpOwotCQlpZiAoIUlTX0VS UihibG9jaykpIHsKLQkJCXByX2luZm8oImJ1ZGR5X2FsbG9jIHVuZXhwZWN0ZWRseSBzdWNjZWVk ZWQgYXQgb3JkZXIgJWQsIGl0IHNob3VsZCBiZSBmdWxsISIsCi0JCQkJb3JkZXIpOwotCQkJbGlz dF9hZGRfdGFpbCgmYmxvY2stPmxpbmssICZibG9ja3MpOwotCQkJZXJyID0gLUVJTlZBTDsKLQkJ CWdvdG8gZXJyOwotCQl9Ci0JfQotCi1lcnI6Ci0JbGlzdF9zcGxpY2VfdGFpbCgmaG9sZXMsICZi bG9ja3MpOwotCWk5MTVfYnVkZHlfZnJlZV9saXN0KCZtbSwgJmJsb2Nrcyk7Ci0JaTkxNV9idWRk eV9maW5pKCZtbSk7Ci0JcmV0dXJuIGVycjsKLX0KLQotc3RhdGljIGludCBpZ3RfYnVkZHlfYWxs b2NfcmFuZ2Uodm9pZCAqYXJnKQotewotCXN0cnVjdCBpOTE1X2J1ZGR5X21tIG1tOwotCXVuc2ln bmVkIGxvbmcgcGFnZV9udW07Ci0JTElTVF9IRUFEKGJsb2Nrcyk7Ci0JdTY0IGNodW5rX3NpemU7 Ci0JdTY0IG9mZnNldDsKLQl1NjQgc2l6ZTsKLQl1NjQgcmVtOwotCWludCBlcnI7Ci0KLQlpZ3Rf bW1fY29uZmlnKCZzaXplLCAmY2h1bmtfc2l6ZSk7Ci0KLQlwcl9pbmZvKCJidWRkeV9pbml0IHdp dGggc2l6ZT0lbGx4LCBjaHVua19zaXplPSVsbHhcbiIsIHNpemUsIGNodW5rX3NpemUpOwotCi0J ZXJyID0gaTkxNV9idWRkeV9pbml0KCZtbSwgc2l6ZSwgY2h1bmtfc2l6ZSk7Ci0JaWYgKGVycikg ewotCQlwcl9lcnIoImJ1ZGR5X2luaXQgZmFpbGVkKCVkKVxuIiwgZXJyKTsKLQkJcmV0dXJuIGVy cjsKLQl9Ci0KLQllcnIgPSBpZ3RfY2hlY2tfbW0oJm1tKTsKLQlpZiAoZXJyKSB7Ci0JCXByX2Vy cigicHJlLW1tIGNoZWNrIGZhaWxlZCwgYWJvcnQsIGFib3J0LCBhYm9ydCFcbiIpOwotCQlnb3Rv IGVycl9maW5pOwotCX0KLQotCXJlbSA9IG1tLnNpemU7Ci0Jb2Zmc2V0ID0gMDsKLQotCWZvcl9l YWNoX3ByaW1lX251bWJlcl9mcm9tKHBhZ2VfbnVtLCAxLCBVTE9OR19NQVggLSAxKSB7Ci0JCXN0 cnVjdCBpOTE1X2J1ZGR5X2Jsb2NrICpibG9jazsKLQkJTElTVF9IRUFEKHRtcCk7Ci0KLQkJc2l6 ZSA9IG1pbihwYWdlX251bSAqIG1tLmNodW5rX3NpemUsIHJlbSk7Ci0KLQkJZXJyID0gaTkxNV9i dWRkeV9hbGxvY19yYW5nZSgmbW0sICZ0bXAsIG9mZnNldCwgc2l6ZSk7Ci0JCWlmIChlcnIpIHsK LQkJCWlmIChlcnIgPT0gLUVOT01FTSkgewotCQkJCXByX2luZm8oImFsbG9jX3JhbmdlIGhpdCAt RU5PTUVNIHdpdGggc2l6ZT0lbGx4XG4iLAotCQkJCQlzaXplKTsKLQkJCX0gZWxzZSB7Ci0JCQkJ cHJfZXJyKCJhbGxvY19yYW5nZSB3aXRoIG9mZnNldD0lbGx4LCBzaXplPSVsbHggZmFpbGVkKCVk KVxuIiwKLQkJCQkgICAgICAgb2Zmc2V0LCBzaXplLCBlcnIpOwotCQkJfQotCi0JCQlicmVhazsK LQkJfQotCi0JCWJsb2NrID0gbGlzdF9maXJzdF9lbnRyeV9vcl9udWxsKCZ0bXAsCi0JCQkJCQkg c3RydWN0IGk5MTVfYnVkZHlfYmxvY2ssCi0JCQkJCQkgbGluayk7Ci0JCWlmICghYmxvY2spIHsK LQkJCXByX2VycigiYWxsb2NfcmFuZ2UgaGFzIG5vIGJsb2Nrc1xuIik7Ci0JCQllcnIgPSAtRUlO VkFMOwotCQkJYnJlYWs7Ci0JCX0KLQotCQlpZiAoaTkxNV9idWRkeV9ibG9ja19vZmZzZXQoYmxv Y2spICE9IG9mZnNldCkgewotCQkJcHJfZXJyKCJhbGxvY19yYW5nZSBzdGFydCBvZmZzZXQgbWlz bWF0Y2gsIGZvdW5kPSVsbHgsIGV4cGVjdGVkPSVsbHhcbiIsCi0JCQkgICAgICAgaTkxNV9idWRk eV9ibG9ja19vZmZzZXQoYmxvY2spLCBvZmZzZXQpOwotCQkJZXJyID0gLUVJTlZBTDsKLQkJfQot Ci0JCWlmICghZXJyKQotCQkJZXJyID0gaWd0X2NoZWNrX2Jsb2NrcygmbW0sICZ0bXAsIHNpemUs IHRydWUpOwotCi0JCWxpc3Rfc3BsaWNlX3RhaWwoJnRtcCwgJmJsb2Nrcyk7Ci0KLQkJaWYgKGVy cikKLQkJCWJyZWFrOwotCi0JCW9mZnNldCArPSBzaXplOwotCi0JCXJlbSAtPSBzaXplOwotCQlp ZiAoIXJlbSkKLQkJCWJyZWFrOwotCi0JCWNvbmRfcmVzY2hlZCgpOwotCX0KLQotCWlmIChlcnIg PT0gLUVOT01FTSkKLQkJZXJyID0gMDsKLQotCWk5MTVfYnVkZHlfZnJlZV9saXN0KCZtbSwgJmJs b2Nrcyk7Ci0KLQlpZiAoIWVycikgewotCQllcnIgPSBpZ3RfY2hlY2tfbW0oJm1tKTsKLQkJaWYg KGVycikKLQkJCXByX2VycigicG9zdC1tbSBjaGVjayBmYWlsZWRcbiIpOwotCX0KLQotZXJyX2Zp bmk6Ci0JaTkxNV9idWRkeV9maW5pKCZtbSk7Ci0KLQlyZXR1cm4gZXJyOwotfQotCi1zdGF0aWMg aW50IGlndF9idWRkeV9hbGxvY19saW1pdCh2b2lkICphcmcpCi17Ci0Jc3RydWN0IGk5MTVfYnVk ZHlfYmxvY2sgKmJsb2NrOwotCXN0cnVjdCBpOTE1X2J1ZGR5X21tIG1tOwotCWNvbnN0IHU2NCBz aXplID0gVTY0X01BWDsKLQlpbnQgZXJyOwotCi0JZXJyID0gaTkxNV9idWRkeV9pbml0KCZtbSwg c2l6ZSwgUEFHRV9TSVpFKTsKLQlpZiAoZXJyKQotCQlyZXR1cm4gZXJyOwotCi0JaWYgKG1tLm1h eF9vcmRlciAhPSBJOTE1X0JVRERZX01BWF9PUkRFUikgewotCQlwcl9lcnIoIm1tLm1heF9vcmRl ciglZCkgIT0gJWRcbiIsCi0JCSAgICAgICBtbS5tYXhfb3JkZXIsIEk5MTVfQlVERFlfTUFYX09S REVSKTsKLQkJZXJyID0gLUVJTlZBTDsKLQkJZ290byBvdXRfZmluaTsKLQl9Ci0KLQlibG9jayA9 IGk5MTVfYnVkZHlfYWxsb2MoJm1tLCBtbS5tYXhfb3JkZXIpOwotCWlmIChJU19FUlIoYmxvY2sp KSB7Ci0JCWVyciA9IFBUUl9FUlIoYmxvY2spOwotCQlnb3RvIG91dF9maW5pOwotCX0KLQotCWlm IChpOTE1X2J1ZGR5X2Jsb2NrX29yZGVyKGJsb2NrKSAhPSBtbS5tYXhfb3JkZXIpIHsKLQkJcHJf ZXJyKCJibG9jayBvcmRlciglZCkgIT0gJWRcbiIsCi0JCSAgICAgICBpOTE1X2J1ZGR5X2Jsb2Nr X29yZGVyKGJsb2NrKSwgbW0ubWF4X29yZGVyKTsKLQkJZXJyID0gLUVJTlZBTDsKLQkJZ290byBv dXRfZnJlZTsKLQl9Ci0KLQlpZiAoaTkxNV9idWRkeV9ibG9ja19zaXplKCZtbSwgYmxvY2spICE9 Ci0JICAgIEJJVF9VTEwobW0ubWF4X29yZGVyKSAqIFBBR0VfU0laRSkgewotCQlwcl9lcnIoImJs b2NrIHNpemUoJWxsdSkgIT0gJWxsdVxuIiwKLQkJICAgICAgIGk5MTVfYnVkZHlfYmxvY2tfc2l6 ZSgmbW0sIGJsb2NrKSwKLQkJICAgICAgIEJJVF9VTEwobW0ubWF4X29yZGVyKSAqIFBBR0VfU0la RSk7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JCWdvdG8gb3V0X2ZyZWU7Ci0JfQotCi1vdXRfZnJlZToK LQlpOTE1X2J1ZGR5X2ZyZWUoJm1tLCBibG9jayk7Ci1vdXRfZmluaToKLQlpOTE1X2J1ZGR5X2Zp bmkoJm1tKTsKLQlyZXR1cm4gZXJyOwotfQotCi1pbnQgaTkxNV9idWRkeV9tb2NrX3NlbGZ0ZXN0 cyh2b2lkKQotewotCXN0YXRpYyBjb25zdCBzdHJ1Y3QgaTkxNV9zdWJ0ZXN0IHRlc3RzW10gPSB7 Ci0JCVNVQlRFU1QoaWd0X2J1ZGR5X2FsbG9jX3Blc3NpbWlzdGljKSwKLQkJU1VCVEVTVChpZ3Rf YnVkZHlfYWxsb2Nfb3B0aW1pc3RpYyksCi0JCVNVQlRFU1QoaWd0X2J1ZGR5X2FsbG9jX3BhdGhv bG9naWNhbCksCi0JCVNVQlRFU1QoaWd0X2J1ZGR5X2FsbG9jX3Ntb2tlKSwKLQkJU1VCVEVTVChp Z3RfYnVkZHlfYWxsb2NfcmFuZ2UpLAotCQlTVUJURVNUKGlndF9idWRkeV9hbGxvY19saW1pdCks Ci0JfTsKLQotCXJldHVybiBpOTE1X3N1YnRlc3RzKHRlc3RzLCBOVUxMKTsKLX0KZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9pOTE1X21vY2tfc2VsZnRlc3RzLmgg Yi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9zZWxmdGVzdHMvaTkxNV9tb2NrX3NlbGZ0ZXN0cy5oCmlu ZGV4IDNkYjM0ZDNlZWE1OC4uMzRlNWNhZjM4MDkzIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9k cm0vaTkxNS9zZWxmdGVzdHMvaTkxNV9tb2NrX3NlbGZ0ZXN0cy5oCisrKyBiL2RyaXZlcnMvZ3B1 L2RybS9pOTE1L3NlbGZ0ZXN0cy9pOTE1X21vY2tfc2VsZnRlc3RzLmgKQEAgLTMzLDUgKzMzLDQg QEAgc2VsZnRlc3QoZXZpY3QsIGk5MTVfZ2VtX2V2aWN0X21vY2tfc2VsZnRlc3RzKQogc2VsZnRl c3QoZ3R0LCBpOTE1X2dlbV9ndHRfbW9ja19zZWxmdGVzdHMpCiBzZWxmdGVzdChodWdlcGFnZXMs IGk5MTVfZ2VtX2h1Z2VfcGFnZV9tb2NrX3NlbGZ0ZXN0cykKIHNlbGZ0ZXN0KGNvbnRleHRzLCBp OTE1X2dlbV9jb250ZXh0X21vY2tfc2VsZnRlc3RzKQotc2VsZnRlc3QoYnVkZHksIGk5MTVfYnVk ZHlfbW9ja19zZWxmdGVzdHMpCiBzZWxmdGVzdChtZW1vcnlfcmVnaW9uLCBpbnRlbF9tZW1vcnlf cmVnaW9uX21vY2tfc2VsZnRlc3RzKQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUv c2VsZnRlc3RzL2ludGVsX21lbW9yeV9yZWdpb24uYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3Nl bGZ0ZXN0cy9pbnRlbF9tZW1vcnlfcmVnaW9uLmMKaW5kZXggZjg1ZmQ4Y2JmYmY1Li5jODVkNTE2 Yjg1Y2QgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9pbnRlbF9t ZW1vcnlfcmVnaW9uLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvc2VsZnRlc3RzL2ludGVs X21lbW9yeV9yZWdpb24uYwpAQCAtNTcsOSArNTcsMTAgQEAgc3RhdGljIGludCBpZ3RfbW9ja19m aWxsKHZvaWQgKmFyZykKIAlMSVNUX0hFQUQob2JqZWN0cyk7CiAJaW50IGVyciA9IDA7CiAKLQlw YWdlX3NpemUgPSBtZW0tPm1tLmNodW5rX3NpemU7Ci0JbWF4X3BhZ2VzID0gZGl2NjRfdTY0KHRv dGFsLCBwYWdlX3NpemUpOworCXBhZ2Vfc2l6ZSA9IG1lbS0+Y2h1bmtfc2l6ZTsKIAlyZW0gPSB0 b3RhbDsKK3JldHJ5OgorCW1heF9wYWdlcyA9IGRpdjY0X3U2NChyZW0sIHBhZ2Vfc2l6ZSk7CiAK IAlmb3JfZWFjaF9wcmltZV9udW1iZXJfZnJvbShwYWdlX251bSwgMSwgbWF4X3BhZ2VzKSB7CiAJ CXJlc291cmNlX3NpemVfdCBzaXplID0gcGFnZV9udW0gKiBwYWdlX3NpemU7CkBAIC04NSw2ICs4 NiwxMSBAQCBzdGF0aWMgaW50IGlndF9tb2NrX2ZpbGwodm9pZCAqYXJnKQogCQllcnIgPSAwOwog CWlmIChlcnIgPT0gLUVOWElPKSB7CiAJCWlmIChwYWdlX251bSAqIHBhZ2Vfc2l6ZSA8PSByZW0p IHsKKwkJCWlmIChtZW0tPmlzX3JhbmdlX21hbmFnZXIgJiYgbWF4X3BhZ2VzID4gMSkgeworCQkJ CW1heF9wYWdlcyA+Pj0gMTsKKwkJCQlnb3RvIHJldHJ5OworCQkJfQorCiAJCQlwcl9lcnIoIiVz IGZhaWxlZCwgc3BhY2Ugc3RpbGwgbGVmdCBpbiByZWdpb25cbiIsCiAJCQkgICAgICAgX19mdW5j X18pOwogCQkJZXJyID0gLUVJTlZBTDsKQEAgLTE5OSwxMiArMjA1LDE4IEBAIHN0YXRpYyBpbnQg aWd0X21vY2tfcmVzZXJ2ZSh2b2lkICphcmcpCiAJZG8gewogCQl1MzIgc2l6ZSA9IGk5MTVfcHJh bmRvbV91MzJfbWF4X3N0YXRlKGN1cl9hdmFpbCwgJnBybmcpOwogCityZXRyeToKIAkJc2l6ZSA9 IG1heF90KHUzMiwgcm91bmRfdXAoc2l6ZSwgUEFHRV9TSVpFKSwgUEFHRV9TSVpFKTsKIAkJb2Jq ID0gaWd0X29iamVjdF9jcmVhdGUobWVtLCAmb2JqZWN0cywgc2l6ZSwgMCk7CiAJCWlmIChJU19F UlIob2JqKSkgewotCQkJaWYgKFBUUl9FUlIob2JqKSA9PSAtRU5YSU8pCisJCQlpZiAoUFRSX0VS UihvYmopID09IC1FTlhJTykgeworCQkJCWlmIChtZW0tPmlzX3JhbmdlX21hbmFnZXIgJiYKKwkJ CQkgICAgc2l6ZSA+IG1lbS0+Y2h1bmtfc2l6ZSkgeworCQkJCQlzaXplID4+PSAxOworCQkJCQln b3RvIHJldHJ5OworCQkJCX0KIAkJCQlicmVhazsKLQorCQkJfQogCQkJZXJyID0gUFRSX0VSUihv YmopOwogCQkJZ290byBvdXRfY2xvc2U7CiAJCX0KQEAgLTIyMCw3ICsyMzIsNyBAQCBzdGF0aWMg aW50IGlndF9tb2NrX3Jlc2VydmUodm9pZCAqYXJnKQogb3V0X2Nsb3NlOgogCWtmcmVlKG9yZGVy KTsKIAljbG9zZV9vYmplY3RzKG1lbSwgJm9iamVjdHMpOwotCWk5MTVfYnVkZHlfZnJlZV9saXN0 KCZtZW0tPm1tLCAmbWVtLT5yZXNlcnZlZCk7CisJaW50ZWxfbWVtb3J5X3JlZ2lvbl91bnJlc2Vy dmUobWVtKTsKIAlyZXR1cm4gZXJyOwogfQogCkBAIC0yNDAsNyArMjUyLDcgQEAgc3RhdGljIGlu dCBpZ3RfbW9ja19jb250aWd1b3VzKHZvaWQgKmFyZykKIAl0b3RhbCA9IHJlc291cmNlX3NpemUo Jm1lbS0+cmVnaW9uKTsKIAogCS8qIE1pbiBzaXplICovCi0Jb2JqID0gaWd0X29iamVjdF9jcmVh dGUobWVtLCAmb2JqZWN0cywgbWVtLT5tbS5jaHVua19zaXplLAorCW9iaiA9IGlndF9vYmplY3Rf Y3JlYXRlKG1lbSwgJm9iamVjdHMsIG1lbS0+Y2h1bmtfc2l6ZSwKIAkJCQlJOTE1X0JPX0FMTE9D X0NPTlRJR1VPVVMpOwogCWlmIChJU19FUlIob2JqKSkKIAkJcmV0dXJuIFBUUl9FUlIob2JqKTsK QEAgLTMyMSwxNCArMzMzLDE2IEBAIHN0YXRpYyBpbnQgaWd0X21vY2tfY29udGlndW91cyh2b2lk ICphcmcpCiAJbWluID0gdGFyZ2V0OwogCXRhcmdldCA9IHRvdGFsID4+IDE7CiAKLQkvKiBNYWtl IHN1cmUgd2UgY2FuIHN0aWxsIGFsbG9jYXRlIGFsbCB0aGUgZnJhZ21lbnRlZCBzcGFjZSAqLwot CW9iaiA9IGlndF9vYmplY3RfY3JlYXRlKG1lbSwgJm9iamVjdHMsIHRhcmdldCwgMCk7Ci0JaWYg KElTX0VSUihvYmopKSB7Ci0JCWVyciA9IFBUUl9FUlIob2JqKTsKLQkJZ290byBlcnJfY2xvc2Vf b2JqZWN0czsKLQl9CisJaWYgKCFtZW0tPmlzX3JhbmdlX21hbmFnZXIpIHsKKwkJLyogTWFrZSBz dXJlIHdlIGNhbiBzdGlsbCBhbGxvY2F0ZSBhbGwgdGhlIGZyYWdtZW50ZWQgc3BhY2UgKi8KKwkJ b2JqID0gaWd0X29iamVjdF9jcmVhdGUobWVtLCAmb2JqZWN0cywgdGFyZ2V0LCAwKTsKKwkJaWYg KElTX0VSUihvYmopKSB7CisJCQllcnIgPSBQVFJfRVJSKG9iaik7CisJCQlnb3RvIGVycl9jbG9z ZV9vYmplY3RzOworCQl9CiAKLQlpZ3Rfb2JqZWN0X3JlbGVhc2Uob2JqKTsKKwkJaWd0X29iamVj dF9yZWxlYXNlKG9iaik7CisJfQogCiAJLyoKIAkgKiBFdmVuIHRob3VnaCB3ZSBoYXZlIGVub3Vn aCBmcmVlIHNwYWNlLCB3ZSBkb24ndCBoYXZlIGEgYmlnIGVub3VnaApAQCAtMzQ4LDcgKzM2Miw3 IEBAIHN0YXRpYyBpbnQgaWd0X21vY2tfY29udGlndW91cyh2b2lkICphcmcpCiAJCX0KIAogCQl0 YXJnZXQgPj49IDE7Ci0JfSB3aGlsZSAodGFyZ2V0ID49IG1lbS0+bW0uY2h1bmtfc2l6ZSk7CisJ fSB3aGlsZSAodGFyZ2V0ID49IG1lbS0+Y2h1bmtfc2l6ZSk7CiAKIGVycl9jbG9zZV9vYmplY3Rz OgogCWxpc3Rfc3BsaWNlX3RhaWwoJmhvbGVzLCAmb2JqZWN0cyk7CkBAIC0zNjgsNyArMzgyLDcg QEAgc3RhdGljIGludCBpZ3RfbW9ja19zcGxpbnRlcmVkX3JlZ2lvbih2b2lkICphcmcpCiAKIAkv KgogCSAqIFNhbml0eSBjaGVjayB3ZSBjYW4gc3RpbGwgYWxsb2NhdGUgZXZlcnl0aGluZyBldmVu IGlmIHRoZQotCSAqIG1tLm1heF9vcmRlciAhPSBtbS5zaXplLiBpLmUgb3VyIHN0YXJ0aW5nIGFk ZHJlc3Mgc3BhY2Ugc2l6ZSBpcyBub3QgYQorCSAqIG1heF9vcmRlciAhPSBtbS5zaXplLiBpLmUg b3VyIHN0YXJ0aW5nIGFkZHJlc3Mgc3BhY2Ugc2l6ZSBpcyBub3QgYQogCSAqIHBvd2VyLW9mLXR3 by4KIAkgKi8KIApAQCAtMzc3LDE3ICszOTEsMTAgQEAgc3RhdGljIGludCBpZ3RfbW9ja19zcGxp bnRlcmVkX3JlZ2lvbih2b2lkICphcmcpCiAJaWYgKElTX0VSUihtZW0pKQogCQlyZXR1cm4gUFRS X0VSUihtZW0pOwogCi0JaWYgKG1lbS0+bW0uc2l6ZSAhPSBzaXplKSB7Ci0JCXByX2VycigiJXMg c2l6ZSBtaXNtYXRjaCglbGx1ICE9ICVsbHUpXG4iLAotCQkgICAgICAgX19mdW5jX18sIG1lbS0+ bW0uc2l6ZSwgc2l6ZSk7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JCWdvdG8gb3V0X3B1dDsKLQl9Ci0K IAlleHBlY3RlZF9vcmRlciA9IGdldF9vcmRlcihyb3VuZGRvd25fcG93X29mX3R3byhzaXplKSk7 Ci0JaWYgKG1lbS0+bW0ubWF4X29yZGVyICE9IGV4cGVjdGVkX29yZGVyKSB7CisJaWYgKG1lbS0+ bWF4X29yZGVyICE9IGV4cGVjdGVkX29yZGVyKSB7CiAJCXByX2VycigiJXMgb3JkZXIgbWlzbWF0 Y2goJXUgIT0gJXUpXG4iLAotCQkgICAgICAgX19mdW5jX18sIG1lbS0+bW0ubWF4X29yZGVyLCBl eHBlY3RlZF9vcmRlcik7CisJCSAgICAgICBfX2Z1bmNfXywgbWVtLT5tYXhfb3JkZXIsIGV4cGVj dGVkX29yZGVyKTsKIAkJZXJyID0gLUVJTlZBTDsKIAkJZ290byBvdXRfcHV0OwogCX0KQEAgLTQw OCwxMiArNDE1LDE1IEBAIHN0YXRpYyBpbnQgaWd0X21vY2tfc3BsaW50ZXJlZF9yZWdpb24odm9p ZCAqYXJnKQogCSAqIHN1cmUgdGhhdCBkb2VzIGluZGVlZCBob2xkIHRydWUuCiAJICovCiAKLQlv YmogPSBpZ3Rfb2JqZWN0X2NyZWF0ZShtZW0sICZvYmplY3RzLCBzaXplLCBJOTE1X0JPX0FMTE9D X0NPTlRJR1VPVVMpOwotCWlmICghSVNfRVJSKG9iaikpIHsKLQkJcHJfZXJyKCIlcyB0b28gbGFy Z2UgY29udGlndW91cyBhbGxvY2F0aW9uIHdhcyBub3QgcmVqZWN0ZWRcbiIsCi0JCSAgICAgICBf X2Z1bmNfXyk7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JCWdvdG8gb3V0X2Nsb3NlOworCWlmICghbWVt LT5pc19yYW5nZV9tYW5hZ2VyKSB7CisJCW9iaiA9IGlndF9vYmplY3RfY3JlYXRlKG1lbSwgJm9i amVjdHMsIHNpemUsCisJCQkJCUk5MTVfQk9fQUxMT0NfQ09OVElHVU9VUyk7CisJCWlmICghSVNf RVJSKG9iaikpIHsKKwkJCXByX2VycigiJXMgdG9vIGxhcmdlIGNvbnRpZ3VvdXMgYWxsb2NhdGlv biB3YXMgbm90IHJlamVjdGVkXG4iLAorCQkJICAgICAgIF9fZnVuY19fKTsKKwkJCWVyciA9IC1F SU5WQUw7CisJCQlnb3RvIG91dF9jbG9zZTsKKwkJfQogCX0KIAogCW9iaiA9IGlndF9vYmplY3Rf Y3JlYXRlKG1lbSwgJm9iamVjdHMsIHJvdW5kZG93bl9wb3dfb2ZfdHdvKHNpemUpLApAQCAtNDMy LDY4ICs0NDIsNiBAQCBzdGF0aWMgaW50IGlndF9tb2NrX3NwbGludGVyZWRfcmVnaW9uKHZvaWQg KmFyZykKIAlyZXR1cm4gZXJyOwogfQogCi0jaWZuZGVmIFNaXzhHCi0jZGVmaW5lIFNaXzhHIEJJ VF9VTEwoMzMpCi0jZW5kaWYKLQotc3RhdGljIGludCBpZ3RfbW9ja19tYXhfc2VnbWVudCh2b2lk ICphcmcpCi17Ci0JY29uc3QgdW5zaWduZWQgaW50IG1heF9zZWdtZW50ID0gaTkxNV9zZ19zZWdt ZW50X3NpemUoKTsKLQlzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtID0gYXJnOwotCXN0 cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1ID0gbWVtLT5pOTE1OwotCXN0cnVjdCBkcm1faTkx NV9nZW1fb2JqZWN0ICpvYmo7Ci0Jc3RydWN0IGk5MTVfYnVkZHlfYmxvY2sgKmJsb2NrOwotCXN0 cnVjdCBzY2F0dGVybGlzdCAqc2c7Ci0JTElTVF9IRUFEKG9iamVjdHMpOwotCXU2NCBzaXplOwot CWludCBlcnIgPSAwOwotCi0JLyoKLQkgKiBXaGlsZSB3ZSBtYXkgY3JlYXRlIHZlcnkgbGFyZ2Ug Y29udGlndW91cyBibG9ja3MsIHdlIG1heSBuZWVkCi0JICogdG8gYnJlYWsgdGhvc2UgZG93biBm b3IgY29uc3VtcHRpb24gZWxzZXdoZXJlLiBJbiBwYXJ0aWN1bGFyLAotCSAqIGRtYS1tYXBwaW5n IHdpdGggc2NhdHRlcmxpc3QgZWxlbWVudHMgaGF2ZSBhbiBpbXBsaWNpdCBsaW1pdCBvZgotCSAq IFVJTlRfTUFYIG9uIGVhY2ggZWxlbWVudC4KLQkgKi8KLQotCXNpemUgPSBTWl84RzsKLQltZW0g PSBtb2NrX3JlZ2lvbl9jcmVhdGUoaTkxNSwgMCwgc2l6ZSwgUEFHRV9TSVpFLCAwKTsKLQlpZiAo SVNfRVJSKG1lbSkpCi0JCXJldHVybiBQVFJfRVJSKG1lbSk7Ci0KLQlvYmogPSBpZ3Rfb2JqZWN0 X2NyZWF0ZShtZW0sICZvYmplY3RzLCBzaXplLCAwKTsKLQlpZiAoSVNfRVJSKG9iaikpIHsKLQkJ ZXJyID0gUFRSX0VSUihvYmopOwotCQlnb3RvIG91dF9wdXQ7Ci0JfQotCi0Jc2l6ZSA9IDA7Ci0J bGlzdF9mb3JfZWFjaF9lbnRyeShibG9jaywgJm9iai0+bW0uYmxvY2tzLCBsaW5rKSB7Ci0JCWlm IChpOTE1X2J1ZGR5X2Jsb2NrX3NpemUoJm1lbS0+bW0sIGJsb2NrKSA+IHNpemUpCi0JCQlzaXpl ID0gaTkxNV9idWRkeV9ibG9ja19zaXplKCZtZW0tPm1tLCBibG9jayk7Ci0JfQotCWlmIChzaXpl IDwgbWF4X3NlZ21lbnQpIHsKLQkJcHJfZXJyKCIlczogRmFpbGVkIHRvIGNyZWF0ZSBhIGh1Z2Ug Y29udGlndW91cyBibG9jayBbPiAldV0sIGxhcmdlc3QgYmxvY2sgJWxsZFxuIiwKLQkJICAgICAg IF9fZnVuY19fLCBtYXhfc2VnbWVudCwgc2l6ZSk7Ci0JCWVyciA9IC1FSU5WQUw7Ci0JCWdvdG8g b3V0X2Nsb3NlOwotCX0KLQotCWZvciAoc2cgPSBvYmotPm1tLnBhZ2VzLT5zZ2w7IHNnOyBzZyA9 IHNnX25leHQoc2cpKSB7Ci0JCWlmIChzZy0+bGVuZ3RoID4gbWF4X3NlZ21lbnQpIHsKLQkJCXBy X2VycigiJXM6IENyZWF0ZWQgYW4gb3ZlcnNpemVkIHNjYXR0ZXJsaXN0IGVudHJ5LCAldSA+ICV1 XG4iLAotCQkJICAgICAgIF9fZnVuY19fLCBzZy0+bGVuZ3RoLCBtYXhfc2VnbWVudCk7Ci0JCQll cnIgPSAtRUlOVkFMOwotCQkJZ290byBvdXRfY2xvc2U7Ci0JCX0KLQl9Ci0KLW91dF9jbG9zZToK LQljbG9zZV9vYmplY3RzKG1lbSwgJm9iamVjdHMpOwotb3V0X3B1dDoKLQlpbnRlbF9tZW1vcnlf cmVnaW9uX3B1dChtZW0pOwotCXJldHVybiBlcnI7Ci19Ci0KIHN0YXRpYyBpbnQgaWd0X2dwdV93 cml0ZV9kdyhzdHJ1Y3QgaW50ZWxfY29udGV4dCAqY2UsCiAJCQkgICAgc3RydWN0IGk5MTVfdm1h ICp2bWEsCiAJCQkgICAgdTMyIGR3b3JkLApAQCAtMTA5OCw3ICsxMDQ2LDYgQEAgaW50IGludGVs X21lbW9yeV9yZWdpb25fbW9ja19zZWxmdGVzdHModm9pZCkKIAkJU1VCVEVTVChpZ3RfbW9ja19m aWxsKSwKIAkJU1VCVEVTVChpZ3RfbW9ja19jb250aWd1b3VzKSwKIAkJU1VCVEVTVChpZ3RfbW9j a19zcGxpbnRlcmVkX3JlZ2lvbiksCi0JCVNVQlRFU1QoaWd0X21vY2tfbWF4X3NlZ21lbnQpLAog CX07CiAJc3RydWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbTsKIAlzdHJ1Y3QgZHJtX2k5MTVf cHJpdmF0ZSAqaTkxNTsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0 cy9tb2NrX2dlbV9kZXZpY2UuYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9tb2Nr X2dlbV9kZXZpY2UuYwppbmRleCBjZjQwMDA0YmM5MmEuLmQxODljNGJkNGJlZiAxMDA2NDQKLS0t IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvc2VsZnRlc3RzL21vY2tfZ2VtX2RldmljZS5jCisrKyBi L2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9tb2NrX2dlbV9kZXZpY2UuYwpAQCAtMzIs NiArMzIsNyBAQAogI2luY2x1ZGUgImd0L2ludGVsX2d0X3JlcXVlc3RzLmgiCiAjaW5jbHVkZSAi Z3QvbW9ja19lbmdpbmUuaCIKICNpbmNsdWRlICJpbnRlbF9tZW1vcnlfcmVnaW9uLmgiCisjaW5j bHVkZSAiaW50ZWxfcmVnaW9uX3R0bS5oIgogCiAjaW5jbHVkZSAibW9ja19yZXF1ZXN0LmgiCiAj aW5jbHVkZSAibW9ja19nZW1fZGV2aWNlLmgiCkBAIC03MCw2ICs3MSw3IEBAIHN0YXRpYyB2b2lk IG1vY2tfZGV2aWNlX3JlbGVhc2Uoc3RydWN0IGRybV9kZXZpY2UgKmRldikKIAltb2NrX2Zpbmlf Z2d0dCgmaTkxNS0+Z2d0dCk7CiAJZGVzdHJveV93b3JrcXVldWUoaTkxNS0+d3EpOwogCisJaW50 ZWxfcmVnaW9uX3R0bV9kZXZpY2VfZmluaShpOTE1KTsKIAlpbnRlbF9ndF9kcml2ZXJfbGF0ZV9y ZWxlYXNlKCZpOTE1LT5ndCk7CiAJaW50ZWxfbWVtb3J5X3JlZ2lvbnNfZHJpdmVyX3JlbGVhc2Uo aTkxNSk7CiAKQEAgLTExNiw2ICsxMTgsNyBAQCBzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqbW9j a19nZW1fZGV2aWNlKHZvaWQpCiAjZW5kaWYKIAlzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqaTkx NTsKIAlzdHJ1Y3QgcGNpX2RldiAqcGRldjsKKwlpbnQgcmV0OwogCiAJcGRldiA9IGt6YWxsb2Mo c2l6ZW9mKCpwZGV2KSwgR0ZQX0tFUk5FTCk7CiAJaWYgKCFwZGV2KQpAQCAtMTc4LDYgKzE4MSwx MCBAQCBzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqbW9ja19nZW1fZGV2aWNlKHZvaWQpCiAJYXRv bWljX2luYygmaTkxNS0+Z3Qud2FrZXJlZi5jb3VudCk7IC8qIGRpc2FibGU7IG5vIGh3IHN1cHBv cnQgKi8KIAlpOTE1LT5ndC5hd2FrZSA9IC1FTk9ERVY7CiAKKwlyZXQgPSBpbnRlbF9yZWdpb25f dHRtX2RldmljZV9pbml0KGk5MTUpOworCWlmIChyZXQpCisJCWdvdG8gZXJyX3R0bTsKKwogCWk5 MTUtPndxID0gYWxsb2Nfb3JkZXJlZF93b3JrcXVldWUoIm1vY2siLCAwKTsKIAlpZiAoIWk5MTUt PndxKQogCQlnb3RvIGVycl9kcnY7CkBAIC0yMDEsNiArMjA4LDcgQEAgc3RydWN0IGRybV9pOTE1 X3ByaXZhdGUgKm1vY2tfZ2VtX2RldmljZSh2b2lkKQogCWludGVsX2VuZ2luZXNfZHJpdmVyX3Jl Z2lzdGVyKGk5MTUpOwogCiAJaTkxNS0+ZG9fcmVsZWFzZSA9IHRydWU7CisJaWRhX2luaXQoJmk5 MTUtPnNlbGZ0ZXN0Lm1vY2tfcmVnaW9uX2luc3RhbmNlcyk7CiAKIAlyZXR1cm4gaTkxNTsKIApA QCAtMjA5LDYgKzIxNyw4IEBAIHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICptb2NrX2dlbV9kZXZp Y2Uodm9pZCkKIGVycl91bmxvY2s6CiAJZGVzdHJveV93b3JrcXVldWUoaTkxNS0+d3EpOwogZXJy X2RydjoKKwlpbnRlbF9yZWdpb25fdHRtX2RldmljZV9maW5pKGk5MTUpOworZXJyX3R0bToKIAlp bnRlbF9ndF9kcml2ZXJfbGF0ZV9yZWxlYXNlKCZpOTE1LT5ndCk7CiAJaW50ZWxfbWVtb3J5X3Jl Z2lvbnNfZHJpdmVyX3JlbGVhc2UoaTkxNSk7CiAJZHJtX21vZGVfY29uZmlnX2NsZWFudXAoJmk5 MTUtPmRybSk7CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9zZWxmdGVzdHMvbW9j a19yZWdpb24uYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L3NlbGZ0ZXN0cy9tb2NrX3JlZ2lvbi5j CmluZGV4IDVkMmQwMTBhMWUyMi4uZWFmYzVhMDQ5NzVjIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dw dS9kcm0vaTkxNS9zZWxmdGVzdHMvbW9ja19yZWdpb24uYworKysgYi9kcml2ZXJzL2dwdS9kcm0v aTkxNS9zZWxmdGVzdHMvbW9ja19yZWdpb24uYwpAQCAtMSwxNyArMSw1NiBAQAogLy8gU1BEWC1M aWNlbnNlLUlkZW50aWZpZXI6IE1JVAogLyoKLSAqIENvcHlyaWdodCDCqSAyMDE5IEludGVsIENv cnBvcmF0aW9uCisgKiBDb3B5cmlnaHQgwqkgMjAxOS0yMDIxIEludGVsIENvcnBvcmF0aW9uCiAg Ki8KIAorI2luY2x1ZGUgPGxpbnV4L3NjYXR0ZXJsaXN0Lmg+CisKKyNpbmNsdWRlIDxkcm0vdHRt L3R0bV9wbGFjZW1lbnQuaD4KKwogI2luY2x1ZGUgImdlbS9pOTE1X2dlbV9yZWdpb24uaCIKICNp bmNsdWRlICJpbnRlbF9tZW1vcnlfcmVnaW9uLmgiCisjaW5jbHVkZSAiaW50ZWxfcmVnaW9uX3R0 bS5oIgogCiAjaW5jbHVkZSAibW9ja19yZWdpb24uaCIKIAorc3RhdGljIHZvaWQgbW9ja19yZWdp b25fcHV0X3BhZ2VzKHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmosCisJCQkJICBzdHJ1 Y3Qgc2dfdGFibGUgKnBhZ2VzKQoreworCWludGVsX3JlZ2lvbl90dG1fbm9kZV9mcmVlKG9iai0+ bW0ucmVnaW9uLCBvYmotPm1tLnN0X21tX25vZGUpOworCXNnX2ZyZWVfdGFibGUocGFnZXMpOwor CWtmcmVlKHBhZ2VzKTsKK30KKworc3RhdGljIGludCBtb2NrX3JlZ2lvbl9nZXRfcGFnZXMoc3Ry dWN0IGRybV9pOTE1X2dlbV9vYmplY3QgKm9iaikKK3sKKwl1bnNpZ25lZCBpbnQgZmxhZ3M7CisJ c3RydWN0IHNnX3RhYmxlICpwYWdlczsKKworCWZsYWdzID0gSTkxNV9BTExPQ19NSU5fUEFHRV9T SVpFOworCWlmIChvYmotPmZsYWdzICYgSTkxNV9CT19BTExPQ19DT05USUdVT1VTKQorCQlmbGFn cyB8PSBJOTE1X0FMTE9DX0NPTlRJR1VPVVM7CisKKwlvYmotPm1tLnN0X21tX25vZGUgPSBpbnRl bF9yZWdpb25fdHRtX25vZGVfYWxsb2Mob2JqLT5tbS5yZWdpb24sCisJCQkJCQkJIG9iai0+YmFz ZS5zaXplLAorCQkJCQkJCSBmbGFncyk7CisJaWYgKElTX0VSUihvYmotPm1tLnN0X21tX25vZGUp KQorCQlyZXR1cm4gUFRSX0VSUihvYmotPm1tLnN0X21tX25vZGUpOworCisJcGFnZXMgPSBpbnRl bF9yZWdpb25fdHRtX25vZGVfdG9fc3Qob2JqLT5tbS5yZWdpb24sIG9iai0+bW0uc3RfbW1fbm9k ZSk7CisJaWYgKElTX0VSUihwYWdlcykpIHsKKwkJaW50ZWxfcmVnaW9uX3R0bV9ub2RlX2ZyZWUo b2JqLT5tbS5yZWdpb24sIG9iai0+bW0uc3RfbW1fbm9kZSk7CisJCXJldHVybiBQVFJfRVJSKHBh Z2VzKTsKKwl9CisKKwlfX2k5MTVfZ2VtX29iamVjdF9zZXRfcGFnZXMob2JqLCBwYWdlcywgaTkx NV9zZ19kbWFfc2l6ZXMocGFnZXMtPnNnbCkpOworCisJcmV0dXJuIDA7Cit9CisKIHN0YXRpYyBj b25zdCBzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVjdF9vcHMgbW9ja19yZWdpb25fb2JqX29wcyA9 IHsKIAkubmFtZSA9ICJtb2NrLXJlZ2lvbiIsCi0JLmdldF9wYWdlcyA9IGk5MTVfZ2VtX29iamVj dF9nZXRfcGFnZXNfYnVkZHksCi0JLnB1dF9wYWdlcyA9IGk5MTVfZ2VtX29iamVjdF9wdXRfcGFn ZXNfYnVkZHksCisJLmdldF9wYWdlcyA9IG1vY2tfcmVnaW9uX2dldF9wYWdlcywKKwkucHV0X3Bh Z2VzID0gbW9ja19yZWdpb25fcHV0X3BhZ2VzLAogCS5yZWxlYXNlID0gaTkxNV9nZW1fb2JqZWN0 X3JlbGVhc2VfbWVtb3J5X3JlZ2lvbiwKIH07CiAKQEAgLTIzLDcgKzYyLDcgQEAgc3RhdGljIGlu dCBtb2NrX29iamVjdF9pbml0KHN0cnVjdCBpbnRlbF9tZW1vcnlfcmVnaW9uICptZW0sCiAJc3Rh dGljIHN0cnVjdCBsb2NrX2NsYXNzX2tleSBsb2NrX2NsYXNzOwogCXN0cnVjdCBkcm1faTkxNV9w cml2YXRlICppOTE1ID0gbWVtLT5pOTE1OwogCi0JaWYgKHNpemUgPiBtZW0tPm1tLnNpemUpCisJ aWYgKHNpemUgPiByZXNvdXJjZV9zaXplKCZtZW0tPnJlZ2lvbikpCiAJCXJldHVybiAtRTJCSUc7 CiAKIAlkcm1fZ2VtX3ByaXZhdGVfb2JqZWN0X2luaXQoJmk5MTUtPmRybSwgJm9iai0+YmFzZSwg c2l6ZSk7CkBAIC0zOCw5ICs3NywxOCBAQCBzdGF0aWMgaW50IG1vY2tfb2JqZWN0X2luaXQoc3Ry dWN0IGludGVsX21lbW9yeV9yZWdpb24gKm1lbSwKIAlyZXR1cm4gMDsKIH0KIAorc3RhdGljIHZv aWQgbW9ja19yZWdpb25fZmluaShzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbiAqbWVtKQorewor CXN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1ID0gbWVtLT5pOTE1OworCWludCBpbnN0YW5j ZSA9IG1lbS0+aW5zdGFuY2U7CisKKwlpbnRlbF9yZWdpb25fdHRtX2ZpbmkobWVtKTsKKwlpZGFf ZnJlZSgmaTkxNS0+c2VsZnRlc3QubW9ja19yZWdpb25faW5zdGFuY2VzLCBpbnN0YW5jZSk7Cit9 CisKIHN0YXRpYyBjb25zdCBzdHJ1Y3QgaW50ZWxfbWVtb3J5X3JlZ2lvbl9vcHMgbW9ja19yZWdp b25fb3BzID0gewotCS5pbml0ID0gaW50ZWxfbWVtb3J5X3JlZ2lvbl9pbml0X2J1ZGR5LAotCS5y ZWxlYXNlID0gaW50ZWxfbWVtb3J5X3JlZ2lvbl9yZWxlYXNlX2J1ZGR5LAorCS5pbml0ID0gaW50 ZWxfcmVnaW9uX3R0bV9pbml0LAorCS5yZWxlYXNlID0gbW9ja19yZWdpb25fZmluaSwKIAkuaW5p dF9vYmplY3QgPSBtb2NrX29iamVjdF9pbml0LAogfTsKIApAQCAtNTEsNiArOTksMTQgQEAgbW9j a19yZWdpb25fY3JlYXRlKHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICppOTE1LAogCQkgICByZXNv dXJjZV9zaXplX3QgbWluX3BhZ2Vfc2l6ZSwKIAkJICAgcmVzb3VyY2Vfc2l6ZV90IGlvX3N0YXJ0 KQogeworCWludCBpbnN0YW5jZSA9IGlkYV9hbGxvY19tYXgoJmk5MTUtPnNlbGZ0ZXN0Lm1vY2tf cmVnaW9uX2luc3RhbmNlcywKKwkJCQkgICAgIFRUTV9OVU1fTUVNX1RZUEVTIC0gVFRNX1BMX1BS SVYgLSAxLAorCQkJCSAgICAgR0ZQX0tFUk5FTCk7CisKKwlpZiAoaW5zdGFuY2UgPCAwKQorCQly ZXR1cm4gRVJSX1BUUihpbnN0YW5jZSk7CisKIAlyZXR1cm4gaW50ZWxfbWVtb3J5X3JlZ2lvbl9j cmVhdGUoaTkxNSwgc3RhcnQsIHNpemUsIG1pbl9wYWdlX3NpemUsCi0JCQkJCSAgaW9fc3RhcnQs ICZtb2NrX3JlZ2lvbl9vcHMpOworCQkJCQkgIGlvX3N0YXJ0LCBJTlRFTF9NRU1PUllfTU9DSywg aW5zdGFuY2UsCisJCQkJCSAgJm1vY2tfcmVnaW9uX29wcyk7CiB9Ci0tIAoyLjMxLjEKCl9fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkludGVsLWdmeCBtYWls aW5nIGxpc3QKSW50ZWwtZ2Z4QGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZy ZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2ludGVsLWdmeAo=