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=-6.9 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS 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 F3559C47404 for ; Sat, 5 Oct 2019 05:42:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2BFC222BE for ; Sat, 5 Oct 2019 05:42:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="F88V2y1e" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726840AbfJEFmL (ORCPT ); Sat, 5 Oct 2019 01:42:11 -0400 Received: from mail-ed1-f66.google.com ([209.85.208.66]:39293 "EHLO mail-ed1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725773AbfJEFmK (ORCPT ); Sat, 5 Oct 2019 01:42:10 -0400 Received: by mail-ed1-f66.google.com with SMTP id a15so7866456edt.6 for ; Fri, 04 Oct 2019 22:42:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=PWoyzSdkF/Vmt1ExNhL7bn0qNiEQ7gP4gPHxcjsUaUg=; b=F88V2y1eJc4eaZx8GdOYU3x9xFMxadZ05hhlVVd8pz1kuXU1tU6ebwq3Y5Ag3jSlBe LZhHWzau9R0Rreew99drOIi8wbw3ytPBlxacEgQQtlp5EF8NMwgtQ3AMUjCtQETD8khh 5Z6ObDMxxyZpc08DltFN9bbYgGcGy4ADgK58g= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=PWoyzSdkF/Vmt1ExNhL7bn0qNiEQ7gP4gPHxcjsUaUg=; b=A3w1WMX9uJCqpyb9zzbfW1yINC8SR5rS2s7wohVEYfqlq0QSZbv8G22owp6KZXdeZB JAfro29H1D7daM8qZt3ZKs0YJbSE1WL21Zw7ycu6HfuUKugsSkkftjSVBhgusBR2KYBz 63jYGCOmamThiIObZV9X+nLyT7rXgYHXFGfLJr4x4LQ4+HvvZlwwc9zyU0qDrsPgr102 EahYzg6uRP9yHIhGXaIfS4g3WZgHCNc5vOxU3u5aQRBqdqZzCeftvyOLK0BU2s+OY6m/ RIkkgF2Y0GvW/cb2ksddnrUrtCvMbfJQyYcqGgvDUsW1/SORlZadyjuLmm4QCzjNwfgj n+/A== X-Gm-Message-State: APjAAAUs0c4/h1lVcBswqeutGtYy7z1jm4L/UFvkGKTlA50tvqkL91hQ SpGHPp37tlbFdUbR1oc1+jmZTT5LUV0WHw== X-Google-Smtp-Source: APXvYqyyPSz0bcwUVaKn/KWfBjUuXdCEN2BrfpmknL2Q9jpLhqGOl/BdOFLF6LTWJF5bIczRxbMM+A== X-Received: by 2002:a50:ab49:: with SMTP id t9mr18728808edc.301.1570254127361; Fri, 04 Oct 2019 22:42:07 -0700 (PDT) Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com. [209.85.128.54]) by smtp.gmail.com with ESMTPSA id 30sm1659244edr.78.2019.10.04.22.42.06 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Oct 2019 22:42:06 -0700 (PDT) Received: by mail-wm1-f54.google.com with SMTP id r19so7677313wmh.2 for ; Fri, 04 Oct 2019 22:42:06 -0700 (PDT) X-Received: by 2002:a7b:c404:: with SMTP id k4mr14251340wmi.90.1570254125528; Fri, 04 Oct 2019 22:42:05 -0700 (PDT) MIME-Version: 1.0 References: <20190912094121.228435-1-tfiga@chromium.org> <20190917132305.GV3958@phenom.ffwll.local> In-Reply-To: <20190917132305.GV3958@phenom.ffwll.local> From: Tomasz Figa Date: Sat, 5 Oct 2019 14:41:54 +0900 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [RFC PATCH] drm/virtio: Export resource handles via DMA-buf API To: Daniel Vetter , Gerd Hoffmann Cc: David Airlie , dri-devel , virtualization@lists.linux-foundation.org, Linux Kernel Mailing List , stevensd@chromium.org, =?UTF-8?Q?St=C3=A9phane_Marchesin?= , Zach Reizner , Keiichi Watanabe , Pawel Osciak Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Daniel, Gerd, On Tue, Sep 17, 2019 at 10:23 PM Daniel Vetter wrote: > > On Thu, Sep 12, 2019 at 06:41:21PM +0900, Tomasz Figa wrote: > > This patch is an early RFC to judge the direction we are following in > > our virtualization efforts in Chrome OS. The purpose is to start a > > discussion on how to handle buffer sharing between multiple virtio > > devices. > > > > On a side note, we are also working on a virtio video decoder interface > > and implementation, with a V4L2 driver for Linux. Those will be posted > > for review in the near future as well. > > > > Any feedback will be appreciated! Thanks in advance. > > > > === > > > > With the range of use cases for virtualization expanding, there is going > > to be more virtio devices added to the ecosystem. Devices such as video > > decoders, encoders, cameras, etc. typically work together with the > > display and GPU in a pipeline manner, which can only be implemented > > efficiently by sharing the buffers between producers and consumers. > > > > Existing buffer management framework in Linux, such as the videobuf2 > > framework in V4L2, implements all the DMA-buf handling inside generic > > code and do not expose any low level information about the buffers to > > the drivers. > > > > To seamlessly enable buffer sharing with drivers using such frameworks, > > make the virtio-gpu driver expose the resource handle as the DMA address > > of the buffer returned from the DMA-buf mapping operation. Arguably, the > > resource handle is a kind of DMA address already, as it is the buffer > > identifier that the device needs to access the backing memory, which is > > exactly the same role a DMA address provides for native devices. > > > > A virtio driver that does memory management fully on its own would have > > code similar to following. The code is identical to what a regular > > driver for real hardware would do to import a DMA-buf. > > > > static int virtio_foo_get_resource_handle(struct virtio_foo *foo, > > struct dma_buf *dma_buf, u32 *id) > > { > > struct dma_buf_attachment *attach; > > struct sg_table *sgt; > > int ret = 0; > > > > attach = dma_buf_attach(dma_buf, foo->dev); > > if (IS_ERR(attach)) > > return PTR_ERR(attach); > > > > sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); > > if (IS_ERR(sgt)) { > > ret = PTR_ERR(sgt); > > goto err_detach; > > } > > > > if (sgt->nents != 1) { > > ret = -EINVAL; > > goto err_unmap; > > } > > > > *id = sg_dma_address(sgt->sgl); > > I agree with Gerd, this looks pretty horrible to me. > > The usual way we've done these kind of special dma-bufs is: > > - They all get allocated at the same place, through some library or > whatever. > > - You add a dma_buf_is_virtio(dma_buf) function, or maybe something that > also upcasts or returns NULL, which checks for dma_buf->ops. > Thanks for a lot of valuable feedback and sorry for the late reply. While I agree that stuffing the resource ID in sg_dma_address() is quite ugly (for example, the regular address arithmetic doesn't work), I still believe we need to convey information about these buffers using regular kernel interfaces. Drivers in some subsystems like DRM tend to open code any buffer management and then it wouldn't be any problem to do what you suggested. However, other subsystems have generic frameworks for buffer management, like videobuf2 for V4L2. Those assume regular DMA-bufs that can be handled with regular dma_buf_() API and described using sgtables and/or pfn vectors and/or DMA addresses. > - Once you've upcasted at runtime by checking for ->ops, you can add > whatever fancy interfaces you want. Including a real&proper interface to > get at whatever underlying id you need to for real buffer sharing > between virtio devices. > > In a way virtio buffer/memory ids are a kind of private bus, entirely > distinct from the dma_addr_t bus. So can't really stuff them under this > same thing like we e.g. do with pci peer2peer. As I mentioned earlier, there is no single "dma_addr_t bus". Each device (as in struct device) can be on its own different DMA bus, with a different DMA address space. There is not even a guarantee that a DMA address obtained for one PCI device will be valid for another if they are on different buses, which could have different address mappings. Putting that aside, we're thinking about a different approach, as Gerd suggested in another thread, the one about the Virtio Video Decoder protocol. I'm going to reply there, making sure to CC everyone involved here. Best regards, Tomasz > -Daniel > > > > > err_unmap: > > dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); > > err_detach: > > dma_buf_detach(dma_buf, attach); > > > > return ret; > > } > > > > On the other hand, a virtio driver that uses an existing kernel > > framework to manage buffers would not need to explicitly handle anything > > at all, as the framework part responsible for importing DMA-bufs would > > already do the work. For example, a V4L2 driver using the videobuf2 > > framework would just call thee vb2_dma_contig_plane_dma_addr() function > > to get what the above open-coded function would return. > > > > Signed-off-by: Tomasz Figa > > --- > > drivers/gpu/drm/virtio/virtgpu_drv.c | 2 + > > drivers/gpu/drm/virtio/virtgpu_drv.h | 4 ++ > > drivers/gpu/drm/virtio/virtgpu_prime.c | 81 ++++++++++++++++++++++++++ > > 3 files changed, 87 insertions(+) > > > > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c > > index 0fc32fa0b3c0..ac095f813134 100644 > > --- a/drivers/gpu/drm/virtio/virtgpu_drv.c > > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c > > @@ -210,6 +210,8 @@ static struct drm_driver driver = { > > #endif > > .prime_handle_to_fd = drm_gem_prime_handle_to_fd, > > .prime_fd_to_handle = drm_gem_prime_fd_to_handle, > > + .gem_prime_export = virtgpu_gem_prime_export, > > + .gem_prime_import = virtgpu_gem_prime_import, > > .gem_prime_get_sg_table = virtgpu_gem_prime_get_sg_table, > > .gem_prime_import_sg_table = virtgpu_gem_prime_import_sg_table, > > .gem_prime_vmap = virtgpu_gem_prime_vmap, > > diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h > > index e28829661724..687cfce91885 100644 > > --- a/drivers/gpu/drm/virtio/virtgpu_drv.h > > +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h > > @@ -367,6 +367,10 @@ void virtio_gpu_object_free_sg_table(struct virtio_gpu_object *bo); > > int virtio_gpu_object_wait(struct virtio_gpu_object *bo, bool no_wait); > > > > /* virtgpu_prime.c */ > > +struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, > > + int flags); > > +struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, > > + struct dma_buf *buf); > > struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj); > > struct drm_gem_object *virtgpu_gem_prime_import_sg_table( > > struct drm_device *dev, struct dma_buf_attachment *attach, > > diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c > > index dc642a884b88..562eb1a2ed5b 100644 > > --- a/drivers/gpu/drm/virtio/virtgpu_prime.c > > +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c > > @@ -22,6 +22,9 @@ > > * Authors: Andreas Pokorny > > */ > > > > +#include > > +#include > > + > > #include > > > > #include "virtgpu_drv.h" > > @@ -30,6 +33,84 @@ > > * device that might share buffers with virtgpu > > */ > > > > +static struct sg_table * > > +virtgpu_gem_map_dma_buf(struct dma_buf_attachment *attach, > > + enum dma_data_direction dir) > > +{ > > + struct drm_gem_object *obj = attach->dmabuf->priv; > > + struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); > > + struct sg_table *sgt; > > + int ret; > > + > > + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); > > + if (!sgt) > > + return ERR_PTR(-ENOMEM); > > + > > + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); > > + if (ret) { > > + kfree(sgt); > > + return ERR_PTR(-ENOMEM); > > + } > > + > > + sg_dma_address(sgt->sgl) = bo->hw_res_handle; > > + sg_dma_len(sgt->sgl) = obj->size; > > + sgt->nents = 1; > > + > > + return sgt; > > +} > > + > > +static void virtgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach, > > + struct sg_table *sgt, > > + enum dma_data_direction dir) > > +{ > > + sg_free_table(sgt); > > + kfree(sgt); > > +} > > + > > +static const struct dma_buf_ops virtgpu_dmabuf_ops = { > > + .cache_sgt_mapping = true, > > + .attach = drm_gem_map_attach, > > + .detach = drm_gem_map_detach, > > + .map_dma_buf = virtgpu_gem_map_dma_buf, > > + .unmap_dma_buf = virtgpu_gem_unmap_dma_buf, > > + .release = drm_gem_dmabuf_release, > > + .mmap = drm_gem_dmabuf_mmap, > > + .vmap = drm_gem_dmabuf_vmap, > > + .vunmap = drm_gem_dmabuf_vunmap, > > +}; > > + > > +struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj, > > + int flags) > > +{ > > + struct dma_buf *buf; > > + > > + buf = drm_gem_prime_export(obj, flags); > > + if (!IS_ERR(buf)) > > + buf->ops = &virtgpu_dmabuf_ops; > > + > > + return buf; > > +} > > + > > +struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, > > + struct dma_buf *buf) > > +{ > > + struct drm_gem_object *obj; > > + > > + if (buf->ops == &virtgpu_dmabuf_ops) { > > + obj = buf->priv; > > + if (obj->dev == dev) { > > + /* > > + * Importing dmabuf exported from our own gem increases > > + * refcount on gem itself instead of f_count of dmabuf. > > + */ > > + drm_gem_object_get(obj); > > + return obj; > > + } > > + } > > + > > + return drm_gem_prime_import(dev, buf); > > +} > > + > > struct sg_table *virtgpu_gem_prime_get_sg_table(struct drm_gem_object *obj) > > { > > struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj); > > -- > > 2.23.0.237.gc6a4ce50a0-goog > > > > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tomasz Figa Subject: Re: [RFC PATCH] drm/virtio: Export resource handles via DMA-buf API Date: Sat, 5 Oct 2019 14:41:54 +0900 Message-ID: References: <20190912094121.228435-1-tfiga@chromium.org> <20190917132305.GV3958@phenom.ffwll.local> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-ed1-x541.google.com (mail-ed1-x541.google.com [IPv6:2a00:1450:4864:20::541]) by gabe.freedesktop.org (Postfix) with ESMTPS id DFD896E1C4 for ; Sat, 5 Oct 2019 05:42:10 +0000 (UTC) Received: by mail-ed1-x541.google.com with SMTP id f20so7855100edv.8 for ; Fri, 04 Oct 2019 22:42:10 -0700 (PDT) Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com. [209.85.128.44]) by smtp.gmail.com with ESMTPSA id e5sm1665996edl.8.2019.10.04.22.42.06 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Oct 2019 22:42:06 -0700 (PDT) Received: by mail-wm1-f44.google.com with SMTP id 3so7685224wmi.3 for ; Fri, 04 Oct 2019 22:42:06 -0700 (PDT) In-Reply-To: <20190917132305.GV3958@phenom.ffwll.local> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Daniel Vetter , Gerd Hoffmann Cc: Zach Reizner , David Airlie , Linux Kernel Mailing List , dri-devel , virtualization@lists.linux-foundation.org, Keiichi Watanabe , stevensd@chromium.org, =?UTF-8?Q?St=C3=A9phane_Marchesin?= , Pawel Osciak List-Id: dri-devel@lists.freedesktop.org SGkgRGFuaWVsLCBHZXJkLAoKT24gVHVlLCBTZXAgMTcsIDIwMTkgYXQgMTA6MjMgUE0gRGFuaWVs IFZldHRlciA8ZGFuaWVsQGZmd2xsLmNoPiB3cm90ZToKPgo+IE9uIFRodSwgU2VwIDEyLCAyMDE5 IGF0IDA2OjQxOjIxUE0gKzA5MDAsIFRvbWFzeiBGaWdhIHdyb3RlOgo+ID4gVGhpcyBwYXRjaCBp cyBhbiBlYXJseSBSRkMgdG8ganVkZ2UgdGhlIGRpcmVjdGlvbiB3ZSBhcmUgZm9sbG93aW5nIGlu Cj4gPiBvdXIgdmlydHVhbGl6YXRpb24gZWZmb3J0cyBpbiBDaHJvbWUgT1MuIFRoZSBwdXJwb3Nl IGlzIHRvIHN0YXJ0IGEKPiA+IGRpc2N1c3Npb24gb24gaG93IHRvIGhhbmRsZSBidWZmZXIgc2hh cmluZyBiZXR3ZWVuIG11bHRpcGxlIHZpcnRpbwo+ID4gZGV2aWNlcy4KPiA+Cj4gPiBPbiBhIHNp ZGUgbm90ZSwgd2UgYXJlIGFsc28gd29ya2luZyBvbiBhIHZpcnRpbyB2aWRlbyBkZWNvZGVyIGlu dGVyZmFjZQo+ID4gYW5kIGltcGxlbWVudGF0aW9uLCB3aXRoIGEgVjRMMiBkcml2ZXIgZm9yIExp bnV4LiBUaG9zZSB3aWxsIGJlIHBvc3RlZAo+ID4gZm9yIHJldmlldyBpbiB0aGUgbmVhciBmdXR1 cmUgYXMgd2VsbC4KPiA+Cj4gPiBBbnkgZmVlZGJhY2sgd2lsbCBiZSBhcHByZWNpYXRlZCEgVGhh bmtzIGluIGFkdmFuY2UuCj4gPgo+ID4gPT09Cj4gPgo+ID4gV2l0aCB0aGUgcmFuZ2Ugb2YgdXNl IGNhc2VzIGZvciB2aXJ0dWFsaXphdGlvbiBleHBhbmRpbmcsIHRoZXJlIGlzIGdvaW5nCj4gPiB0 byBiZSBtb3JlIHZpcnRpbyBkZXZpY2VzIGFkZGVkIHRvIHRoZSBlY29zeXN0ZW0uIERldmljZXMg c3VjaCBhcyB2aWRlbwo+ID4gZGVjb2RlcnMsIGVuY29kZXJzLCBjYW1lcmFzLCBldGMuIHR5cGlj YWxseSB3b3JrIHRvZ2V0aGVyIHdpdGggdGhlCj4gPiBkaXNwbGF5IGFuZCBHUFUgaW4gYSBwaXBl bGluZSBtYW5uZXIsIHdoaWNoIGNhbiBvbmx5IGJlIGltcGxlbWVudGVkCj4gPiBlZmZpY2llbnRs eSBieSBzaGFyaW5nIHRoZSBidWZmZXJzIGJldHdlZW4gcHJvZHVjZXJzIGFuZCBjb25zdW1lcnMu Cj4gPgo+ID4gRXhpc3RpbmcgYnVmZmVyIG1hbmFnZW1lbnQgZnJhbWV3b3JrIGluIExpbnV4LCBz dWNoIGFzIHRoZSB2aWRlb2J1ZjIKPiA+IGZyYW1ld29yayBpbiBWNEwyLCBpbXBsZW1lbnRzIGFs bCB0aGUgRE1BLWJ1ZiBoYW5kbGluZyBpbnNpZGUgZ2VuZXJpYwo+ID4gY29kZSBhbmQgZG8gbm90 IGV4cG9zZSBhbnkgbG93IGxldmVsIGluZm9ybWF0aW9uIGFib3V0IHRoZSBidWZmZXJzIHRvCj4g PiB0aGUgZHJpdmVycy4KPiA+Cj4gPiBUbyBzZWFtbGVzc2x5IGVuYWJsZSBidWZmZXIgc2hhcmlu ZyB3aXRoIGRyaXZlcnMgdXNpbmcgc3VjaCBmcmFtZXdvcmtzLAo+ID4gbWFrZSB0aGUgdmlydGlv LWdwdSBkcml2ZXIgZXhwb3NlIHRoZSByZXNvdXJjZSBoYW5kbGUgYXMgdGhlIERNQSBhZGRyZXNz Cj4gPiBvZiB0aGUgYnVmZmVyIHJldHVybmVkIGZyb20gdGhlIERNQS1idWYgbWFwcGluZyBvcGVy YXRpb24uIEFyZ3VhYmx5LCB0aGUKPiA+IHJlc291cmNlIGhhbmRsZSBpcyBhIGtpbmQgb2YgRE1B IGFkZHJlc3MgYWxyZWFkeSwgYXMgaXQgaXMgdGhlIGJ1ZmZlcgo+ID4gaWRlbnRpZmllciB0aGF0 IHRoZSBkZXZpY2UgbmVlZHMgdG8gYWNjZXNzIHRoZSBiYWNraW5nIG1lbW9yeSwgd2hpY2ggaXMK PiA+IGV4YWN0bHkgdGhlIHNhbWUgcm9sZSBhIERNQSBhZGRyZXNzIHByb3ZpZGVzIGZvciBuYXRp dmUgZGV2aWNlcy4KPiA+Cj4gPiBBIHZpcnRpbyBkcml2ZXIgdGhhdCBkb2VzIG1lbW9yeSBtYW5h Z2VtZW50IGZ1bGx5IG9uIGl0cyBvd24gd291bGQgaGF2ZQo+ID4gY29kZSBzaW1pbGFyIHRvIGZv bGxvd2luZy4gVGhlIGNvZGUgaXMgaWRlbnRpY2FsIHRvIHdoYXQgYSByZWd1bGFyCj4gPiBkcml2 ZXIgZm9yIHJlYWwgaGFyZHdhcmUgd291bGQgZG8gdG8gaW1wb3J0IGEgRE1BLWJ1Zi4KPiA+Cj4g PiBzdGF0aWMgaW50IHZpcnRpb19mb29fZ2V0X3Jlc291cmNlX2hhbmRsZShzdHJ1Y3QgdmlydGlv X2ZvbyAqZm9vLAo+ID4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0 cnVjdCBkbWFfYnVmICpkbWFfYnVmLCB1MzIgKmlkKQo+ID4gewo+ID4gICAgICAgc3RydWN0IGRt YV9idWZfYXR0YWNobWVudCAqYXR0YWNoOwo+ID4gICAgICAgc3RydWN0IHNnX3RhYmxlICpzZ3Q7 Cj4gPiAgICAgICBpbnQgcmV0ID0gMDsKPiA+Cj4gPiAgICAgICBhdHRhY2ggPSBkbWFfYnVmX2F0 dGFjaChkbWFfYnVmLCBmb28tPmRldik7Cj4gPiAgICAgICBpZiAoSVNfRVJSKGF0dGFjaCkpCj4g PiAgICAgICAgICAgICAgIHJldHVybiBQVFJfRVJSKGF0dGFjaCk7Cj4gPgo+ID4gICAgICAgc2d0 ID0gZG1hX2J1Zl9tYXBfYXR0YWNobWVudChhdHRhY2gsIERNQV9CSURJUkVDVElPTkFMKTsKPiA+ ICAgICAgIGlmIChJU19FUlIoc2d0KSkgewo+ID4gICAgICAgICAgICAgICByZXQgPSBQVFJfRVJS KHNndCk7Cj4gPiAgICAgICAgICAgICAgIGdvdG8gZXJyX2RldGFjaDsKPiA+ICAgICAgIH0KPiA+ Cj4gPiAgICAgICBpZiAoc2d0LT5uZW50cyAhPSAxKSB7Cj4gPiAgICAgICAgICAgICAgIHJldCA9 IC1FSU5WQUw7Cj4gPiAgICAgICAgICAgICAgIGdvdG8gZXJyX3VubWFwOwo+ID4gICAgICAgfQo+ ID4KPiA+ICAgICAgICppZCA9IHNnX2RtYV9hZGRyZXNzKHNndC0+c2dsKTsKPgo+IEkgYWdyZWUg d2l0aCBHZXJkLCB0aGlzIGxvb2tzIHByZXR0eSBob3JyaWJsZSB0byBtZS4KPgo+IFRoZSB1c3Vh bCB3YXkgd2UndmUgZG9uZSB0aGVzZSBraW5kIG9mIHNwZWNpYWwgZG1hLWJ1ZnMgaXM6Cj4KPiAt IFRoZXkgYWxsIGdldCBhbGxvY2F0ZWQgYXQgdGhlIHNhbWUgcGxhY2UsIHRocm91Z2ggc29tZSBs aWJyYXJ5IG9yCj4gICB3aGF0ZXZlci4KPgo+IC0gWW91IGFkZCBhIGRtYV9idWZfaXNfdmlydGlv KGRtYV9idWYpIGZ1bmN0aW9uLCBvciBtYXliZSBzb21ldGhpbmcgdGhhdAo+ICAgYWxzbyB1cGNh c3RzIG9yIHJldHVybnMgTlVMTCwgd2hpY2ggY2hlY2tzIGZvciBkbWFfYnVmLT5vcHMuCj4KClRo YW5rcyBmb3IgYSBsb3Qgb2YgdmFsdWFibGUgZmVlZGJhY2sgYW5kIHNvcnJ5IGZvciB0aGUgbGF0 ZSByZXBseS4KCldoaWxlIEkgYWdyZWUgdGhhdCBzdHVmZmluZyB0aGUgcmVzb3VyY2UgSUQgaW4g c2dfZG1hX2FkZHJlc3MoKSBpcwpxdWl0ZSB1Z2x5IChmb3IgZXhhbXBsZSwgdGhlIHJlZ3VsYXIg YWRkcmVzcyBhcml0aG1ldGljIGRvZXNuJ3Qgd29yayksCkkgc3RpbGwgYmVsaWV2ZSB3ZSBuZWVk IHRvIGNvbnZleSBpbmZvcm1hdGlvbiBhYm91dCB0aGVzZSBidWZmZXJzCnVzaW5nIHJlZ3VsYXIg a2VybmVsIGludGVyZmFjZXMuCgpEcml2ZXJzIGluIHNvbWUgc3Vic3lzdGVtcyBsaWtlIERSTSB0 ZW5kIHRvIG9wZW4gY29kZSBhbnkgYnVmZmVyCm1hbmFnZW1lbnQgYW5kIHRoZW4gaXQgd291bGRu J3QgYmUgYW55IHByb2JsZW0gdG8gZG8gd2hhdCB5b3UKc3VnZ2VzdGVkLiBIb3dldmVyLCBvdGhl ciBzdWJzeXN0ZW1zIGhhdmUgZ2VuZXJpYyBmcmFtZXdvcmtzIGZvcgpidWZmZXIgbWFuYWdlbWVu dCwgbGlrZSB2aWRlb2J1ZjIgZm9yIFY0TDIuIFRob3NlIGFzc3VtZSByZWd1bGFyCkRNQS1idWZz IHRoYXQgY2FuIGJlIGhhbmRsZWQgd2l0aCByZWd1bGFyIGRtYV9idWZfKCkgQVBJIGFuZCBkZXNj cmliZWQKdXNpbmcgc2d0YWJsZXMgYW5kL29yIHBmbiB2ZWN0b3JzIGFuZC9vciBETUEgYWRkcmVz c2VzLgoKPiAtIE9uY2UgeW91J3ZlIHVwY2FzdGVkIGF0IHJ1bnRpbWUgYnkgY2hlY2tpbmcgZm9y IC0+b3BzLCB5b3UgY2FuIGFkZAo+ICAgd2hhdGV2ZXIgZmFuY3kgaW50ZXJmYWNlcyB5b3Ugd2Fu dC4gSW5jbHVkaW5nIGEgcmVhbCZwcm9wZXIgaW50ZXJmYWNlIHRvCj4gICBnZXQgYXQgd2hhdGV2 ZXIgdW5kZXJseWluZyBpZCB5b3UgbmVlZCB0byBmb3IgcmVhbCBidWZmZXIgc2hhcmluZwo+ICAg YmV0d2VlbiB2aXJ0aW8gZGV2aWNlcy4KPgo+IEluIGEgd2F5IHZpcnRpbyBidWZmZXIvbWVtb3J5 IGlkcyBhcmUgYSBraW5kIG9mIHByaXZhdGUgYnVzLCBlbnRpcmVseQo+IGRpc3RpbmN0IGZyb20g dGhlIGRtYV9hZGRyX3QgYnVzLiBTbyBjYW4ndCByZWFsbHkgc3R1ZmYgdGhlbSB1bmRlciB0aGlz Cj4gc2FtZSB0aGluZyBsaWtlIHdlIGUuZy4gZG8gd2l0aCBwY2kgcGVlcjJwZWVyLgoKQXMgSSBt ZW50aW9uZWQgZWFybGllciwgdGhlcmUgaXMgbm8gc2luZ2xlICJkbWFfYWRkcl90IGJ1cyIuIEVh Y2gKZGV2aWNlIChhcyBpbiBzdHJ1Y3QgZGV2aWNlKSBjYW4gYmUgb24gaXRzIG93biBkaWZmZXJl bnQgRE1BIGJ1cywgd2l0aAphIGRpZmZlcmVudCBETUEgYWRkcmVzcyBzcGFjZS4gVGhlcmUgaXMg bm90IGV2ZW4gYSBndWFyYW50ZWUgdGhhdCBhCkRNQSBhZGRyZXNzIG9idGFpbmVkIGZvciBvbmUg UENJIGRldmljZSB3aWxsIGJlIHZhbGlkIGZvciBhbm90aGVyIGlmCnRoZXkgYXJlIG9uIGRpZmZl cmVudCBidXNlcywgd2hpY2ggY291bGQgaGF2ZSBkaWZmZXJlbnQgYWRkcmVzcwptYXBwaW5ncy4K ClB1dHRpbmcgdGhhdCBhc2lkZSwgd2UncmUgdGhpbmtpbmcgYWJvdXQgYSBkaWZmZXJlbnQgYXBw cm9hY2gsIGFzIEdlcmQKc3VnZ2VzdGVkIGluIGFub3RoZXIgdGhyZWFkLCB0aGUgb25lIGFib3V0 IHRoZSBWaXJ0aW8gVmlkZW8gRGVjb2Rlcgpwcm90b2NvbC4gSSdtIGdvaW5nIHRvIHJlcGx5IHRo ZXJlLCBtYWtpbmcgc3VyZSB0byBDQyBldmVyeW9uZQppbnZvbHZlZCBoZXJlLgoKQmVzdCByZWdh cmRzLApUb21hc3oKCj4gLURhbmllbAo+Cj4gPgo+ID4gZXJyX3VubWFwOgo+ID4gICAgICAgZG1h X2J1Zl91bm1hcF9hdHRhY2htZW50KGF0dGFjaCwgc2d0LCBETUFfQklESVJFQ1RJT05BTCk7Cj4g PiBlcnJfZGV0YWNoOgo+ID4gICAgICAgZG1hX2J1Zl9kZXRhY2goZG1hX2J1ZiwgYXR0YWNoKTsK PiA+Cj4gPiAgICAgICByZXR1cm4gcmV0Owo+ID4gfQo+ID4KPiA+IE9uIHRoZSBvdGhlciBoYW5k LCBhIHZpcnRpbyBkcml2ZXIgdGhhdCB1c2VzIGFuIGV4aXN0aW5nIGtlcm5lbAo+ID4gZnJhbWV3 b3JrIHRvIG1hbmFnZSBidWZmZXJzIHdvdWxkIG5vdCBuZWVkIHRvIGV4cGxpY2l0bHkgaGFuZGxl IGFueXRoaW5nCj4gPiBhdCBhbGwsIGFzIHRoZSBmcmFtZXdvcmsgcGFydCByZXNwb25zaWJsZSBm b3IgaW1wb3J0aW5nIERNQS1idWZzIHdvdWxkCj4gPiBhbHJlYWR5IGRvIHRoZSB3b3JrLiBGb3Ig ZXhhbXBsZSwgYSBWNEwyIGRyaXZlciB1c2luZyB0aGUgdmlkZW9idWYyCj4gPiBmcmFtZXdvcmsg d291bGQganVzdCBjYWxsIHRoZWUgdmIyX2RtYV9jb250aWdfcGxhbmVfZG1hX2FkZHIoKSBmdW5j dGlvbgo+ID4gdG8gZ2V0IHdoYXQgdGhlIGFib3ZlIG9wZW4tY29kZWQgZnVuY3Rpb24gd291bGQg cmV0dXJuLgo+ID4KPiA+IFNpZ25lZC1vZmYtYnk6IFRvbWFzeiBGaWdhIDx0ZmlnYUBjaHJvbWl1 bS5vcmc+Cj4gPiAtLS0KPiA+ICBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmMg ICB8ICAyICsKPiA+ICBkcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmggICB8ICA0 ICsrCj4gPiAgZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0Z3B1X3ByaW1lLmMgfCA4MSArKysr KysrKysrKysrKysrKysrKysrKysrKwo+ID4gIDMgZmlsZXMgY2hhbmdlZCwgODcgaW5zZXJ0aW9u cygrKQo+ID4KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVf ZHJ2LmMgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmMKPiA+IGluZGV4IDBm YzMyZmEwYjNjMC4uYWMwOTVmODEzMTM0IDEwMDY0NAo+ID4gLS0tIGEvZHJpdmVycy9ncHUvZHJt L3ZpcnRpby92aXJ0Z3B1X2Rydi5jCj4gPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3Zp cnRncHVfZHJ2LmMKPiA+IEBAIC0yMTAsNiArMjEwLDggQEAgc3RhdGljIHN0cnVjdCBkcm1fZHJp dmVyIGRyaXZlciA9IHsKPiA+ICAjZW5kaWYKPiA+ICAgICAgIC5wcmltZV9oYW5kbGVfdG9fZmQg PSBkcm1fZ2VtX3ByaW1lX2hhbmRsZV90b19mZCwKPiA+ICAgICAgIC5wcmltZV9mZF90b19oYW5k bGUgPSBkcm1fZ2VtX3ByaW1lX2ZkX3RvX2hhbmRsZSwKPiA+ICsgICAgIC5nZW1fcHJpbWVfZXhw b3J0ID0gdmlydGdwdV9nZW1fcHJpbWVfZXhwb3J0LAo+ID4gKyAgICAgLmdlbV9wcmltZV9pbXBv cnQgPSB2aXJ0Z3B1X2dlbV9wcmltZV9pbXBvcnQsCj4gPiAgICAgICAuZ2VtX3ByaW1lX2dldF9z Z190YWJsZSA9IHZpcnRncHVfZ2VtX3ByaW1lX2dldF9zZ190YWJsZSwKPiA+ICAgICAgIC5nZW1f cHJpbWVfaW1wb3J0X3NnX3RhYmxlID0gdmlydGdwdV9nZW1fcHJpbWVfaW1wb3J0X3NnX3RhYmxl LAo+ID4gICAgICAgLmdlbV9wcmltZV92bWFwID0gdmlydGdwdV9nZW1fcHJpbWVfdm1hcCwKPiA+ IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmggYi9kcml2 ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmgKPiA+IGluZGV4IGUyODgyOTY2MTcyNC4u Njg3Y2ZjZTkxODg1IDEwMDY0NAo+ID4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3ZpcnRpby92aXJ0 Z3B1X2Rydi5oCj4gPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVfZHJ2LmgK PiA+IEBAIC0zNjcsNiArMzY3LDEwIEBAIHZvaWQgdmlydGlvX2dwdV9vYmplY3RfZnJlZV9zZ190 YWJsZShzdHJ1Y3QgdmlydGlvX2dwdV9vYmplY3QgKmJvKTsKPiA+ICBpbnQgdmlydGlvX2dwdV9v YmplY3Rfd2FpdChzdHJ1Y3QgdmlydGlvX2dwdV9vYmplY3QgKmJvLCBib29sIG5vX3dhaXQpOwo+ ID4KPiA+ICAvKiB2aXJ0Z3B1X3ByaW1lLmMgKi8KPiA+ICtzdHJ1Y3QgZG1hX2J1ZiAqdmlydGdw dV9nZW1fcHJpbWVfZXhwb3J0KHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqLAo+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZsYWdzKTsKPiA+ICtzdHJ1Y3Qg ZHJtX2dlbV9vYmplY3QgKnZpcnRncHVfZ2VtX3ByaW1lX2ltcG9ydChzdHJ1Y3QgZHJtX2Rldmlj ZSAqZGV2LAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHN0cnVjdCBkbWFfYnVmICpidWYpOwo+ID4gIHN0cnVjdCBzZ190YWJsZSAqdmlydGdwdV9nZW1f cHJpbWVfZ2V0X3NnX3RhYmxlKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKTsKPiA+ICBzdHJ1 Y3QgZHJtX2dlbV9vYmplY3QgKnZpcnRncHVfZ2VtX3ByaW1lX2ltcG9ydF9zZ190YWJsZSgKPiA+ ICAgICAgIHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQg KmF0dGFjaCwKPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdmlydGlvL3ZpcnRncHVf cHJpbWUuYyBiL2RyaXZlcnMvZ3B1L2RybS92aXJ0aW8vdmlydGdwdV9wcmltZS5jCj4gPiBpbmRl eCBkYzY0MmE4ODRiODguLjU2MmViMWEyZWQ1YiAxMDA2NDQKPiA+IC0tLSBhL2RyaXZlcnMvZ3B1 L2RybS92aXJ0aW8vdmlydGdwdV9wcmltZS5jCj4gPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vdmly dGlvL3ZpcnRncHVfcHJpbWUuYwo+ID4gQEAgLTIyLDYgKzIyLDkgQEAKPiA+ICAgKiBBdXRob3Jz OiBBbmRyZWFzIFBva29ybnkKPiA+ICAgKi8KPiA+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L2RtYS1i dWYuaD4KPiA+ICsjaW5jbHVkZSA8bGludXgvZG1hLWRpcmVjdGlvbi5oPgo+ID4gKwo+ID4gICNp bmNsdWRlIDxkcm0vZHJtX3ByaW1lLmg+Cj4gPgo+ID4gICNpbmNsdWRlICJ2aXJ0Z3B1X2Rydi5o Igo+ID4gQEAgLTMwLDYgKzMzLDg0IEBACj4gPiAgICogZGV2aWNlIHRoYXQgbWlnaHQgc2hhcmUg YnVmZmVycyB3aXRoIHZpcnRncHUKPiA+ICAgKi8KPiA+Cj4gPiArc3RhdGljIHN0cnVjdCBzZ190 YWJsZSAqCj4gPiArdmlydGdwdV9nZW1fbWFwX2RtYV9idWYoc3RydWN0IGRtYV9idWZfYXR0YWNo bWVudCAqYXR0YWNoLAo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGVudW0gZG1hX2RhdGFfZGly ZWN0aW9uIGRpcikKPiA+ICt7Cj4gPiArICAgICBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaiA9 IGF0dGFjaC0+ZG1hYnVmLT5wcml2Owo+ID4gKyAgICAgc3RydWN0IHZpcnRpb19ncHVfb2JqZWN0 ICpibyA9IGdlbV90b192aXJ0aW9fZ3B1X29iaihvYmopOwo+ID4gKyAgICAgc3RydWN0IHNnX3Rh YmxlICpzZ3Q7Cj4gPiArICAgICBpbnQgcmV0Owo+ID4gKwo+ID4gKyAgICAgc2d0ID0ga3phbGxv YyhzaXplb2YoKnNndCksIEdGUF9LRVJORUwpOwo+ID4gKyAgICAgaWYgKCFzZ3QpCj4gPiArICAg ICAgICAgICAgIHJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwo+ID4gKwo+ID4gKyAgICAgcmV0ID0g c2dfYWxsb2NfdGFibGUoc2d0LCAxLCBHRlBfS0VSTkVMKTsKPiA+ICsgICAgIGlmIChyZXQpIHsK PiA+ICsgICAgICAgICAgICAga2ZyZWUoc2d0KTsKPiA+ICsgICAgICAgICAgICAgcmV0dXJuIEVS Ul9QVFIoLUVOT01FTSk7Cj4gPiArICAgICB9Cj4gPiArCj4gPiArICAgICBzZ19kbWFfYWRkcmVz cyhzZ3QtPnNnbCkgPSBiby0+aHdfcmVzX2hhbmRsZTsKPiA+ICsgICAgIHNnX2RtYV9sZW4oc2d0 LT5zZ2wpID0gb2JqLT5zaXplOwo+ID4gKyAgICAgc2d0LT5uZW50cyA9IDE7Cj4gPiArCj4gPiAr ICAgICByZXR1cm4gc2d0Owo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2aXJ0Z3B1X2dl bV91bm1hcF9kbWFfYnVmKHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQgKmF0dGFjaCwKPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzZ190YWJsZSAqc2d0LAo+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW51bSBkbWFfZGF0YV9kaXJl Y3Rpb24gZGlyKQo+ID4gK3sKPiA+ICsgICAgIHNnX2ZyZWVfdGFibGUoc2d0KTsKPiA+ICsgICAg IGtmcmVlKHNndCk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZG1hX2J1 Zl9vcHMgdmlydGdwdV9kbWFidWZfb3BzID0gIHsKPiA+ICsgICAgIC5jYWNoZV9zZ3RfbWFwcGlu ZyA9IHRydWUsCj4gPiArICAgICAuYXR0YWNoID0gZHJtX2dlbV9tYXBfYXR0YWNoLAo+ID4gKyAg ICAgLmRldGFjaCA9IGRybV9nZW1fbWFwX2RldGFjaCwKPiA+ICsgICAgIC5tYXBfZG1hX2J1ZiA9 IHZpcnRncHVfZ2VtX21hcF9kbWFfYnVmLAo+ID4gKyAgICAgLnVubWFwX2RtYV9idWYgPSB2aXJ0 Z3B1X2dlbV91bm1hcF9kbWFfYnVmLAo+ID4gKyAgICAgLnJlbGVhc2UgPSBkcm1fZ2VtX2RtYWJ1 Zl9yZWxlYXNlLAo+ID4gKyAgICAgLm1tYXAgPSBkcm1fZ2VtX2RtYWJ1Zl9tbWFwLAo+ID4gKyAg ICAgLnZtYXAgPSBkcm1fZ2VtX2RtYWJ1Zl92bWFwLAo+ID4gKyAgICAgLnZ1bm1hcCA9IGRybV9n ZW1fZG1hYnVmX3Z1bm1hcCwKPiA+ICt9Owo+ID4gKwo+ID4gK3N0cnVjdCBkbWFfYnVmICp2aXJ0 Z3B1X2dlbV9wcmltZV9leHBvcnQoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmosCj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZmxhZ3MpCj4gPiArewo+ID4g KyAgICAgc3RydWN0IGRtYV9idWYgKmJ1ZjsKPiA+ICsKPiA+ICsgICAgIGJ1ZiA9IGRybV9nZW1f cHJpbWVfZXhwb3J0KG9iaiwgZmxhZ3MpOwo+ID4gKyAgICAgaWYgKCFJU19FUlIoYnVmKSkKPiA+ ICsgICAgICAgICAgICAgYnVmLT5vcHMgPSAmdmlydGdwdV9kbWFidWZfb3BzOwo+ID4gKwo+ID4g KyAgICAgcmV0dXJuIGJ1ZjsKPiA+ICt9Cj4gPiArCj4gPiArc3RydWN0IGRybV9nZW1fb2JqZWN0 ICp2aXJ0Z3B1X2dlbV9wcmltZV9pbXBvcnQoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZG1hX2J1 ZiAqYnVmKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqOwo+ID4g Kwo+ID4gKyAgICAgaWYgKGJ1Zi0+b3BzID09ICZ2aXJ0Z3B1X2RtYWJ1Zl9vcHMpIHsKPiA+ICsg ICAgICAgICAgICAgb2JqID0gYnVmLT5wcml2Owo+ID4gKyAgICAgICAgICAgICBpZiAob2JqLT5k ZXYgPT0gZGV2KSB7Cj4gPiArICAgICAgICAgICAgICAgICAgICAgLyoKPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgKiBJbXBvcnRpbmcgZG1hYnVmIGV4cG9ydGVkIGZyb20gb3VyIG93biBnZW0g aW5jcmVhc2VzCj4gPiArICAgICAgICAgICAgICAgICAgICAgICogcmVmY291bnQgb24gZ2VtIGl0 c2VsZiBpbnN0ZWFkIG9mIGZfY291bnQgb2YgZG1hYnVmLgo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAqLwo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGRybV9nZW1fb2JqZWN0X2dldChvYmop Owo+ID4gKyAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmo7Cj4gPiArICAgICAgICAgICAg IH0KPiA+ICsgICAgIH0KPiA+ICsKPiA+ICsgICAgIHJldHVybiBkcm1fZ2VtX3ByaW1lX2ltcG9y dChkZXYsIGJ1Zik7Cj4gPiArfQo+ID4gKwo+ID4gIHN0cnVjdCBzZ190YWJsZSAqdmlydGdwdV9n ZW1fcHJpbWVfZ2V0X3NnX3RhYmxlKHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKQo+ID4gIHsK PiA+ICAgICAgIHN0cnVjdCB2aXJ0aW9fZ3B1X29iamVjdCAqYm8gPSBnZW1fdG9fdmlydGlvX2dw dV9vYmoob2JqKTsKPiA+IC0tCj4gPiAyLjIzLjAuMjM3LmdjNmE0Y2U1MGEwLWdvb2cKPiA+Cj4K PiAtLQo+IERhbmllbCBWZXR0ZXIKPiBTb2Z0d2FyZSBFbmdpbmVlciwgSW50ZWwgQ29ycG9yYXRp b24KPiBodHRwOi8vYmxvZy5mZndsbC5jaApfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5m cmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0 aW5mby9kcmktZGV2ZWw=