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.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, 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 A492DC35656 for ; Fri, 21 Feb 2020 14:24:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 533C7208C4 for ; Fri, 21 Feb 2020 14:24:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="XO2u267D" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728824AbgBUOYz (ORCPT ); Fri, 21 Feb 2020 09:24:55 -0500 Received: from esa5.hc3370-68.iphmx.com ([216.71.155.168]:38890 "EHLO esa5.hc3370-68.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728312AbgBUOYy (ORCPT ); Fri, 21 Feb 2020 09:24:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1582295093; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=5V6wc+9mpRmkGpMuMTV0BZEnZVMwxN1rjEGXohUW4aU=; b=XO2u267DmYFgZMPHzg6annFBNSgma9U1RX4+QJ+EHi2RwzPoKSEHhu0f 7UrYpjuUS6FZ5UY5tbTIsHOVFUGcufvpKZBttlkmF1UykzrkrXsNFRoat qCY23xX/IIlbQXZRE1zUXKGlTPmbiGPCm2z8lIHmsuKAJglLanw5s7YxZ Y=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=roger.pau@citrix.com; spf=Pass smtp.mailfrom=roger.pau@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of roger.pau@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of roger.pau@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: y8RSahKbtmuA+ejK3hSCJcCTV55gfvG8rZeZN6TdFVwt04Ma9pf7AlAws+kUAiG0upZFUcg7+/ gUsgrWpPuCp8BFMcGaNAS3INbpdzW9ielDy0b4uKNh1xpMtYbK/obK8NeMDyTsxfyjeUQC8+XT lz/bv7VFxepsDa2CRJe1izjDrWTbhwYZe+tBx6cw/uQ2td/MVMa/AieyA8rvUf9RHc9pgZvvfP emjIhmU535ZkYSo71v6vIWzFBt/g/gVcWFp1rquVByq8voL1a6WEZ2O2Oc18SI2agQw+MzKaCC 0Y4= X-SBRS: 2.7 X-MesageID: 13176928 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.70,468,1574139600"; d="scan'208";a="13176928" Date: Fri, 21 Feb 2020 15:24:45 +0100 From: Roger Pau =?utf-8?B?TW9ubsOp?= To: Anchal Agarwal CC: , , , , , , , , , , , , , , , , , , , , , , , , , , Subject: Re: [RFC PATCH v3 06/12] xen-blkfront: add callbacks for PM suspend and hibernation Message-ID: <20200221142445.GZ4679@Air-de-Roger> References: <890c404c585d7790514527f0c021056a7be6e748.1581721799.git.anchalag@amazon.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline In-Reply-To: <890c404c585d7790514527f0c021056a7be6e748.1581721799.git.anchalag@amazon.com> X-ClientProxiedBy: AMSPEX02CAS01.citrite.net (10.69.22.112) To AMSPEX02CL01.citrite.net (10.69.22.125) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Feb 14, 2020 at 11:25:34PM +0000, Anchal Agarwal wrote: > From: Munehisa Kamata > Add freeze, thaw and restore callbacks for PM suspend and hibernation > support. All frontend drivers that needs to use PM_HIBERNATION/PM_SUSPEND > events, need to implement these xenbus_driver callbacks. > The freeze handler stops a block-layer queue and disconnect the > frontend from the backend while freeing ring_info and associated resources. > The restore handler re-allocates ring_info and re-connect to the > backend, so the rest of the kernel can continue to use the block device > transparently. Also, the handlers are used for both PM suspend and > hibernation so that we can keep the existing suspend/resume callbacks for > Xen suspend without modification. Before disconnecting from backend, > we need to prevent any new IO from being queued and wait for existing > IO to complete. Freeze/unfreeze of the queues will guarantee that there > are no requests in use on the shared ring. > > Note:For older backends,if a backend doesn't have commit'12ea729645ace' > xen/blkback: unmap all persistent grants when frontend gets disconnected, > the frontend may see massive amount of grant table warning when freeing > resources. > [ 36.852659] deferring g.e. 0xf9 (pfn 0xffffffffffffffff) > [ 36.855089] xen:grant_table: WARNING:e.g. 0x112 still in use! > > In this case, persistent grants would need to be disabled. > > [Anchal Changelog: Removed timeout/request during blkfront freeze. > Fixed major part of the code to work with blk-mq] > Signed-off-by: Anchal Agarwal > Signed-off-by: Munehisa Kamata > --- > drivers/block/xen-blkfront.c | 119 ++++++++++++++++++++++++++++++++--- > 1 file changed, 112 insertions(+), 7 deletions(-) > > diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c > index 478120233750..d715ed3cb69a 100644 > --- a/drivers/block/xen-blkfront.c > +++ b/drivers/block/xen-blkfront.c > @@ -47,6 +47,8 @@ > #include > #include > #include > +#include > +#include > > #include > #include > @@ -79,6 +81,8 @@ enum blkif_state { > BLKIF_STATE_DISCONNECTED, > BLKIF_STATE_CONNECTED, > BLKIF_STATE_SUSPENDED, > + BLKIF_STATE_FREEZING, > + BLKIF_STATE_FROZEN > }; > > struct grant { > @@ -220,6 +224,7 @@ struct blkfront_info > struct list_head requests; > struct bio_list bio_list; > struct list_head info_list; > + struct completion wait_backend_disconnected; > }; > > static unsigned int nr_minors; > @@ -261,6 +266,7 @@ static DEFINE_SPINLOCK(minor_lock); > static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo); > static void blkfront_gather_backend_features(struct blkfront_info *info); > static int negotiate_mq(struct blkfront_info *info); > +static void __blkif_free(struct blkfront_info *info); I'm not particularly found of adding underscore prefixes to functions, I would rather use a more descriptive name if possible. blkif_free_{queues/rings} maybe? > > static int get_id_from_freelist(struct blkfront_ring_info *rinfo) > { > @@ -995,6 +1001,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, > info->sector_size = sector_size; > info->physical_sector_size = physical_sector_size; > blkif_set_queue_limits(info); > + init_completion(&info->wait_backend_disconnected); > > return 0; > } > @@ -1218,6 +1225,8 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) > /* Already hold rinfo->ring_lock. */ > static inline void kick_pending_request_queues_locked(struct blkfront_ring_info *rinfo) > { > + if (unlikely(rinfo->dev_info->connected == BLKIF_STATE_FREEZING)) > + return; Do you really need this check here? The queue will be frozen and quiesced in blkfront_freeze when the state is set to BLKIF_STATE_FREEZING, and then the call to blk_mq_start_stopped_hw_queues is just a noop as long as the queue is quiesced (see blk_mq_run_hw_queue). > if (!RING_FULL(&rinfo->ring)) > blk_mq_start_stopped_hw_queues(rinfo->dev_info->rq, true); > } > @@ -1341,8 +1350,6 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) > > static void blkif_free(struct blkfront_info *info, int suspend) > { > - unsigned int i; > - > /* Prevent new requests being issued until we fix things up. */ > info->connected = suspend ? > BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED; > @@ -1350,6 +1357,13 @@ static void blkif_free(struct blkfront_info *info, int suspend) > if (info->rq) > blk_mq_stop_hw_queues(info->rq); > > + __blkif_free(info); > +} > + > +static void __blkif_free(struct blkfront_info *info) > +{ > + unsigned int i; > + > for (i = 0; i < info->nr_rings; i++) > blkif_free_ring(&info->rinfo[i]); > > @@ -1553,8 +1567,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) > struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id; > struct blkfront_info *info = rinfo->dev_info; > > - if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) > - return IRQ_HANDLED; > + if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { > + if (info->connected != BLKIF_STATE_FREEZING) Please fold this into the previous if condition: if (unlikely(info->connected != BLKIF_STATE_CONNECTED && info->connected != BLKIF_STATE_FREEZING)) return IRQ_HANDLED; > + } > > spin_lock_irqsave(&rinfo->ring_lock, flags); > again: > @@ -2020,6 +2036,7 @@ static int blkif_recover(struct blkfront_info *info) > struct bio *bio; > unsigned int segs; > > + bool frozen = info->connected == BLKIF_STATE_FROZEN; Please place this together with the rest of the local variable declarations. > blkfront_gather_backend_features(info); > /* Reset limits changed by blk_mq_update_nr_hw_queues(). */ > blkif_set_queue_limits(info); > @@ -2046,6 +2063,9 @@ static int blkif_recover(struct blkfront_info *info) > kick_pending_request_queues(rinfo); > } > > + if (frozen) > + return 0; I have to admit my memory is fuzzy here, but don't you need to re-queue requests in case the backend has different limits of indirect descriptors per request for example? Or do we expect that the frontend is always going to be resumed on the same backend, and thus features won't change? > + > list_for_each_entry_safe(req, n, &info->requests, queuelist) { > /* Requeue pending requests (flush or discard) */ > list_del_init(&req->queuelist); > @@ -2359,6 +2379,7 @@ static void blkfront_connect(struct blkfront_info *info) > > return; > case BLKIF_STATE_SUSPENDED: > + case BLKIF_STATE_FROZEN: > /* > * If we are recovering from suspension, we need to wait > * for the backend to announce it's features before > @@ -2476,12 +2497,37 @@ static void blkback_changed(struct xenbus_device *dev, > break; > > case XenbusStateClosed: > - if (dev->state == XenbusStateClosed) > + if (dev->state == XenbusStateClosed) { > + if (info->connected == BLKIF_STATE_FREEZING) { > + __blkif_free(info); > + info->connected = BLKIF_STATE_FROZEN; > + complete(&info->wait_backend_disconnected); > + break; > + } > + > break; > + } > + > + /* > + * We may somehow receive backend's Closed again while thawing > + * or restoring and it causes thawing or restoring to fail. > + * Ignore such unexpected state anyway. > + */ > + if (info->connected == BLKIF_STATE_FROZEN && > + dev->state == XenbusStateInitialised) { I'm not sure you need the extra dev->state == XenbusStateInitialised. If the frotnend is in state BLKIF_STATE_FROZEN you can likely ignore the notification of the backend switched to closed state, regardless of the frontend state? > + dev_dbg(&dev->dev, > + "ignore the backend's Closed state: %s", > + dev->nodename); > + break; > + } > /* fall through */ > case XenbusStateClosing: > - if (info) > - blkfront_closing(info); > + if (info) { > + if (info->connected == BLKIF_STATE_FREEZING) > + xenbus_frontend_closed(dev); > + else > + blkfront_closing(info); > + } > break; > } > } > @@ -2625,6 +2671,62 @@ static void blkif_release(struct gendisk *disk, fmode_t mode) > mutex_unlock(&blkfront_mutex); > } > > +static int blkfront_freeze(struct xenbus_device *dev) > +{ > + unsigned int i; > + struct blkfront_info *info = dev_get_drvdata(&dev->dev); > + struct blkfront_ring_info *rinfo; > + /* This would be reasonable timeout as used in xenbus_dev_shutdown() */ > + unsigned int timeout = 5 * HZ; > + int err = 0; > + > + info->connected = BLKIF_STATE_FREEZING; > + > + blk_mq_freeze_queue(info->rq); > + blk_mq_quiesce_queue(info->rq); Don't you need to also drain the queue and make sure it's empty? > + > + for (i = 0; i < info->nr_rings; i++) { > + rinfo = &info->rinfo[i]; > + > + gnttab_cancel_free_callback(&rinfo->callback); > + flush_work(&rinfo->work); > + } > + > + /* Kick the backend to disconnect */ > + xenbus_switch_state(dev, XenbusStateClosing); > + > + /* > + * We don't want to move forward before the frontend is diconnected > + * from the backend cleanly. > + */ > + timeout = wait_for_completion_timeout(&info->wait_backend_disconnected, > + timeout); > + if (!timeout) { > + err = -EBUSY; > + xenbus_dev_error(dev, err, "Freezing timed out;" > + "the device may become inconsistent state"); > + } > + > + return err; > +} > + > +static int blkfront_restore(struct xenbus_device *dev) > +{ > + struct blkfront_info *info = dev_get_drvdata(&dev->dev); > + int err = 0; > + > + err = talk_to_blkback(dev, info); > + blk_mq_unquiesce_queue(info->rq); > + blk_mq_unfreeze_queue(info->rq); > + > + if (err) > + goto out; There's no need for an out label here, just return err, or even simpler: if (!err) blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings); return err; Thanks, Roger. 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.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 CE7FBC35646 for ; Fri, 21 Feb 2020 14:25:09 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (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 93952208C4 for ; Fri, 21 Feb 2020 14:25:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="FcJht7ZC" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 93952208C4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1j59Ef-0000Wo-2M; Fri, 21 Feb 2020 14:24:57 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1j59Ed-0000Wc-S0 for xen-devel@lists.xenproject.org; Fri, 21 Feb 2020 14:24:55 +0000 X-Inumbo-ID: ed854448-54b5-11ea-8681-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id ed854448-54b5-11ea-8681-12813bfff9fa; Fri, 21 Feb 2020 14:24:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1582295094; h=date:from:to:cc:subject:message-id:references: mime-version:in-reply-to; bh=5V6wc+9mpRmkGpMuMTV0BZEnZVMwxN1rjEGXohUW4aU=; b=FcJht7ZCvGG7BM40G4UOlv9aF+pkskgIDeOVWlaF2Dwnd5ZsS0diTURj Y8x779HWRynmolZiVfVycpuv2/cCJBiaLX7b423ELjAcv+huDuL9pyBBc xtZ5QnWdvoB61Tlr1s8OGpWPHE/d0tnw4G1y0u4ASzZUhWmTZvboXwTsZ M=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=roger.pau@citrix.com; spf=Pass smtp.mailfrom=roger.pau@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of roger.pau@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of roger.pau@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: y8RSahKbtmuA+ejK3hSCJcCTV55gfvG8rZeZN6TdFVwt04Ma9pf7AlAws+kUAiG0upZFUcg7+/ gUsgrWpPuCp8BFMcGaNAS3INbpdzW9ielDy0b4uKNh1xpMtYbK/obK8NeMDyTsxfyjeUQC8+XT lz/bv7VFxepsDa2CRJe1izjDrWTbhwYZe+tBx6cw/uQ2td/MVMa/AieyA8rvUf9RHc9pgZvvfP emjIhmU535ZkYSo71v6vIWzFBt/g/gVcWFp1rquVByq8voL1a6WEZ2O2Oc18SI2agQw+MzKaCC 0Y4= X-SBRS: 2.7 X-MesageID: 13176928 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.70,468,1574139600"; d="scan'208";a="13176928" Date: Fri, 21 Feb 2020 15:24:45 +0100 From: Roger Pau =?utf-8?B?TW9ubsOp?= To: Anchal Agarwal Message-ID: <20200221142445.GZ4679@Air-de-Roger> References: <890c404c585d7790514527f0c021056a7be6e748.1581721799.git.anchalag@amazon.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <890c404c585d7790514527f0c021056a7be6e748.1581721799.git.anchalag@amazon.com> X-ClientProxiedBy: AMSPEX02CAS01.citrite.net (10.69.22.112) To AMSPEX02CL01.citrite.net (10.69.22.125) Subject: Re: [Xen-devel] [RFC PATCH v3 06/12] xen-blkfront: add callbacks for PM suspend and hibernation X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: eduval@amazon.com, len.brown@intel.com, peterz@infradead.org, benh@kernel.crashing.org, x86@kernel.org, linux-mm@kvack.org, pavel@ucw.cz, hpa@zytor.com, tglx@linutronix.de, sstabellini@kernel.org, fllinden@amaozn.com, kamatam@amazon.com, mingo@redhat.com, xen-devel@lists.xenproject.org, sblbir@amazon.com, axboe@kernel.dk, konrad.wilk@oracle.com, bp@alien8.de, boris.ostrovsky@oracle.com, jgross@suse.com, netdev@vger.kernel.org, linux-pm@vger.kernel.org, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, vkuznets@redhat.com, davem@davemloft.net, dwmw@amazon.co.uk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" T24gRnJpLCBGZWIgMTQsIDIwMjAgYXQgMTE6MjU6MzRQTSArMDAwMCwgQW5jaGFsIEFnYXJ3YWwg d3JvdGU6Cj4gRnJvbTogTXVuZWhpc2EgS2FtYXRhIDxrYW1hdGFtQGFtYXpvbi5jb20KPiAKPiBB ZGQgZnJlZXplLCB0aGF3IGFuZCByZXN0b3JlIGNhbGxiYWNrcyBmb3IgUE0gc3VzcGVuZCBhbmQg aGliZXJuYXRpb24KPiBzdXBwb3J0LiBBbGwgZnJvbnRlbmQgZHJpdmVycyB0aGF0IG5lZWRzIHRv IHVzZSBQTV9ISUJFUk5BVElPTi9QTV9TVVNQRU5ECj4gZXZlbnRzLCBuZWVkIHRvIGltcGxlbWVu dCB0aGVzZSB4ZW5idXNfZHJpdmVyIGNhbGxiYWNrcy4KPiBUaGUgZnJlZXplIGhhbmRsZXIgc3Rv cHMgYSBibG9jay1sYXllciBxdWV1ZSBhbmQgZGlzY29ubmVjdCB0aGUKPiBmcm9udGVuZCBmcm9t IHRoZSBiYWNrZW5kIHdoaWxlIGZyZWVpbmcgcmluZ19pbmZvIGFuZCBhc3NvY2lhdGVkIHJlc291 cmNlcy4KPiBUaGUgcmVzdG9yZSBoYW5kbGVyIHJlLWFsbG9jYXRlcyByaW5nX2luZm8gYW5kIHJl LWNvbm5lY3QgdG8gdGhlCj4gYmFja2VuZCwgc28gdGhlIHJlc3Qgb2YgdGhlIGtlcm5lbCBjYW4g Y29udGludWUgdG8gdXNlIHRoZSBibG9jayBkZXZpY2UKPiB0cmFuc3BhcmVudGx5LiBBbHNvLCB0 aGUgaGFuZGxlcnMgYXJlIHVzZWQgZm9yIGJvdGggUE0gc3VzcGVuZCBhbmQKPiBoaWJlcm5hdGlv biBzbyB0aGF0IHdlIGNhbiBrZWVwIHRoZSBleGlzdGluZyBzdXNwZW5kL3Jlc3VtZSBjYWxsYmFj a3MgZm9yCj4gWGVuIHN1c3BlbmQgd2l0aG91dCBtb2RpZmljYXRpb24uIEJlZm9yZSBkaXNjb25u ZWN0aW5nIGZyb20gYmFja2VuZCwKPiB3ZSBuZWVkIHRvIHByZXZlbnQgYW55IG5ldyBJTyBmcm9t IGJlaW5nIHF1ZXVlZCBhbmQgd2FpdCBmb3IgZXhpc3RpbmcKPiBJTyB0byBjb21wbGV0ZS4gRnJl ZXplL3VuZnJlZXplIG9mIHRoZSBxdWV1ZXMgd2lsbCBndWFyYW50ZWUgdGhhdCB0aGVyZQo+IGFy ZSBubyByZXF1ZXN0cyBpbiB1c2Ugb24gdGhlIHNoYXJlZCByaW5nLgo+IAo+IE5vdGU6Rm9yIG9s ZGVyIGJhY2tlbmRzLGlmIGEgYmFja2VuZCBkb2Vzbid0IGhhdmUgY29tbWl0JzEyZWE3Mjk2NDVh Y2UnCj4geGVuL2Jsa2JhY2s6IHVubWFwIGFsbCBwZXJzaXN0ZW50IGdyYW50cyB3aGVuIGZyb250 ZW5kIGdldHMgZGlzY29ubmVjdGVkLAo+IHRoZSBmcm9udGVuZCBtYXkgc2VlIG1hc3NpdmUgYW1v dW50IG9mIGdyYW50IHRhYmxlIHdhcm5pbmcgd2hlbiBmcmVlaW5nCj4gcmVzb3VyY2VzLgo+IFsg ICAzNi44NTI2NTldIGRlZmVycmluZyBnLmUuIDB4ZjkgKHBmbiAweGZmZmZmZmZmZmZmZmZmZmYp Cj4gWyAgIDM2Ljg1NTA4OV0geGVuOmdyYW50X3RhYmxlOiBXQVJOSU5HOmUuZy4gMHgxMTIgc3Rp bGwgaW4gdXNlIQo+IAo+IEluIHRoaXMgY2FzZSwgcGVyc2lzdGVudCBncmFudHMgd291bGQgbmVl ZCB0byBiZSBkaXNhYmxlZC4KPiAKPiBbQW5jaGFsIENoYW5nZWxvZzogUmVtb3ZlZCB0aW1lb3V0 L3JlcXVlc3QgZHVyaW5nIGJsa2Zyb250IGZyZWV6ZS4KPiBGaXhlZCBtYWpvciBwYXJ0IG9mIHRo ZSBjb2RlIHRvIHdvcmsgd2l0aCBibGstbXFdCj4gU2lnbmVkLW9mZi1ieTogQW5jaGFsIEFnYXJ3 YWwgPGFuY2hhbGFnQGFtYXpvbi5jb20+Cj4gU2lnbmVkLW9mZi1ieTogTXVuZWhpc2EgS2FtYXRh IDxrYW1hdGFtQGFtYXpvbi5jb20+Cj4gLS0tCj4gIGRyaXZlcnMvYmxvY2sveGVuLWJsa2Zyb250 LmMgfCAxMTkgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystLS0KPiAgMSBmaWxlIGNo YW5nZWQsIDExMiBpbnNlcnRpb25zKCspLCA3IGRlbGV0aW9ucygtKQo+IAo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL2Jsb2NrL3hlbi1ibGtmcm9udC5jIGIvZHJpdmVycy9ibG9jay94ZW4tYmxrZnJv bnQuYwo+IGluZGV4IDQ3ODEyMDIzMzc1MC4uZDcxNWVkM2NiNjlhIDEwMDY0NAo+IC0tLSBhL2Ry aXZlcnMvYmxvY2sveGVuLWJsa2Zyb250LmMKPiArKysgYi9kcml2ZXJzL2Jsb2NrL3hlbi1ibGtm cm9udC5jCj4gQEAgLTQ3LDYgKzQ3LDggQEAKPiAgI2luY2x1ZGUgPGxpbnV4L2JpdG1hcC5oPgo+ ICAjaW5jbHVkZSA8bGludXgvbGlzdC5oPgo+ICAjaW5jbHVkZSA8bGludXgvd29ya3F1ZXVlLmg+ Cj4gKyNpbmNsdWRlIDxsaW51eC9jb21wbGV0aW9uLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9kZWxh eS5oPgo+ICAKPiAgI2luY2x1ZGUgPHhlbi94ZW4uaD4KPiAgI2luY2x1ZGUgPHhlbi94ZW5idXMu aD4KPiBAQCAtNzksNiArODEsOCBAQCBlbnVtIGJsa2lmX3N0YXRlIHsKPiAgCUJMS0lGX1NUQVRF X0RJU0NPTk5FQ1RFRCwKPiAgCUJMS0lGX1NUQVRFX0NPTk5FQ1RFRCwKPiAgCUJMS0lGX1NUQVRF X1NVU1BFTkRFRCwKPiArCUJMS0lGX1NUQVRFX0ZSRUVaSU5HLAo+ICsJQkxLSUZfU1RBVEVfRlJP WkVOCj4gIH07Cj4gIAo+ICBzdHJ1Y3QgZ3JhbnQgewo+IEBAIC0yMjAsNiArMjI0LDcgQEAgc3Ry dWN0IGJsa2Zyb250X2luZm8KPiAgCXN0cnVjdCBsaXN0X2hlYWQgcmVxdWVzdHM7Cj4gIAlzdHJ1 Y3QgYmlvX2xpc3QgYmlvX2xpc3Q7Cj4gIAlzdHJ1Y3QgbGlzdF9oZWFkIGluZm9fbGlzdDsKPiAr CXN0cnVjdCBjb21wbGV0aW9uIHdhaXRfYmFja2VuZF9kaXNjb25uZWN0ZWQ7Cj4gIH07Cj4gIAo+ ICBzdGF0aWMgdW5zaWduZWQgaW50IG5yX21pbm9yczsKPiBAQCAtMjYxLDYgKzI2Niw3IEBAIHN0 YXRpYyBERUZJTkVfU1BJTkxPQ0sobWlub3JfbG9jayk7Cj4gIHN0YXRpYyBpbnQgYmxrZnJvbnRf c2V0dXBfaW5kaXJlY3Qoc3RydWN0IGJsa2Zyb250X3JpbmdfaW5mbyAqcmluZm8pOwo+ICBzdGF0 aWMgdm9pZCBibGtmcm9udF9nYXRoZXJfYmFja2VuZF9mZWF0dXJlcyhzdHJ1Y3QgYmxrZnJvbnRf aW5mbyAqaW5mbyk7Cj4gIHN0YXRpYyBpbnQgbmVnb3RpYXRlX21xKHN0cnVjdCBibGtmcm9udF9p bmZvICppbmZvKTsKPiArc3RhdGljIHZvaWQgX19ibGtpZl9mcmVlKHN0cnVjdCBibGtmcm9udF9p bmZvICppbmZvKTsKCkknbSBub3QgcGFydGljdWxhcmx5IGZvdW5kIG9mIGFkZGluZyB1bmRlcnNj b3JlIHByZWZpeGVzIHRvIGZ1bmN0aW9ucywKSSB3b3VsZCByYXRoZXIgdXNlIGEgbW9yZSBkZXNj cmlwdGl2ZSBuYW1lIGlmIHBvc3NpYmxlLgpibGtpZl9mcmVlX3txdWV1ZXMvcmluZ3N9IG1heWJl PwoKPiAgCj4gIHN0YXRpYyBpbnQgZ2V0X2lkX2Zyb21fZnJlZWxpc3Qoc3RydWN0IGJsa2Zyb250 X3JpbmdfaW5mbyAqcmluZm8pCj4gIHsKPiBAQCAtOTk1LDYgKzEwMDEsNyBAQCBzdGF0aWMgaW50 IHhsdmJkX2luaXRfYmxrX3F1ZXVlKHN0cnVjdCBnZW5kaXNrICpnZCwgdTE2IHNlY3Rvcl9zaXpl LAo+ICAJaW5mby0+c2VjdG9yX3NpemUgPSBzZWN0b3Jfc2l6ZTsKPiAgCWluZm8tPnBoeXNpY2Fs X3NlY3Rvcl9zaXplID0gcGh5c2ljYWxfc2VjdG9yX3NpemU7Cj4gIAlibGtpZl9zZXRfcXVldWVf bGltaXRzKGluZm8pOwo+ICsJaW5pdF9jb21wbGV0aW9uKCZpbmZvLT53YWl0X2JhY2tlbmRfZGlz Y29ubmVjdGVkKTsKPiAgCj4gIAlyZXR1cm4gMDsKPiAgfQo+IEBAIC0xMjE4LDYgKzEyMjUsOCBA QCBzdGF0aWMgdm9pZCB4bHZiZF9yZWxlYXNlX2dlbmRpc2soc3RydWN0IGJsa2Zyb250X2luZm8g KmluZm8pCj4gIC8qIEFscmVhZHkgaG9sZCByaW5mby0+cmluZ19sb2NrLiAqLwo+ICBzdGF0aWMg aW5saW5lIHZvaWQga2lja19wZW5kaW5nX3JlcXVlc3RfcXVldWVzX2xvY2tlZChzdHJ1Y3QgYmxr ZnJvbnRfcmluZ19pbmZvICpyaW5mbykKPiAgewo+ICsJaWYgKHVubGlrZWx5KHJpbmZvLT5kZXZf aW5mby0+Y29ubmVjdGVkID09IEJMS0lGX1NUQVRFX0ZSRUVaSU5HKSkKPiArCQlyZXR1cm47CgpE byB5b3UgcmVhbGx5IG5lZWQgdGhpcyBjaGVjayBoZXJlPwoKVGhlIHF1ZXVlIHdpbGwgYmUgZnJv emVuIGFuZCBxdWllc2NlZCBpbiBibGtmcm9udF9mcmVlemUgd2hlbiB0aGUgc3RhdGUKaXMgc2V0 IHRvIEJMS0lGX1NUQVRFX0ZSRUVaSU5HLCBhbmQgdGhlbiB0aGUgY2FsbCB0bwpibGtfbXFfc3Rh cnRfc3RvcHBlZF9od19xdWV1ZXMgaXMganVzdCBhIG5vb3AgYXMgbG9uZyBhcyB0aGUgcXVldWUg aXMKcXVpZXNjZWQgKHNlZSBibGtfbXFfcnVuX2h3X3F1ZXVlKS4KCj4gIAlpZiAoIVJJTkdfRlVM TCgmcmluZm8tPnJpbmcpKQo+ICAJCWJsa19tcV9zdGFydF9zdG9wcGVkX2h3X3F1ZXVlcyhyaW5m by0+ZGV2X2luZm8tPnJxLCB0cnVlKTsKPiAgfQo+IEBAIC0xMzQxLDggKzEzNTAsNiBAQCBzdGF0 aWMgdm9pZCBibGtpZl9mcmVlX3Jpbmcoc3RydWN0IGJsa2Zyb250X3JpbmdfaW5mbyAqcmluZm8p Cj4gIAo+ICBzdGF0aWMgdm9pZCBibGtpZl9mcmVlKHN0cnVjdCBibGtmcm9udF9pbmZvICppbmZv LCBpbnQgc3VzcGVuZCkKPiAgewo+IC0JdW5zaWduZWQgaW50IGk7Cj4gLQo+ICAJLyogUHJldmVu dCBuZXcgcmVxdWVzdHMgYmVpbmcgaXNzdWVkIHVudGlsIHdlIGZpeCB0aGluZ3MgdXAuICovCj4g IAlpbmZvLT5jb25uZWN0ZWQgPSBzdXNwZW5kID8KPiAgCQlCTEtJRl9TVEFURV9TVVNQRU5ERUQg OiBCTEtJRl9TVEFURV9ESVNDT05ORUNURUQ7Cj4gQEAgLTEzNTAsNiArMTM1NywxMyBAQCBzdGF0 aWMgdm9pZCBibGtpZl9mcmVlKHN0cnVjdCBibGtmcm9udF9pbmZvICppbmZvLCBpbnQgc3VzcGVu ZCkKPiAgCWlmIChpbmZvLT5ycSkKPiAgCQlibGtfbXFfc3RvcF9od19xdWV1ZXMoaW5mby0+cnEp Owo+ICAKPiArCV9fYmxraWZfZnJlZShpbmZvKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgX19i bGtpZl9mcmVlKHN0cnVjdCBibGtmcm9udF9pbmZvICppbmZvKQo+ICt7Cj4gKwl1bnNpZ25lZCBp bnQgaTsKPiArCj4gIAlmb3IgKGkgPSAwOyBpIDwgaW5mby0+bnJfcmluZ3M7IGkrKykKPiAgCQli bGtpZl9mcmVlX3JpbmcoJmluZm8tPnJpbmZvW2ldKTsKPiAgCj4gQEAgLTE1NTMsOCArMTU2Nywx MCBAQCBzdGF0aWMgaXJxcmV0dXJuX3QgYmxraWZfaW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRl dl9pZCkKPiAgCXN0cnVjdCBibGtmcm9udF9yaW5nX2luZm8gKnJpbmZvID0gKHN0cnVjdCBibGtm cm9udF9yaW5nX2luZm8gKilkZXZfaWQ7Cj4gIAlzdHJ1Y3QgYmxrZnJvbnRfaW5mbyAqaW5mbyA9 IHJpbmZvLT5kZXZfaW5mbzsKPiAgCj4gLQlpZiAodW5saWtlbHkoaW5mby0+Y29ubmVjdGVkICE9 IEJMS0lGX1NUQVRFX0NPTk5FQ1RFRCkpCj4gLQkJcmV0dXJuIElSUV9IQU5ETEVEOwo+ICsJaWYg KHVubGlrZWx5KGluZm8tPmNvbm5lY3RlZCAhPSBCTEtJRl9TVEFURV9DT05ORUNURUQpKSB7Cj4g KwkJaWYgKGluZm8tPmNvbm5lY3RlZCAhPSBCTEtJRl9TVEFURV9GUkVFWklORykKClBsZWFzZSBm b2xkIHRoaXMgaW50byB0aGUgcHJldmlvdXMgaWYgY29uZGl0aW9uOgoKaWYgKHVubGlrZWx5KGlu Zm8tPmNvbm5lY3RlZCAhPSBCTEtJRl9TVEFURV9DT05ORUNURUQgJiYKICAgICAgICAgICAgIGlu Zm8tPmNvbm5lY3RlZCAhPSBCTEtJRl9TVEFURV9GUkVFWklORykpCglyZXR1cm4gSVJRX0hBTkRM RUQ7Cgo+ICsJfQo+ICAKPiAgCXNwaW5fbG9ja19pcnFzYXZlKCZyaW5mby0+cmluZ19sb2NrLCBm bGFncyk7Cj4gICBhZ2FpbjoKPiBAQCAtMjAyMCw2ICsyMDM2LDcgQEAgc3RhdGljIGludCBibGtp Zl9yZWNvdmVyKHN0cnVjdCBibGtmcm9udF9pbmZvICppbmZvKQo+ICAJc3RydWN0IGJpbyAqYmlv Owo+ICAJdW5zaWduZWQgaW50IHNlZ3M7Cj4gIAo+ICsJYm9vbCBmcm96ZW4gPSBpbmZvLT5jb25u ZWN0ZWQgPT0gQkxLSUZfU1RBVEVfRlJPWkVOOwoKUGxlYXNlIHBsYWNlIHRoaXMgdG9nZXRoZXIg d2l0aCB0aGUgcmVzdCBvZiB0aGUgbG9jYWwgdmFyaWFibGUKZGVjbGFyYXRpb25zLgoKPiAgCWJs a2Zyb250X2dhdGhlcl9iYWNrZW5kX2ZlYXR1cmVzKGluZm8pOwo+ICAJLyogUmVzZXQgbGltaXRz IGNoYW5nZWQgYnkgYmxrX21xX3VwZGF0ZV9ucl9od19xdWV1ZXMoKS4gKi8KPiAgCWJsa2lmX3Nl dF9xdWV1ZV9saW1pdHMoaW5mbyk7Cj4gQEAgLTIwNDYsNiArMjA2Myw5IEBAIHN0YXRpYyBpbnQg YmxraWZfcmVjb3ZlcihzdHJ1Y3QgYmxrZnJvbnRfaW5mbyAqaW5mbykKPiAgCQlraWNrX3BlbmRp bmdfcmVxdWVzdF9xdWV1ZXMocmluZm8pOwo+ICAJfQo+ICAKPiArCWlmIChmcm96ZW4pCj4gKwkJ cmV0dXJuIDA7CgpJIGhhdmUgdG8gYWRtaXQgbXkgbWVtb3J5IGlzIGZ1enp5IGhlcmUsIGJ1dCBk b24ndCB5b3UgbmVlZCB0bwpyZS1xdWV1ZSByZXF1ZXN0cyBpbiBjYXNlIHRoZSBiYWNrZW5kIGhh cyBkaWZmZXJlbnQgbGltaXRzIG9mIGluZGlyZWN0CmRlc2NyaXB0b3JzIHBlciByZXF1ZXN0IGZv ciBleGFtcGxlPwoKT3IgZG8gd2UgZXhwZWN0IHRoYXQgdGhlIGZyb250ZW5kIGlzIGFsd2F5cyBn b2luZyB0byBiZSByZXN1bWVkIG9uIHRoZQpzYW1lIGJhY2tlbmQsIGFuZCB0aHVzIGZlYXR1cmVz IHdvbid0IGNoYW5nZT8KCj4gKwo+ICAJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKHJlcSwgbiwg JmluZm8tPnJlcXVlc3RzLCBxdWV1ZWxpc3QpIHsKPiAgCQkvKiBSZXF1ZXVlIHBlbmRpbmcgcmVx dWVzdHMgKGZsdXNoIG9yIGRpc2NhcmQpICovCj4gIAkJbGlzdF9kZWxfaW5pdCgmcmVxLT5xdWV1 ZWxpc3QpOwo+IEBAIC0yMzU5LDYgKzIzNzksNyBAQCBzdGF0aWMgdm9pZCBibGtmcm9udF9jb25u ZWN0KHN0cnVjdCBibGtmcm9udF9pbmZvICppbmZvKQo+ICAKPiAgCQlyZXR1cm47Cj4gIAljYXNl IEJMS0lGX1NUQVRFX1NVU1BFTkRFRDoKPiArCWNhc2UgQkxLSUZfU1RBVEVfRlJPWkVOOgo+ICAJ CS8qCj4gIAkJICogSWYgd2UgYXJlIHJlY292ZXJpbmcgZnJvbSBzdXNwZW5zaW9uLCB3ZSBuZWVk IHRvIHdhaXQKPiAgCQkgKiBmb3IgdGhlIGJhY2tlbmQgdG8gYW5ub3VuY2UgaXQncyBmZWF0dXJl cyBiZWZvcmUKPiBAQCAtMjQ3NiwxMiArMjQ5NywzNyBAQCBzdGF0aWMgdm9pZCBibGtiYWNrX2No YW5nZWQoc3RydWN0IHhlbmJ1c19kZXZpY2UgKmRldiwKPiAgCQlicmVhazsKPiAgCj4gIAljYXNl IFhlbmJ1c1N0YXRlQ2xvc2VkOgo+IC0JCWlmIChkZXYtPnN0YXRlID09IFhlbmJ1c1N0YXRlQ2xv c2VkKQo+ICsJCWlmIChkZXYtPnN0YXRlID09IFhlbmJ1c1N0YXRlQ2xvc2VkKSB7Cj4gKwkJCWlm IChpbmZvLT5jb25uZWN0ZWQgPT0gQkxLSUZfU1RBVEVfRlJFRVpJTkcpIHsKPiArCQkJCV9fYmxr aWZfZnJlZShpbmZvKTsKPiArCQkJCWluZm8tPmNvbm5lY3RlZCA9IEJMS0lGX1NUQVRFX0ZST1pF TjsKPiArCQkJCWNvbXBsZXRlKCZpbmZvLT53YWl0X2JhY2tlbmRfZGlzY29ubmVjdGVkKTsKPiAr CQkJCWJyZWFrOwo+ICsJCQl9Cj4gKwo+ICAJCQlicmVhazsKPiArCQl9Cj4gKwo+ICsJCS8qCj4g KwkJICogV2UgbWF5IHNvbWVob3cgcmVjZWl2ZSBiYWNrZW5kJ3MgQ2xvc2VkIGFnYWluIHdoaWxl IHRoYXdpbmcKPiArCQkgKiBvciByZXN0b3JpbmcgYW5kIGl0IGNhdXNlcyB0aGF3aW5nIG9yIHJl c3RvcmluZyB0byBmYWlsLgo+ICsJCSAqIElnbm9yZSBzdWNoIHVuZXhwZWN0ZWQgc3RhdGUgYW55 d2F5Lgo+ICsJCSAqLwo+ICsJCWlmIChpbmZvLT5jb25uZWN0ZWQgPT0gQkxLSUZfU1RBVEVfRlJP WkVOICYmCj4gKwkJCQlkZXYtPnN0YXRlID09IFhlbmJ1c1N0YXRlSW5pdGlhbGlzZWQpIHsKCkkn bSBub3Qgc3VyZSB5b3UgbmVlZCB0aGUgZXh0cmEgZGV2LT5zdGF0ZSA9PSBYZW5idXNTdGF0ZUlu aXRpYWxpc2VkLgpJZiB0aGUgZnJvdG5lbmQgaXMgaW4gc3RhdGUgQkxLSUZfU1RBVEVfRlJPWkVO IHlvdSBjYW4gbGlrZWx5IGlnbm9yZQp0aGUgbm90aWZpY2F0aW9uIG9mIHRoZSBiYWNrZW5kIHN3 aXRjaGVkIHRvIGNsb3NlZCBzdGF0ZSwgcmVnYXJkbGVzcwpvZiB0aGUgZnJvbnRlbmQgc3RhdGU/ Cgo+ICsJCQlkZXZfZGJnKCZkZXYtPmRldiwKPiArCQkJCQkiaWdub3JlIHRoZSBiYWNrZW5kJ3Mg Q2xvc2VkIHN0YXRlOiAlcyIsCj4gKwkJCQkJZGV2LT5ub2RlbmFtZSk7Cj4gKwkJCWJyZWFrOwo+ ICsJCX0KPiAgCQkvKiBmYWxsIHRocm91Z2ggKi8KPiAgCWNhc2UgWGVuYnVzU3RhdGVDbG9zaW5n Ogo+IC0JCWlmIChpbmZvKQo+IC0JCQlibGtmcm9udF9jbG9zaW5nKGluZm8pOwo+ICsJCWlmIChp bmZvKSB7Cj4gKwkJCWlmIChpbmZvLT5jb25uZWN0ZWQgPT0gQkxLSUZfU1RBVEVfRlJFRVpJTkcp Cj4gKwkJCQl4ZW5idXNfZnJvbnRlbmRfY2xvc2VkKGRldik7Cj4gKwkJCWVsc2UKPiArCQkJCWJs a2Zyb250X2Nsb3NpbmcoaW5mbyk7Cj4gKwkJfQo+ICAJCWJyZWFrOwo+ICAJfQo+ICB9Cj4gQEAg LTI2MjUsNiArMjY3MSw2MiBAQCBzdGF0aWMgdm9pZCBibGtpZl9yZWxlYXNlKHN0cnVjdCBnZW5k aXNrICpkaXNrLCBmbW9kZV90IG1vZGUpCj4gIAltdXRleF91bmxvY2soJmJsa2Zyb250X211dGV4 KTsKPiAgfQo+ICAKPiArc3RhdGljIGludCBibGtmcm9udF9mcmVlemUoc3RydWN0IHhlbmJ1c19k ZXZpY2UgKmRldikKPiArewo+ICsJdW5zaWduZWQgaW50IGk7Cj4gKwlzdHJ1Y3QgYmxrZnJvbnRf aW5mbyAqaW5mbyA9IGRldl9nZXRfZHJ2ZGF0YSgmZGV2LT5kZXYpOwo+ICsJc3RydWN0IGJsa2Zy b250X3JpbmdfaW5mbyAqcmluZm87Cj4gKwkvKiBUaGlzIHdvdWxkIGJlIHJlYXNvbmFibGUgdGlt ZW91dCBhcyB1c2VkIGluIHhlbmJ1c19kZXZfc2h1dGRvd24oKSAqLwo+ICsJdW5zaWduZWQgaW50 IHRpbWVvdXQgPSA1ICogSFo7Cj4gKwlpbnQgZXJyID0gMDsKPiArCj4gKwlpbmZvLT5jb25uZWN0 ZWQgPSBCTEtJRl9TVEFURV9GUkVFWklORzsKPiArCj4gKwlibGtfbXFfZnJlZXplX3F1ZXVlKGlu Zm8tPnJxKTsKPiArCWJsa19tcV9xdWllc2NlX3F1ZXVlKGluZm8tPnJxKTsKCkRvbid0IHlvdSBu ZWVkIHRvIGFsc28gZHJhaW4gdGhlIHF1ZXVlIGFuZCBtYWtlIHN1cmUgaXQncyBlbXB0eT8KCj4g Kwo+ICsJZm9yIChpID0gMDsgaSA8IGluZm8tPm5yX3JpbmdzOyBpKyspIHsKPiArCQlyaW5mbyA9 ICZpbmZvLT5yaW5mb1tpXTsKPiArCj4gKwkJZ250dGFiX2NhbmNlbF9mcmVlX2NhbGxiYWNrKCZy aW5mby0+Y2FsbGJhY2spOwo+ICsJCWZsdXNoX3dvcmsoJnJpbmZvLT53b3JrKTsKPiArCX0KPiAr Cj4gKwkvKiBLaWNrIHRoZSBiYWNrZW5kIHRvIGRpc2Nvbm5lY3QgKi8KPiArCXhlbmJ1c19zd2l0 Y2hfc3RhdGUoZGV2LCBYZW5idXNTdGF0ZUNsb3NpbmcpOwo+ICsKPiArCS8qCj4gKwkgKiBXZSBk b24ndCB3YW50IHRvIG1vdmUgZm9yd2FyZCBiZWZvcmUgdGhlIGZyb250ZW5kIGlzIGRpY29ubmVj dGVkCj4gKwkgKiBmcm9tIHRoZSBiYWNrZW5kIGNsZWFubHkuCj4gKwkgKi8KPiArCXRpbWVvdXQg PSB3YWl0X2Zvcl9jb21wbGV0aW9uX3RpbWVvdXQoJmluZm8tPndhaXRfYmFja2VuZF9kaXNjb25u ZWN0ZWQsCj4gKwkJCQkJICAgICAgdGltZW91dCk7Cj4gKwlpZiAoIXRpbWVvdXQpIHsKPiArCQll cnIgPSAtRUJVU1k7Cj4gKwkJeGVuYnVzX2Rldl9lcnJvcihkZXYsIGVyciwgIkZyZWV6aW5nIHRp bWVkIG91dDsiCj4gKwkJCQkgInRoZSBkZXZpY2UgbWF5IGJlY29tZSBpbmNvbnNpc3RlbnQgc3Rh dGUiKTsKPiArCX0KPiArCj4gKwlyZXR1cm4gZXJyOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGJs a2Zyb250X3Jlc3RvcmUoc3RydWN0IHhlbmJ1c19kZXZpY2UgKmRldikKPiArewo+ICsJc3RydWN0 IGJsa2Zyb250X2luZm8gKmluZm8gPSBkZXZfZ2V0X2RydmRhdGEoJmRldi0+ZGV2KTsKPiArCWlu dCBlcnIgPSAwOwo+ICsKPiArCWVyciA9IHRhbGtfdG9fYmxrYmFjayhkZXYsIGluZm8pOwo+ICsJ YmxrX21xX3VucXVpZXNjZV9xdWV1ZShpbmZvLT5ycSk7Cj4gKwlibGtfbXFfdW5mcmVlemVfcXVl dWUoaW5mby0+cnEpOwo+ICsKPiArCWlmIChlcnIpCj4gKwkJZ290byBvdXQ7CgpUaGVyZSdzIG5v IG5lZWQgZm9yIGFuIG91dCBsYWJlbCBoZXJlLCBqdXN0IHJldHVybiBlcnIsIG9yIGV2ZW4Kc2lt cGxlcjoKCmlmICghZXJyKQoJYmxrX21xX3VwZGF0ZV9ucl9od19xdWV1ZXMoJmluZm8tPnRhZ19z ZXQsIGluZm8tPm5yX3JpbmdzKTsKCnJldHVybiBlcnI7CgpUaGFua3MsIFJvZ2VyLgoKX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVsIG1haWxp bmcgbGlzdApYZW4tZGV2ZWxAbGlzdHMueGVucHJvamVjdC5vcmcKaHR0cHM6Ly9saXN0cy54ZW5w cm9qZWN0Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL3hlbi1kZXZlbA==