From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dmitry Osipenko Subject: Re: [Regression 5.5-rc1] Extremely low GPU performance on NVIDIA Tegra20/30 Date: Thu, 30 Jan 2020 07:36:36 +0300 Message-ID: References: <20191213151045.GB222809@ulmo> <2f5c6fda-adf9-c6c3-7601-fa912813ce1f@gmail.com> <20200129123935.GG2479935@ulmo> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Return-path: In-Reply-To: <20200129123935.GG2479935@ulmo> Content-Language: en-US Sender: linux-tegra-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Thierry Reding Cc: "linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , DRI Development List-Id: linux-tegra@vger.kernel.org 29.01.2020 15:39, Thierry Reding пишет: > On Mon, Jan 20, 2020 at 05:53:03AM +0300, Dmitry Osipenko wrote: >> 13.12.2019 18:35, Dmitry Osipenko пишет: ... >> Hello Thierry, >> >> I took another look at the problem and here what was found: >> >> 1) The "Optionally attach clients to the IOMMU" patch is wrong because: >> >> 1. host1x_drm_probe() is invoked *before* any of the >> host1x_client_iommu_attach() happens, so there is no way >> on earth the 'use_explicit_iommu' could ever be true. > > That's not correct. host1x_client_iommu_attach() happens during > host1x_device_init(), which is called during host1x_drm_probe(). Looks like I previously got confused by accident, my bad. > The idea is that host1x_drm_probe() sets up the minimum IOMMU so that all > devices can attach, if they want to. If any of them connect (because > they aren't already attached via something like the DMA/IOMMU glue) > then the tegra->use_explicit_iommu is set to true, in which case the > IOMMU domain setup for explicit IOMMU API usage is completed. If, on > the other hand, none of the clients have a need for the explicit IOMMU > domain, there's no need to set it up and host1x_drm_probe() will just > discard it. This matches my understanding of what you wanted to achieve, thanks. >> 2. Not attaching DRM clients to IOMMU if HOST1x isn't >> attached is wrong because it never attached in the case >> of CONFIG_TEGRA_HOST1X_FIREWALL=y [1] and this also >> makes no sense for T20/30 that do not support LPAE. > > It's not at all wrong. Take for example the case of Tegra124 and > Tegra210 where host1x and its clients can address 34 bits. In those > cases, allocating individual pages via shmem has a high probability of > hitting physical addresses beyond the 32-bit range, which means that the > host1x can not access them unless it is also attached to an IOMMU where > physical addresses to >= 4 GiB addresses can be translated into < 4 GiB > virtual addresses. This is a very real problem that I was running into > when testing on Tegra124 and Tegra210. Why not to set the DMA mask to 32bits if IOMMU is unavailable? I'm a bit puzzled by the actual need to support the case where Host1x is backed by IOMMU and clients not.. How we could ever end up with this scenario in the upstream kernel? What about the reverse scenario? You won't be able to patch cmdstream properly for >32bit addresses. The root of the problem is that Tegra DRM UAPI doesn't support 64bit addresses, so you can't use "wide" opcodes and can't patch cmdstream. Perhaps it is better not to add any new things or quirks to the Host1x / Tegra DRM for now. The drivers need a serious clean up, otherwise mess only continues to grow up. Don't you think so? > But I agree that this shouldn't be necessary on Tegra20 and Tegra30. We > should be able to remedy the situation on Tegra20 and Tegra30 by adding > another check, based on the DMA mask. Something like the below should > work: > > --- >8 --- [snip] > --- >8 --- This works, thanks. >> [1] >> https://elixir.bootlin.com/linux/v5.5-rc6/source/drivers/gpu/host1x/dev.c#L205 >> >> 2) Because of the above problems, the DRM clients are erroneously not >> getting attached to IOMMU at all and thus CMA is getting used for the BO >> allocations. Here comes the problems introduced by the "gpu: host1x: >> Support DMA mapping of buffers" patch, which makes DMA API to perform >> CPU cache maintenance on each job submission and apparently this is >> super bad for performance. This also makes no sense in comparison to the >> case of enabled IOMMU, where cache maintenance isn't performed at all >> (like it should be). > > It actually does make a lot of sense. Very strictly speaking we were > violating the DMA API prior to the above patch because we were not DMA > mapping the buffers at all. Whenever you pass a buffer to hardware you > need to map it for the device. At that point, the kernel does not know > whether or not the buffer is dirty, so it has to perform a cache flush. > Similarily, when the hardware is done with a buffer, we need to unmap it > so that the CPU can access it again. This typically requires a cache > invalidate. > > That things even worked to begin with more by accident than by design. > > So yes, this is different from what we were doing before, but it's > actually the right thing to do. That said, I'm sure we can find ways to > optimize this. For example, as part of the DMA API conversion series I > added the possibility to set direction flags for relocation buffers. In > cases where it is known that a certain buffer will only be used for > reading, we should be able to avoid at least the cache invalidate > operation after a job is done, since the hardware won't have modified > the contents (when using an SMMU this can even be enforced). It's > slightly trickier to avoid cache flushes. For buffers that are only > going to be written, there's no need to flush the cache because the CPUs > changes can be assumed to be overwritten by the hardware anyway. However > we still need to make sure that we invalidate the caches in that case to > ensure subsequent cache flushes don't overwrite data already written by > hardware. > > One other potential optimization I can imagine is to add flags to make > cache maintenance optional on buffers when we know it's safe to do so. > I'm not sure we can always know, so this is going to require further > thought. Doesn't sound good to me.. this is not going to be good for GPU drivers. All cache maintenance should be in control of userspace, the userspace should be telling kernel driver when it needs to get CPU access and when to finish the access. DMABUF has generic UAPI for the synchronizations, although a mature GPU driver may need more than that. Today Tegra DRM driver supports only write-combined BO allocations, and thus, we don't need to do more than to flush CPU buffers before executing HW job. >> Please let me know if you're going to fix the problems or if you'd >> prefer me to create the patches. >> >> Here is a draft of the fix for #2, it doesn't cover case of imported >> buffers (which should be statically mapped, IIUC): >> >> @@ -38,7 +38,7 @@ static struct sg_table *tegra_bo_pin(struct device >> *dev, struct host1x_bo *bo, >> * If we've manually mapped the buffer object through the IOMMU, >> make >> * sure to return the IOVA address of our mapping. >> */ >> - if (phys && obj->mm) { >> + if (phys && (obj->mm || obj->vaddr)) { >> *phys = obj->iova; > > This doesn't work for the case where we use the DMA API for mapping. Or > at least it isn't going to work in the general case. Right, looks like I'll need to update my memory about the DMA API usage. > The reason is because obj->iova is only valid for whatever the device was that mapped > or allocated the buffer, which in this case is the host1x device, which > isn't even a real device, so it won't work. The only case where it does > work is if we're not behind an IOMMU, so obj->iova will actually be the > physical address. But why do you need to dynamically map/unmap the statically-allocated buffers on each job submission, could you please explain what is the point? Perhaps it's a temporary workaround just to get a minimum of things working for the case of implicit IOMMU? All buffers should be statically allocated and statically mapped, and when there is a need to sync an already mapped buffer, the dma_sync_* API should be used. Like I said above, the syncing should be done by userspace for the buffers that are in control of userspace. > So what this basically ends up doing is avoid dma_map_*() all the time, > which I guess is what you're trying to achieve. But it also gives you > the wrong I/O virtual address in any case where an IOMMU is involved. > Also, as discussed above, avoiding cache maintenance isn't correct. Alright, then right now we need to bypass the dma_map_*() in a case of a non-implicit IOMMU, in order to bring back the good old behavior (at least temporary, until there will be a more comprehensive solution). What do you think about this variant: --- >8 --- diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 1237df157e05..555a6424e9fa 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -54,16 +54,25 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo, dma_addr_t *phys) { struct tegra_bo *obj = host1x_to_tegra_bo(bo); + struct tegra_drm *tegra = obj->gem.dev->dev_private; struct sg_table *sgt; int err; - /* - * If we've manually mapped the buffer object through the IOMMU, make - * sure to return the IOVA address of our mapping. - */ - if (phys && obj->mm) { - *phys = obj->iova; - return NULL; + if (phys && iommu_get_domain_for_dev(dev) == tegra->domain) { + /* if IOMMU isn't available, return IOVA=PHYS of the mapping */ + if (obj->vaddr) { + *phys = obj->iova; + return NULL; + } + + /* + * If we've manually mapped the buffer object through the + * IOMMU, make sure to return the IOVA address of our mapping. + */ + if (obj->mm) { + *phys = obj->iova; + return NULL; + } } /* diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 6d1872ddef17..91304b9034fa 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -97,16 +97,15 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) for (i = 0; i < state->base.fb->format->num_planes; i++) { struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); + struct sg_table *sgt; - if (!dc->client.group) { - struct sg_table *sgt; - - sgt = host1x_bo_pin(dc->dev, &bo->base, NULL); - if (IS_ERR(sgt)) { - err = PTR_ERR(sgt); - goto unpin; - } + sgt = host1x_bo_pin(dc->dev, &bo->base, &state->iova[i]); + if (IS_ERR(sgt)) { + err = PTR_ERR(sgt); + goto unpin; + } + if (sgt) { err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE); if (err == 0) { @@ -127,8 +126,6 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) state->iova[i] = sg_dma_address(sgt->sgl); state->sgt[i] = sgt; - } else { - state->iova[i] = bo->iova; } } @@ -141,8 +138,11 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state) struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i); struct sg_table *sgt = state->sgt[i]; - dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE); - host1x_bo_unpin(dc->dev, &bo->base, sgt); + if (sgt) { + dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents, + DMA_TO_DEVICE); + host1x_bo_unpin(dc->dev, &bo->base, sgt); + } state->iova[i] = DMA_MAPPING_ERROR; state->sgt[i] = NULL; diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index 60b2fedd0061..538c0f0b40a4 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -108,7 +108,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) for (i = 0; i < job->num_relocs; i++) { struct host1x_reloc *reloc = &job->relocs[i]; - dma_addr_t phys_addr, *phys; + dma_addr_t phys_addr; struct sg_table *sgt; reloc->target.bo = host1x_bo_get(reloc->target.bo); @@ -117,12 +117,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } - if (client->group) - phys = &phys_addr; - else - phys = NULL; - - sgt = host1x_bo_pin(dev, reloc->target.bo, phys); + sgt = host1x_bo_pin(dev, reloc->target.bo, &phys_addr); if (IS_ERR(sgt)) { err = PTR_ERR(sgt); goto unpin; @@ -168,6 +163,13 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) job->num_unpins++; } + /* + * In a case of enabled firewall, all user gathers are copied into + * the secured job->gather_copy_mapped. + */ + if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) + return 0; + for (i = 0; i < job->num_gathers; i++) { struct host1x_job_gather *g = &job->gathers[i]; size_t gather_size = 0; @@ -184,13 +186,13 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) goto unpin; } - sgt = host1x_bo_pin(host->dev, g->bo, NULL); + sgt = host1x_bo_pin(host->dev, g->bo, &phys_addr); if (IS_ERR(sgt)) { err = PTR_ERR(sgt); goto unpin; } - if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) { + if (host->domain) { for_each_sg(sgt->sgl, sg, sgt->nents, j) gather_size += sg->length; gather_size = iova_align(&host->iova, gather_size); @@ -214,7 +216,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job) job->unpins[job->num_unpins].size = gather_size; phys_addr = iova_dma_addr(&host->iova, alloc); - } else { + } else if (sgt) { err = dma_map_sg(host->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE); if (!err) { --- >8 --- 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=-4.8 required=3.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,USER_AGENT_SANE_1 autolearn=no 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 2B31DC33CB3 for ; Thu, 30 Jan 2020 08:33:03 +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 5EBE9214AF for ; Thu, 30 Jan 2020 08:33:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="M/+0qHcT" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EBE9214AF Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.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 9E17F6F904; Thu, 30 Jan 2020 08:32:46 +0000 (UTC) Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9DBE96F8E5 for ; Thu, 30 Jan 2020 04:36:42 +0000 (UTC) Received: by mail-lj1-x241.google.com with SMTP id v17so1819247ljg.4 for ; Wed, 29 Jan 2020 20:36:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=oMLDcrmwGbZaDGy9KIAjsb7h1p7DOYmGR7M3dlAhSb4=; b=M/+0qHcT1s9jIFE6d1eLs4c//rdoF6InuD/gJl2yDrYx2QCjub34/a5T3YghJTEB+3 ZXtOtqoPv2+OwLLhRjS/ol1wLsAmUtNHgayAM9H2ay01TM4rgIErAxlijaDWUOULw0dw cQBNqE/fCx1oS7ieciAaq/3cuP+zAY9lQTVFTa/J3WQuNlvpv+Y+G0rpr/dF7wXTBxgs i0zYOS8JnlOam6aM8j29qHBHEB2ccfWwK3x8OEzIJEqaBO+CW2Bzu5dW2b8PxSBZaKTD sWPX3XlGLEuWo88oEruxnWLpy+EqGK3+M9K5vNst8fgYZ2UV8Yi4+dcByd61biu7wcJ+ 6EhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=oMLDcrmwGbZaDGy9KIAjsb7h1p7DOYmGR7M3dlAhSb4=; b=CghXAoWmR7SJaw5ZhKsHSZ6u00H/lC7EDkvSAWmDhwDdIPFyHvyaj9EQYBQ1zqzmYp qRjd7Hd5V9JnhS2zC51lsE8PEXsAo1ovts7cCozy5Eiw11856Hcm8JRdGr4SiNlQfpUY p5I8qtayE9jK6mcIe7nkuJuSEEMA063iTfFx7jiR8RTZp2kjafSeeM4cyKn6XgeBd03L YwJkDxe2cL+cHnFIMAqHr7qjdvu3Khi2DGNuEiteRVybp0kKZbwi6PfLGlGYcAKdz94l kgpSXgLti0J8P2nUJ6UrEG73ZQZIg+mxsLQDONtPvHkTTW+ea5YTK1b2D7mqC/uzjZ+E JEXQ== X-Gm-Message-State: APjAAAXyHT3bq5EcYT75lyTyJojK66cM+xT2mHivNAbaSMJRCIo6sWo8 c2wh3Tgtjpe56WeznfQ2FU5OcLfQ X-Google-Smtp-Source: APXvYqy7XklXlC/r1IFyydf3A8yo8o+/vQlrVWdlY8eWOrEHbIX1ctqWH2Hd4Eb607Sjy7du9IoAjg== X-Received: by 2002:a2e:7818:: with SMTP id t24mr1474901ljc.195.1580359000381; Wed, 29 Jan 2020 20:36:40 -0800 (PST) Received: from [192.168.2.145] (79-139-233-37.dynamic.spd-mgts.ru. [79.139.233.37]) by smtp.googlemail.com with ESMTPSA id w9sm2015472ljh.106.2020.01.29.20.36.39 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 29 Jan 2020 20:36:39 -0800 (PST) Subject: Re: [Regression 5.5-rc1] Extremely low GPU performance on NVIDIA Tegra20/30 To: Thierry Reding References: <20191213151045.GB222809@ulmo> <2f5c6fda-adf9-c6c3-7601-fa912813ce1f@gmail.com> <20200129123935.GG2479935@ulmo> From: Dmitry Osipenko Message-ID: Date: Thu, 30 Jan 2020 07:36:36 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.3.0 MIME-Version: 1.0 In-Reply-To: <20200129123935.GG2479935@ulmo> Content-Language: en-US X-Mailman-Approved-At: Thu, 30 Jan 2020 08:32:45 +0000 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: "linux-tegra@vger.kernel.org" , DRI Development Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" MjkuMDEuMjAyMCAxNTozOSwgVGhpZXJyeSBSZWRpbmcg0L/QuNGI0LXRgjoKPiBPbiBNb24sIEph biAyMCwgMjAyMCBhdCAwNTo1MzowM0FNICswMzAwLCBEbWl0cnkgT3NpcGVua28gd3JvdGU6Cj4+ IDEzLjEyLjIwMTkgMTg6MzUsIERtaXRyeSBPc2lwZW5rbyDQv9C40YjQtdGCOgouLi4KPj4gSGVs bG8gVGhpZXJyeSwKPj4KPj4gSSB0b29rIGFub3RoZXIgbG9vayBhdCB0aGUgcHJvYmxlbSBhbmQg aGVyZSB3aGF0IHdhcyBmb3VuZDoKPj4KPj4gMSkgVGhlICJPcHRpb25hbGx5IGF0dGFjaCBjbGll bnRzIHRvIHRoZSBJT01NVSIgcGF0Y2ggaXMgd3JvbmcgYmVjYXVzZToKPj4KPj4gICAgIDEuIGhv c3QxeF9kcm1fcHJvYmUoKSBpcyBpbnZva2VkICpiZWZvcmUqIGFueSBvZiB0aGUKPj4gICAgICAg IGhvc3QxeF9jbGllbnRfaW9tbXVfYXR0YWNoKCkgaGFwcGVucywgc28gdGhlcmUgaXMgbm8gd2F5 Cj4+ICAgICAgICBvbiBlYXJ0aCB0aGUgJ3VzZV9leHBsaWNpdF9pb21tdScgY291bGQgZXZlciBi ZSB0cnVlLgo+IAo+IFRoYXQncyBub3QgY29ycmVjdC4gaG9zdDF4X2NsaWVudF9pb21tdV9hdHRh Y2goKSBoYXBwZW5zIGR1cmluZwo+IGhvc3QxeF9kZXZpY2VfaW5pdCgpLCB3aGljaCBpcyBjYWxs ZWQgZHVyaW5nIGhvc3QxeF9kcm1fcHJvYmUoKS4KCkxvb2tzIGxpa2UgSSBwcmV2aW91c2x5IGdv dCBjb25mdXNlZCBieSBhY2NpZGVudCwgbXkgYmFkLgoKPiBUaGUgaWRlYSBpcyB0aGF0IGhvc3Qx eF9kcm1fcHJvYmUoKSBzZXRzIHVwIHRoZSBtaW5pbXVtIElPTU1VIHNvIHRoYXQgYWxsCj4gZGV2 aWNlcyBjYW4gYXR0YWNoLCBpZiB0aGV5IHdhbnQgdG8uIElmIGFueSBvZiB0aGVtIGNvbm5lY3Qg KGJlY2F1c2UKPiB0aGV5IGFyZW4ndCBhbHJlYWR5IGF0dGFjaGVkIHZpYSBzb21ldGhpbmcgbGlr ZSB0aGUgRE1BL0lPTU1VIGdsdWUpCj4gdGhlbiB0aGUgdGVncmEtPnVzZV9leHBsaWNpdF9pb21t dSBpcyBzZXQgdG8gdHJ1ZSwgaW4gd2hpY2ggY2FzZSB0aGUKPiBJT01NVSBkb21haW4gc2V0dXAg Zm9yIGV4cGxpY2l0IElPTU1VIEFQSSB1c2FnZSBpcyBjb21wbGV0ZWQuIElmLCBvbgo+IHRoZSBv dGhlciBoYW5kLCBub25lIG9mIHRoZSBjbGllbnRzIGhhdmUgYSBuZWVkIGZvciB0aGUgZXhwbGlj aXQgSU9NTVUKPiBkb21haW4sIHRoZXJlJ3Mgbm8gbmVlZCB0byBzZXQgaXQgdXAgYW5kIGhvc3Qx eF9kcm1fcHJvYmUoKSB3aWxsIGp1c3QKPiBkaXNjYXJkIGl0LgoKVGhpcyBtYXRjaGVzIG15IHVu ZGVyc3RhbmRpbmcgb2Ygd2hhdCB5b3Ugd2FudGVkIHRvIGFjaGlldmUsIHRoYW5rcy4KCj4+ICAg ICAyLiBOb3QgYXR0YWNoaW5nIERSTSBjbGllbnRzIHRvIElPTU1VIGlmIEhPU1QxeCBpc24ndAo+ PiAgICAgICAgYXR0YWNoZWQgaXMgd3JvbmcgYmVjYXVzZSBpdCBuZXZlciBhdHRhY2hlZCBpbiB0 aGUgY2FzZQo+PiAgICAgICAgb2YgQ09ORklHX1RFR1JBX0hPU1QxWF9GSVJFV0FMTD15IFsxXSBh bmQgdGhpcyBhbHNvCj4+ICAgICAgICBtYWtlcyBubyBzZW5zZSBmb3IgVDIwLzMwIHRoYXQgZG8g bm90IHN1cHBvcnQgTFBBRS4KPiAKPiBJdCdzIG5vdCBhdCBhbGwgd3JvbmcuIFRha2UgZm9yIGV4 YW1wbGUgdGhlIGNhc2Ugb2YgVGVncmExMjQgYW5kCj4gVGVncmEyMTAgd2hlcmUgaG9zdDF4IGFu ZCBpdHMgY2xpZW50cyBjYW4gYWRkcmVzcyAzNCBiaXRzLiBJbiB0aG9zZQo+IGNhc2VzLCBhbGxv Y2F0aW5nIGluZGl2aWR1YWwgcGFnZXMgdmlhIHNobWVtIGhhcyBhIGhpZ2ggcHJvYmFiaWxpdHkg b2YKPiBoaXR0aW5nIHBoeXNpY2FsIGFkZHJlc3NlcyBiZXlvbmQgdGhlIDMyLWJpdCByYW5nZSwg d2hpY2ggbWVhbnMgdGhhdCB0aGUKPiBob3N0MXggY2FuIG5vdCBhY2Nlc3MgdGhlbSB1bmxlc3Mg aXQgaXMgYWxzbyBhdHRhY2hlZCB0byBhbiBJT01NVSB3aGVyZQo+IHBoeXNpY2FsIGFkZHJlc3Nl cyB0byA+PSA0IEdpQiBhZGRyZXNzZXMgY2FuIGJlIHRyYW5zbGF0ZWQgaW50byA8IDQgR2lCCj4g dmlydHVhbCBhZGRyZXNzZXMuIFRoaXMgaXMgYSB2ZXJ5IHJlYWwgcHJvYmxlbSB0aGF0IEkgd2Fz IHJ1bm5pbmcgaW50bwo+IHdoZW4gdGVzdGluZyBvbiBUZWdyYTEyNCBhbmQgVGVncmEyMTAuCgpX aHkgbm90IHRvIHNldCB0aGUgRE1BIG1hc2sgdG8gMzJiaXRzIGlmIElPTU1VIGlzIHVuYXZhaWxh YmxlPwoKSSdtIGEgYml0IHB1enpsZWQgYnkgdGhlIGFjdHVhbCBuZWVkIHRvIHN1cHBvcnQgdGhl IGNhc2Ugd2hlcmUgSG9zdDF4IGlzCmJhY2tlZCBieSBJT01NVSBhbmQgY2xpZW50cyBub3QuLiBI b3cgd2UgY291bGQgZXZlciBlbmQgdXAgd2l0aCB0aGlzCnNjZW5hcmlvIGluIHRoZSB1cHN0cmVh bSBrZXJuZWw/CgpXaGF0IGFib3V0IHRoZSByZXZlcnNlIHNjZW5hcmlvPyBZb3Ugd29uJ3QgYmUg YWJsZSB0byBwYXRjaCBjbWRzdHJlYW0KcHJvcGVybHkgZm9yID4zMmJpdCBhZGRyZXNzZXMuCgpU aGUgcm9vdCBvZiB0aGUgcHJvYmxlbSBpcyB0aGF0IFRlZ3JhIERSTSBVQVBJIGRvZXNuJ3Qgc3Vw cG9ydCA2NGJpdAphZGRyZXNzZXMsIHNvIHlvdSBjYW4ndCB1c2UgIndpZGUiIG9wY29kZXMgYW5k IGNhbid0IHBhdGNoIGNtZHN0cmVhbS4KClBlcmhhcHMgaXQgaXMgYmV0dGVyIG5vdCB0byBhZGQg YW55IG5ldyB0aGluZ3Mgb3IgcXVpcmtzIHRvIHRoZSBIb3N0MXggLwpUZWdyYSBEUk0gZm9yIG5v dy4gVGhlIGRyaXZlcnMgbmVlZCBhIHNlcmlvdXMgY2xlYW4gdXAsIG90aGVyd2lzZSBtZXNzCm9u bHkgY29udGludWVzIHRvIGdyb3cgdXAuIERvbid0IHlvdSB0aGluayBzbz8KCj4gQnV0IEkgYWdy ZWUgdGhhdCB0aGlzIHNob3VsZG4ndCBiZSBuZWNlc3Nhcnkgb24gVGVncmEyMCBhbmQgVGVncmEz MC4gV2UKPiBzaG91bGQgYmUgYWJsZSB0byByZW1lZHkgdGhlIHNpdHVhdGlvbiBvbiBUZWdyYTIw IGFuZCBUZWdyYTMwIGJ5IGFkZGluZwo+IGFub3RoZXIgY2hlY2ssIGJhc2VkIG9uIHRoZSBETUEg bWFzay4gU29tZXRoaW5nIGxpa2UgdGhlIGJlbG93IHNob3VsZAo+IHdvcms6Cj4gCj4gLS0tID44 IC0tLQpbc25pcF0KPiAtLS0gPjggLS0tCgpUaGlzIHdvcmtzLCB0aGFua3MuCgo+PiBbMV0KPj4g aHR0cHM6Ly9lbGl4aXIuYm9vdGxpbi5jb20vbGludXgvdjUuNS1yYzYvc291cmNlL2RyaXZlcnMv Z3B1L2hvc3QxeC9kZXYuYyNMMjA1Cj4+Cj4+IDIpIEJlY2F1c2Ugb2YgdGhlIGFib3ZlIHByb2Js ZW1zLCB0aGUgRFJNIGNsaWVudHMgYXJlIGVycm9uZW91c2x5IG5vdAo+PiBnZXR0aW5nIGF0dGFj aGVkIHRvIElPTU1VIGF0IGFsbCBhbmQgdGh1cyBDTUEgaXMgZ2V0dGluZyB1c2VkIGZvciB0aGUg Qk8KPj4gYWxsb2NhdGlvbnMuIEhlcmUgY29tZXMgdGhlIHByb2JsZW1zIGludHJvZHVjZWQgYnkg dGhlICJncHU6IGhvc3QxeDoKPj4gU3VwcG9ydCBETUEgbWFwcGluZyBvZiBidWZmZXJzIiBwYXRj aCwgd2hpY2ggbWFrZXMgRE1BIEFQSSB0byBwZXJmb3JtCj4+IENQVSBjYWNoZSBtYWludGVuYW5j ZSBvbiBlYWNoIGpvYiBzdWJtaXNzaW9uIGFuZCBhcHBhcmVudGx5IHRoaXMgaXMKPj4gc3VwZXIg YmFkIGZvciBwZXJmb3JtYW5jZS4gVGhpcyBhbHNvIG1ha2VzIG5vIHNlbnNlIGluIGNvbXBhcmlz b24gdG8gdGhlCj4+IGNhc2Ugb2YgZW5hYmxlZCBJT01NVSwgd2hlcmUgY2FjaGUgbWFpbnRlbmFu Y2UgaXNuJ3QgcGVyZm9ybWVkIGF0IGFsbAo+PiAobGlrZSBpdCBzaG91bGQgYmUpLgo+IAo+IEl0 IGFjdHVhbGx5IGRvZXMgbWFrZSBhIGxvdCBvZiBzZW5zZS4gVmVyeSBzdHJpY3RseSBzcGVha2lu ZyB3ZSB3ZXJlCj4gdmlvbGF0aW5nIHRoZSBETUEgQVBJIHByaW9yIHRvIHRoZSBhYm92ZSBwYXRj aCBiZWNhdXNlIHdlIHdlcmUgbm90IERNQQo+IG1hcHBpbmcgdGhlIGJ1ZmZlcnMgYXQgYWxsLiBX aGVuZXZlciB5b3UgcGFzcyBhIGJ1ZmZlciB0byBoYXJkd2FyZSB5b3UKPiBuZWVkIHRvIG1hcCBp dCBmb3IgdGhlIGRldmljZS4gQXQgdGhhdCBwb2ludCwgdGhlIGtlcm5lbCBkb2VzIG5vdCBrbm93 Cj4gd2hldGhlciBvciBub3QgdGhlIGJ1ZmZlciBpcyBkaXJ0eSwgc28gaXQgaGFzIHRvIHBlcmZv cm0gYSBjYWNoZSBmbHVzaC4KPiBTaW1pbGFyaWx5LCB3aGVuIHRoZSBoYXJkd2FyZSBpcyBkb25l IHdpdGggYSBidWZmZXIsIHdlIG5lZWQgdG8gdW5tYXAgaXQKPiBzbyB0aGF0IHRoZSBDUFUgY2Fu IGFjY2VzcyBpdCBhZ2Fpbi4gVGhpcyB0eXBpY2FsbHkgcmVxdWlyZXMgYSBjYWNoZQo+IGludmFs aWRhdGUuCj4gCj4gVGhhdCB0aGluZ3MgZXZlbiB3b3JrZWQgdG8gYmVnaW4gd2l0aCBtb3JlIGJ5 IGFjY2lkZW50IHRoYW4gYnkgZGVzaWduLgo+IAo+IFNvIHllcywgdGhpcyBpcyBkaWZmZXJlbnQg ZnJvbSB3aGF0IHdlIHdlcmUgZG9pbmcgYmVmb3JlLCBidXQgaXQncwo+IGFjdHVhbGx5IHRoZSBy aWdodCB0aGluZyB0byBkby4gVGhhdCBzYWlkLCBJJ20gc3VyZSB3ZSBjYW4gZmluZCB3YXlzIHRv Cj4gb3B0aW1pemUgdGhpcy4gRm9yIGV4YW1wbGUsIGFzIHBhcnQgb2YgdGhlIERNQSBBUEkgY29u dmVyc2lvbiBzZXJpZXMgSQo+IGFkZGVkIHRoZSBwb3NzaWJpbGl0eSB0byBzZXQgZGlyZWN0aW9u IGZsYWdzIGZvciByZWxvY2F0aW9uIGJ1ZmZlcnMuIEluCj4gY2FzZXMgd2hlcmUgaXQgaXMga25v d24gdGhhdCBhIGNlcnRhaW4gYnVmZmVyIHdpbGwgb25seSBiZSB1c2VkIGZvcgo+IHJlYWRpbmcs IHdlIHNob3VsZCBiZSBhYmxlIHRvIGF2b2lkIGF0IGxlYXN0IHRoZSBjYWNoZSBpbnZhbGlkYXRl Cj4gb3BlcmF0aW9uIGFmdGVyIGEgam9iIGlzIGRvbmUsIHNpbmNlIHRoZSBoYXJkd2FyZSB3b24n dCBoYXZlIG1vZGlmaWVkCj4gdGhlIGNvbnRlbnRzICh3aGVuIHVzaW5nIGFuIFNNTVUgdGhpcyBj YW4gZXZlbiBiZSBlbmZvcmNlZCkuIEl0J3MKPiBzbGlnaHRseSB0cmlja2llciB0byBhdm9pZCBj YWNoZSBmbHVzaGVzLiBGb3IgYnVmZmVycyB0aGF0IGFyZSBvbmx5Cj4gZ29pbmcgdG8gYmUgd3Jp dHRlbiwgdGhlcmUncyBubyBuZWVkIHRvIGZsdXNoIHRoZSBjYWNoZSBiZWNhdXNlIHRoZSBDUFVz Cj4gY2hhbmdlcyBjYW4gYmUgYXNzdW1lZCB0byBiZSBvdmVyd3JpdHRlbiBieSB0aGUgaGFyZHdh cmUgYW55d2F5LiBIb3dldmVyCj4gd2Ugc3RpbGwgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB3ZSBp bnZhbGlkYXRlIHRoZSBjYWNoZXMgaW4gdGhhdCBjYXNlIHRvCj4gZW5zdXJlIHN1YnNlcXVlbnQg Y2FjaGUgZmx1c2hlcyBkb24ndCBvdmVyd3JpdGUgZGF0YSBhbHJlYWR5IHdyaXR0ZW4gYnkKPiBo YXJkd2FyZS4KPiAKPiBPbmUgb3RoZXIgcG90ZW50aWFsIG9wdGltaXphdGlvbiBJIGNhbiBpbWFn aW5lIGlzIHRvIGFkZCBmbGFncyB0byBtYWtlCj4gY2FjaGUgbWFpbnRlbmFuY2Ugb3B0aW9uYWwg b24gYnVmZmVycyB3aGVuIHdlIGtub3cgaXQncyBzYWZlIHRvIGRvIHNvLgo+IEknbSBub3Qgc3Vy ZSB3ZSBjYW4gYWx3YXlzIGtub3csIHNvIHRoaXMgaXMgZ29pbmcgdG8gcmVxdWlyZSBmdXJ0aGVy Cj4gdGhvdWdodC4KCkRvZXNuJ3Qgc291bmQgZ29vZCB0byBtZS4uIHRoaXMgaXMgbm90IGdvaW5n IHRvIGJlIGdvb2QgZm9yIEdQVSBkcml2ZXJzLgpBbGwgY2FjaGUgbWFpbnRlbmFuY2Ugc2hvdWxk IGJlIGluIGNvbnRyb2wgb2YgdXNlcnNwYWNlLCB0aGUgdXNlcnNwYWNlCnNob3VsZCBiZSB0ZWxs aW5nIGtlcm5lbCBkcml2ZXIgd2hlbiBpdCBuZWVkcyB0byBnZXQgQ1BVIGFjY2VzcyBhbmQgd2hl bgp0byBmaW5pc2ggdGhlIGFjY2Vzcy4gRE1BQlVGIGhhcyBnZW5lcmljIFVBUEkgZm9yIHRoZSBz eW5jaHJvbml6YXRpb25zLAphbHRob3VnaCBhIG1hdHVyZSBHUFUgZHJpdmVyIG1heSBuZWVkIG1v cmUgdGhhbiB0aGF0LgoKVG9kYXkgVGVncmEgRFJNIGRyaXZlciBzdXBwb3J0cyBvbmx5IHdyaXRl LWNvbWJpbmVkIEJPIGFsbG9jYXRpb25zLCBhbmQKdGh1cywgd2UgZG9uJ3QgbmVlZCB0byBkbyBt b3JlIHRoYW4gdG8gZmx1c2ggQ1BVIGJ1ZmZlcnMgYmVmb3JlCmV4ZWN1dGluZyBIVyBqb2IuCgo+ PiBQbGVhc2UgbGV0IG1lIGtub3cgaWYgeW91J3JlIGdvaW5nIHRvIGZpeCB0aGUgcHJvYmxlbXMg b3IgaWYgeW91J2QKPj4gcHJlZmVyIG1lIHRvIGNyZWF0ZSB0aGUgcGF0Y2hlcy4KPj4KPj4gSGVy ZSBpcyBhIGRyYWZ0IG9mIHRoZSBmaXggZm9yICMyLCBpdCBkb2Vzbid0IGNvdmVyIGNhc2Ugb2Yg aW1wb3J0ZWQKPj4gYnVmZmVycyAod2hpY2ggc2hvdWxkIGJlIHN0YXRpY2FsbHkgbWFwcGVkLCBJ SVVDKToKPj4KPj4gQEAgLTM4LDcgKzM4LDcgQEAgc3RhdGljIHN0cnVjdCBzZ190YWJsZSAqdGVn cmFfYm9fcGluKHN0cnVjdCBkZXZpY2UKPj4gKmRldiwgc3RydWN0IGhvc3QxeF9ibyAqYm8sCj4+ ICAgICAgICAgICogSWYgd2UndmUgbWFudWFsbHkgbWFwcGVkIHRoZSBidWZmZXIgb2JqZWN0IHRo cm91Z2ggdGhlIElPTU1VLAo+PiBtYWtlCj4+ICAgICAgICAgICogc3VyZSB0byByZXR1cm4gdGhl IElPVkEgYWRkcmVzcyBvZiBvdXIgbWFwcGluZy4KPj4gICAgICAgICAgKi8KPj4gLSAgICAgICBp ZiAocGh5cyAmJiBvYmotPm1tKSB7Cj4+ICsgICAgICAgaWYgKHBoeXMgJiYgKG9iai0+bW0gfHwg b2JqLT52YWRkcikpIHsKPj4gICAgICAgICAgICAgICAgICpwaHlzID0gb2JqLT5pb3ZhOwo+IAo+ IFRoaXMgZG9lc24ndCB3b3JrIGZvciB0aGUgY2FzZSB3aGVyZSB3ZSB1c2UgdGhlIERNQSBBUEkg Zm9yIG1hcHBpbmcuIE9yCj4gYXQgbGVhc3QgaXQgaXNuJ3QgZ29pbmcgdG8gd29yayBpbiB0aGUg Z2VuZXJhbCBjYXNlLgoKUmlnaHQsIGxvb2tzIGxpa2UgSSdsbCBuZWVkIHRvIHVwZGF0ZSBteSBt ZW1vcnkgYWJvdXQgdGhlIERNQSBBUEkgdXNhZ2UuCgo+IFRoZSByZWFzb24gaXMgYmVjYXVzZSBv YmotPmlvdmEgaXMgb25seSB2YWxpZCBmb3Igd2hhdGV2ZXIgdGhlIGRldmljZSB3YXMgdGhhdCBt YXBwZWQKPiBvciBhbGxvY2F0ZWQgdGhlIGJ1ZmZlciwgd2hpY2ggaW4gdGhpcyBjYXNlIGlzIHRo ZSBob3N0MXggZGV2aWNlLCB3aGljaAo+IGlzbid0IGV2ZW4gYSByZWFsIGRldmljZSwgc28gaXQg d29uJ3Qgd29yay4gVGhlIG9ubHkgY2FzZSB3aGVyZSBpdCBkb2VzCj4gd29yayBpcyBpZiB3ZSdy ZSBub3QgYmVoaW5kIGFuIElPTU1VLCBzbyBvYmotPmlvdmEgd2lsbCBhY3R1YWxseSBiZSB0aGUK PiBwaHlzaWNhbCBhZGRyZXNzLgoKQnV0IHdoeSBkbyB5b3UgbmVlZCB0byBkeW5hbWljYWxseSBt YXAvdW5tYXAgdGhlIHN0YXRpY2FsbHktYWxsb2NhdGVkCmJ1ZmZlcnMgb24gZWFjaCBqb2Igc3Vi bWlzc2lvbiwgY291bGQgeW91IHBsZWFzZSBleHBsYWluIHdoYXQgaXMgdGhlCnBvaW50PyBQZXJo YXBzIGl0J3MgYSB0ZW1wb3Jhcnkgd29ya2Fyb3VuZCBqdXN0IHRvIGdldCBhIG1pbmltdW0gb2YK dGhpbmdzIHdvcmtpbmcgZm9yIHRoZSBjYXNlIG9mIGltcGxpY2l0IElPTU1VPwoKQWxsIGJ1ZmZl cnMgc2hvdWxkIGJlIHN0YXRpY2FsbHkgYWxsb2NhdGVkIGFuZCBzdGF0aWNhbGx5IG1hcHBlZCwg YW5kCndoZW4gdGhlcmUgaXMgYSBuZWVkIHRvIHN5bmMgYW4gYWxyZWFkeSBtYXBwZWQgYnVmZmVy LCB0aGUgZG1hX3N5bmNfKgpBUEkgc2hvdWxkIGJlIHVzZWQuCgpMaWtlIEkgc2FpZCBhYm92ZSwg dGhlIHN5bmNpbmcgc2hvdWxkIGJlIGRvbmUgYnkgdXNlcnNwYWNlIGZvciB0aGUKYnVmZmVycyB0 aGF0IGFyZSBpbiBjb250cm9sIG9mIHVzZXJzcGFjZS4KCj4gU28gd2hhdCB0aGlzIGJhc2ljYWxs eSBlbmRzIHVwIGRvaW5nIGlzIGF2b2lkIGRtYV9tYXBfKigpIGFsbCB0aGUgdGltZSwKPiB3aGlj aCBJIGd1ZXNzIGlzIHdoYXQgeW91J3JlIHRyeWluZyB0byBhY2hpZXZlLiBCdXQgaXQgYWxzbyBn aXZlcyB5b3UKPiB0aGUgd3JvbmcgSS9PIHZpcnR1YWwgYWRkcmVzcyBpbiBhbnkgY2FzZSB3aGVy ZSBhbiBJT01NVSBpcyBpbnZvbHZlZC4KPiBBbHNvLCBhcyBkaXNjdXNzZWQgYWJvdmUsIGF2b2lk aW5nIGNhY2hlIG1haW50ZW5hbmNlIGlzbid0IGNvcnJlY3QuCgpBbHJpZ2h0LCB0aGVuIHJpZ2h0 IG5vdyB3ZSBuZWVkIHRvIGJ5cGFzcyB0aGUgZG1hX21hcF8qKCkgaW4gYSBjYXNlIG9mIGEKbm9u LWltcGxpY2l0IElPTU1VLCBpbiBvcmRlciB0byBicmluZyBiYWNrIHRoZSBnb29kIG9sZCBiZWhh dmlvciAoYXQKbGVhc3QgdGVtcG9yYXJ5LCB1bnRpbCB0aGVyZSB3aWxsIGJlIGEgbW9yZSBjb21w cmVoZW5zaXZlIHNvbHV0aW9uKS4KCldoYXQgZG8geW91IHRoaW5rIGFib3V0IHRoaXMgdmFyaWFu dDoKCi0tLSA+OCAtLS0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9nZW0uYyBi L2RyaXZlcnMvZ3B1L2RybS90ZWdyYS9nZW0uYwppbmRleCAxMjM3ZGYxNTdlMDUuLjU1NWE2NDI0 ZTlmYSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3RlZ3JhL2dlbS5jCisrKyBiL2RyaXZl cnMvZ3B1L2RybS90ZWdyYS9nZW0uYwpAQCAtNTQsMTYgKzU0LDI1IEBAIHN0YXRpYyBzdHJ1Y3Qg c2dfdGFibGUgKnRlZ3JhX2JvX3BpbihzdHJ1Y3QgZGV2aWNlCipkZXYsIHN0cnVjdCBob3N0MXhf Ym8gKmJvLAogCQkJCSAgICAgZG1hX2FkZHJfdCAqcGh5cykKIHsKIAlzdHJ1Y3QgdGVncmFfYm8g Km9iaiA9IGhvc3QxeF90b190ZWdyYV9ibyhibyk7CisJc3RydWN0IHRlZ3JhX2RybSAqdGVncmEg PSBvYmotPmdlbS5kZXYtPmRldl9wcml2YXRlOwogCXN0cnVjdCBzZ190YWJsZSAqc2d0OwogCWlu dCBlcnI7CgotCS8qCi0JICogSWYgd2UndmUgbWFudWFsbHkgbWFwcGVkIHRoZSBidWZmZXIgb2Jq ZWN0IHRocm91Z2ggdGhlIElPTU1VLCBtYWtlCi0JICogc3VyZSB0byByZXR1cm4gdGhlIElPVkEg YWRkcmVzcyBvZiBvdXIgbWFwcGluZy4KLQkgKi8KLQlpZiAocGh5cyAmJiBvYmotPm1tKSB7Ci0J CSpwaHlzID0gb2JqLT5pb3ZhOwotCQlyZXR1cm4gTlVMTDsKKwlpZiAocGh5cyAmJiBpb21tdV9n ZXRfZG9tYWluX2Zvcl9kZXYoZGV2KSA9PSB0ZWdyYS0+ZG9tYWluKSB7CisJCS8qIGlmIElPTU1V IGlzbid0IGF2YWlsYWJsZSwgcmV0dXJuIElPVkE9UEhZUyBvZiB0aGUgbWFwcGluZyAqLworCQlp ZiAob2JqLT52YWRkcikgeworCQkJKnBoeXMgPSBvYmotPmlvdmE7CisJCQlyZXR1cm4gTlVMTDsK KwkJfQorCisJCS8qCisJCSAqIElmIHdlJ3ZlIG1hbnVhbGx5IG1hcHBlZCB0aGUgYnVmZmVyIG9i amVjdCB0aHJvdWdoIHRoZQorCQkgKiBJT01NVSwgbWFrZSBzdXJlIHRvIHJldHVybiB0aGUgSU9W QSBhZGRyZXNzIG9mIG91ciBtYXBwaW5nLgorCQkgKi8KKwkJaWYgKG9iai0+bW0pIHsKKwkJCSpw aHlzID0gb2JqLT5pb3ZhOworCQkJcmV0dXJuIE5VTEw7CisJCX0KIAl9CgogCS8qCmRpZmYgLS1n aXQgYS9kcml2ZXJzL2dwdS9kcm0vdGVncmEvcGxhbmUuYyBiL2RyaXZlcnMvZ3B1L2RybS90ZWdy YS9wbGFuZS5jCmluZGV4IDZkMTg3MmRkZWYxNy4uOTEzMDRiOTAzNGZhIDEwMDY0NAotLS0gYS9k cml2ZXJzL2dwdS9kcm0vdGVncmEvcGxhbmUuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vdGVncmEv cGxhbmUuYwpAQCAtOTcsMTYgKzk3LDE1IEBAIHN0YXRpYyBpbnQgdGVncmFfZGNfcGluKHN0cnVj dCB0ZWdyYV9kYyAqZGMsIHN0cnVjdAp0ZWdyYV9wbGFuZV9zdGF0ZSAqc3RhdGUpCgogCWZvciAo aSA9IDA7IGkgPCBzdGF0ZS0+YmFzZS5mYi0+Zm9ybWF0LT5udW1fcGxhbmVzOyBpKyspIHsKIAkJ c3RydWN0IHRlZ3JhX2JvICpibyA9IHRlZ3JhX2ZiX2dldF9wbGFuZShzdGF0ZS0+YmFzZS5mYiwg aSk7CisJCXN0cnVjdCBzZ190YWJsZSAqc2d0OwoKLQkJaWYgKCFkYy0+Y2xpZW50Lmdyb3VwKSB7 Ci0JCQlzdHJ1Y3Qgc2dfdGFibGUgKnNndDsKLQotCQkJc2d0ID0gaG9zdDF4X2JvX3BpbihkYy0+ ZGV2LCAmYm8tPmJhc2UsIE5VTEwpOwotCQkJaWYgKElTX0VSUihzZ3QpKSB7Ci0JCQkJZXJyID0g UFRSX0VSUihzZ3QpOwotCQkJCWdvdG8gdW5waW47Ci0JCQl9CisJCXNndCA9IGhvc3QxeF9ib19w aW4oZGMtPmRldiwgJmJvLT5iYXNlLCAmc3RhdGUtPmlvdmFbaV0pOworCQlpZiAoSVNfRVJSKHNn dCkpIHsKKwkJCWVyciA9IFBUUl9FUlIoc2d0KTsKKwkJCWdvdG8gdW5waW47CisJCX0KCisJCWlm IChzZ3QpIHsKIAkJCWVyciA9IGRtYV9tYXBfc2coZGMtPmRldiwgc2d0LT5zZ2wsIHNndC0+bmVu dHMsCiAJCQkJCSBETUFfVE9fREVWSUNFKTsKIAkJCWlmIChlcnIgPT0gMCkgewpAQCAtMTI3LDgg KzEyNiw2IEBAIHN0YXRpYyBpbnQgdGVncmFfZGNfcGluKHN0cnVjdCB0ZWdyYV9kYyAqZGMsIHN0 cnVjdAp0ZWdyYV9wbGFuZV9zdGF0ZSAqc3RhdGUpCgogCQkJc3RhdGUtPmlvdmFbaV0gPSBzZ19k bWFfYWRkcmVzcyhzZ3QtPnNnbCk7CiAJCQlzdGF0ZS0+c2d0W2ldID0gc2d0OwotCQl9IGVsc2Ug ewotCQkJc3RhdGUtPmlvdmFbaV0gPSBiby0+aW92YTsKIAkJfQogCX0KCkBAIC0xNDEsOCArMTM4 LDExIEBAIHN0YXRpYyBpbnQgdGVncmFfZGNfcGluKHN0cnVjdCB0ZWdyYV9kYyAqZGMsIHN0cnVj dAp0ZWdyYV9wbGFuZV9zdGF0ZSAqc3RhdGUpCiAJCXN0cnVjdCB0ZWdyYV9ibyAqYm8gPSB0ZWdy YV9mYl9nZXRfcGxhbmUoc3RhdGUtPmJhc2UuZmIsIGkpOwogCQlzdHJ1Y3Qgc2dfdGFibGUgKnNn dCA9IHN0YXRlLT5zZ3RbaV07CgotCQlkbWFfdW5tYXBfc2coZGMtPmRldiwgc2d0LT5zZ2wsIHNn dC0+bmVudHMsIERNQV9UT19ERVZJQ0UpOwotCQlob3N0MXhfYm9fdW5waW4oZGMtPmRldiwgJmJv LT5iYXNlLCBzZ3QpOworCQlpZiAoc2d0KSB7CisJCQlkbWFfdW5tYXBfc2coZGMtPmRldiwgc2d0 LT5zZ2wsIHNndC0+bmVudHMsCisJCQkJICAgICBETUFfVE9fREVWSUNFKTsKKwkJCWhvc3QxeF9i b191bnBpbihkYy0+ZGV2LCAmYm8tPmJhc2UsIHNndCk7CisJCX0KCiAJCXN0YXRlLT5pb3ZhW2ld ID0gRE1BX01BUFBJTkdfRVJST1I7CiAJCXN0YXRlLT5zZ3RbaV0gPSBOVUxMOwpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvaG9zdDF4L2pvYi5jIGIvZHJpdmVycy9ncHUvaG9zdDF4L2pvYi5jCmlu ZGV4IDYwYjJmZWRkMDA2MS4uNTM4YzBmMGI0MGE0IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9o b3N0MXgvam9iLmMKKysrIGIvZHJpdmVycy9ncHUvaG9zdDF4L2pvYi5jCkBAIC0xMDgsNyArMTA4 LDcgQEAgc3RhdGljIHVuc2lnbmVkIGludCBwaW5fam9iKHN0cnVjdCBob3N0MXggKmhvc3QsCnN0 cnVjdCBob3N0MXhfam9iICpqb2IpCgogCWZvciAoaSA9IDA7IGkgPCBqb2ItPm51bV9yZWxvY3M7 IGkrKykgewogCQlzdHJ1Y3QgaG9zdDF4X3JlbG9jICpyZWxvYyA9ICZqb2ItPnJlbG9jc1tpXTsK LQkJZG1hX2FkZHJfdCBwaHlzX2FkZHIsICpwaHlzOworCQlkbWFfYWRkcl90IHBoeXNfYWRkcjsK IAkJc3RydWN0IHNnX3RhYmxlICpzZ3Q7CgogCQlyZWxvYy0+dGFyZ2V0LmJvID0gaG9zdDF4X2Jv X2dldChyZWxvYy0+dGFyZ2V0LmJvKTsKQEAgLTExNywxMiArMTE3LDcgQEAgc3RhdGljIHVuc2ln bmVkIGludCBwaW5fam9iKHN0cnVjdCBob3N0MXggKmhvc3QsCnN0cnVjdCBob3N0MXhfam9iICpq b2IpCiAJCQlnb3RvIHVucGluOwogCQl9CgotCQlpZiAoY2xpZW50LT5ncm91cCkKLQkJCXBoeXMg PSAmcGh5c19hZGRyOwotCQllbHNlCi0JCQlwaHlzID0gTlVMTDsKLQotCQlzZ3QgPSBob3N0MXhf Ym9fcGluKGRldiwgcmVsb2MtPnRhcmdldC5ibywgcGh5cyk7CisJCXNndCA9IGhvc3QxeF9ib19w aW4oZGV2LCByZWxvYy0+dGFyZ2V0LmJvLCAmcGh5c19hZGRyKTsKIAkJaWYgKElTX0VSUihzZ3Qp KSB7CiAJCQllcnIgPSBQVFJfRVJSKHNndCk7CiAJCQlnb3RvIHVucGluOwpAQCAtMTY4LDYgKzE2 MywxMyBAQCBzdGF0aWMgdW5zaWduZWQgaW50IHBpbl9qb2Ioc3RydWN0IGhvc3QxeCAqaG9zdCwK c3RydWN0IGhvc3QxeF9qb2IgKmpvYikKIAkJam9iLT5udW1fdW5waW5zKys7CiAJfQoKKwkvKgor CSAqIEluIGEgY2FzZSBvZiBlbmFibGVkIGZpcmV3YWxsLCBhbGwgdXNlciBnYXRoZXJzIGFyZSBj b3BpZWQgaW50bworCSAqIHRoZSBzZWN1cmVkIGpvYi0+Z2F0aGVyX2NvcHlfbWFwcGVkLgorCSAq LworCWlmIChJU19FTkFCTEVEKENPTkZJR19URUdSQV9IT1NUMVhfRklSRVdBTEwpKQorCQlyZXR1 cm4gMDsKKwogCWZvciAoaSA9IDA7IGkgPCBqb2ItPm51bV9nYXRoZXJzOyBpKyspIHsKIAkJc3Ry dWN0IGhvc3QxeF9qb2JfZ2F0aGVyICpnID0gJmpvYi0+Z2F0aGVyc1tpXTsKIAkJc2l6ZV90IGdh dGhlcl9zaXplID0gMDsKQEAgLTE4NCwxMyArMTg2LDEzIEBAIHN0YXRpYyB1bnNpZ25lZCBpbnQg cGluX2pvYihzdHJ1Y3QgaG9zdDF4ICpob3N0LApzdHJ1Y3QgaG9zdDF4X2pvYiAqam9iKQogCQkJ Z290byB1bnBpbjsKIAkJfQoKLQkJc2d0ID0gaG9zdDF4X2JvX3Bpbihob3N0LT5kZXYsIGctPmJv LCBOVUxMKTsKKwkJc2d0ID0gaG9zdDF4X2JvX3Bpbihob3N0LT5kZXYsIGctPmJvLCAmcGh5c19h ZGRyKTsKIAkJaWYgKElTX0VSUihzZ3QpKSB7CiAJCQllcnIgPSBQVFJfRVJSKHNndCk7CiAJCQln b3RvIHVucGluOwogCQl9CgotCQlpZiAoIUlTX0VOQUJMRUQoQ09ORklHX1RFR1JBX0hPU1QxWF9G SVJFV0FMTCkgJiYgaG9zdC0+ZG9tYWluKSB7CisJCWlmIChob3N0LT5kb21haW4pIHsKIAkJCWZv cl9lYWNoX3NnKHNndC0+c2dsLCBzZywgc2d0LT5uZW50cywgaikKIAkJCQlnYXRoZXJfc2l6ZSAr PSBzZy0+bGVuZ3RoOwogCQkJZ2F0aGVyX3NpemUgPSBpb3ZhX2FsaWduKCZob3N0LT5pb3ZhLCBn YXRoZXJfc2l6ZSk7CkBAIC0yMTQsNyArMjE2LDcgQEAgc3RhdGljIHVuc2lnbmVkIGludCBwaW5f am9iKHN0cnVjdCBob3N0MXggKmhvc3QsCnN0cnVjdCBob3N0MXhfam9iICpqb2IpCgogCQkJam9i LT51bnBpbnNbam9iLT5udW1fdW5waW5zXS5zaXplID0gZ2F0aGVyX3NpemU7CiAJCQlwaHlzX2Fk ZHIgPSBpb3ZhX2RtYV9hZGRyKCZob3N0LT5pb3ZhLCBhbGxvYyk7Ci0JCX0gZWxzZSB7CisJCX0g ZWxzZSBpZiAoc2d0KSB7CiAJCQllcnIgPSBkbWFfbWFwX3NnKGhvc3QtPmRldiwgc2d0LT5zZ2ws IHNndC0+bmVudHMsCiAJCQkJCSBETUFfVE9fREVWSUNFKTsKIAkJCWlmICghZXJyKSB7CgotLS0g PjggLS0tCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRy aS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRw czovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=