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=-9.7 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 33CE5C3A59F for ; Thu, 29 Aug 2019 16:52:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D9AA12189D for ; Thu, 29 Aug 2019 16:52:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="V0d6iID4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728042AbfH2Qv1 (ORCPT ); Thu, 29 Aug 2019 12:51:27 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:40695 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726973AbfH2Qv0 (ORCPT ); Thu, 29 Aug 2019 12:51:26 -0400 Received: by mail-pf1-f196.google.com with SMTP id w16so2446971pfn.7; Thu, 29 Aug 2019 09:51:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WY14fNnQfDZbwvukjVidd+cNTb3XxlOXu8Bid6B2SsI=; b=V0d6iID4dF1SGAik+Q9+yp6A3FrMtzmS0Vf7bJZitFEbEbKkIfEu+xubaEJzyCBzoJ /ro6QoEoOcOvxNWFLa/K7bjbT8T+8TTPJArGpRxiiYtZrT/9tPkzhKEm7nuQbbbS+9nI 17JHFeD1VcwyRSPuatsS0iZ/fXLZ/Rqm412yflvuAr2PsTwpMbfO/mh03jj6+V2NrxX9 5kK3OJPZssHewZTdpgEL0teRd/HSi28AaUIuLJMxPWgTFjk/u9Dvei5xMOn4Vlg8M2iR cUPiOHPOUkfYJMQUR/Fi+GZX+79TC844f063FJQQR4DVbvveDQAxK1IU8IFq7td7Ssiv lRag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WY14fNnQfDZbwvukjVidd+cNTb3XxlOXu8Bid6B2SsI=; b=W1DPCJdLO9/e/j0o0QPIJuPvyLAlvIsDVGVaZXKqRFcHb8CPk0bcJJQ44pQQCOXbfi dSieAICj+O2pEWQ8BqS5n2xuuvpk6WFiLvZSrULUeVuH31w/Wq8+iUqMORe1eee+B68i ULu0f1IaqeoZVjAg8tw4POBk3b5U2OktQgICdLRM97US79heG24t5NTMqI8PGbuJN3mr YN4/Gor2BkqND2rkDgrc0naLBDQYO9obdaJ08HCPtVsNz9mArpcxn0wtZqYoDMZQzX52 mWVO6UXGVqa8EFoUKtqqL5oJCjjc8WxBoX5eOdYLAMbhw6xY+jHDuuPGj2HoGPC0NIgk Yx4g== X-Gm-Message-State: APjAAAWEH8JjfgftMxf1PRK/1Ho666znC5E5bX+ZP0NAp9Fes8uu3LpW 0ndbtQpHNGnX+WMwYOQauIo= X-Google-Smtp-Source: APXvYqyioGD+VQLXDqjg6l7vqjzi8fvyTO3YfavcIii1CPzairNYKNa/9Py3el/axzHd1iZ5G1A7OQ== X-Received: by 2002:a63:1918:: with SMTP id z24mr8824522pgl.94.1567097484943; Thu, 29 Aug 2019 09:51:24 -0700 (PDT) Received: from localhost ([100.118.89.196]) by smtp.gmail.com with ESMTPSA id y68sm8599981pfy.25.2019.08.29.09.51.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 29 Aug 2019 09:51:24 -0700 (PDT) From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: Rob Clark , Sean Paul , Rob Clark , David Airlie , Daniel Vetter , Jeykumar Sankaran , Bruce Wang , Jordan Crouse , Sravanthi Kollukuduru , Thomas Gleixner , Abhinav Kumar , Allison Randal , Greg Kroah-Hartman , linux-arm-msm@vger.kernel.org (open list:DRM DRIVER FOR MSM ADRENO GPU), freedreno@lists.freedesktop.org (open list:DRM DRIVER FOR MSM ADRENO GPU), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 01/10] drm/msm/dpu: unwind async commit handling Date: Thu, 29 Aug 2019 09:45:09 -0700 Message-Id: <20190829164601.11615-2-robdclark@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190829164601.11615-1-robdclark@gmail.com> References: <20190829164601.11615-1-robdclark@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org From: Rob Clark It attempted to avoid fps drops in the presence of cursor updates. But it is racing, and can result in hw updates after flush before vblank, which leads to underruns. Signed-off-by: Rob Clark Reviewed-by: Sean Paul --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 41 ++++++++++----------- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 39 +++++++------------- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 5 +-- drivers/gpu/drm/msm/msm_atomic.c | 3 +- 6 files changed, 37 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index a52439e029c9..c3f7154017c4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -610,7 +610,7 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) return rc; } -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) { struct drm_encoder *encoder; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); @@ -636,35 +636,32 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) crtc->state->encoder_mask) dpu_encoder_prepare_for_kickoff(encoder); - if (!async) { - /* wait for previous frame_event_done completion */ - DPU_ATRACE_BEGIN("wait_for_frame_done_event"); - ret = _dpu_crtc_wait_for_frame_done(crtc); - DPU_ATRACE_END("wait_for_frame_done_event"); - if (ret) { - DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", - crtc->base.id, - atomic_read(&dpu_crtc->frame_pending)); - goto end; - } + /* wait for previous frame_event_done completion */ + DPU_ATRACE_BEGIN("wait_for_frame_done_event"); + ret = _dpu_crtc_wait_for_frame_done(crtc); + DPU_ATRACE_END("wait_for_frame_done_event"); + if (ret) { + DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", + crtc->base.id, + atomic_read(&dpu_crtc->frame_pending)); + goto end; + } - if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { - /* acquire bandwidth and other resources */ - DPU_DEBUG("crtc%d first commit\n", crtc->base.id); - } else - DPU_DEBUG("crtc%d commit\n", crtc->base.id); + if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { + /* acquire bandwidth and other resources */ + DPU_DEBUG("crtc%d first commit\n", crtc->base.id); + } else + DPU_DEBUG("crtc%d commit\n", crtc->base.id); - dpu_crtc->play_count++; - } + dpu_crtc->play_count++; dpu_vbif_clear_errors(dpu_kms); drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) - dpu_encoder_kickoff(encoder, async); + dpu_encoder_kickoff(encoder); end: - if (!async) - reinit_completion(&dpu_crtc->frame_done_comp); + reinit_completion(&dpu_crtc->frame_done_comp); DPU_ATRACE_END("crtc_commit"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 5181f079a6a1..10f78459f6c2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -238,9 +238,8 @@ void dpu_crtc_vblank_callback(struct drm_crtc *crtc); /** * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc * @crtc: Pointer to drm crtc object - * @async: true if the commit is asynchronous, false otherwise */ -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async); +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc); /** * dpu_crtc_complete_commit - callback signalling completion of current commit diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 627c57594221..ac2d534bf59e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1421,8 +1421,7 @@ static void dpu_encoder_off_work(struct work_struct *work) * extra_flush_bits: Additional bit mask to include in flush trigger */ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, - struct dpu_encoder_phys *phys, uint32_t extra_flush_bits, - bool async) + struct dpu_encoder_phys *phys, uint32_t extra_flush_bits) { struct dpu_hw_ctl *ctl; int pending_kickoff_cnt; @@ -1439,10 +1438,7 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, return; } - if (!async) - pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); - else - pending_kickoff_cnt = atomic_read(&phys->pending_kickoff_cnt); + pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); if (extra_flush_bits && ctl->ops.update_pending_flush) ctl->ops.update_pending_flush(ctl, extra_flush_bits); @@ -1553,8 +1549,7 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) * a time. * dpu_enc: Pointer to virtual encoder structure */ -static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, - bool async) +static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc) { struct dpu_hw_ctl *ctl; uint32_t i, pending_flush; @@ -1581,13 +1576,12 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, * for async commits. So don't set this for async, since it'll * roll over to the next commit. */ - if (!async && phys->split_role != ENC_ROLE_SLAVE) + if (phys->split_role != ENC_ROLE_SLAVE) set_bit(i, dpu_enc->frame_busy_mask); if (!phys->ops.needs_single_flush || !phys->ops.needs_single_flush(phys)) - _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0, - async); + _dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0); else if (ctl->ops.get_pending_flush) pending_flush |= ctl->ops.get_pending_flush(ctl); } @@ -1597,7 +1591,7 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, _dpu_encoder_trigger_flush( &dpu_enc->base, dpu_enc->cur_master, - pending_flush, async); + pending_flush); } _dpu_encoder_trigger_start(dpu_enc->cur_master); @@ -1815,11 +1809,12 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) } } -void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) +void dpu_encoder_kickoff(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; struct dpu_encoder_phys *phys; ktime_t wakeup_time; + unsigned long timeout_ms; unsigned int i; DPU_ATRACE_BEGIN("encoder_kickoff"); @@ -1827,23 +1822,15 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc, bool async) trace_dpu_enc_kickoff(DRMID(drm_enc)); - /* - * Asynchronous frames don't handle FRAME_DONE events. As such, they - * shouldn't enable the frame_done watchdog since it will always time - * out. - */ - if (!async) { - unsigned long timeout_ms; - timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / + timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 / drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode); - atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); - mod_timer(&dpu_enc->frame_done_timer, - jiffies + msecs_to_jiffies(timeout_ms)); - } + atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms); + mod_timer(&dpu_enc->frame_done_timer, + jiffies + msecs_to_jiffies(timeout_ms)); /* All phys encs are ready to go, trigger the kickoff */ - _dpu_encoder_kickoff_phys(dpu_enc, async); + _dpu_encoder_kickoff_phys(dpu_enc); /* allow phys encs to handle any post-kickoff business */ for (i = 0; i < dpu_enc->num_phys_encs; i++) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 997d131c2440..8465b37adf3b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -82,9 +82,8 @@ void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *encoder); * dpu_encoder_kickoff - trigger a double buffer flip of the ctl path * (i.e. ctl flush and start) immediately. * @encoder: encoder pointer - * @async: true if this is an asynchronous commit */ -void dpu_encoder_kickoff(struct drm_encoder *encoder, bool async); +void dpu_encoder_kickoff(struct drm_encoder *encoder); /** * dpu_encoder_wait_for_event - Waits for encoder events diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index b8d264bd15df..31454cc5d8c5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -298,7 +298,7 @@ void dpu_kms_encoder_enable(struct drm_encoder *encoder) continue; trace_dpu_kms_enc_enable(DRMID(crtc)); - dpu_crtc_commit_kickoff(crtc, false); + dpu_crtc_commit_kickoff(crtc); } } @@ -315,8 +315,7 @@ static void dpu_kms_commit(struct msm_kms *kms, struct drm_atomic_state *state) if (crtc->state->active) { trace_dpu_kms_commit(DRMID(crtc)); - dpu_crtc_commit_kickoff(crtc, - state->legacy_cursor_update); + dpu_crtc_commit_kickoff(crtc); } } } diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index dd16babdd8c0..e5aae1645933 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -70,8 +70,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state) kms->funcs->commit(kms, state); } - if (!state->legacy_cursor_update) - msm_atomic_wait_for_commit_done(dev, state); + msm_atomic_wait_for_commit_done(dev, state); kms->funcs->complete_commit(kms, state); -- 2.21.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rob Clark Subject: [PATCH 01/10] drm/msm/dpu: unwind async commit handling Date: Thu, 29 Aug 2019 09:45:09 -0700 Message-ID: <20190829164601.11615-2-robdclark@gmail.com> References: <20190829164601.11615-1-robdclark@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20190829164601.11615-1-robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: freedreno-bounces-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Sender: "Freedreno" To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Cc: Rob Clark , "open list:DRM DRIVER FOR MSM ADRENO GPU" , David Airlie , Greg Kroah-Hartman , Jordan Crouse , Abhinav Kumar , open list , Bruce Wang , Rob Clark , Allison Randal , Daniel Vetter , "open list:DRM DRIVER FOR MSM ADRENO GPU" , Jeykumar Sankaran , Sean Paul , Thomas Gleixner , Sravanthi Kollukuduru List-Id: dri-devel@lists.freedesktop.org RnJvbTogUm9iIENsYXJrIDxyb2JkY2xhcmtAY2hyb21pdW0ub3JnPgoKSXQgYXR0ZW1wdGVkIHRv IGF2b2lkIGZwcyBkcm9wcyBpbiB0aGUgcHJlc2VuY2Ugb2YgY3Vyc29yIHVwZGF0ZXMuICBCdXQK aXQgaXMgcmFjaW5nLCBhbmQgY2FuIHJlc3VsdCBpbiBodyB1cGRhdGVzIGFmdGVyIGZsdXNoIGJl Zm9yZSB2YmxhbmssCndoaWNoIGxlYWRzIHRvIHVuZGVycnVucy4KClNpZ25lZC1vZmYtYnk6IFJv YiBDbGFyayA8cm9iZGNsYXJrQGNocm9taXVtLm9yZz4KUmV2aWV3ZWQtYnk6IFNlYW4gUGF1bCA8 c2VhbkBwb29ybHkucnVuPgotLS0KIGRyaXZlcnMvZ3B1L2RybS9tc20vZGlzcC9kcHUxL2RwdV9j cnRjLmMgICAgfCA0MSArKysrKysrKysrLS0tLS0tLS0tLS0KIGRyaXZlcnMvZ3B1L2RybS9tc20v ZGlzcC9kcHUxL2RwdV9jcnRjLmggICAgfCAgMyArLQogZHJpdmVycy9ncHUvZHJtL21zbS9kaXNw L2RwdTEvZHB1X2VuY29kZXIuYyB8IDM5ICsrKysrKystLS0tLS0tLS0tLS0tCiBkcml2ZXJzL2dw dS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfZW5jb2Rlci5oIHwgIDMgKy0KIGRyaXZlcnMvZ3B1L2Ry bS9tc20vZGlzcC9kcHUxL2RwdV9rbXMuYyAgICAgfCAgNSArLS0KIGRyaXZlcnMvZ3B1L2RybS9t c20vbXNtX2F0b21pYy5jICAgICAgICAgICAgfCAgMyArLQogNiBmaWxlcyBjaGFuZ2VkLCAzNyBp bnNlcnRpb25zKCspLCA1NyBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9k cm0vbXNtL2Rpc3AvZHB1MS9kcHVfY3J0Yy5jIGIvZHJpdmVycy9ncHUvZHJtL21zbS9kaXNwL2Rw dTEvZHB1X2NydGMuYwppbmRleCBhNTI0MzllMDI5YzkuLmMzZjcxNTQwMTdjNCAxMDA2NDQKLS0t IGEvZHJpdmVycy9ncHUvZHJtL21zbS9kaXNwL2RwdTEvZHB1X2NydGMuYworKysgYi9kcml2ZXJz L2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfY3J0Yy5jCkBAIC02MTAsNyArNjEwLDcgQEAgc3Rh dGljIGludCBfZHB1X2NydGNfd2FpdF9mb3JfZnJhbWVfZG9uZShzdHJ1Y3QgZHJtX2NydGMgKmNy dGMpCiAJcmV0dXJuIHJjOwogfQogCi12b2lkIGRwdV9jcnRjX2NvbW1pdF9raWNrb2ZmKHN0cnVj dCBkcm1fY3J0YyAqY3J0YywgYm9vbCBhc3luYykKK3ZvaWQgZHB1X2NydGNfY29tbWl0X2tpY2tv ZmYoc3RydWN0IGRybV9jcnRjICpjcnRjKQogewogCXN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2Rl cjsKIAlzdHJ1Y3QgZHB1X2NydGMgKmRwdV9jcnRjID0gdG9fZHB1X2NydGMoY3J0Yyk7CkBAIC02 MzYsMzUgKzYzNiwzMiBAQCB2b2lkIGRwdV9jcnRjX2NvbW1pdF9raWNrb2ZmKHN0cnVjdCBkcm1f Y3J0YyAqY3J0YywgYm9vbCBhc3luYykKIAkJCQkgIGNydGMtPnN0YXRlLT5lbmNvZGVyX21hc2sp CiAJCWRwdV9lbmNvZGVyX3ByZXBhcmVfZm9yX2tpY2tvZmYoZW5jb2Rlcik7CiAKLQlpZiAoIWFz eW5jKSB7Ci0JCS8qIHdhaXQgZm9yIHByZXZpb3VzIGZyYW1lX2V2ZW50X2RvbmUgY29tcGxldGlv biAqLwotCQlEUFVfQVRSQUNFX0JFR0lOKCJ3YWl0X2Zvcl9mcmFtZV9kb25lX2V2ZW50Iik7Ci0J CXJldCA9IF9kcHVfY3J0Y193YWl0X2Zvcl9mcmFtZV9kb25lKGNydGMpOwotCQlEUFVfQVRSQUNF X0VORCgid2FpdF9mb3JfZnJhbWVfZG9uZV9ldmVudCIpOwotCQlpZiAocmV0KSB7Ci0JCQlEUFVf RVJST1IoImNydGMlZCB3YWl0IGZvciBmcmFtZSBkb25lIGZhaWxlZDtmcmFtZV9wZW5kaW5nJWRc biIsCi0JCQkJCWNydGMtPmJhc2UuaWQsCi0JCQkJCWF0b21pY19yZWFkKCZkcHVfY3J0Yy0+ZnJh bWVfcGVuZGluZykpOwotCQkJZ290byBlbmQ7Ci0JCX0KKwkvKiB3YWl0IGZvciBwcmV2aW91cyBm cmFtZV9ldmVudF9kb25lIGNvbXBsZXRpb24gKi8KKwlEUFVfQVRSQUNFX0JFR0lOKCJ3YWl0X2Zv cl9mcmFtZV9kb25lX2V2ZW50Iik7CisJcmV0ID0gX2RwdV9jcnRjX3dhaXRfZm9yX2ZyYW1lX2Rv bmUoY3J0Yyk7CisJRFBVX0FUUkFDRV9FTkQoIndhaXRfZm9yX2ZyYW1lX2RvbmVfZXZlbnQiKTsK KwlpZiAocmV0KSB7CisJCURQVV9FUlJPUigiY3J0YyVkIHdhaXQgZm9yIGZyYW1lIGRvbmUgZmFp bGVkO2ZyYW1lX3BlbmRpbmclZFxuIiwKKwkJCQljcnRjLT5iYXNlLmlkLAorCQkJCWF0b21pY19y ZWFkKCZkcHVfY3J0Yy0+ZnJhbWVfcGVuZGluZykpOworCQlnb3RvIGVuZDsKKwl9CiAKLQkJaWYg KGF0b21pY19pbmNfcmV0dXJuKCZkcHVfY3J0Yy0+ZnJhbWVfcGVuZGluZykgPT0gMSkgewotCQkJ LyogYWNxdWlyZSBiYW5kd2lkdGggYW5kIG90aGVyIHJlc291cmNlcyAqLwotCQkJRFBVX0RFQlVH KCJjcnRjJWQgZmlyc3QgY29tbWl0XG4iLCBjcnRjLT5iYXNlLmlkKTsKLQkJfSBlbHNlCi0JCQlE UFVfREVCVUcoImNydGMlZCBjb21taXRcbiIsIGNydGMtPmJhc2UuaWQpOworCWlmIChhdG9taWNf aW5jX3JldHVybigmZHB1X2NydGMtPmZyYW1lX3BlbmRpbmcpID09IDEpIHsKKwkJLyogYWNxdWly ZSBiYW5kd2lkdGggYW5kIG90aGVyIHJlc291cmNlcyAqLworCQlEUFVfREVCVUcoImNydGMlZCBm aXJzdCBjb21taXRcbiIsIGNydGMtPmJhc2UuaWQpOworCX0gZWxzZQorCQlEUFVfREVCVUcoImNy dGMlZCBjb21taXRcbiIsIGNydGMtPmJhc2UuaWQpOwogCi0JCWRwdV9jcnRjLT5wbGF5X2NvdW50 Kys7Ci0JfQorCWRwdV9jcnRjLT5wbGF5X2NvdW50Kys7CiAKIAlkcHVfdmJpZl9jbGVhcl9lcnJv cnMoZHB1X2ttcyk7CiAKIAlkcm1fZm9yX2VhY2hfZW5jb2Rlcl9tYXNrKGVuY29kZXIsIGNydGMt PmRldiwgY3J0Yy0+c3RhdGUtPmVuY29kZXJfbWFzaykKLQkJZHB1X2VuY29kZXJfa2lja29mZihl bmNvZGVyLCBhc3luYyk7CisJCWRwdV9lbmNvZGVyX2tpY2tvZmYoZW5jb2Rlcik7CiAKIGVuZDoK LQlpZiAoIWFzeW5jKQotCQlyZWluaXRfY29tcGxldGlvbigmZHB1X2NydGMtPmZyYW1lX2RvbmVf Y29tcCk7CisJcmVpbml0X2NvbXBsZXRpb24oJmRwdV9jcnRjLT5mcmFtZV9kb25lX2NvbXApOwog CURQVV9BVFJBQ0VfRU5EKCJjcnRjX2NvbW1pdCIpOwogfQogCmRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfY3J0Yy5oIGIvZHJpdmVycy9ncHUvZHJtL21zbS9k aXNwL2RwdTEvZHB1X2NydGMuaAppbmRleCA1MTgxZjA3OWE2YTEuLjEwZjc4NDU5ZjZjMiAxMDA2 NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL21zbS9kaXNwL2RwdTEvZHB1X2NydGMuaAorKysgYi9k cml2ZXJzL2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfY3J0Yy5oCkBAIC0yMzgsOSArMjM4LDgg QEAgdm9pZCBkcHVfY3J0Y192YmxhbmtfY2FsbGJhY2soc3RydWN0IGRybV9jcnRjICpjcnRjKTsK IC8qKgogICogZHB1X2NydGNfY29tbWl0X2tpY2tvZmYgLSB0cmlnZ2VyIGtpY2tvZmYgb2YgdGhl IGNvbW1pdCBmb3IgdGhpcyBjcnRjCiAgKiBAY3J0YzogUG9pbnRlciB0byBkcm0gY3J0YyBvYmpl Y3QKLSAqIEBhc3luYzogdHJ1ZSBpZiB0aGUgY29tbWl0IGlzIGFzeW5jaHJvbm91cywgZmFsc2Ug b3RoZXJ3aXNlCiAgKi8KLXZvaWQgZHB1X2NydGNfY29tbWl0X2tpY2tvZmYoc3RydWN0IGRybV9j cnRjICpjcnRjLCBib29sIGFzeW5jKTsKK3ZvaWQgZHB1X2NydGNfY29tbWl0X2tpY2tvZmYoc3Ry dWN0IGRybV9jcnRjICpjcnRjKTsKIAogLyoqCiAgKiBkcHVfY3J0Y19jb21wbGV0ZV9jb21taXQg LSBjYWxsYmFjayBzaWduYWxsaW5nIGNvbXBsZXRpb24gb2YgY3VycmVudCBjb21taXQKZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZGlzcC9kcHUxL2RwdV9lbmNvZGVyLmMgYi9kcml2 ZXJzL2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfZW5jb2Rlci5jCmluZGV4IDYyN2M1NzU5NDIy MS4uYWMyZDUzNGJmNTllIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vbXNtL2Rpc3AvZHB1 MS9kcHVfZW5jb2Rlci5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9tc20vZGlzcC9kcHUxL2RwdV9l bmNvZGVyLmMKQEAgLTE0MjEsOCArMTQyMSw3IEBAIHN0YXRpYyB2b2lkIGRwdV9lbmNvZGVyX29m Zl93b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKICAqIGV4dHJhX2ZsdXNoX2JpdHM6IEFk ZGl0aW9uYWwgYml0IG1hc2sgdG8gaW5jbHVkZSBpbiBmbHVzaCB0cmlnZ2VyCiAgKi8KIHN0YXRp YyB2b2lkIF9kcHVfZW5jb2Rlcl90cmlnZ2VyX2ZsdXNoKHN0cnVjdCBkcm1fZW5jb2RlciAqZHJt X2VuYywKLQkJc3RydWN0IGRwdV9lbmNvZGVyX3BoeXMgKnBoeXMsIHVpbnQzMl90IGV4dHJhX2Zs dXNoX2JpdHMsCi0JCWJvb2wgYXN5bmMpCisJCXN0cnVjdCBkcHVfZW5jb2Rlcl9waHlzICpwaHlz LCB1aW50MzJfdCBleHRyYV9mbHVzaF9iaXRzKQogewogCXN0cnVjdCBkcHVfaHdfY3RsICpjdGw7 CiAJaW50IHBlbmRpbmdfa2lja29mZl9jbnQ7CkBAIC0xNDM5LDEwICsxNDM4LDcgQEAgc3RhdGlj IHZvaWQgX2RwdV9lbmNvZGVyX3RyaWdnZXJfZmx1c2goc3RydWN0IGRybV9lbmNvZGVyICpkcm1f ZW5jLAogCQlyZXR1cm47CiAJfQogCi0JaWYgKCFhc3luYykKLQkJcGVuZGluZ19raWNrb2ZmX2Nu dCA9IGRwdV9lbmNvZGVyX3BoeXNfaW5jX3BlbmRpbmcocGh5cyk7Ci0JZWxzZQotCQlwZW5kaW5n X2tpY2tvZmZfY250ID0gYXRvbWljX3JlYWQoJnBoeXMtPnBlbmRpbmdfa2lja29mZl9jbnQpOwor CXBlbmRpbmdfa2lja29mZl9jbnQgPSBkcHVfZW5jb2Rlcl9waHlzX2luY19wZW5kaW5nKHBoeXMp OwogCiAJaWYgKGV4dHJhX2ZsdXNoX2JpdHMgJiYgY3RsLT5vcHMudXBkYXRlX3BlbmRpbmdfZmx1 c2gpCiAJCWN0bC0+b3BzLnVwZGF0ZV9wZW5kaW5nX2ZsdXNoKGN0bCwgZXh0cmFfZmx1c2hfYml0 cyk7CkBAIC0xNTUzLDggKzE1NDksNyBAQCBzdGF0aWMgdm9pZCBkcHVfZW5jb2Rlcl9oZWxwZXJf aHdfcmVzZXQoc3RydWN0IGRwdV9lbmNvZGVyX3BoeXMgKnBoeXNfZW5jKQogICoJYSB0aW1lLgog ICogZHB1X2VuYzogUG9pbnRlciB0byB2aXJ0dWFsIGVuY29kZXIgc3RydWN0dXJlCiAgKi8KLXN0 YXRpYyB2b2lkIF9kcHVfZW5jb2Rlcl9raWNrb2ZmX3BoeXMoc3RydWN0IGRwdV9lbmNvZGVyX3Zp cnQgKmRwdV9lbmMsCi0JCQkJICAgICAgYm9vbCBhc3luYykKK3N0YXRpYyB2b2lkIF9kcHVfZW5j b2Rlcl9raWNrb2ZmX3BoeXMoc3RydWN0IGRwdV9lbmNvZGVyX3ZpcnQgKmRwdV9lbmMpCiB7CiAJ c3RydWN0IGRwdV9od19jdGwgKmN0bDsKIAl1aW50MzJfdCBpLCBwZW5kaW5nX2ZsdXNoOwpAQCAt MTU4MSwxMyArMTU3NiwxMiBAQCBzdGF0aWMgdm9pZCBfZHB1X2VuY29kZXJfa2lja29mZl9waHlz KHN0cnVjdCBkcHVfZW5jb2Rlcl92aXJ0ICpkcHVfZW5jLAogCQkgKiBmb3IgYXN5bmMgY29tbWl0 cy4gU28gZG9uJ3Qgc2V0IHRoaXMgZm9yIGFzeW5jLCBzaW5jZSBpdCdsbAogCQkgKiByb2xsIG92 ZXIgdG8gdGhlIG5leHQgY29tbWl0LgogCQkgKi8KLQkJaWYgKCFhc3luYyAmJiBwaHlzLT5zcGxp dF9yb2xlICE9IEVOQ19ST0xFX1NMQVZFKQorCQlpZiAocGh5cy0+c3BsaXRfcm9sZSAhPSBFTkNf Uk9MRV9TTEFWRSkKIAkJCXNldF9iaXQoaSwgZHB1X2VuYy0+ZnJhbWVfYnVzeV9tYXNrKTsKIAog CQlpZiAoIXBoeXMtPm9wcy5uZWVkc19zaW5nbGVfZmx1c2ggfHwKIAkJCQkhcGh5cy0+b3BzLm5l ZWRzX3NpbmdsZV9mbHVzaChwaHlzKSkKLQkJCV9kcHVfZW5jb2Rlcl90cmlnZ2VyX2ZsdXNoKCZk cHVfZW5jLT5iYXNlLCBwaHlzLCAweDAsCi0JCQkJCQkgICBhc3luYyk7CisJCQlfZHB1X2VuY29k ZXJfdHJpZ2dlcl9mbHVzaCgmZHB1X2VuYy0+YmFzZSwgcGh5cywgMHgwKTsKIAkJZWxzZSBpZiAo Y3RsLT5vcHMuZ2V0X3BlbmRpbmdfZmx1c2gpCiAJCQlwZW5kaW5nX2ZsdXNoIHw9IGN0bC0+b3Bz LmdldF9wZW5kaW5nX2ZsdXNoKGN0bCk7CiAJfQpAQCAtMTU5Nyw3ICsxNTkxLDcgQEAgc3RhdGlj IHZvaWQgX2RwdV9lbmNvZGVyX2tpY2tvZmZfcGh5cyhzdHJ1Y3QgZHB1X2VuY29kZXJfdmlydCAq ZHB1X2VuYywKIAkJX2RwdV9lbmNvZGVyX3RyaWdnZXJfZmx1c2goCiAJCQkJJmRwdV9lbmMtPmJh c2UsCiAJCQkJZHB1X2VuYy0+Y3VyX21hc3RlciwKLQkJCQlwZW5kaW5nX2ZsdXNoLCBhc3luYyk7 CisJCQkJcGVuZGluZ19mbHVzaCk7CiAJfQogCiAJX2RwdV9lbmNvZGVyX3RyaWdnZXJfc3RhcnQo ZHB1X2VuYy0+Y3VyX21hc3Rlcik7CkBAIC0xODE1LDExICsxODA5LDEyIEBAIHZvaWQgZHB1X2Vu Y29kZXJfcHJlcGFyZV9mb3Jfa2lja29mZihzdHJ1Y3QgZHJtX2VuY29kZXIgKmRybV9lbmMpCiAJ fQogfQogCi12b2lkIGRwdV9lbmNvZGVyX2tpY2tvZmYoc3RydWN0IGRybV9lbmNvZGVyICpkcm1f ZW5jLCBib29sIGFzeW5jKQordm9pZCBkcHVfZW5jb2Rlcl9raWNrb2ZmKHN0cnVjdCBkcm1fZW5j b2RlciAqZHJtX2VuYykKIHsKIAlzdHJ1Y3QgZHB1X2VuY29kZXJfdmlydCAqZHB1X2VuYzsKIAlz dHJ1Y3QgZHB1X2VuY29kZXJfcGh5cyAqcGh5czsKIAlrdGltZV90IHdha2V1cF90aW1lOworCXVu c2lnbmVkIGxvbmcgdGltZW91dF9tczsKIAl1bnNpZ25lZCBpbnQgaTsKIAogCURQVV9BVFJBQ0Vf QkVHSU4oImVuY29kZXJfa2lja29mZiIpOwpAQCAtMTgyNywyMyArMTgyMiwxNSBAQCB2b2lkIGRw dV9lbmNvZGVyX2tpY2tvZmYoc3RydWN0IGRybV9lbmNvZGVyICpkcm1fZW5jLCBib29sIGFzeW5j KQogCiAJdHJhY2VfZHB1X2VuY19raWNrb2ZmKERSTUlEKGRybV9lbmMpKTsKIAotCS8qCi0JICog QXN5bmNocm9ub3VzIGZyYW1lcyBkb24ndCBoYW5kbGUgRlJBTUVfRE9ORSBldmVudHMuIEFzIHN1 Y2gsIHRoZXkKLQkgKiBzaG91bGRuJ3QgZW5hYmxlIHRoZSBmcmFtZV9kb25lIHdhdGNoZG9nIHNp bmNlIGl0IHdpbGwgYWx3YXlzIHRpbWUKLQkgKiBvdXQuCi0JICovCi0JaWYgKCFhc3luYykgewot CQl1bnNpZ25lZCBsb25nIHRpbWVvdXRfbXM7Ci0JCXRpbWVvdXRfbXMgPSBEUFVfRU5DT0RFUl9G UkFNRV9ET05FX1RJTUVPVVRfRlJBTUVTICogMTAwMCAvCisJdGltZW91dF9tcyA9IERQVV9FTkNP REVSX0ZSQU1FX0RPTkVfVElNRU9VVF9GUkFNRVMgKiAxMDAwIC8KIAkJCWRybV9tb2RlX3ZyZWZy ZXNoKCZkcm1fZW5jLT5jcnRjLT5zdGF0ZS0+YWRqdXN0ZWRfbW9kZSk7CiAKLQkJYXRvbWljX3Nl dCgmZHB1X2VuYy0+ZnJhbWVfZG9uZV90aW1lb3V0X21zLCB0aW1lb3V0X21zKTsKLQkJbW9kX3Rp bWVyKCZkcHVfZW5jLT5mcmFtZV9kb25lX3RpbWVyLAotCQkJICBqaWZmaWVzICsgbXNlY3NfdG9f amlmZmllcyh0aW1lb3V0X21zKSk7Ci0JfQorCWF0b21pY19zZXQoJmRwdV9lbmMtPmZyYW1lX2Rv bmVfdGltZW91dF9tcywgdGltZW91dF9tcyk7CisJbW9kX3RpbWVyKCZkcHVfZW5jLT5mcmFtZV9k b25lX3RpbWVyLAorCQkJamlmZmllcyArIG1zZWNzX3RvX2ppZmZpZXModGltZW91dF9tcykpOwog CiAJLyogQWxsIHBoeXMgZW5jcyBhcmUgcmVhZHkgdG8gZ28sIHRyaWdnZXIgdGhlIGtpY2tvZmYg Ki8KLQlfZHB1X2VuY29kZXJfa2lja29mZl9waHlzKGRwdV9lbmMsIGFzeW5jKTsKKwlfZHB1X2Vu Y29kZXJfa2lja29mZl9waHlzKGRwdV9lbmMpOwogCiAJLyogYWxsb3cgcGh5cyBlbmNzIHRvIGhh bmRsZSBhbnkgcG9zdC1raWNrb2ZmIGJ1c2luZXNzICovCiAJZm9yIChpID0gMDsgaSA8IGRwdV9l bmMtPm51bV9waHlzX2VuY3M7IGkrKykgewpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL21z bS9kaXNwL2RwdTEvZHB1X2VuY29kZXIuaCBiL2RyaXZlcnMvZ3B1L2RybS9tc20vZGlzcC9kcHUx L2RwdV9lbmNvZGVyLmgKaW5kZXggOTk3ZDEzMWMyNDQwLi44NDY1YjM3YWRmM2IgMTAwNjQ0Ci0t LSBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZGlzcC9kcHUxL2RwdV9lbmNvZGVyLmgKKysrIGIvZHJp dmVycy9ncHUvZHJtL21zbS9kaXNwL2RwdTEvZHB1X2VuY29kZXIuaApAQCAtODIsOSArODIsOCBA QCB2b2lkIGRwdV9lbmNvZGVyX3RyaWdnZXJfa2lja29mZl9wZW5kaW5nKHN0cnVjdCBkcm1fZW5j b2RlciAqZW5jb2Rlcik7CiAgKiBkcHVfZW5jb2Rlcl9raWNrb2ZmIC0gdHJpZ2dlciBhIGRvdWJs ZSBidWZmZXIgZmxpcCBvZiB0aGUgY3RsIHBhdGgKICAqCShpLmUuIGN0bCBmbHVzaCBhbmQgc3Rh cnQpIGltbWVkaWF0ZWx5LgogICogQGVuY29kZXI6CWVuY29kZXIgcG9pbnRlcgotICogQGFzeW5j Ogl0cnVlIGlmIHRoaXMgaXMgYW4gYXN5bmNocm9ub3VzIGNvbW1pdAogICovCi12b2lkIGRwdV9l bmNvZGVyX2tpY2tvZmYoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyLCBib29sIGFzeW5jKTsK K3ZvaWQgZHB1X2VuY29kZXJfa2lja29mZihzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpOwog CiAvKioKICAqIGRwdV9lbmNvZGVyX3dhaXRfZm9yX2V2ZW50IC0gV2FpdHMgZm9yIGVuY29kZXIg ZXZlbnRzCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfa21z LmMgYi9kcml2ZXJzL2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVfa21zLmMKaW5kZXggYjhkMjY0 YmQxNWRmLi4zMTQ1NGNjNWQ4YzUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9tc20vZGlz cC9kcHUxL2RwdV9rbXMuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vbXNtL2Rpc3AvZHB1MS9kcHVf a21zLmMKQEAgLTI5OCw3ICsyOTgsNyBAQCB2b2lkIGRwdV9rbXNfZW5jb2Rlcl9lbmFibGUoc3Ry dWN0IGRybV9lbmNvZGVyICplbmNvZGVyKQogCQkJY29udGludWU7CiAKIAkJdHJhY2VfZHB1X2tt c19lbmNfZW5hYmxlKERSTUlEKGNydGMpKTsKLQkJZHB1X2NydGNfY29tbWl0X2tpY2tvZmYoY3J0 YywgZmFsc2UpOworCQlkcHVfY3J0Y19jb21taXRfa2lja29mZihjcnRjKTsKIAl9CiB9CiAKQEAg LTMxNSw4ICszMTUsNyBAQCBzdGF0aWMgdm9pZCBkcHVfa21zX2NvbW1pdChzdHJ1Y3QgbXNtX2tt cyAqa21zLCBzdHJ1Y3QgZHJtX2F0b21pY19zdGF0ZSAqc3RhdGUpCiAKIAkJaWYgKGNydGMtPnN0 YXRlLT5hY3RpdmUpIHsKIAkJCXRyYWNlX2RwdV9rbXNfY29tbWl0KERSTUlEKGNydGMpKTsKLQkJ CWRwdV9jcnRjX2NvbW1pdF9raWNrb2ZmKGNydGMsCi0JCQkJCQlzdGF0ZS0+bGVnYWN5X2N1cnNv cl91cGRhdGUpOworCQkJZHB1X2NydGNfY29tbWl0X2tpY2tvZmYoY3J0Yyk7CiAJCX0KIAl9CiB9 CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vbXNtL21zbV9hdG9taWMuYyBiL2RyaXZlcnMv Z3B1L2RybS9tc20vbXNtX2F0b21pYy5jCmluZGV4IGRkMTZiYWJkZDhjMC4uZTVhYWUxNjQ1OTMz IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vbXNtL21zbV9hdG9taWMuYworKysgYi9kcml2 ZXJzL2dwdS9kcm0vbXNtL21zbV9hdG9taWMuYwpAQCAtNzAsOCArNzAsNyBAQCB2b2lkIG1zbV9h dG9taWNfY29tbWl0X3RhaWwoc3RydWN0IGRybV9hdG9taWNfc3RhdGUgKnN0YXRlKQogCQlrbXMt PmZ1bmNzLT5jb21taXQoa21zLCBzdGF0ZSk7CiAJfQogCi0JaWYgKCFzdGF0ZS0+bGVnYWN5X2N1 cnNvcl91cGRhdGUpCi0JCW1zbV9hdG9taWNfd2FpdF9mb3JfY29tbWl0X2RvbmUoZGV2LCBzdGF0 ZSk7CisJbXNtX2F0b21pY193YWl0X2Zvcl9jb21taXRfZG9uZShkZXYsIHN0YXRlKTsKIAogCWtt cy0+ZnVuY3MtPmNvbXBsZXRlX2NvbW1pdChrbXMsIHN0YXRlKTsKIAotLSAKMi4yMS4wCgpfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpGcmVlZHJlbm8gbWFp bGluZyBsaXN0CkZyZWVkcmVub0BsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5m cmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9mcmVlZHJlbm8=