From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753403AbeCFJ11 (ORCPT ); Tue, 6 Mar 2018 04:27:27 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:38678 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750865AbeCFJ1E (ORCPT ); Tue, 6 Mar 2018 04:27:04 -0500 X-Google-Smtp-Source: AG47ELuHmkV/k87QVBEgkvdrwvpVbM46akW7wDZ/rMKmTCWFQnc1qCasOmWkkG5AB/b7ZKtfP5o0ZQ== Date: Tue, 6 Mar 2018 10:26:59 +0100 From: Daniel Vetter To: Oleksandr Andrushchenko Cc: Oleksandr Andrushchenko , xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Subject: Re: [PATCH 9/9] drm/xen-front: Implement communication with backend Message-ID: <20180306092659.GN22212@phenom.ffwll.local> Mail-Followup-To: Oleksandr Andrushchenko , Oleksandr Andrushchenko , xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com References: <1519200222-20623-1-git-send-email-andr2000@gmail.com> <1519200222-20623-10-git-send-email-andr2000@gmail.com> <20180305092515.GJ22212@phenom.ffwll.local> <7a6d19be-a740-dae4-551b-17740171aedf@epam.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <7a6d19be-a740-dae4-551b-17740171aedf@epam.com> X-Operating-System: Linux phenom 4.14.0-3-amd64 User-Agent: Mutt/1.9.3 (2018-01-21) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Mar 05, 2018 at 11:30:35AM +0200, Oleksandr Andrushchenko wrote: > On 03/05/2018 11:25 AM, Daniel Vetter wrote: > > On Wed, Feb 21, 2018 at 10:03:42AM +0200, Oleksandr Andrushchenko wrote: > > > From: Oleksandr Andrushchenko > > > > > > Handle communication with the backend: > > > - send requests and wait for the responses according > > > to the displif protocol > > > - serialize access to the communication channel > > > - time-out used for backend communication is set to 3000 ms > > > - manage display buffers shared with the backend > > > > > > Signed-off-by: Oleksandr Andrushchenko > > After the demidlayering it probably makes sense to merge this with the > > overall kms/basic-drm-driver patch. Up to you really. > The reason for such partitioning here and before was that > I can have Xen/DRM parts separate, so those are easier for > review by Xen/DRM communities. So, I would prefer to have it > as it is Well for reviewing the kms parts I need to check what the xen parts are doing (at least sometimes), since semantics of what you're doing matter, and there's a few cases which new drivers tend to get wrong. So for me, this splitting makes stuff actually harder to review. And I guess for the xen folks it won't hurt if they see a bit clearer how it's used on the drm side (even if they might not really understand what's going on). If we have some superficial abstraction in between each of the subsystem maintainers might make assumptions about what the other side of the code is doing which turn out to be wrong, and that's not good. Just explaining my motivation for why I don't like abstractions and splitting stuff up into patches that don't make much sense on their own (because the code is just hanging out there without being wired up anywhere). -Daniel > > -Daniel > > > --- > > > drivers/gpu/drm/xen/xen_drm_front.c | 327 +++++++++++++++++++++++++++++++++++- > > > drivers/gpu/drm/xen/xen_drm_front.h | 5 + > > > 2 files changed, 327 insertions(+), 5 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c > > > index 8de88e359d5e..5ad546231d30 100644 > > > --- a/drivers/gpu/drm/xen/xen_drm_front.c > > > +++ b/drivers/gpu/drm/xen/xen_drm_front.c > > > @@ -31,12 +31,146 @@ > > > #include "xen_drm_front_evtchnl.h" > > > #include "xen_drm_front_shbuf.h" > > > +/* timeout in ms to wait for backend to respond */ > > > +#define VDRM_WAIT_BACK_MS 3000 > > > + > > > +struct xen_drm_front_dbuf { > > > + struct list_head list; > > > + uint64_t dbuf_cookie; > > > + uint64_t fb_cookie; > > > + struct xen_drm_front_shbuf *shbuf; > > > +}; > > > + > > > +static int dbuf_add_to_list(struct xen_drm_front_info *front_info, > > > + struct xen_drm_front_shbuf *shbuf, uint64_t dbuf_cookie) > > > +{ > > > + struct xen_drm_front_dbuf *dbuf; > > > + > > > + dbuf = kzalloc(sizeof(*dbuf), GFP_KERNEL); > > > + if (!dbuf) > > > + return -ENOMEM; > > > + > > > + dbuf->dbuf_cookie = dbuf_cookie; > > > + dbuf->shbuf = shbuf; > > > + list_add(&dbuf->list, &front_info->dbuf_list); > > > + return 0; > > > +} > > > + > > > +static struct xen_drm_front_dbuf *dbuf_get(struct list_head *dbuf_list, > > > + uint64_t dbuf_cookie) > > > +{ > > > + struct xen_drm_front_dbuf *buf, *q; > > > + > > > + list_for_each_entry_safe(buf, q, dbuf_list, list) > > > + if (buf->dbuf_cookie == dbuf_cookie) > > > + return buf; > > > + > > > + return NULL; > > > +} > > > + > > > +static void dbuf_flush_fb(struct list_head *dbuf_list, uint64_t fb_cookie) > > > +{ > > > + struct xen_drm_front_dbuf *buf, *q; > > > + > > > + list_for_each_entry_safe(buf, q, dbuf_list, list) > > > + if (buf->fb_cookie == fb_cookie) > > > + xen_drm_front_shbuf_flush(buf->shbuf); > > > +} > > > + > > > +static void dbuf_free(struct list_head *dbuf_list, uint64_t dbuf_cookie) > > > +{ > > > + struct xen_drm_front_dbuf *buf, *q; > > > + > > > + list_for_each_entry_safe(buf, q, dbuf_list, list) > > > + if (buf->dbuf_cookie == dbuf_cookie) { > > > + list_del(&buf->list); > > > + xen_drm_front_shbuf_unmap(buf->shbuf); > > > + xen_drm_front_shbuf_free(buf->shbuf); > > > + kfree(buf); > > > + break; > > > + } > > > +} > > > + > > > +static void dbuf_free_all(struct list_head *dbuf_list) > > > +{ > > > + struct xen_drm_front_dbuf *buf, *q; > > > + > > > + list_for_each_entry_safe(buf, q, dbuf_list, list) { > > > + list_del(&buf->list); > > > + xen_drm_front_shbuf_unmap(buf->shbuf); > > > + xen_drm_front_shbuf_free(buf->shbuf); > > > + kfree(buf); > > > + } > > > +} > > > + > > > +static struct xendispl_req *be_prepare_req( > > > + struct xen_drm_front_evtchnl *evtchnl, uint8_t operation) > > > +{ > > > + struct xendispl_req *req; > > > + > > > + req = RING_GET_REQUEST(&evtchnl->u.req.ring, > > > + evtchnl->u.req.ring.req_prod_pvt); > > > + req->operation = operation; > > > + req->id = evtchnl->evt_next_id++; > > > + evtchnl->evt_id = req->id; > > > + return req; > > > +} > > > + > > > +static int be_stream_do_io(struct xen_drm_front_evtchnl *evtchnl, > > > + struct xendispl_req *req) > > > +{ > > > + reinit_completion(&evtchnl->u.req.completion); > > > + if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED)) > > > + return -EIO; > > > + > > > + xen_drm_front_evtchnl_flush(evtchnl); > > > + return 0; > > > +} > > > + > > > +static int be_stream_wait_io(struct xen_drm_front_evtchnl *evtchnl) > > > +{ > > > + if (wait_for_completion_timeout(&evtchnl->u.req.completion, > > > + msecs_to_jiffies(VDRM_WAIT_BACK_MS)) <= 0) > > > + return -ETIMEDOUT; > > > + > > > + return evtchnl->u.req.resp_status; > > > +} > > > + > > > static int be_mode_set(struct xen_drm_front_drm_pipeline *pipeline, uint32_t x, > > > uint32_t y, uint32_t width, uint32_t height, uint32_t bpp, > > > uint64_t fb_cookie) > > > { > > > - return 0; > > > + struct xen_drm_front_evtchnl *evtchnl; > > > + struct xen_drm_front_info *front_info; > > > + struct xendispl_req *req; > > > + unsigned long flags; > > > + int ret; > > > + > > > + front_info = pipeline->drm_info->front_info; > > > + evtchnl = &front_info->evt_pairs[pipeline->index].req; > > > + if (unlikely(!evtchnl)) > > > + return -EIO; > > > + > > > + mutex_lock(&front_info->req_io_lock); > > > + > > > + spin_lock_irqsave(&front_info->io_lock, flags); > > > + req = be_prepare_req(evtchnl, XENDISPL_OP_SET_CONFIG); > > > + req->op.set_config.x = x; > > > + req->op.set_config.y = y; > > > + req->op.set_config.width = width; > > > + req->op.set_config.height = height; > > > + req->op.set_config.bpp = bpp; > > > + req->op.set_config.fb_cookie = fb_cookie; > > > + > > > + ret = be_stream_do_io(evtchnl, req); > > > + spin_unlock_irqrestore(&front_info->io_lock, flags); > > > + > > > + if (ret == 0) > > > + ret = be_stream_wait_io(evtchnl); > > > + > > > + mutex_unlock(&front_info->req_io_lock); > > > + return ret; > > > } > > > static int be_dbuf_create_int(struct xen_drm_front_info *front_info, > > > @@ -44,7 +178,69 @@ static int be_dbuf_create_int(struct xen_drm_front_info *front_info, > > > uint32_t bpp, uint64_t size, struct page **pages, > > > struct sg_table *sgt) > > > { > > > + struct xen_drm_front_evtchnl *evtchnl; > > > + struct xen_drm_front_shbuf *shbuf; > > > + struct xendispl_req *req; > > > + struct xen_drm_front_shbuf_cfg buf_cfg; > > > + unsigned long flags; > > > + int ret; > > > + > > > + evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req; > > > + if (unlikely(!evtchnl)) > > > + return -EIO; > > > + > > > + memset(&buf_cfg, 0, sizeof(buf_cfg)); > > > + buf_cfg.xb_dev = front_info->xb_dev; > > > + buf_cfg.pages = pages; > > > + buf_cfg.size = size; > > > + buf_cfg.sgt = sgt; > > > + buf_cfg.be_alloc = front_info->cfg.be_alloc; > > > + > > > + shbuf = xen_drm_front_shbuf_alloc(&buf_cfg); > > > + if (!shbuf) > > > + return -ENOMEM; > > > + > > > + ret = dbuf_add_to_list(front_info, shbuf, dbuf_cookie); > > > + if (ret < 0) { > > > + xen_drm_front_shbuf_free(shbuf); > > > + return ret; > > > + } > > > + > > > + mutex_lock(&front_info->req_io_lock); > > > + > > > + spin_lock_irqsave(&front_info->io_lock, flags); > > > + req = be_prepare_req(evtchnl, XENDISPL_OP_DBUF_CREATE); > > > + req->op.dbuf_create.gref_directory = > > > + xen_drm_front_shbuf_get_dir_start(shbuf); > > > + req->op.dbuf_create.buffer_sz = size; > > > + req->op.dbuf_create.dbuf_cookie = dbuf_cookie; > > > + req->op.dbuf_create.width = width; > > > + req->op.dbuf_create.height = height; > > > + req->op.dbuf_create.bpp = bpp; > > > + if (buf_cfg.be_alloc) > > > + req->op.dbuf_create.flags |= XENDISPL_DBUF_FLG_REQ_ALLOC; > > > + > > > + ret = be_stream_do_io(evtchnl, req); > > > + spin_unlock_irqrestore(&front_info->io_lock, flags); > > > + > > > + if (ret < 0) > > > + goto fail; > > > + > > > + ret = be_stream_wait_io(evtchnl); > > > + if (ret < 0) > > > + goto fail; > > > + > > > + ret = xen_drm_front_shbuf_map(shbuf); > > > + if (ret < 0) > > > + goto fail; > > > + > > > + mutex_unlock(&front_info->req_io_lock); > > > return 0; > > > + > > > +fail: > > > + mutex_unlock(&front_info->req_io_lock); > > > + dbuf_free(&front_info->dbuf_list, dbuf_cookie); > > > + return ret; > > > } > > > static int be_dbuf_create_from_sgt(struct xen_drm_front_info *front_info, > > > @@ -66,26 +262,144 @@ static int be_dbuf_create_from_pages(struct xen_drm_front_info *front_info, > > > static int be_dbuf_destroy(struct xen_drm_front_info *front_info, > > > uint64_t dbuf_cookie) > > > { > > > - return 0; > > > + struct xen_drm_front_evtchnl *evtchnl; > > > + struct xendispl_req *req; > > > + unsigned long flags; > > > + bool be_alloc; > > > + int ret; > > > + > > > + evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req; > > > + if (unlikely(!evtchnl)) > > > + return -EIO; > > > + > > > + be_alloc = front_info->cfg.be_alloc; > > > + > > > + /* > > > + * for the backend allocated buffer release references now, so backend > > > + * can free the buffer > > > + */ > > > + if (be_alloc) > > > + dbuf_free(&front_info->dbuf_list, dbuf_cookie); > > > + > > > + mutex_lock(&front_info->req_io_lock); > > > + > > > + spin_lock_irqsave(&front_info->io_lock, flags); > > > + req = be_prepare_req(evtchnl, XENDISPL_OP_DBUF_DESTROY); > > > + req->op.dbuf_destroy.dbuf_cookie = dbuf_cookie; > > > + > > > + ret = be_stream_do_io(evtchnl, req); > > > + spin_unlock_irqrestore(&front_info->io_lock, flags); > > > + > > > + if (ret == 0) > > > + ret = be_stream_wait_io(evtchnl); > > > + > > > + /* > > > + * do this regardless of communication status with the backend: > > > + * if we cannot remove remote resources remove what we can locally > > > + */ > > > + if (!be_alloc) > > > + dbuf_free(&front_info->dbuf_list, dbuf_cookie); > > > + > > > + mutex_unlock(&front_info->req_io_lock); > > > + return ret; > > > } > > > static int be_fb_attach(struct xen_drm_front_info *front_info, > > > uint64_t dbuf_cookie, uint64_t fb_cookie, uint32_t width, > > > uint32_t height, uint32_t pixel_format) > > > { > > > - return 0; > > > + struct xen_drm_front_evtchnl *evtchnl; > > > + struct xen_drm_front_dbuf *buf; > > > + struct xendispl_req *req; > > > + unsigned long flags; > > > + int ret; > > > + > > > + evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req; > > > + if (unlikely(!evtchnl)) > > > + return -EIO; > > > + > > > + buf = dbuf_get(&front_info->dbuf_list, dbuf_cookie); > > > + if (!buf) > > > + return -EINVAL; > > > + > > > + buf->fb_cookie = fb_cookie; > > > + > > > + mutex_lock(&front_info->req_io_lock); > > > + > > > + spin_lock_irqsave(&front_info->io_lock, flags); > > > + req = be_prepare_req(evtchnl, XENDISPL_OP_FB_ATTACH); > > > + req->op.fb_attach.dbuf_cookie = dbuf_cookie; > > > + req->op.fb_attach.fb_cookie = fb_cookie; > > > + req->op.fb_attach.width = width; > > > + req->op.fb_attach.height = height; > > > + req->op.fb_attach.pixel_format = pixel_format; > > > + > > > + ret = be_stream_do_io(evtchnl, req); > > > + spin_unlock_irqrestore(&front_info->io_lock, flags); > > > + > > > + if (ret == 0) > > > + ret = be_stream_wait_io(evtchnl); > > > + > > > + mutex_unlock(&front_info->req_io_lock); > > > + return ret; > > > } > > > static int be_fb_detach(struct xen_drm_front_info *front_info, > > > uint64_t fb_cookie) > > > { > > > - return 0; > > > + struct xen_drm_front_evtchnl *evtchnl; > > > + struct xendispl_req *req; > > > + unsigned long flags; > > > + int ret; > > > + > > > + evtchnl = &front_info->evt_pairs[GENERIC_OP_EVT_CHNL].req; > > > + if (unlikely(!evtchnl)) > > > + return -EIO; > > > + > > > + mutex_lock(&front_info->req_io_lock); > > > + > > > + spin_lock_irqsave(&front_info->io_lock, flags); > > > + req = be_prepare_req(evtchnl, XENDISPL_OP_FB_DETACH); > > > + req->op.fb_detach.fb_cookie = fb_cookie; > > > + > > > + ret = be_stream_do_io(evtchnl, req); > > > + spin_unlock_irqrestore(&front_info->io_lock, flags); > > > + > > > + if (ret == 0) > > > + ret = be_stream_wait_io(evtchnl); > > > + > > > + mutex_unlock(&front_info->req_io_lock); > > > + return ret; > > > } > > > static int be_page_flip(struct xen_drm_front_info *front_info, int conn_idx, > > > uint64_t fb_cookie) > > > { > > > - return 0; > > > + struct xen_drm_front_evtchnl *evtchnl; > > > + struct xendispl_req *req; > > > + unsigned long flags; > > > + int ret; > > > + > > > + if (unlikely(conn_idx >= front_info->num_evt_pairs)) > > > + return -EINVAL; > > > + > > > + dbuf_flush_fb(&front_info->dbuf_list, fb_cookie); > > > + evtchnl = &front_info->evt_pairs[conn_idx].req; > > > + > > > + mutex_lock(&front_info->req_io_lock); > > > + > > > + spin_lock_irqsave(&front_info->io_lock, flags); > > > + req = be_prepare_req(evtchnl, XENDISPL_OP_PG_FLIP); > > > + req->op.pg_flip.fb_cookie = fb_cookie; > > > + > > > + ret = be_stream_do_io(evtchnl, req); > > > + spin_unlock_irqrestore(&front_info->io_lock, flags); > > > + > > > + if (ret == 0) > > > + ret = be_stream_wait_io(evtchnl); > > > + > > > + mutex_unlock(&front_info->req_io_lock); > > > + return ret; > > > } > > > static void xen_drm_drv_unload(struct xen_drm_front_info *front_info) > > > @@ -183,6 +497,7 @@ static void xen_drv_remove_internal(struct xen_drm_front_info *front_info) > > > { > > > xen_drm_drv_deinit(front_info); > > > xen_drm_front_evtchnl_free_all(front_info); > > > + dbuf_free_all(&front_info->dbuf_list); > > > } > > > static int backend_on_initwait(struct xen_drm_front_info *front_info) > > > @@ -310,6 +625,8 @@ static int xen_drv_probe(struct xenbus_device *xb_dev, > > > front_info->xb_dev = xb_dev; > > > spin_lock_init(&front_info->io_lock); > > > + mutex_init(&front_info->req_io_lock); > > > + INIT_LIST_HEAD(&front_info->dbuf_list); > > > front_info->drm_pdrv_registered = false; > > > dev_set_drvdata(&xb_dev->dev, front_info); > > > return xenbus_switch_state(xb_dev, XenbusStateInitialising); > > > diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h > > > index c6f52c892434..db32d00145d1 100644 > > > --- a/drivers/gpu/drm/xen/xen_drm_front.h > > > +++ b/drivers/gpu/drm/xen/xen_drm_front.h > > > @@ -137,6 +137,8 @@ struct xen_drm_front_info { > > > struct xenbus_device *xb_dev; > > > /* to protect data between backend IO code and interrupt handler */ > > > spinlock_t io_lock; > > > + /* serializer for backend IO: request/response */ > > > + struct mutex req_io_lock; > > > bool drm_pdrv_registered; > > > /* virtual DRM platform device */ > > > struct platform_device *drm_pdev; > > > @@ -144,6 +146,9 @@ struct xen_drm_front_info { > > > int num_evt_pairs; > > > struct xen_drm_front_evtchnl_pair *evt_pairs; > > > struct xen_drm_front_cfg cfg; > > > + > > > + /* display buffers */ > > > + struct list_head dbuf_list; > > > }; > > > #endif /* __XEN_DRM_FRONT_H_ */ > > > -- > > > 2.7.4 > > > > > > _______________________________________________ > > > dri-devel mailing list > > > dri-devel@lists.freedesktop.org > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH 9/9] drm/xen-front: Implement communication with backend Date: Tue, 6 Mar 2018 10:26:59 +0100 Message-ID: <20180306092659.GN22212@phenom.ffwll.local> References: <1519200222-20623-1-git-send-email-andr2000@gmail.com> <1519200222-20623-10-git-send-email-andr2000@gmail.com> <20180305092515.GJ22212@phenom.ffwll.local> <7a6d19be-a740-dae4-551b-17740171aedf@epam.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-wm0-x242.google.com (mail-wm0-x242.google.com [IPv6:2a00:1450:400c:c09::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 200476E5B9 for ; Tue, 6 Mar 2018 09:27:04 +0000 (UTC) Received: by mail-wm0-x242.google.com with SMTP id 188so20753467wme.1 for ; Tue, 06 Mar 2018 01:27:04 -0800 (PST) Content-Disposition: inline In-Reply-To: <7a6d19be-a740-dae4-551b-17740171aedf@epam.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Oleksandr Andrushchenko Cc: jgross@suse.com, konrad.wilk@oracle.com, Oleksandr Andrushchenko , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, xen-devel@lists.xenproject.org, boris.ostrovsky@oracle.com List-Id: dri-devel@lists.freedesktop.org T24gTW9uLCBNYXIgMDUsIDIwMTggYXQgMTE6MzA6MzVBTSArMDIwMCwgT2xla3NhbmRyIEFuZHJ1 c2hjaGVua28gd3JvdGU6Cj4gT24gMDMvMDUvMjAxOCAxMToyNSBBTSwgRGFuaWVsIFZldHRlciB3 cm90ZToKPiA+IE9uIFdlZCwgRmViIDIxLCAyMDE4IGF0IDEwOjAzOjQyQU0gKzAyMDAsIE9sZWtz YW5kciBBbmRydXNoY2hlbmtvIHdyb3RlOgo+ID4gPiBGcm9tOiBPbGVrc2FuZHIgQW5kcnVzaGNo ZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBhbS5jb20+Cj4gPiA+IAo+ID4gPiBIYW5k bGUgY29tbXVuaWNhdGlvbiB3aXRoIHRoZSBiYWNrZW5kOgo+ID4gPiAgIC0gc2VuZCByZXF1ZXN0 cyBhbmQgd2FpdCBmb3IgdGhlIHJlc3BvbnNlcyBhY2NvcmRpbmcKPiA+ID4gICAgIHRvIHRoZSBk aXNwbGlmIHByb3RvY29sCj4gPiA+ICAgLSBzZXJpYWxpemUgYWNjZXNzIHRvIHRoZSBjb21tdW5p Y2F0aW9uIGNoYW5uZWwKPiA+ID4gICAtIHRpbWUtb3V0IHVzZWQgZm9yIGJhY2tlbmQgY29tbXVu aWNhdGlvbiBpcyBzZXQgdG8gMzAwMCBtcwo+ID4gPiAgIC0gbWFuYWdlIGRpc3BsYXkgYnVmZmVy cyBzaGFyZWQgd2l0aCB0aGUgYmFja2VuZAo+ID4gPiAKPiA+ID4gU2lnbmVkLW9mZi1ieTogT2xl a3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVwYW0uY29tPgo+ ID4gQWZ0ZXIgdGhlIGRlbWlkbGF5ZXJpbmcgaXQgcHJvYmFibHkgbWFrZXMgc2Vuc2UgdG8gbWVy Z2UgdGhpcyB3aXRoIHRoZQo+ID4gb3ZlcmFsbCBrbXMvYmFzaWMtZHJtLWRyaXZlciBwYXRjaC4g VXAgdG8geW91IHJlYWxseS4KPiBUaGUgcmVhc29uIGZvciBzdWNoIHBhcnRpdGlvbmluZyBoZXJl IGFuZCBiZWZvcmUgd2FzIHRoYXQKPiBJIGNhbiBoYXZlIFhlbi9EUk0gcGFydHMgc2VwYXJhdGUs IHNvIHRob3NlIGFyZSBlYXNpZXIgZm9yCj4gcmV2aWV3IGJ5IFhlbi9EUk0gY29tbXVuaXRpZXMu IFNvLCBJIHdvdWxkIHByZWZlciB0byBoYXZlIGl0Cj4gYXMgaXQgaXMKCldlbGwgZm9yIHJldmll d2luZyB0aGUga21zIHBhcnRzIEkgbmVlZCB0byBjaGVjayB3aGF0IHRoZSB4ZW4gcGFydHMgYXJl CmRvaW5nIChhdCBsZWFzdCBzb21ldGltZXMpLCBzaW5jZSBzZW1hbnRpY3Mgb2Ygd2hhdCB5b3Un cmUgZG9pbmcgbWF0dGVyLAphbmQgdGhlcmUncyBhIGZldyBjYXNlcyB3aGljaCBuZXcgZHJpdmVy cyB0ZW5kIHRvIGdldCB3cm9uZy4gU28gZm9yIG1lLAp0aGlzIHNwbGl0dGluZyBtYWtlcyBzdHVm ZiBhY3R1YWxseSBoYXJkZXIgdG8gcmV2aWV3LgoKQW5kIEkgZ3Vlc3MgZm9yIHRoZSB4ZW4gZm9s a3MgaXQgd29uJ3QgaHVydCBpZiB0aGV5IHNlZSBhIGJpdCBjbGVhcmVyIGhvdwppdCdzIHVzZWQg b24gdGhlIGRybSBzaWRlIChldmVuIGlmIHRoZXkgbWlnaHQgbm90IHJlYWxseSB1bmRlcnN0YW5k IHdoYXQncwpnb2luZyBvbikuIElmIHdlIGhhdmUgc29tZSBzdXBlcmZpY2lhbCBhYnN0cmFjdGlv biBpbiBiZXR3ZWVuIGVhY2ggb2YgdGhlCnN1YnN5c3RlbSBtYWludGFpbmVycyBtaWdodCBtYWtl IGFzc3VtcHRpb25zIGFib3V0IHdoYXQgdGhlIG90aGVyIHNpZGUgb2YKdGhlIGNvZGUgaXMgZG9p bmcgd2hpY2ggdHVybiBvdXQgdG8gYmUgd3JvbmcsIGFuZCB0aGF0J3Mgbm90IGdvb2QuCgpKdXN0 IGV4cGxhaW5pbmcgbXkgbW90aXZhdGlvbiBmb3Igd2h5IEkgZG9uJ3QgbGlrZSBhYnN0cmFjdGlv bnMgYW5kCnNwbGl0dGluZyBzdHVmZiB1cCBpbnRvIHBhdGNoZXMgdGhhdCBkb24ndCBtYWtlIG11 Y2ggc2Vuc2Ugb24gdGhlaXIgb3duCihiZWNhdXNlIHRoZSBjb2RlIGlzIGp1c3QgaGFuZ2luZyBv dXQgdGhlcmUgd2l0aG91dCBiZWluZyB3aXJlZCB1cAphbnl3aGVyZSkuCi1EYW5pZWwKPiA+IC1E YW5pZWwKPiA+ID4gLS0tCj4gPiA+ICAgZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250 LmMgfCAzMjcgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystCj4gPiA+ICAgZHJp dmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250LmggfCAgIDUgKwo+ID4gPiAgIDIgZmlsZXMg Y2hhbmdlZCwgMzI3IGluc2VydGlvbnMoKyksIDUgZGVsZXRpb25zKC0pCj4gPiA+IAo+ID4gPiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250LmMgYi9kcml2ZXJz L2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuYwo+ID4gPiBpbmRleCA4ZGU4OGUzNTlkNWUuLjVh ZDU0NjIzMWQzMCAxMDA2NDQKPiA+ID4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJt X2Zyb250LmMKPiA+ID4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250LmMK PiA+ID4gQEAgLTMxLDEyICszMSwxNDYgQEAKPiA+ID4gICAjaW5jbHVkZSAieGVuX2RybV9mcm9u dF9ldnRjaG5sLmgiCj4gPiA+ICAgI2luY2x1ZGUgInhlbl9kcm1fZnJvbnRfc2hidWYuaCIKPiA+ ID4gKy8qIHRpbWVvdXQgaW4gbXMgdG8gd2FpdCBmb3IgYmFja2VuZCB0byByZXNwb25kICovCj4g PiA+ICsjZGVmaW5lIFZEUk1fV0FJVF9CQUNLX01TCTMwMDAKPiA+ID4gKwo+ID4gPiArc3RydWN0 IHhlbl9kcm1fZnJvbnRfZGJ1ZiB7Cj4gPiA+ICsJc3RydWN0IGxpc3RfaGVhZCBsaXN0Owo+ID4g PiArCXVpbnQ2NF90IGRidWZfY29va2llOwo+ID4gPiArCXVpbnQ2NF90IGZiX2Nvb2tpZTsKPiA+ ID4gKwlzdHJ1Y3QgeGVuX2RybV9mcm9udF9zaGJ1ZiAqc2hidWY7Cj4gPiA+ICt9Owo+ID4gPiAr Cj4gPiA+ICtzdGF0aWMgaW50IGRidWZfYWRkX3RvX2xpc3Qoc3RydWN0IHhlbl9kcm1fZnJvbnRf aW5mbyAqZnJvbnRfaW5mbywKPiA+ID4gKwkJc3RydWN0IHhlbl9kcm1fZnJvbnRfc2hidWYgKnNo YnVmLCB1aW50NjRfdCBkYnVmX2Nvb2tpZSkKPiA+ID4gK3sKPiA+ID4gKwlzdHJ1Y3QgeGVuX2Ry bV9mcm9udF9kYnVmICpkYnVmOwo+ID4gPiArCj4gPiA+ICsJZGJ1ZiA9IGt6YWxsb2Moc2l6ZW9m KCpkYnVmKSwgR0ZQX0tFUk5FTCk7Cj4gPiA+ICsJaWYgKCFkYnVmKQo+ID4gPiArCQlyZXR1cm4g LUVOT01FTTsKPiA+ID4gKwo+ID4gPiArCWRidWYtPmRidWZfY29va2llID0gZGJ1Zl9jb29raWU7 Cj4gPiA+ICsJZGJ1Zi0+c2hidWYgPSBzaGJ1ZjsKPiA+ID4gKwlsaXN0X2FkZCgmZGJ1Zi0+bGlz dCwgJmZyb250X2luZm8tPmRidWZfbGlzdCk7Cj4gPiA+ICsJcmV0dXJuIDA7Cj4gPiA+ICt9Cj4g PiA+ICsKPiA+ID4gK3N0YXRpYyBzdHJ1Y3QgeGVuX2RybV9mcm9udF9kYnVmICpkYnVmX2dldChz dHJ1Y3QgbGlzdF9oZWFkICpkYnVmX2xpc3QsCj4gPiA+ICsJCXVpbnQ2NF90IGRidWZfY29va2ll KQo+ID4gPiArewo+ID4gPiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2RidWYgKmJ1ZiwgKnE7Cj4g PiA+ICsKPiA+ID4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoYnVmLCBxLCBkYnVmX2xpc3Qs IGxpc3QpCj4gPiA+ICsJCWlmIChidWYtPmRidWZfY29va2llID09IGRidWZfY29va2llKQo+ID4g PiArCQkJcmV0dXJuIGJ1ZjsKPiA+ID4gKwo+ID4gPiArCXJldHVybiBOVUxMOwo+ID4gPiArfQo+ ID4gPiArCj4gPiA+ICtzdGF0aWMgdm9pZCBkYnVmX2ZsdXNoX2ZiKHN0cnVjdCBsaXN0X2hlYWQg KmRidWZfbGlzdCwgdWludDY0X3QgZmJfY29va2llKQo+ID4gPiArewo+ID4gPiArCXN0cnVjdCB4 ZW5fZHJtX2Zyb250X2RidWYgKmJ1ZiwgKnE7Cj4gPiA+ICsKPiA+ID4gKwlsaXN0X2Zvcl9lYWNo X2VudHJ5X3NhZmUoYnVmLCBxLCBkYnVmX2xpc3QsIGxpc3QpCj4gPiA+ICsJCWlmIChidWYtPmZi X2Nvb2tpZSA9PSBmYl9jb29raWUpCj4gPiA+ICsJCQl4ZW5fZHJtX2Zyb250X3NoYnVmX2ZsdXNo KGJ1Zi0+c2hidWYpOwo+ID4gPiArfQo+ID4gPiArCj4gPiA+ICtzdGF0aWMgdm9pZCBkYnVmX2Zy ZWUoc3RydWN0IGxpc3RfaGVhZCAqZGJ1Zl9saXN0LCB1aW50NjRfdCBkYnVmX2Nvb2tpZSkKPiA+ ID4gK3sKPiA+ID4gKwlzdHJ1Y3QgeGVuX2RybV9mcm9udF9kYnVmICpidWYsICpxOwo+ID4gPiAr Cj4gPiA+ICsJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGJ1ZiwgcSwgZGJ1Zl9saXN0LCBsaXN0 KQo+ID4gPiArCQlpZiAoYnVmLT5kYnVmX2Nvb2tpZSA9PSBkYnVmX2Nvb2tpZSkgewo+ID4gPiAr CQkJbGlzdF9kZWwoJmJ1Zi0+bGlzdCk7Cj4gPiA+ICsJCQl4ZW5fZHJtX2Zyb250X3NoYnVmX3Vu bWFwKGJ1Zi0+c2hidWYpOwo+ID4gPiArCQkJeGVuX2RybV9mcm9udF9zaGJ1Zl9mcmVlKGJ1Zi0+ c2hidWYpOwo+ID4gPiArCQkJa2ZyZWUoYnVmKTsKPiA+ID4gKwkJCWJyZWFrOwo+ID4gPiArCQl9 Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyB2b2lkIGRidWZfZnJlZV9hbGwoc3RydWN0 IGxpc3RfaGVhZCAqZGJ1Zl9saXN0KQo+ID4gPiArewo+ID4gPiArCXN0cnVjdCB4ZW5fZHJtX2Zy b250X2RidWYgKmJ1ZiwgKnE7Cj4gPiA+ICsKPiA+ID4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3Nh ZmUoYnVmLCBxLCBkYnVmX2xpc3QsIGxpc3QpIHsKPiA+ID4gKwkJbGlzdF9kZWwoJmJ1Zi0+bGlz dCk7Cj4gPiA+ICsJCXhlbl9kcm1fZnJvbnRfc2hidWZfdW5tYXAoYnVmLT5zaGJ1Zik7Cj4gPiA+ ICsJCXhlbl9kcm1fZnJvbnRfc2hidWZfZnJlZShidWYtPnNoYnVmKTsKPiA+ID4gKwkJa2ZyZWUo YnVmKTsKPiA+ID4gKwl9Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBzdHJ1Y3QgeGVu ZGlzcGxfcmVxICpiZV9wcmVwYXJlX3JlcSgKPiA+ID4gKwkJc3RydWN0IHhlbl9kcm1fZnJvbnRf ZXZ0Y2hubCAqZXZ0Y2hubCwgdWludDhfdCBvcGVyYXRpb24pCj4gPiA+ICt7Cj4gPiA+ICsJc3Ry dWN0IHhlbmRpc3BsX3JlcSAqcmVxOwo+ID4gPiArCj4gPiA+ICsJcmVxID0gUklOR19HRVRfUkVR VUVTVCgmZXZ0Y2hubC0+dS5yZXEucmluZywKPiA+ID4gKwkJCWV2dGNobmwtPnUucmVxLnJpbmcu cmVxX3Byb2RfcHZ0KTsKPiA+ID4gKwlyZXEtPm9wZXJhdGlvbiA9IG9wZXJhdGlvbjsKPiA+ID4g KwlyZXEtPmlkID0gZXZ0Y2hubC0+ZXZ0X25leHRfaWQrKzsKPiA+ID4gKwlldnRjaG5sLT5ldnRf aWQgPSByZXEtPmlkOwo+ID4gPiArCXJldHVybiByZXE7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4g K3N0YXRpYyBpbnQgYmVfc3RyZWFtX2RvX2lvKHN0cnVjdCB4ZW5fZHJtX2Zyb250X2V2dGNobmwg KmV2dGNobmwsCj4gPiA+ICsJCXN0cnVjdCB4ZW5kaXNwbF9yZXEgKnJlcSkKPiA+ID4gK3sKPiA+ ID4gKwlyZWluaXRfY29tcGxldGlvbigmZXZ0Y2hubC0+dS5yZXEuY29tcGxldGlvbik7Cj4gPiA+ ICsJaWYgKHVubGlrZWx5KGV2dGNobmwtPnN0YXRlICE9IEVWVENITkxfU1RBVEVfQ09OTkVDVEVE KSkKPiA+ID4gKwkJcmV0dXJuIC1FSU87Cj4gPiA+ICsKPiA+ID4gKwl4ZW5fZHJtX2Zyb250X2V2 dGNobmxfZmx1c2goZXZ0Y2hubCk7Cj4gPiA+ICsJcmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsK PiA+ID4gK3N0YXRpYyBpbnQgYmVfc3RyZWFtX3dhaXRfaW8oc3RydWN0IHhlbl9kcm1fZnJvbnRf ZXZ0Y2hubCAqZXZ0Y2hubCkKPiA+ID4gK3sKPiA+ID4gKwlpZiAod2FpdF9mb3JfY29tcGxldGlv bl90aW1lb3V0KCZldnRjaG5sLT51LnJlcS5jb21wbGV0aW9uLAo+ID4gPiArCQkJbXNlY3NfdG9f amlmZmllcyhWRFJNX1dBSVRfQkFDS19NUykpIDw9IDApCj4gPiA+ICsJCXJldHVybiAtRVRJTUVE T1VUOwo+ID4gPiArCj4gPiA+ICsJcmV0dXJuIGV2dGNobmwtPnUucmVxLnJlc3Bfc3RhdHVzOwo+ ID4gPiArfQo+ID4gPiArCj4gPiA+ICAgc3RhdGljIGludCBiZV9tb2RlX3NldChzdHJ1Y3QgeGVu X2RybV9mcm9udF9kcm1fcGlwZWxpbmUgKnBpcGVsaW5lLCB1aW50MzJfdCB4LAo+ID4gPiAgIAkJ dWludDMyX3QgeSwgdWludDMyX3Qgd2lkdGgsIHVpbnQzMl90IGhlaWdodCwgdWludDMyX3QgYnBw LAo+ID4gPiAgIAkJdWludDY0X3QgZmJfY29va2llKQo+ID4gPiAgIHsKPiA+ID4gLQlyZXR1cm4g MDsKPiA+ID4gKwlzdHJ1Y3QgeGVuX2RybV9mcm9udF9ldnRjaG5sICpldnRjaG5sOwo+ID4gPiAr CXN0cnVjdCB4ZW5fZHJtX2Zyb250X2luZm8gKmZyb250X2luZm87Cj4gPiA+ICsJc3RydWN0IHhl bmRpc3BsX3JlcSAqcmVxOwo+ID4gPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gPiA+ICsJaW50 IHJldDsKPiA+ID4gKwo+ID4gPiArCWZyb250X2luZm8gPSBwaXBlbGluZS0+ZHJtX2luZm8tPmZy b250X2luZm87Cj4gPiA+ICsJZXZ0Y2hubCA9ICZmcm9udF9pbmZvLT5ldnRfcGFpcnNbcGlwZWxp bmUtPmluZGV4XS5yZXE7Cj4gPiA+ICsJaWYgKHVubGlrZWx5KCFldnRjaG5sKSkKPiA+ID4gKwkJ cmV0dXJuIC1FSU87Cj4gPiA+ICsKPiA+ID4gKwltdXRleF9sb2NrKCZmcm9udF9pbmZvLT5yZXFf aW9fbG9jayk7Cj4gPiA+ICsKPiA+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmZnJvbnRfaW5mby0+ aW9fbG9jaywgZmxhZ3MpOwo+ID4gPiArCXJlcSA9IGJlX3ByZXBhcmVfcmVxKGV2dGNobmwsIFhF TkRJU1BMX09QX1NFVF9DT05GSUcpOwo+ID4gPiArCXJlcS0+b3Auc2V0X2NvbmZpZy54ID0geDsK PiA+ID4gKwlyZXEtPm9wLnNldF9jb25maWcueSA9IHk7Cj4gPiA+ICsJcmVxLT5vcC5zZXRfY29u ZmlnLndpZHRoID0gd2lkdGg7Cj4gPiA+ICsJcmVxLT5vcC5zZXRfY29uZmlnLmhlaWdodCA9IGhl aWdodDsKPiA+ID4gKwlyZXEtPm9wLnNldF9jb25maWcuYnBwID0gYnBwOwo+ID4gPiArCXJlcS0+ b3Auc2V0X2NvbmZpZy5mYl9jb29raWUgPSBmYl9jb29raWU7Cj4gPiA+ICsKPiA+ID4gKwlyZXQg PSBiZV9zdHJlYW1fZG9faW8oZXZ0Y2hubCwgcmVxKTsKPiA+ID4gKwlzcGluX3VubG9ja19pcnFy ZXN0b3JlKCZmcm9udF9pbmZvLT5pb19sb2NrLCBmbGFncyk7Cj4gPiA+ICsKPiA+ID4gKwlpZiAo cmV0ID09IDApCj4gPiA+ICsJCXJldCA9IGJlX3N0cmVhbV93YWl0X2lvKGV2dGNobmwpOwo+ID4g PiArCj4gPiA+ICsJbXV0ZXhfdW5sb2NrKCZmcm9udF9pbmZvLT5yZXFfaW9fbG9jayk7Cj4gPiA+ ICsJcmV0dXJuIHJldDsKPiA+ID4gICB9Cj4gPiA+ICAgc3RhdGljIGludCBiZV9kYnVmX2NyZWF0 ZV9pbnQoc3RydWN0IHhlbl9kcm1fZnJvbnRfaW5mbyAqZnJvbnRfaW5mbywKPiA+ID4gQEAgLTQ0 LDcgKzE3OCw2OSBAQCBzdGF0aWMgaW50IGJlX2RidWZfY3JlYXRlX2ludChzdHJ1Y3QgeGVuX2Ry bV9mcm9udF9pbmZvICpmcm9udF9pbmZvLAo+ID4gPiAgIAkJdWludDMyX3QgYnBwLCB1aW50NjRf dCBzaXplLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAo+ID4gPiAgIAkJc3RydWN0IHNnX3RhYmxlICpz Z3QpCj4gPiA+ICAgewo+ID4gPiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2V2dGNobmwgKmV2dGNo bmw7Cj4gPiA+ICsJc3RydWN0IHhlbl9kcm1fZnJvbnRfc2hidWYgKnNoYnVmOwo+ID4gPiArCXN0 cnVjdCB4ZW5kaXNwbF9yZXEgKnJlcTsKPiA+ID4gKwlzdHJ1Y3QgeGVuX2RybV9mcm9udF9zaGJ1 Zl9jZmcgYnVmX2NmZzsKPiA+ID4gKwl1bnNpZ25lZCBsb25nIGZsYWdzOwo+ID4gPiArCWludCBy ZXQ7Cj4gPiA+ICsKPiA+ID4gKwlldnRjaG5sID0gJmZyb250X2luZm8tPmV2dF9wYWlyc1tHRU5F UklDX09QX0VWVF9DSE5MXS5yZXE7Cj4gPiA+ICsJaWYgKHVubGlrZWx5KCFldnRjaG5sKSkKPiA+ ID4gKwkJcmV0dXJuIC1FSU87Cj4gPiA+ICsKPiA+ID4gKwltZW1zZXQoJmJ1Zl9jZmcsIDAsIHNp emVvZihidWZfY2ZnKSk7Cj4gPiA+ICsJYnVmX2NmZy54Yl9kZXYgPSBmcm9udF9pbmZvLT54Yl9k ZXY7Cj4gPiA+ICsJYnVmX2NmZy5wYWdlcyA9IHBhZ2VzOwo+ID4gPiArCWJ1Zl9jZmcuc2l6ZSA9 IHNpemU7Cj4gPiA+ICsJYnVmX2NmZy5zZ3QgPSBzZ3Q7Cj4gPiA+ICsJYnVmX2NmZy5iZV9hbGxv YyA9IGZyb250X2luZm8tPmNmZy5iZV9hbGxvYzsKPiA+ID4gKwo+ID4gPiArCXNoYnVmID0geGVu X2RybV9mcm9udF9zaGJ1Zl9hbGxvYygmYnVmX2NmZyk7Cj4gPiA+ICsJaWYgKCFzaGJ1ZikKPiA+ ID4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gPiA+ICsKPiA+ID4gKwlyZXQgPSBkYnVmX2FkZF90b19s aXN0KGZyb250X2luZm8sIHNoYnVmLCBkYnVmX2Nvb2tpZSk7Cj4gPiA+ICsJaWYgKHJldCA8IDAp IHsKPiA+ID4gKwkJeGVuX2RybV9mcm9udF9zaGJ1Zl9mcmVlKHNoYnVmKTsKPiA+ID4gKwkJcmV0 dXJuIHJldDsKPiA+ID4gKwl9Cj4gPiA+ICsKPiA+ID4gKwltdXRleF9sb2NrKCZmcm9udF9pbmZv LT5yZXFfaW9fbG9jayk7Cj4gPiA+ICsKPiA+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmZnJvbnRf aW5mby0+aW9fbG9jaywgZmxhZ3MpOwo+ID4gPiArCXJlcSA9IGJlX3ByZXBhcmVfcmVxKGV2dGNo bmwsIFhFTkRJU1BMX09QX0RCVUZfQ1JFQVRFKTsKPiA+ID4gKwlyZXEtPm9wLmRidWZfY3JlYXRl LmdyZWZfZGlyZWN0b3J5ID0KPiA+ID4gKwkJCXhlbl9kcm1fZnJvbnRfc2hidWZfZ2V0X2Rpcl9z dGFydChzaGJ1Zik7Cj4gPiA+ICsJcmVxLT5vcC5kYnVmX2NyZWF0ZS5idWZmZXJfc3ogPSBzaXpl Owo+ID4gPiArCXJlcS0+b3AuZGJ1Zl9jcmVhdGUuZGJ1Zl9jb29raWUgPSBkYnVmX2Nvb2tpZTsK PiA+ID4gKwlyZXEtPm9wLmRidWZfY3JlYXRlLndpZHRoID0gd2lkdGg7Cj4gPiA+ICsJcmVxLT5v cC5kYnVmX2NyZWF0ZS5oZWlnaHQgPSBoZWlnaHQ7Cj4gPiA+ICsJcmVxLT5vcC5kYnVmX2NyZWF0 ZS5icHAgPSBicHA7Cj4gPiA+ICsJaWYgKGJ1Zl9jZmcuYmVfYWxsb2MpCj4gPiA+ICsJCXJlcS0+ b3AuZGJ1Zl9jcmVhdGUuZmxhZ3MgfD0gWEVORElTUExfREJVRl9GTEdfUkVRX0FMTE9DOwo+ID4g PiArCj4gPiA+ICsJcmV0ID0gYmVfc3RyZWFtX2RvX2lvKGV2dGNobmwsIHJlcSk7Cj4gPiA+ICsJ c3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZnJvbnRfaW5mby0+aW9fbG9jaywgZmxhZ3MpOwo+ID4g PiArCj4gPiA+ICsJaWYgKHJldCA8IDApCj4gPiA+ICsJCWdvdG8gZmFpbDsKPiA+ID4gKwo+ID4g PiArCXJldCA9IGJlX3N0cmVhbV93YWl0X2lvKGV2dGNobmwpOwo+ID4gPiArCWlmIChyZXQgPCAw KQo+ID4gPiArCQlnb3RvIGZhaWw7Cj4gPiA+ICsKPiA+ID4gKwlyZXQgPSB4ZW5fZHJtX2Zyb250 X3NoYnVmX21hcChzaGJ1Zik7Cj4gPiA+ICsJaWYgKHJldCA8IDApCj4gPiA+ICsJCWdvdG8gZmFp bDsKPiA+ID4gKwo+ID4gPiArCW11dGV4X3VubG9jaygmZnJvbnRfaW5mby0+cmVxX2lvX2xvY2sp Owo+ID4gPiAgIAlyZXR1cm4gMDsKPiA+ID4gKwo+ID4gPiArZmFpbDoKPiA+ID4gKwltdXRleF91 bmxvY2soJmZyb250X2luZm8tPnJlcV9pb19sb2NrKTsKPiA+ID4gKwlkYnVmX2ZyZWUoJmZyb250 X2luZm8tPmRidWZfbGlzdCwgZGJ1Zl9jb29raWUpOwo+ID4gPiArCXJldHVybiByZXQ7Cj4gPiA+ ICAgfQo+ID4gPiAgIHN0YXRpYyBpbnQgYmVfZGJ1Zl9jcmVhdGVfZnJvbV9zZ3Qoc3RydWN0IHhl bl9kcm1fZnJvbnRfaW5mbyAqZnJvbnRfaW5mbywKPiA+ID4gQEAgLTY2LDI2ICsyNjIsMTQ0IEBA IHN0YXRpYyBpbnQgYmVfZGJ1Zl9jcmVhdGVfZnJvbV9wYWdlcyhzdHJ1Y3QgeGVuX2RybV9mcm9u dF9pbmZvICpmcm9udF9pbmZvLAo+ID4gPiAgIHN0YXRpYyBpbnQgYmVfZGJ1Zl9kZXN0cm95KHN0 cnVjdCB4ZW5fZHJtX2Zyb250X2luZm8gKmZyb250X2luZm8sCj4gPiA+ICAgCQl1aW50NjRfdCBk YnVmX2Nvb2tpZSkKPiA+ID4gICB7Cj4gPiA+IC0JcmV0dXJuIDA7Cj4gPiA+ICsJc3RydWN0IHhl bl9kcm1fZnJvbnRfZXZ0Y2hubCAqZXZ0Y2hubDsKPiA+ID4gKwlzdHJ1Y3QgeGVuZGlzcGxfcmVx ICpyZXE7Cj4gPiA+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsKPiA+ID4gKwlib29sIGJlX2FsbG9j Owo+ID4gPiArCWludCByZXQ7Cj4gPiA+ICsKPiA+ID4gKwlldnRjaG5sID0gJmZyb250X2luZm8t PmV2dF9wYWlyc1tHRU5FUklDX09QX0VWVF9DSE5MXS5yZXE7Cj4gPiA+ICsJaWYgKHVubGlrZWx5 KCFldnRjaG5sKSkKPiA+ID4gKwkJcmV0dXJuIC1FSU87Cj4gPiA+ICsKPiA+ID4gKwliZV9hbGxv YyA9IGZyb250X2luZm8tPmNmZy5iZV9hbGxvYzsKPiA+ID4gKwo+ID4gPiArCS8qCj4gPiA+ICsJ ICogZm9yIHRoZSBiYWNrZW5kIGFsbG9jYXRlZCBidWZmZXIgcmVsZWFzZSByZWZlcmVuY2VzIG5v dywgc28gYmFja2VuZAo+ID4gPiArCSAqIGNhbiBmcmVlIHRoZSBidWZmZXIKPiA+ID4gKwkgKi8K PiA+ID4gKwlpZiAoYmVfYWxsb2MpCj4gPiA+ICsJCWRidWZfZnJlZSgmZnJvbnRfaW5mby0+ZGJ1 Zl9saXN0LCBkYnVmX2Nvb2tpZSk7Cj4gPiA+ICsKPiA+ID4gKwltdXRleF9sb2NrKCZmcm9udF9p bmZvLT5yZXFfaW9fbG9jayk7Cj4gPiA+ICsKPiA+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmZnJv bnRfaW5mby0+aW9fbG9jaywgZmxhZ3MpOwo+ID4gPiArCXJlcSA9IGJlX3ByZXBhcmVfcmVxKGV2 dGNobmwsIFhFTkRJU1BMX09QX0RCVUZfREVTVFJPWSk7Cj4gPiA+ICsJcmVxLT5vcC5kYnVmX2Rl c3Ryb3kuZGJ1Zl9jb29raWUgPSBkYnVmX2Nvb2tpZTsKPiA+ID4gKwo+ID4gPiArCXJldCA9IGJl X3N0cmVhbV9kb19pbyhldnRjaG5sLCByZXEpOwo+ID4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3Rv cmUoJmZyb250X2luZm8tPmlvX2xvY2ssIGZsYWdzKTsKPiA+ID4gKwo+ID4gPiArCWlmIChyZXQg PT0gMCkKPiA+ID4gKwkJcmV0ID0gYmVfc3RyZWFtX3dhaXRfaW8oZXZ0Y2hubCk7Cj4gPiA+ICsK PiA+ID4gKwkvKgo+ID4gPiArCSAqIGRvIHRoaXMgcmVnYXJkbGVzcyBvZiBjb21tdW5pY2F0aW9u IHN0YXR1cyB3aXRoIHRoZSBiYWNrZW5kOgo+ID4gPiArCSAqIGlmIHdlIGNhbm5vdCByZW1vdmUg cmVtb3RlIHJlc291cmNlcyByZW1vdmUgd2hhdCB3ZSBjYW4gbG9jYWxseQo+ID4gPiArCSAqLwo+ ID4gPiArCWlmICghYmVfYWxsb2MpCj4gPiA+ICsJCWRidWZfZnJlZSgmZnJvbnRfaW5mby0+ZGJ1 Zl9saXN0LCBkYnVmX2Nvb2tpZSk7Cj4gPiA+ICsKPiA+ID4gKwltdXRleF91bmxvY2soJmZyb250 X2luZm8tPnJlcV9pb19sb2NrKTsKPiA+ID4gKwlyZXR1cm4gcmV0Owo+ID4gPiAgIH0KPiA+ID4g ICBzdGF0aWMgaW50IGJlX2ZiX2F0dGFjaChzdHJ1Y3QgeGVuX2RybV9mcm9udF9pbmZvICpmcm9u dF9pbmZvLAo+ID4gPiAgIAkJdWludDY0X3QgZGJ1Zl9jb29raWUsIHVpbnQ2NF90IGZiX2Nvb2tp ZSwgdWludDMyX3Qgd2lkdGgsCj4gPiA+ICAgCQl1aW50MzJfdCBoZWlnaHQsIHVpbnQzMl90IHBp eGVsX2Zvcm1hdCkKPiA+ID4gICB7Cj4gPiA+IC0JcmV0dXJuIDA7Cj4gPiA+ICsJc3RydWN0IHhl bl9kcm1fZnJvbnRfZXZ0Y2hubCAqZXZ0Y2hubDsKPiA+ID4gKwlzdHJ1Y3QgeGVuX2RybV9mcm9u dF9kYnVmICpidWY7Cj4gPiA+ICsJc3RydWN0IHhlbmRpc3BsX3JlcSAqcmVxOwo+ID4gPiArCXVu c2lnbmVkIGxvbmcgZmxhZ3M7Cj4gPiA+ICsJaW50IHJldDsKPiA+ID4gKwo+ID4gPiArCWV2dGNo bmwgPSAmZnJvbnRfaW5mby0+ZXZ0X3BhaXJzW0dFTkVSSUNfT1BfRVZUX0NITkxdLnJlcTsKPiA+ ID4gKwlpZiAodW5saWtlbHkoIWV2dGNobmwpKQo+ID4gPiArCQlyZXR1cm4gLUVJTzsKPiA+ID4g Kwo+ID4gPiArCWJ1ZiA9IGRidWZfZ2V0KCZmcm9udF9pbmZvLT5kYnVmX2xpc3QsIGRidWZfY29v a2llKTsKPiA+ID4gKwlpZiAoIWJ1ZikKPiA+ID4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gPiA+ICsK PiA+ID4gKwlidWYtPmZiX2Nvb2tpZSA9IGZiX2Nvb2tpZTsKPiA+ID4gKwo+ID4gPiArCW11dGV4 X2xvY2soJmZyb250X2luZm8tPnJlcV9pb19sb2NrKTsKPiA+ID4gKwo+ID4gPiArCXNwaW5fbG9j a19pcnFzYXZlKCZmcm9udF9pbmZvLT5pb19sb2NrLCBmbGFncyk7Cj4gPiA+ICsJcmVxID0gYmVf cHJlcGFyZV9yZXEoZXZ0Y2hubCwgWEVORElTUExfT1BfRkJfQVRUQUNIKTsKPiA+ID4gKwlyZXEt Pm9wLmZiX2F0dGFjaC5kYnVmX2Nvb2tpZSA9IGRidWZfY29va2llOwo+ID4gPiArCXJlcS0+b3Au ZmJfYXR0YWNoLmZiX2Nvb2tpZSA9IGZiX2Nvb2tpZTsKPiA+ID4gKwlyZXEtPm9wLmZiX2F0dGFj aC53aWR0aCA9IHdpZHRoOwo+ID4gPiArCXJlcS0+b3AuZmJfYXR0YWNoLmhlaWdodCA9IGhlaWdo dDsKPiA+ID4gKwlyZXEtPm9wLmZiX2F0dGFjaC5waXhlbF9mb3JtYXQgPSBwaXhlbF9mb3JtYXQ7 Cj4gPiA+ICsKPiA+ID4gKwlyZXQgPSBiZV9zdHJlYW1fZG9faW8oZXZ0Y2hubCwgcmVxKTsKPiA+ ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZmcm9udF9pbmZvLT5pb19sb2NrLCBmbGFncyk7 Cj4gPiA+ICsKPiA+ID4gKwlpZiAocmV0ID09IDApCj4gPiA+ICsJCXJldCA9IGJlX3N0cmVhbV93 YWl0X2lvKGV2dGNobmwpOwo+ID4gPiArCj4gPiA+ICsJbXV0ZXhfdW5sb2NrKCZmcm9udF9pbmZv LT5yZXFfaW9fbG9jayk7Cj4gPiA+ICsJcmV0dXJuIHJldDsKPiA+ID4gICB9Cj4gPiA+ICAgc3Rh dGljIGludCBiZV9mYl9kZXRhY2goc3RydWN0IHhlbl9kcm1fZnJvbnRfaW5mbyAqZnJvbnRfaW5m bywKPiA+ID4gICAJCXVpbnQ2NF90IGZiX2Nvb2tpZSkKPiA+ID4gICB7Cj4gPiA+IC0JcmV0dXJu IDA7Cj4gPiA+ICsJc3RydWN0IHhlbl9kcm1fZnJvbnRfZXZ0Y2hubCAqZXZ0Y2hubDsKPiA+ID4g KwlzdHJ1Y3QgeGVuZGlzcGxfcmVxICpyZXE7Cj4gPiA+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsK PiA+ID4gKwlpbnQgcmV0Owo+ID4gPiArCj4gPiA+ICsJZXZ0Y2hubCA9ICZmcm9udF9pbmZvLT5l dnRfcGFpcnNbR0VORVJJQ19PUF9FVlRfQ0hOTF0ucmVxOwo+ID4gPiArCWlmICh1bmxpa2VseSgh ZXZ0Y2hubCkpCj4gPiA+ICsJCXJldHVybiAtRUlPOwo+ID4gPiArCj4gPiA+ICsJbXV0ZXhfbG9j aygmZnJvbnRfaW5mby0+cmVxX2lvX2xvY2spOwo+ID4gPiArCj4gPiA+ICsJc3Bpbl9sb2NrX2ly cXNhdmUoJmZyb250X2luZm8tPmlvX2xvY2ssIGZsYWdzKTsKPiA+ID4gKwlyZXEgPSBiZV9wcmVw YXJlX3JlcShldnRjaG5sLCBYRU5ESVNQTF9PUF9GQl9ERVRBQ0gpOwo+ID4gPiArCXJlcS0+b3Au ZmJfZGV0YWNoLmZiX2Nvb2tpZSA9IGZiX2Nvb2tpZTsKPiA+ID4gKwo+ID4gPiArCXJldCA9IGJl X3N0cmVhbV9kb19pbyhldnRjaG5sLCByZXEpOwo+ID4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3Rv cmUoJmZyb250X2luZm8tPmlvX2xvY2ssIGZsYWdzKTsKPiA+ID4gKwo+ID4gPiArCWlmIChyZXQg PT0gMCkKPiA+ID4gKwkJcmV0ID0gYmVfc3RyZWFtX3dhaXRfaW8oZXZ0Y2hubCk7Cj4gPiA+ICsK PiA+ID4gKwltdXRleF91bmxvY2soJmZyb250X2luZm8tPnJlcV9pb19sb2NrKTsKPiA+ID4gKwly ZXR1cm4gcmV0Owo+ID4gPiAgIH0KPiA+ID4gICBzdGF0aWMgaW50IGJlX3BhZ2VfZmxpcChzdHJ1 Y3QgeGVuX2RybV9mcm9udF9pbmZvICpmcm9udF9pbmZvLCBpbnQgY29ubl9pZHgsCj4gPiA+ICAg CQl1aW50NjRfdCBmYl9jb29raWUpCj4gPiA+ICAgewo+ID4gPiAtCXJldHVybiAwOwo+ID4gPiAr CXN0cnVjdCB4ZW5fZHJtX2Zyb250X2V2dGNobmwgKmV2dGNobmw7Cj4gPiA+ICsJc3RydWN0IHhl bmRpc3BsX3JlcSAqcmVxOwo+ID4gPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gPiA+ICsJaW50 IHJldDsKPiA+ID4gKwo+ID4gPiArCWlmICh1bmxpa2VseShjb25uX2lkeCA+PSBmcm9udF9pbmZv LT5udW1fZXZ0X3BhaXJzKSkKPiA+ID4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gPiA+ICsKPiA+ID4g KwlkYnVmX2ZsdXNoX2ZiKCZmcm9udF9pbmZvLT5kYnVmX2xpc3QsIGZiX2Nvb2tpZSk7Cj4gPiA+ ICsJZXZ0Y2hubCA9ICZmcm9udF9pbmZvLT5ldnRfcGFpcnNbY29ubl9pZHhdLnJlcTsKPiA+ID4g Kwo+ID4gPiArCW11dGV4X2xvY2soJmZyb250X2luZm8tPnJlcV9pb19sb2NrKTsKPiA+ID4gKwo+ ID4gPiArCXNwaW5fbG9ja19pcnFzYXZlKCZmcm9udF9pbmZvLT5pb19sb2NrLCBmbGFncyk7Cj4g PiA+ICsJcmVxID0gYmVfcHJlcGFyZV9yZXEoZXZ0Y2hubCwgWEVORElTUExfT1BfUEdfRkxJUCk7 Cj4gPiA+ICsJcmVxLT5vcC5wZ19mbGlwLmZiX2Nvb2tpZSA9IGZiX2Nvb2tpZTsKPiA+ID4gKwo+ ID4gPiArCXJldCA9IGJlX3N0cmVhbV9kb19pbyhldnRjaG5sLCByZXEpOwo+ID4gPiArCXNwaW5f dW5sb2NrX2lycXJlc3RvcmUoJmZyb250X2luZm8tPmlvX2xvY2ssIGZsYWdzKTsKPiA+ID4gKwo+ ID4gPiArCWlmIChyZXQgPT0gMCkKPiA+ID4gKwkJcmV0ID0gYmVfc3RyZWFtX3dhaXRfaW8oZXZ0 Y2hubCk7Cj4gPiA+ICsKPiA+ID4gKwltdXRleF91bmxvY2soJmZyb250X2luZm8tPnJlcV9pb19s b2NrKTsKPiA+ID4gKwlyZXR1cm4gcmV0Owo+ID4gPiAgIH0KPiA+ID4gICBzdGF0aWMgdm9pZCB4 ZW5fZHJtX2Rydl91bmxvYWQoc3RydWN0IHhlbl9kcm1fZnJvbnRfaW5mbyAqZnJvbnRfaW5mbykK PiA+ID4gQEAgLTE4Myw2ICs0OTcsNyBAQCBzdGF0aWMgdm9pZCB4ZW5fZHJ2X3JlbW92ZV9pbnRl cm5hbChzdHJ1Y3QgeGVuX2RybV9mcm9udF9pbmZvICpmcm9udF9pbmZvKQo+ID4gPiAgIHsKPiA+ ID4gICAJeGVuX2RybV9kcnZfZGVpbml0KGZyb250X2luZm8pOwo+ID4gPiAgIAl4ZW5fZHJtX2Zy b250X2V2dGNobmxfZnJlZV9hbGwoZnJvbnRfaW5mbyk7Cj4gPiA+ICsJZGJ1Zl9mcmVlX2FsbCgm ZnJvbnRfaW5mby0+ZGJ1Zl9saXN0KTsKPiA+ID4gICB9Cj4gPiA+ICAgc3RhdGljIGludCBiYWNr ZW5kX29uX2luaXR3YWl0KHN0cnVjdCB4ZW5fZHJtX2Zyb250X2luZm8gKmZyb250X2luZm8pCj4g PiA+IEBAIC0zMTAsNiArNjI1LDggQEAgc3RhdGljIGludCB4ZW5fZHJ2X3Byb2JlKHN0cnVjdCB4 ZW5idXNfZGV2aWNlICp4Yl9kZXYsCj4gPiA+ICAgCWZyb250X2luZm8tPnhiX2RldiA9IHhiX2Rl djsKPiA+ID4gICAJc3Bpbl9sb2NrX2luaXQoJmZyb250X2luZm8tPmlvX2xvY2spOwo+ID4gPiAr CW11dGV4X2luaXQoJmZyb250X2luZm8tPnJlcV9pb19sb2NrKTsKPiA+ID4gKwlJTklUX0xJU1Rf SEVBRCgmZnJvbnRfaW5mby0+ZGJ1Zl9saXN0KTsKPiA+ID4gICAJZnJvbnRfaW5mby0+ZHJtX3Bk cnZfcmVnaXN0ZXJlZCA9IGZhbHNlOwo+ID4gPiAgIAlkZXZfc2V0X2RydmRhdGEoJnhiX2Rldi0+ ZGV2LCBmcm9udF9pbmZvKTsKPiA+ID4gICAJcmV0dXJuIHhlbmJ1c19zd2l0Y2hfc3RhdGUoeGJf ZGV2LCBYZW5idXNTdGF0ZUluaXRpYWxpc2luZyk7Cj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuaCBiL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2Ry bV9mcm9udC5oCj4gPiA+IGluZGV4IGM2ZjUyYzg5MjQzNC4uZGIzMmQwMDE0NWQxIDEwMDY0NAo+ ID4gPiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuaAo+ID4gPiArKysg Yi9kcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuaAo+ID4gPiBAQCAtMTM3LDYgKzEz Nyw4IEBAIHN0cnVjdCB4ZW5fZHJtX2Zyb250X2luZm8gewo+ID4gPiAgIAlzdHJ1Y3QgeGVuYnVz X2RldmljZSAqeGJfZGV2Owo+ID4gPiAgIAkvKiB0byBwcm90ZWN0IGRhdGEgYmV0d2VlbiBiYWNr ZW5kIElPIGNvZGUgYW5kIGludGVycnVwdCBoYW5kbGVyICovCj4gPiA+ICAgCXNwaW5sb2NrX3Qg aW9fbG9jazsKPiA+ID4gKwkvKiBzZXJpYWxpemVyIGZvciBiYWNrZW5kIElPOiByZXF1ZXN0L3Jl c3BvbnNlICovCj4gPiA+ICsJc3RydWN0IG11dGV4IHJlcV9pb19sb2NrOwo+ID4gPiAgIAlib29s IGRybV9wZHJ2X3JlZ2lzdGVyZWQ7Cj4gPiA+ICAgCS8qIHZpcnR1YWwgRFJNIHBsYXRmb3JtIGRl dmljZSAqLwo+ID4gPiAgIAlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpkcm1fcGRldjsKPiA+ID4g QEAgLTE0NCw2ICsxNDYsOSBAQCBzdHJ1Y3QgeGVuX2RybV9mcm9udF9pbmZvIHsKPiA+ID4gICAJ aW50IG51bV9ldnRfcGFpcnM7Cj4gPiA+ICAgCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2V2dGNobmxf cGFpciAqZXZ0X3BhaXJzOwo+ID4gPiAgIAlzdHJ1Y3QgeGVuX2RybV9mcm9udF9jZmcgY2ZnOwo+ ID4gPiArCj4gPiA+ICsJLyogZGlzcGxheSBidWZmZXJzICovCj4gPiA+ICsJc3RydWN0IGxpc3Rf aGVhZCBkYnVmX2xpc3Q7Cj4gPiA+ICAgfTsKPiA+ID4gICAjZW5kaWYgLyogX19YRU5fRFJNX0ZS T05UX0hfICovCj4gPiA+IC0tIAo+ID4gPiAyLjcuNAo+ID4gPiAKPiA+ID4gX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KPiA+ID4gZHJpLWRldmVsIG1haWxp bmcgbGlzdAo+ID4gPiBkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCj4gPiA+IGh0dHBz Oi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCj4gCj4g X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KPiBkcmktZGV2 ZWwgbWFpbGluZyBsaXN0Cj4gZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwo+IGh0dHBz Oi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCgotLSAK RGFuaWVsIFZldHRlcgpTb2Z0d2FyZSBFbmdpbmVlciwgSW50ZWwgQ29ycG9yYXRpb24KaHR0cDov L2Jsb2cuZmZ3bGwuY2gKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Au b3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRl dmVsCg==