From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751305AbeCHXY6 (ORCPT ); Thu, 8 Mar 2018 18:24:58 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:36030 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751279AbeCHXYc (ORCPT ); Thu, 8 Mar 2018 18:24:32 -0500 From: Lyude Paul To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: Manasi Navare , =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , David Airlie , linux-kernel@vger.kernel.org Subject: [PATCH 6/6] drm/i915: Implement proper fallback training for MST Date: Thu, 8 Mar 2018 18:24:20 -0500 Message-Id: <20180308232421.14049-7-lyude@redhat.com> In-Reply-To: <20180308232421.14049-1-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For a while we actually haven't had any way of retraining MST links with fallback link parameters like we do with SST. While uncommon, certain setups such as my Caldigit TS3 + EVGA MST hub require this since otherwise, they end up getting stuck in an infinite MST retraining loop. MST retraining is somewhat different then SST retraining. While it's possible during the normal link retraining sequence for a hub to indicate bad link status, it's also possible for a hub to only indicate this status through ESI messages and it's possible for this to happen after the initial link training succeeds. This can lead to a pattern that looks like this: - Train MST link - Training completes successfully - MST hub sets Channel EQ failed bit in ESI - Retraining starts - Retraining completes successfully - MST hub sets Channel EQ failed bit in ESI again - Rinse and repeat In these situations, we need to be able to actually trigger fallback link training from the ESI handler as well, along with using the ESI handler during retraining to figure out whether or not our retraining actually succeeded. This gets a bit more complicated since we have to ensure that we don't block the ESI handler at all while doing retraining. If we do, due to DisplayPort's general issues with being sensitive to IRQ latency most MST hubs will just stop responding to us if their interrupts aren't handled in a timely manner. So: move retraining into it's own seperate handler. Running in a seperate handler allows us to avoid stalling the ESI during link retraining, and we can have the ESI signal that the channel EQ bit was cleared through a simple completion struct. Additionally, we take care to stick as much of this into the SST retraining path as possible since sharing is caring. Signed-off-by: Lyude Paul Cc: Manasi Navare Cc: Ville Syrjälä --- drivers/gpu/drm/i915/intel_dp.c | 342 +++++++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_dp_mst.c | 42 ++++- drivers/gpu/drm/i915/intel_drv.h | 8 + 3 files changed, 302 insertions(+), 90 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5645a194de92..7626652732b6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -45,6 +45,8 @@ #define DP_DPRX_ESI_LEN 14 +#define DP_MST_RETRAIN_TIMEOUT (msecs_to_jiffies(100)) + /* Compliance test status bits */ #define INTEL_DP_RESOLUTION_SHIFT_MASK 0 #define INTEL_DP_RESOLUTION_PREFERRED (1 << INTEL_DP_RESOLUTION_SHIFT_MASK) @@ -4224,6 +4226,118 @@ static void intel_dp_handle_test_request(struct intel_dp *intel_dp) DRM_DEBUG_KMS("Could not write test response to sink\n"); } +/* Get a mask of the CRTCs that are running on the given intel_dp struct. For + * MST, this returns a crtc mask containing all of the CRTCs driving + * downstream sinks, for SST it just returns a mask of the attached + * connector's CRTC. + */ +int +intel_dp_get_crtc_mask(struct intel_dp *intel_dp) +{ + struct drm_device *dev = dp_to_dig_port(intel_dp)->base.base.dev; + struct drm_connector *connector; + struct drm_connector_state *conn_state; + struct intel_connector *intel_connector; + struct drm_crtc *crtc; + int crtc_mask = 0; + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + + if (intel_dp->is_mst) { + struct drm_connector_list_iter conn_iter; + + drm_connector_list_iter_begin(dev, &conn_iter); + for_each_intel_connector_iter(intel_connector, &conn_iter) { + if (intel_connector->mst_port != intel_dp) + continue; + + conn_state = intel_connector->base.state; + if (!conn_state->crtc) + continue; + + crtc_mask |= drm_crtc_mask(conn_state->crtc); + } + drm_connector_list_iter_end(&conn_iter); + } else { + connector = &intel_dp->attached_connector->base; + crtc = connector->state->crtc; + + if (crtc) + crtc_mask |= drm_crtc_mask(crtc); + } + + return crtc_mask; +} + +static bool +intel_dp_needs_link_retrain(struct intel_dp *intel_dp, + const u8 esi[DP_DPRX_ESI_LEN]) +{ + u8 buf[max(DP_LINK_STATUS_SIZE, DP_DPRX_ESI_LEN)]; + const u8 *link_status = NULL; + + if (intel_dp->is_mst) { + if (!intel_dp->active_mst_links) + return false; + if (intel_dp->mst_link_is_bad) + return false; + + if (esi) { + link_status = &esi[10]; + } else { + /* We're not running from the ESI handler, so wait a + * little bit to see if the ESI handler lets us know + * that the link status is OK + */ + if (wait_for_completion_timeout( + &intel_dp->mst_retrain_completion, + DP_MST_RETRAIN_TIMEOUT)) + return false; + } + } else { + if (intel_dp->link_trained) + return false; + if (!intel_dp_get_link_status(intel_dp, buf)) + return false; + + link_status = buf; + } + + /* + * Validate the cached values of intel_dp->link_rate and + * intel_dp->lane_count before attempting to retrain. + */ + if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate, + intel_dp->lane_count)) + return false; + + if (link_status) { + return !drm_dp_channel_eq_ok(link_status, + intel_dp->lane_count); + } else { + return true; + } +} + +static inline void +intel_dp_mst_check_link_status(struct intel_dp *intel_dp, + const u8 esi[DP_DPRX_ESI_LEN]) +{ + if (intel_dp_needs_link_retrain(intel_dp, esi)) { + DRM_DEBUG_KMS("Channel EQ failing\n"); + + if (!work_busy(&intel_dp->mst_retrain_work)) { + reinit_completion(&intel_dp->mst_retrain_completion); + schedule_work(&intel_dp->mst_retrain_work); + DRM_DEBUG_KMS("Retraining started\n"); + } + } else if (work_busy(&intel_dp->mst_retrain_work) && + !completion_done(&intel_dp->mst_retrain_completion)) { + DRM_DEBUG_KMS("Channel EQ stable\n"); + complete_all(&intel_dp->mst_retrain_completion); + } +} + static int intel_dp_check_mst_status(struct intel_dp *intel_dp) { @@ -4237,14 +4351,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) bret = intel_dp_get_sink_irq_esi(intel_dp, esi); go_again: if (bret == true) { - - /* check link status - esi[10] = 0x200c */ - if (intel_dp->active_mst_links && - !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { - DRM_DEBUG_KMS("channel EQ not ok, retraining\n"); - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); - } + intel_dp_mst_check_link_status(intel_dp, esi); DRM_DEBUG_KMS("got esi %3ph\n", esi); ret = drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled); @@ -4281,29 +4388,6 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) return -EINVAL; } -static bool -intel_dp_needs_link_retrain(struct intel_dp *intel_dp) -{ - u8 link_status[DP_LINK_STATUS_SIZE]; - - if (!intel_dp->link_trained) - return false; - - if (!intel_dp_get_link_status(intel_dp, link_status)) - return false; - - /* - * Validate the cached values of intel_dp->link_rate and - * intel_dp->lane_count before attempting to retrain. - */ - if (!intel_dp_link_params_valid(intel_dp, intel_dp->link_rate, - intel_dp->lane_count)) - return false; - - /* Retrain if Channel EQ or CR not ok */ - return !drm_dp_channel_eq_ok(link_status, intel_dp->lane_count); -} - /* * If display is now connected check links status, * there has been known issues of link loss triggering @@ -4319,64 +4403,78 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) int intel_dp_retrain_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); - struct intel_connector *connector = intel_dp->attached_connector; - struct drm_connector_state *conn_state; - struct intel_crtc_state *crtc_state; - struct intel_crtc *crtc; + struct drm_crtc *crtc; + struct intel_crtc *intel_crtc; + int crtc_mask, retry_count = 0; int ret; - /* FIXME handle the MST connectors as well */ - - if (!connector || connector->base.status != connector_status_connected) - return 0; - ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, ctx); if (ret) return ret; - conn_state = connector->base.state; - - crtc = to_intel_crtc(conn_state->crtc); - if (!crtc) - return 0; + crtc_mask = intel_dp_get_crtc_mask(intel_dp); + for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) { + struct drm_crtc_state *crtc_state; + struct intel_crtc_state *intel_crtc_state; - ret = drm_modeset_lock(&crtc->base.mutex, ctx); - if (ret) - return ret; + crtc = &intel_crtc->base; + ret = drm_modeset_lock(&crtc->mutex, ctx); + if (ret) + return ret; - crtc_state = to_intel_crtc_state(crtc->base.state); + crtc_state = crtc->state; + intel_crtc_state = to_intel_crtc_state(crtc_state); + WARN_ON(!intel_crtc_has_dp_encoder(intel_crtc_state)); - WARN_ON(!intel_crtc_has_dp_encoder(crtc_state)); + if (crtc_state->commit && + !try_wait_for_completion(&crtc_state->commit->hw_done)) + return 0; + } - if (!crtc_state->base.active) + if (!intel_dp_needs_link_retrain(intel_dp, NULL)) return 0; - if (conn_state->commit && - !try_wait_for_completion(&conn_state->commit->hw_done)) - return 0; + for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) { + intel_set_cpu_fifo_underrun_reporting( + dev_priv, intel_crtc->pipe, false); - if (!intel_dp_needs_link_retrain(intel_dp)) - return 0; + if (intel_crtc->config->has_pch_encoder) { + intel_set_pch_fifo_underrun_reporting( + dev_priv, intel_crtc_pch_transcoder(intel_crtc), + false); + } + } - /* Suppress underruns caused by re-training */ - intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false); - if (crtc->config->has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev_priv, - intel_crtc_pch_transcoder(crtc), false); + do { + if (++retry_count > 5) { + DRM_DEBUG_KMS("Too many retries, can't retrain\n"); + return -EINVAL; + } - intel_dp_start_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); + intel_dp_start_link_train(intel_dp); + intel_dp_stop_link_train(intel_dp); + } while (intel_dp_needs_link_retrain(intel_dp, NULL)); + + /* Wait for things to become stable */ + for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) + intel_wait_for_vblank(dev_priv, intel_crtc->pipe); - /* Keep underrun reporting disabled until things are stable */ - intel_wait_for_vblank(dev_priv, crtc->pipe); + /* Now that we know everything is OK, finally re-enable underrun + * reporting */ + for_each_intel_crtc_mask(dev, intel_crtc, crtc_mask) { + intel_set_cpu_fifo_underrun_reporting( + dev_priv, intel_crtc->pipe, true); - intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true); - if (crtc->config->has_pch_encoder) - intel_set_pch_fifo_underrun_reporting(dev_priv, - intel_crtc_pch_transcoder(crtc), true); + if (intel_crtc->config->has_pch_encoder) { + intel_set_pch_fifo_underrun_reporting( + dev_priv, intel_crtc_pch_transcoder(intel_crtc), + true); + } + } return 0; } @@ -4402,6 +4500,10 @@ static bool intel_dp_hotplug(struct intel_encoder *encoder, changed = intel_encoder_hotplug(encoder, connector); + /* We don't want to end up trying to retrain MST links! */ + if (encoder && enc_to_intel_dp(&encoder->base)->is_mst) + return changed; + drm_modeset_acquire_init(&ctx, 0); for (;;) { @@ -4478,7 +4580,7 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) } /* defer to the hotplug work for link retraining if needed */ - if (intel_dp_needs_link_retrain(intel_dp)) + if (intel_dp_needs_link_retrain(intel_dp, NULL)) return false; if (intel_dp->compliance.test_type == DP_TEST_LINK_TRAINING) { @@ -6266,25 +6368,98 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, return false; } +static void intel_dp_mst_retrain_link_work(struct work_struct *work) +{ + struct drm_modeset_acquire_ctx ctx; + struct intel_dp *intel_dp = container_of(work, typeof(*intel_dp), + mst_retrain_work); + struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_device *dev = intel_encoder->base.dev; + int ret; + bool had_error = false; + + drm_modeset_acquire_init(&ctx, 0); + + for (;;) { + ret = intel_dp_retrain_link(intel_encoder, &ctx); + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + continue; + } + + break; + } + if (!ret) { + DRM_DEBUG_KMS("Retrain complete\n"); + goto out; + } else if (ret == -EIO) { + DRM_ERROR("IO error with sink during retrain? Aborting\n"); + had_error = true; + goto out; + } + + DRM_DEBUG_KMS("Retraining failed with %d, marking link status as bad\n", + ret); + + /* We ran out of retries, if the sink hasn't changed the link rate in + * it's dpcd yet force us to fallback to a lower link rate/count */ + if (ret == -EINVAL) { + ret = intel_dp_get_dpcd(intel_dp); + if (!ret) { + DRM_ERROR("IO error while reading dpcd from sink\n"); + had_error = true; + goto out; + } + + if (intel_dp->link_rate == intel_dp_max_link_rate(intel_dp) && + intel_dp->lane_count == intel_dp_max_lane_count(intel_dp)) { + intel_dp_get_link_train_fallback_values( + intel_dp, intel_dp_max_link_rate(intel_dp), + intel_dp_max_lane_count(intel_dp)); + } + } + + intel_dp->mst_link_is_bad = true; + intel_dp->mst_bw_locked = false; + schedule_work(&intel_dp->modeset_retry_work); +out: + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + if (had_error) + drm_kms_helper_hotplug_event(dev); +} + static void intel_dp_modeset_retry_work_fn(struct work_struct *work) { struct intel_dp *intel_dp = container_of(work, typeof(*intel_dp), modeset_retry_work); - struct drm_connector *connector = &intel_dp->attached_connector->base; + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = intel_dig_port->base.base.dev; + struct drm_connector *connector; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, - connector->name); + mutex_lock(&dev->mode_config.mutex); - /* Grab the locks before changing connector property*/ - mutex_lock(&connector->dev->mode_config.mutex); - /* Set connector link status to BAD and send a Uevent to notify - * userspace to do a modeset. + /* Set the connector link status of all (possibly downstream) ports to + * BAD and send a Uevent to notify userspace to do a modeset. */ - drm_mode_connector_set_link_status_property(connector, - DRM_MODE_LINK_STATUS_BAD); - mutex_unlock(&connector->dev->mode_config.mutex); + if (intel_dp->is_mst) { + drm_dp_mst_topology_mgr_lower_link_rate( + &intel_dp->mst_mgr, + intel_dp_max_link_rate(intel_dp), + intel_dp_max_lane_count(intel_dp)); + } else { + connector = &intel_dp->attached_connector->base; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", + connector->base.id, connector->name); + drm_mode_connector_set_link_status_property( + connector, DRM_MODE_LINK_STATUS_BAD); + } + + mutex_unlock(&dev->mode_config.mutex); + /* Send Hotplug uevent so userspace can reprobe */ - drm_kms_helper_hotplug_event(connector->dev); + drm_kms_helper_hotplug_event(dev); } bool @@ -6302,6 +6477,9 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, /* Initialize the work for modeset in case of link train failure */ INIT_WORK(&intel_dp->modeset_retry_work, intel_dp_modeset_retry_work_fn); + INIT_WORK(&intel_dp->mst_retrain_work, + intel_dp_mst_retrain_link_work); + init_completion(&intel_dp->mst_retrain_completion); if (WARN(intel_dig_port->max_lanes < 1, "Not enough lanes (%d) for DP on port %c\n", diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index c0553456b18e..31202f838e89 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c @@ -110,21 +110,32 @@ static int intel_dp_mst_atomic_check(struct drm_connector *connector, struct drm_connector_state *old_conn_state; struct drm_crtc *old_crtc; struct drm_crtc_state *crtc_state; + struct drm_dp_mst_topology_mgr *mgr; + struct drm_encoder *encoder; int slots, ret = 0; + bool could_retrain = false; + + if (new_conn_state->crtc) { + crtc_state = drm_atomic_get_new_crtc_state( + state, new_conn_state->crtc); + if (crtc_state && drm_atomic_crtc_needs_modeset(crtc_state)) + could_retrain = true; + } old_conn_state = drm_atomic_get_old_connector_state(state, connector); old_crtc = old_conn_state->crtc; if (!old_crtc) - return ret; + goto out; crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc); - slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu; - if (drm_atomic_crtc_needs_modeset(crtc_state) && slots > 0) { - struct drm_dp_mst_topology_mgr *mgr; - struct drm_encoder *old_encoder; + if (!drm_atomic_crtc_needs_modeset(crtc_state)) + goto out; + could_retrain = true; - old_encoder = old_conn_state->best_encoder; - mgr = &enc_to_mst(old_encoder)->primary->dp.mst_mgr; + slots = to_intel_crtc_state(crtc_state)->dp_m_n.tu; + if (slots > 0) { + encoder = old_conn_state->best_encoder; + mgr = &enc_to_mst(encoder)->primary->dp.mst_mgr; ret = drm_dp_atomic_release_vcpi_slots(state, mgr, slots); if (ret) @@ -132,6 +143,18 @@ static int intel_dp_mst_atomic_check(struct drm_connector *connector, else to_intel_crtc_state(crtc_state)->dp_m_n.tu = 0; } + +out: + if (could_retrain && + old_conn_state->link_status == DRM_MODE_LINK_STATUS_BAD) { + if (new_conn_state->best_encoder) + encoder = new_conn_state->best_encoder; + else + encoder = old_conn_state->best_encoder; + + mgr = &enc_to_mst(encoder)->primary->dp.mst_mgr; + ret = drm_atomic_dp_mst_retrain_topology(state, mgr); + } return ret; } @@ -186,9 +209,12 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder, intel_dp->active_mst_links--; intel_mst->connector = NULL; - if (intel_dp->active_mst_links == 0) + if (intel_dp->active_mst_links == 0) { + intel_dp->mst_link_is_bad = false; + intel_dig_port->base.post_disable(&intel_dig_port->base, old_crtc_state, NULL); + } DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e5d3ef6754a5..c63c65923c3e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1122,6 +1122,13 @@ struct intel_dp { /* mst connector list */ struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES]; struct drm_dp_mst_topology_mgr mst_mgr; + /* We can't handle retraining from the dig workqueue, so... */ + struct work_struct mst_retrain_work; + struct completion mst_retrain_completion; + /* Set when retraining the link at the current parameters is + * impossible for an MST connection + */ + bool mst_link_is_bad; uint32_t (*get_aux_clock_divider)(struct intel_dp *dp, int index); /* @@ -1689,6 +1696,7 @@ void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp); bool intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]); +int intel_dp_get_crtc_mask(struct intel_dp *intel_dp); static inline unsigned int intel_dp_unused_lane_mask(int lane_count) { -- 2.14.3 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Lyude Paul Subject: [PATCH 6/6] drm/i915: Implement proper fallback training for MST Date: Thu, 8 Mar 2018 18:24:20 -0500 Message-ID: <20180308232421.14049-7-lyude@redhat.com> References: <20180308232421.14049-1-lyude@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180308232421.14049-1-lyude@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org Cc: David Airlie , linux-kernel@vger.kernel.org, Rodrigo Vivi List-Id: dri-devel@lists.freedesktop.org Rm9yIGEgd2hpbGUgd2UgYWN0dWFsbHkgaGF2ZW4ndCBoYWQgYW55IHdheSBvZiByZXRyYWluaW5n IE1TVCBsaW5rcyB3aXRoCmZhbGxiYWNrIGxpbmsgcGFyYW1ldGVycyBsaWtlIHdlIGRvIHdpdGgg U1NULiBXaGlsZSB1bmNvbW1vbiwgY2VydGFpbgpzZXR1cHMgc3VjaCBhcyBteSBDYWxkaWdpdCBU UzMgKyBFVkdBIE1TVCBodWIgcmVxdWlyZSB0aGlzIHNpbmNlCm90aGVyd2lzZSwgdGhleSBlbmQg dXAgZ2V0dGluZyBzdHVjayBpbiBhbiBpbmZpbml0ZSBNU1QgcmV0cmFpbmluZyBsb29wLgoKTVNU IHJldHJhaW5pbmcgaXMgc29tZXdoYXQgZGlmZmVyZW50IHRoZW4gU1NUIHJldHJhaW5pbmcuIFdo aWxlIGl0J3MKcG9zc2libGUgZHVyaW5nIHRoZSBub3JtYWwgbGluayByZXRyYWluaW5nIHNlcXVl bmNlIGZvciBhIGh1YiB0byBpbmRpY2F0ZQpiYWQgbGluayBzdGF0dXMsIGl0J3MgYWxzbyBwb3Nz aWJsZSBmb3IgYSBodWIgdG8gb25seSBpbmRpY2F0ZSB0aGlzCnN0YXR1cyB0aHJvdWdoIEVTSSBt ZXNzYWdlcyBhbmQgaXQncyBwb3NzaWJsZSBmb3IgdGhpcyB0byBoYXBwZW4gYWZ0ZXIKdGhlIGlu aXRpYWwgbGluayB0cmFpbmluZyBzdWNjZWVkcy4gVGhpcyBjYW4gbGVhZCB0byBhIHBhdHRlcm4g dGhhdApsb29rcyBsaWtlIHRoaXM6CgotIFRyYWluIE1TVCBsaW5rCi0gVHJhaW5pbmcgY29tcGxl dGVzIHN1Y2Nlc3NmdWxseQotIE1TVCBodWIgc2V0cyBDaGFubmVsIEVRIGZhaWxlZCBiaXQgaW4g RVNJCi0gUmV0cmFpbmluZyBzdGFydHMKLSBSZXRyYWluaW5nIGNvbXBsZXRlcyBzdWNjZXNzZnVs bHkKLSBNU1QgaHViIHNldHMgQ2hhbm5lbCBFUSBmYWlsZWQgYml0IGluIEVTSSBhZ2FpbgotIFJp bnNlIGFuZCByZXBlYXQKCkluIHRoZXNlIHNpdHVhdGlvbnMsIHdlIG5lZWQgdG8gYmUgYWJsZSB0 byBhY3R1YWxseSB0cmlnZ2VyIGZhbGxiYWNrCmxpbmsgdHJhaW5pbmcgZnJvbSB0aGUgRVNJIGhh bmRsZXIgYXMgd2VsbCwgYWxvbmcgd2l0aCB1c2luZyB0aGUgRVNJCmhhbmRsZXIgZHVyaW5nIHJl dHJhaW5pbmcgdG8gZmlndXJlIG91dCB3aGV0aGVyIG9yIG5vdCBvdXIgcmV0cmFpbmluZwphY3R1 YWxseSBzdWNjZWVkZWQuCgpUaGlzIGdldHMgYSBiaXQgbW9yZSBjb21wbGljYXRlZCBzaW5jZSB3 ZSBoYXZlIHRvIGVuc3VyZSB0aGF0IHdlIGRvbid0CmJsb2NrIHRoZSBFU0kgaGFuZGxlciBhdCBh bGwgd2hpbGUgZG9pbmcgcmV0cmFpbmluZy4gSWYgd2UgZG8sIGR1ZSB0bwpEaXNwbGF5UG9ydCdz IGdlbmVyYWwgaXNzdWVzIHdpdGggYmVpbmcgc2Vuc2l0aXZlIHRvIElSUSBsYXRlbmN5IG1vc3QK TVNUIGh1YnMgd2lsbCBqdXN0IHN0b3AgcmVzcG9uZGluZyB0byB1cyBpZiB0aGVpciBpbnRlcnJ1 cHRzIGFyZW4ndApoYW5kbGVkIGluIGEgdGltZWx5IG1hbm5lci4KClNvOiBtb3ZlIHJldHJhaW5p bmcgaW50byBpdCdzIG93biBzZXBlcmF0ZSBoYW5kbGVyLiBSdW5uaW5nIGluIGEKc2VwZXJhdGUg aGFuZGxlciBhbGxvd3MgdXMgdG8gYXZvaWQgc3RhbGxpbmcgdGhlIEVTSSBkdXJpbmcgbGluawpy ZXRyYWluaW5nLCBhbmQgd2UgY2FuIGhhdmUgdGhlIEVTSSBzaWduYWwgdGhhdCB0aGUgY2hhbm5l bCBFUSBiaXQgd2FzCmNsZWFyZWQgdGhyb3VnaCBhIHNpbXBsZSBjb21wbGV0aW9uIHN0cnVjdC4g QWRkaXRpb25hbGx5LCB3ZSB0YWtlIGNhcmUKdG8gc3RpY2sgYXMgbXVjaCBvZiB0aGlzIGludG8g dGhlIFNTVCByZXRyYWluaW5nIHBhdGggYXMgcG9zc2libGUgc2luY2UKc2hhcmluZyBpcyBjYXJp bmcuCgpTaWduZWQtb2ZmLWJ5OiBMeXVkZSBQYXVsIDxseXVkZUByZWRoYXQuY29tPgpDYzogTWFu YXNpIE5hdmFyZSA8bWFuYXNpLmQubmF2YXJlQGludGVsLmNvbT4KQ2M6IFZpbGxlIFN5cmrDpGzD pCA8dmlsbGUuc3lyamFsYUBsaW51eC5pbnRlbC5jb20+Ci0tLQogZHJpdmVycy9ncHUvZHJtL2k5 MTUvaW50ZWxfZHAuYyAgICAgfCAzNDIgKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0t LS0tCiBkcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcF9tc3QuYyB8ICA0MiArKysrLQogZHJp dmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHJ2LmggICAgfCAgIDggKwogMyBmaWxlcyBjaGFuZ2Vk LCAzMDIgaW5zZXJ0aW9ucygrKSwgOTAgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVy cy9ncHUvZHJtL2k5MTUvaW50ZWxfZHAuYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rw LmMKaW5kZXggNTY0NWExOTRkZTkyLi43NjI2NjUyNzMyYjYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMv Z3B1L2RybS9pOTE1L2ludGVsX2RwLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxf ZHAuYwpAQCAtNDUsNiArNDUsOCBAQAogCiAjZGVmaW5lIERQX0RQUlhfRVNJX0xFTiAxNAogCisj ZGVmaW5lIERQX01TVF9SRVRSQUlOX1RJTUVPVVQgKG1zZWNzX3RvX2ppZmZpZXMoMTAwKSkKKwog LyogQ29tcGxpYW5jZSB0ZXN0IHN0YXR1cyBiaXRzICAqLwogI2RlZmluZSBJTlRFTF9EUF9SRVNP TFVUSU9OX1NISUZUX01BU0sJMAogI2RlZmluZSBJTlRFTF9EUF9SRVNPTFVUSU9OX1BSRUZFUlJF RAkoMSA8PCBJTlRFTF9EUF9SRVNPTFVUSU9OX1NISUZUX01BU0spCkBAIC00MjI0LDYgKzQyMjYs MTE4IEBAIHN0YXRpYyB2b2lkIGludGVsX2RwX2hhbmRsZV90ZXN0X3JlcXVlc3Qoc3RydWN0IGlu dGVsX2RwICppbnRlbF9kcCkKIAkJRFJNX0RFQlVHX0tNUygiQ291bGQgbm90IHdyaXRlIHRlc3Qg cmVzcG9uc2UgdG8gc2lua1xuIik7CiB9CiAKKy8qIEdldCBhIG1hc2sgb2YgdGhlIENSVENzIHRo YXQgYXJlIHJ1bm5pbmcgb24gdGhlIGdpdmVuIGludGVsX2RwIHN0cnVjdC4gRm9yCisgKiBNU1Qs IHRoaXMgcmV0dXJucyBhIGNydGMgbWFzayBjb250YWluaW5nIGFsbCBvZiB0aGUgQ1JUQ3MgZHJp dmluZworICogZG93bnN0cmVhbSBzaW5rcywgZm9yIFNTVCBpdCBqdXN0IHJldHVybnMgYSBtYXNr IG9mIHRoZSBhdHRhY2hlZAorICogY29ubmVjdG9yJ3MgQ1JUQy4KKyAqLworaW50CitpbnRlbF9k cF9nZXRfY3J0Y19tYXNrKHN0cnVjdCBpbnRlbF9kcCAqaW50ZWxfZHApCit7CisJc3RydWN0IGRy bV9kZXZpY2UgKmRldiA9IGRwX3RvX2RpZ19wb3J0KGludGVsX2RwKS0+YmFzZS5iYXNlLmRldjsK KwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yOworCXN0cnVjdCBkcm1fY29ubmVjdG9y X3N0YXRlICpjb25uX3N0YXRlOworCXN0cnVjdCBpbnRlbF9jb25uZWN0b3IgKmludGVsX2Nvbm5l Y3RvcjsKKwlzdHJ1Y3QgZHJtX2NydGMgKmNydGM7CisJaW50IGNydGNfbWFzayA9IDA7CisKKwlX QVJOX09OKCFkcm1fbW9kZXNldF9pc19sb2NrZWQoJmRldi0+bW9kZV9jb25maWcuY29ubmVjdGlv bl9tdXRleCkpOworCisJaWYgKGludGVsX2RwLT5pc19tc3QpIHsKKwkJc3RydWN0IGRybV9jb25u ZWN0b3JfbGlzdF9pdGVyIGNvbm5faXRlcjsKKworCQlkcm1fY29ubmVjdG9yX2xpc3RfaXRlcl9i ZWdpbihkZXYsICZjb25uX2l0ZXIpOworCQlmb3JfZWFjaF9pbnRlbF9jb25uZWN0b3JfaXRlcihp bnRlbF9jb25uZWN0b3IsICZjb25uX2l0ZXIpIHsKKwkJCWlmIChpbnRlbF9jb25uZWN0b3ItPm1z dF9wb3J0ICE9IGludGVsX2RwKQorCQkJCWNvbnRpbnVlOworCisJCQljb25uX3N0YXRlID0gaW50 ZWxfY29ubmVjdG9yLT5iYXNlLnN0YXRlOworCQkJaWYgKCFjb25uX3N0YXRlLT5jcnRjKQorCQkJ CWNvbnRpbnVlOworCisJCQljcnRjX21hc2sgfD0gZHJtX2NydGNfbWFzayhjb25uX3N0YXRlLT5j cnRjKTsKKwkJfQorCQlkcm1fY29ubmVjdG9yX2xpc3RfaXRlcl9lbmQoJmNvbm5faXRlcik7CisJ fSBlbHNlIHsKKwkJY29ubmVjdG9yID0gJmludGVsX2RwLT5hdHRhY2hlZF9jb25uZWN0b3ItPmJh c2U7CisJCWNydGMgPSBjb25uZWN0b3ItPnN0YXRlLT5jcnRjOworCisJCWlmIChjcnRjKQorCQkJ Y3J0Y19tYXNrIHw9IGRybV9jcnRjX21hc2soY3J0Yyk7CisJfQorCisJcmV0dXJuIGNydGNfbWFz azsKK30KKworc3RhdGljIGJvb2wKK2ludGVsX2RwX25lZWRzX2xpbmtfcmV0cmFpbihzdHJ1Y3Qg aW50ZWxfZHAgKmludGVsX2RwLAorCQkJICAgIGNvbnN0IHU4IGVzaVtEUF9EUFJYX0VTSV9MRU5d KQoreworCXU4IGJ1ZlttYXgoRFBfTElOS19TVEFUVVNfU0laRSwgRFBfRFBSWF9FU0lfTEVOKV07 CisJY29uc3QgdTggKmxpbmtfc3RhdHVzID0gTlVMTDsKKworCWlmIChpbnRlbF9kcC0+aXNfbXN0 KSB7CisJCWlmICghaW50ZWxfZHAtPmFjdGl2ZV9tc3RfbGlua3MpCisJCQlyZXR1cm4gZmFsc2U7 CisJCWlmIChpbnRlbF9kcC0+bXN0X2xpbmtfaXNfYmFkKQorCQkJcmV0dXJuIGZhbHNlOworCisJ CWlmIChlc2kpIHsKKwkJCWxpbmtfc3RhdHVzID0gJmVzaVsxMF07CisJCX0gZWxzZSB7CisJCQkv KiBXZSdyZSBub3QgcnVubmluZyBmcm9tIHRoZSBFU0kgaGFuZGxlciwgc28gd2FpdCBhCisJCQkg KiBsaXR0bGUgYml0IHRvIHNlZSBpZiB0aGUgRVNJIGhhbmRsZXIgbGV0cyB1cyBrbm93CisJCQkg KiB0aGF0IHRoZSBsaW5rIHN0YXR1cyBpcyBPSworCQkJICovCisJCQlpZiAod2FpdF9mb3JfY29t cGxldGlvbl90aW1lb3V0KAorCQkJCSZpbnRlbF9kcC0+bXN0X3JldHJhaW5fY29tcGxldGlvbiwK KwkJCQlEUF9NU1RfUkVUUkFJTl9USU1FT1VUKSkKKwkJCQlyZXR1cm4gZmFsc2U7CisJCX0KKwl9 IGVsc2UgeworCQlpZiAoaW50ZWxfZHAtPmxpbmtfdHJhaW5lZCkKKwkJCXJldHVybiBmYWxzZTsK KwkJaWYgKCFpbnRlbF9kcF9nZXRfbGlua19zdGF0dXMoaW50ZWxfZHAsIGJ1ZikpCisJCQlyZXR1 cm4gZmFsc2U7CisKKwkJbGlua19zdGF0dXMgPSBidWY7CisJfQorCisJLyoKKwkgKiBWYWxpZGF0 ZSB0aGUgY2FjaGVkIHZhbHVlcyBvZiBpbnRlbF9kcC0+bGlua19yYXRlIGFuZAorCSAqIGludGVs X2RwLT5sYW5lX2NvdW50IGJlZm9yZSBhdHRlbXB0aW5nIHRvIHJldHJhaW4uCisJICovCisJaWYg KCFpbnRlbF9kcF9saW5rX3BhcmFtc192YWxpZChpbnRlbF9kcCwgaW50ZWxfZHAtPmxpbmtfcmF0 ZSwKKwkJCQkJaW50ZWxfZHAtPmxhbmVfY291bnQpKQorCQlyZXR1cm4gZmFsc2U7CisKKwlpZiAo bGlua19zdGF0dXMpIHsKKwkJcmV0dXJuICFkcm1fZHBfY2hhbm5lbF9lcV9vayhsaW5rX3N0YXR1 cywKKwkJCQkJICAgICBpbnRlbF9kcC0+bGFuZV9jb3VudCk7CisJfSBlbHNlIHsKKwkJcmV0dXJu IHRydWU7CisJfQorfQorCitzdGF0aWMgaW5saW5lIHZvaWQKK2ludGVsX2RwX21zdF9jaGVja19s aW5rX3N0YXR1cyhzdHJ1Y3QgaW50ZWxfZHAgKmludGVsX2RwLAorCQkJICAgICAgIGNvbnN0IHU4 IGVzaVtEUF9EUFJYX0VTSV9MRU5dKQoreworCWlmIChpbnRlbF9kcF9uZWVkc19saW5rX3JldHJh aW4oaW50ZWxfZHAsIGVzaSkpIHsKKwkJRFJNX0RFQlVHX0tNUygiQ2hhbm5lbCBFUSBmYWlsaW5n XG4iKTsKKworCQlpZiAoIXdvcmtfYnVzeSgmaW50ZWxfZHAtPm1zdF9yZXRyYWluX3dvcmspKSB7 CisJCQlyZWluaXRfY29tcGxldGlvbigmaW50ZWxfZHAtPm1zdF9yZXRyYWluX2NvbXBsZXRpb24p OworCQkJc2NoZWR1bGVfd29yaygmaW50ZWxfZHAtPm1zdF9yZXRyYWluX3dvcmspOworCQkJRFJN X0RFQlVHX0tNUygiUmV0cmFpbmluZyBzdGFydGVkXG4iKTsKKwkJfQorCX0gZWxzZSBpZiAod29y a19idXN5KCZpbnRlbF9kcC0+bXN0X3JldHJhaW5fd29yaykgJiYKKwkJICAgIWNvbXBsZXRpb25f ZG9uZSgmaW50ZWxfZHAtPm1zdF9yZXRyYWluX2NvbXBsZXRpb24pKSB7CisJCURSTV9ERUJVR19L TVMoIkNoYW5uZWwgRVEgc3RhYmxlXG4iKTsKKwkJY29tcGxldGVfYWxsKCZpbnRlbF9kcC0+bXN0 X3JldHJhaW5fY29tcGxldGlvbik7CisJfQorfQorCiBzdGF0aWMgaW50CiBpbnRlbF9kcF9jaGVj a19tc3Rfc3RhdHVzKHN0cnVjdCBpbnRlbF9kcCAqaW50ZWxfZHApCiB7CkBAIC00MjM3LDE0ICs0 MzUxLDcgQEAgaW50ZWxfZHBfY2hlY2tfbXN0X3N0YXR1cyhzdHJ1Y3QgaW50ZWxfZHAgKmludGVs X2RwKQogCQlicmV0ID0gaW50ZWxfZHBfZ2V0X3NpbmtfaXJxX2VzaShpbnRlbF9kcCwgZXNpKTsK IGdvX2FnYWluOgogCQlpZiAoYnJldCA9PSB0cnVlKSB7Ci0KLQkJCS8qIGNoZWNrIGxpbmsgc3Rh dHVzIC0gZXNpWzEwXSA9IDB4MjAwYyAqLwotCQkJaWYgKGludGVsX2RwLT5hY3RpdmVfbXN0X2xp bmtzICYmCi0JCQkgICAgIWRybV9kcF9jaGFubmVsX2VxX29rKCZlc2lbMTBdLCBpbnRlbF9kcC0+ bGFuZV9jb3VudCkpIHsKLQkJCQlEUk1fREVCVUdfS01TKCJjaGFubmVsIEVRIG5vdCBvaywgcmV0 cmFpbmluZ1xuIik7Ci0JCQkJaW50ZWxfZHBfc3RhcnRfbGlua190cmFpbihpbnRlbF9kcCk7Ci0J CQkJaW50ZWxfZHBfc3RvcF9saW5rX3RyYWluKGludGVsX2RwKTsKLQkJCX0KKwkJCWludGVsX2Rw X21zdF9jaGVja19saW5rX3N0YXR1cyhpbnRlbF9kcCwgZXNpKTsKIAogCQkJRFJNX0RFQlVHX0tN UygiZ290IGVzaSAlM3BoXG4iLCBlc2kpOwogCQkJcmV0ID0gZHJtX2RwX21zdF9ocGRfaXJxKCZp bnRlbF9kcC0+bXN0X21nciwgZXNpLCAmaGFuZGxlZCk7CkBAIC00MjgxLDI5ICs0Mzg4LDYgQEAg aW50ZWxfZHBfY2hlY2tfbXN0X3N0YXR1cyhzdHJ1Y3QgaW50ZWxfZHAgKmludGVsX2RwKQogCXJl dHVybiAtRUlOVkFMOwogfQogCi1zdGF0aWMgYm9vbAotaW50ZWxfZHBfbmVlZHNfbGlua19yZXRy YWluKHN0cnVjdCBpbnRlbF9kcCAqaW50ZWxfZHApCi17Ci0JdTggbGlua19zdGF0dXNbRFBfTElO S19TVEFUVVNfU0laRV07Ci0KLQlpZiAoIWludGVsX2RwLT5saW5rX3RyYWluZWQpCi0JCXJldHVy biBmYWxzZTsKLQotCWlmICghaW50ZWxfZHBfZ2V0X2xpbmtfc3RhdHVzKGludGVsX2RwLCBsaW5r X3N0YXR1cykpCi0JCXJldHVybiBmYWxzZTsKLQotCS8qCi0JICogVmFsaWRhdGUgdGhlIGNhY2hl ZCB2YWx1ZXMgb2YgaW50ZWxfZHAtPmxpbmtfcmF0ZSBhbmQKLQkgKiBpbnRlbF9kcC0+bGFuZV9j b3VudCBiZWZvcmUgYXR0ZW1wdGluZyB0byByZXRyYWluLgotCSAqLwotCWlmICghaW50ZWxfZHBf bGlua19wYXJhbXNfdmFsaWQoaW50ZWxfZHAsIGludGVsX2RwLT5saW5rX3JhdGUsCi0JCQkJCWlu dGVsX2RwLT5sYW5lX2NvdW50KSkKLQkJcmV0dXJuIGZhbHNlOwotCi0JLyogUmV0cmFpbiBpZiBD aGFubmVsIEVRIG9yIENSIG5vdCBvayAqLwotCXJldHVybiAhZHJtX2RwX2NoYW5uZWxfZXFfb2so bGlua19zdGF0dXMsIGludGVsX2RwLT5sYW5lX2NvdW50KTsKLX0KLQogLyoKICAqIElmIGRpc3Bs YXkgaXMgbm93IGNvbm5lY3RlZCBjaGVjayBsaW5rcyBzdGF0dXMsCiAgKiB0aGVyZSBoYXMgYmVl biBrbm93biBpc3N1ZXMgb2YgbGluayBsb3NzIHRyaWdnZXJpbmcKQEAgLTQzMTksNjQgKzQ0MDMs NzggQEAgaW50ZWxfZHBfbmVlZHNfbGlua19yZXRyYWluKHN0cnVjdCBpbnRlbF9kcCAqaW50ZWxf ZHApCiBpbnQgaW50ZWxfZHBfcmV0cmFpbl9saW5rKHN0cnVjdCBpbnRlbF9lbmNvZGVyICplbmNv ZGVyLAogCQkJICBzdHJ1Y3QgZHJtX21vZGVzZXRfYWNxdWlyZV9jdHggKmN0eCkKIHsKLQlzdHJ1 Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYgPSB0b19pOTE1KGVuY29kZXItPmJhc2UuZGV2 KTsKKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gZW5jb2Rlci0+YmFzZS5kZXY7CisJc3RydWN0 IGRybV9pOTE1X3ByaXZhdGUgKmRldl9wcml2ID0gdG9faTkxNShkZXYpOwogCXN0cnVjdCBpbnRl bF9kcCAqaW50ZWxfZHAgPSBlbmNfdG9faW50ZWxfZHAoJmVuY29kZXItPmJhc2UpOwotCXN0cnVj dCBpbnRlbF9jb25uZWN0b3IgKmNvbm5lY3RvciA9IGludGVsX2RwLT5hdHRhY2hlZF9jb25uZWN0 b3I7Ci0Jc3RydWN0IGRybV9jb25uZWN0b3Jfc3RhdGUgKmNvbm5fc3RhdGU7Ci0Jc3RydWN0IGlu dGVsX2NydGNfc3RhdGUgKmNydGNfc3RhdGU7Ci0Jc3RydWN0IGludGVsX2NydGMgKmNydGM7CisJ c3RydWN0IGRybV9jcnRjICpjcnRjOworCXN0cnVjdCBpbnRlbF9jcnRjICppbnRlbF9jcnRjOwor CWludCBjcnRjX21hc2ssIHJldHJ5X2NvdW50ID0gMDsKIAlpbnQgcmV0OwogCi0JLyogRklYTUUg aGFuZGxlIHRoZSBNU1QgY29ubmVjdG9ycyBhcyB3ZWxsICovCi0KLQlpZiAoIWNvbm5lY3RvciB8 fCBjb25uZWN0b3ItPmJhc2Uuc3RhdHVzICE9IGNvbm5lY3Rvcl9zdGF0dXNfY29ubmVjdGVkKQot CQlyZXR1cm4gMDsKLQogCXJldCA9IGRybV9tb2Rlc2V0X2xvY2soJmRldl9wcml2LT5kcm0ubW9k ZV9jb25maWcuY29ubmVjdGlvbl9tdXRleCwKIAkJCSAgICAgICBjdHgpOwogCWlmIChyZXQpCiAJ CXJldHVybiByZXQ7CiAKLQljb25uX3N0YXRlID0gY29ubmVjdG9yLT5iYXNlLnN0YXRlOwotCi0J Y3J0YyA9IHRvX2ludGVsX2NydGMoY29ubl9zdGF0ZS0+Y3J0Yyk7Ci0JaWYgKCFjcnRjKQotCQly ZXR1cm4gMDsKKwljcnRjX21hc2sgPSBpbnRlbF9kcF9nZXRfY3J0Y19tYXNrKGludGVsX2RwKTsK Kwlmb3JfZWFjaF9pbnRlbF9jcnRjX21hc2soZGV2LCBpbnRlbF9jcnRjLCBjcnRjX21hc2spIHsK KwkJc3RydWN0IGRybV9jcnRjX3N0YXRlICpjcnRjX3N0YXRlOworCQlzdHJ1Y3QgaW50ZWxfY3J0 Y19zdGF0ZSAqaW50ZWxfY3J0Y19zdGF0ZTsKIAotCXJldCA9IGRybV9tb2Rlc2V0X2xvY2soJmNy dGMtPmJhc2UubXV0ZXgsIGN0eCk7Ci0JaWYgKHJldCkKLQkJcmV0dXJuIHJldDsKKwkJY3J0YyA9 ICZpbnRlbF9jcnRjLT5iYXNlOworCQlyZXQgPSBkcm1fbW9kZXNldF9sb2NrKCZjcnRjLT5tdXRl eCwgY3R4KTsKKwkJaWYgKHJldCkKKwkJCXJldHVybiByZXQ7CiAKLQljcnRjX3N0YXRlID0gdG9f aW50ZWxfY3J0Y19zdGF0ZShjcnRjLT5iYXNlLnN0YXRlKTsKKwkJY3J0Y19zdGF0ZSA9IGNydGMt PnN0YXRlOworCQlpbnRlbF9jcnRjX3N0YXRlID0gdG9faW50ZWxfY3J0Y19zdGF0ZShjcnRjX3N0 YXRlKTsKKwkJV0FSTl9PTighaW50ZWxfY3J0Y19oYXNfZHBfZW5jb2RlcihpbnRlbF9jcnRjX3N0 YXRlKSk7CiAKLQlXQVJOX09OKCFpbnRlbF9jcnRjX2hhc19kcF9lbmNvZGVyKGNydGNfc3RhdGUp KTsKKwkJaWYgKGNydGNfc3RhdGUtPmNvbW1pdCAmJgorCQkgICAgIXRyeV93YWl0X2Zvcl9jb21w bGV0aW9uKCZjcnRjX3N0YXRlLT5jb21taXQtPmh3X2RvbmUpKQorCQkJcmV0dXJuIDA7CisJfQog Ci0JaWYgKCFjcnRjX3N0YXRlLT5iYXNlLmFjdGl2ZSkKKwlpZiAoIWludGVsX2RwX25lZWRzX2xp bmtfcmV0cmFpbihpbnRlbF9kcCwgTlVMTCkpCiAJCXJldHVybiAwOwogCi0JaWYgKGNvbm5fc3Rh dGUtPmNvbW1pdCAmJgotCSAgICAhdHJ5X3dhaXRfZm9yX2NvbXBsZXRpb24oJmNvbm5fc3RhdGUt PmNvbW1pdC0+aHdfZG9uZSkpCi0JCXJldHVybiAwOworCWZvcl9lYWNoX2ludGVsX2NydGNfbWFz ayhkZXYsIGludGVsX2NydGMsIGNydGNfbWFzaykgeworCQlpbnRlbF9zZXRfY3B1X2ZpZm9fdW5k ZXJydW5fcmVwb3J0aW5nKAorCQkgICAgZGV2X3ByaXYsIGludGVsX2NydGMtPnBpcGUsIGZhbHNl KTsKIAotCWlmICghaW50ZWxfZHBfbmVlZHNfbGlua19yZXRyYWluKGludGVsX2RwKSkKLQkJcmV0 dXJuIDA7CisJCWlmIChpbnRlbF9jcnRjLT5jb25maWctPmhhc19wY2hfZW5jb2RlcikgeworCQkJ aW50ZWxfc2V0X3BjaF9maWZvX3VuZGVycnVuX3JlcG9ydGluZygKKwkJCSAgICBkZXZfcHJpdiwg aW50ZWxfY3J0Y19wY2hfdHJhbnNjb2RlcihpbnRlbF9jcnRjKSwKKwkJCSAgICBmYWxzZSk7CisJ CX0KKwl9CiAKLQkvKiBTdXBwcmVzcyB1bmRlcnJ1bnMgY2F1c2VkIGJ5IHJlLXRyYWluaW5nICov Ci0JaW50ZWxfc2V0X2NwdV9maWZvX3VuZGVycnVuX3JlcG9ydGluZyhkZXZfcHJpdiwgY3J0Yy0+ cGlwZSwgZmFsc2UpOwotCWlmIChjcnRjLT5jb25maWctPmhhc19wY2hfZW5jb2RlcikKLQkJaW50 ZWxfc2V0X3BjaF9maWZvX3VuZGVycnVuX3JlcG9ydGluZyhkZXZfcHJpdiwKLQkJCQkJCSAgICAg IGludGVsX2NydGNfcGNoX3RyYW5zY29kZXIoY3J0YyksIGZhbHNlKTsKKwlkbyB7CisJCWlmICgr K3JldHJ5X2NvdW50ID4gNSkgeworCQkJRFJNX0RFQlVHX0tNUygiVG9vIG1hbnkgcmV0cmllcywg Y2FuJ3QgcmV0cmFpblxuIik7CisJCQlyZXR1cm4gLUVJTlZBTDsKKwkJfQogCi0JaW50ZWxfZHBf c3RhcnRfbGlua190cmFpbihpbnRlbF9kcCk7Ci0JaW50ZWxfZHBfc3RvcF9saW5rX3RyYWluKGlu dGVsX2RwKTsKKwkJaW50ZWxfZHBfc3RhcnRfbGlua190cmFpbihpbnRlbF9kcCk7CisJCWludGVs X2RwX3N0b3BfbGlua190cmFpbihpbnRlbF9kcCk7CisJfSB3aGlsZSAoaW50ZWxfZHBfbmVlZHNf bGlua19yZXRyYWluKGludGVsX2RwLCBOVUxMKSk7CisKKwkvKiBXYWl0IGZvciB0aGluZ3MgdG8g YmVjb21lIHN0YWJsZSAqLworCWZvcl9lYWNoX2ludGVsX2NydGNfbWFzayhkZXYsIGludGVsX2Ny dGMsIGNydGNfbWFzaykKKwkJaW50ZWxfd2FpdF9mb3JfdmJsYW5rKGRldl9wcml2LCBpbnRlbF9j cnRjLT5waXBlKTsKIAotCS8qIEtlZXAgdW5kZXJydW4gcmVwb3J0aW5nIGRpc2FibGVkIHVudGls IHRoaW5ncyBhcmUgc3RhYmxlICovCi0JaW50ZWxfd2FpdF9mb3JfdmJsYW5rKGRldl9wcml2LCBj cnRjLT5waXBlKTsKKwkvKiBOb3cgdGhhdCB3ZSBrbm93IGV2ZXJ5dGhpbmcgaXMgT0ssIGZpbmFs bHkgcmUtZW5hYmxlIHVuZGVycnVuCisJICogcmVwb3J0aW5nICovCisJZm9yX2VhY2hfaW50ZWxf Y3J0Y19tYXNrKGRldiwgaW50ZWxfY3J0YywgY3J0Y19tYXNrKSB7CisJCWludGVsX3NldF9jcHVf Zmlmb191bmRlcnJ1bl9yZXBvcnRpbmcoCisJCSAgICBkZXZfcHJpdiwgaW50ZWxfY3J0Yy0+cGlw ZSwgdHJ1ZSk7CiAKLQlpbnRlbF9zZXRfY3B1X2ZpZm9fdW5kZXJydW5fcmVwb3J0aW5nKGRldl9w cml2LCBjcnRjLT5waXBlLCB0cnVlKTsKLQlpZiAoY3J0Yy0+Y29uZmlnLT5oYXNfcGNoX2VuY29k ZXIpCi0JCWludGVsX3NldF9wY2hfZmlmb191bmRlcnJ1bl9yZXBvcnRpbmcoZGV2X3ByaXYsCi0J CQkJCQkgICAgICBpbnRlbF9jcnRjX3BjaF90cmFuc2NvZGVyKGNydGMpLCB0cnVlKTsKKwkJaWYg KGludGVsX2NydGMtPmNvbmZpZy0+aGFzX3BjaF9lbmNvZGVyKSB7CisJCQlpbnRlbF9zZXRfcGNo X2ZpZm9fdW5kZXJydW5fcmVwb3J0aW5nKAorCQkJICAgIGRldl9wcml2LCBpbnRlbF9jcnRjX3Bj aF90cmFuc2NvZGVyKGludGVsX2NydGMpLAorCQkJICAgIHRydWUpOworCQl9CisJfQogCiAJcmV0 dXJuIDA7CiB9CkBAIC00NDAyLDYgKzQ1MDAsMTAgQEAgc3RhdGljIGJvb2wgaW50ZWxfZHBfaG90 cGx1ZyhzdHJ1Y3QgaW50ZWxfZW5jb2RlciAqZW5jb2RlciwKIAogCWNoYW5nZWQgPSBpbnRlbF9l bmNvZGVyX2hvdHBsdWcoZW5jb2RlciwgY29ubmVjdG9yKTsKIAorCS8qIFdlIGRvbid0IHdhbnQg dG8gZW5kIHVwIHRyeWluZyB0byByZXRyYWluIE1TVCBsaW5rcyEgKi8KKwlpZiAoZW5jb2RlciAm JiBlbmNfdG9faW50ZWxfZHAoJmVuY29kZXItPmJhc2UpLT5pc19tc3QpCisJCXJldHVybiBjaGFu Z2VkOworCiAJZHJtX21vZGVzZXRfYWNxdWlyZV9pbml0KCZjdHgsIDApOwogCiAJZm9yICg7Oykg ewpAQCAtNDQ3OCw3ICs0NTgwLDcgQEAgaW50ZWxfZHBfc2hvcnRfcHVsc2Uoc3RydWN0IGludGVs X2RwICppbnRlbF9kcCkKIAl9CiAKIAkvKiBkZWZlciB0byB0aGUgaG90cGx1ZyB3b3JrIGZvciBs aW5rIHJldHJhaW5pbmcgaWYgbmVlZGVkICovCi0JaWYgKGludGVsX2RwX25lZWRzX2xpbmtfcmV0 cmFpbihpbnRlbF9kcCkpCisJaWYgKGludGVsX2RwX25lZWRzX2xpbmtfcmV0cmFpbihpbnRlbF9k cCwgTlVMTCkpCiAJCXJldHVybiBmYWxzZTsKIAogCWlmIChpbnRlbF9kcC0+Y29tcGxpYW5jZS50 ZXN0X3R5cGUgPT0gRFBfVEVTVF9MSU5LX1RSQUlOSU5HKSB7CkBAIC02MjY2LDI1ICs2MzY4LDk4 IEBAIHN0YXRpYyBib29sIGludGVsX2VkcF9pbml0X2Nvbm5lY3RvcihzdHJ1Y3QgaW50ZWxfZHAg KmludGVsX2RwLAogCXJldHVybiBmYWxzZTsKIH0KIAorc3RhdGljIHZvaWQgaW50ZWxfZHBfbXN0 X3JldHJhaW5fbGlua193b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKK3sKKwlzdHJ1Y3Qg ZHJtX21vZGVzZXRfYWNxdWlyZV9jdHggY3R4OworCXN0cnVjdCBpbnRlbF9kcCAqaW50ZWxfZHAg PSBjb250YWluZXJfb2Yod29yaywgdHlwZW9mKCppbnRlbF9kcCksCisJCQkJCQkgbXN0X3JldHJh aW5fd29yayk7CisJc3RydWN0IGludGVsX2VuY29kZXIgKmludGVsX2VuY29kZXIgPSAmZHBfdG9f ZGlnX3BvcnQoaW50ZWxfZHApLT5iYXNlOworCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYgPSBpbnRl bF9lbmNvZGVyLT5iYXNlLmRldjsKKwlpbnQgcmV0OworCWJvb2wgaGFkX2Vycm9yID0gZmFsc2U7 CisKKwlkcm1fbW9kZXNldF9hY3F1aXJlX2luaXQoJmN0eCwgMCk7CisKKwlmb3IgKDs7KSB7CisJ CXJldCA9IGludGVsX2RwX3JldHJhaW5fbGluayhpbnRlbF9lbmNvZGVyLCAmY3R4KTsKKwkJaWYg KHJldCA9PSAtRURFQURMSykgeworCQkJZHJtX21vZGVzZXRfYmFja29mZigmY3R4KTsKKwkJCWNv bnRpbnVlOworCQl9CisKKwkJYnJlYWs7CisJfQorCWlmICghcmV0KSB7CisJCURSTV9ERUJVR19L TVMoIlJldHJhaW4gY29tcGxldGVcbiIpOworCQlnb3RvIG91dDsKKwl9IGVsc2UgaWYgKHJldCA9 PSAtRUlPKSB7CisJCURSTV9FUlJPUigiSU8gZXJyb3Igd2l0aCBzaW5rIGR1cmluZyByZXRyYWlu PyBBYm9ydGluZ1xuIik7CisJCWhhZF9lcnJvciA9IHRydWU7CisJCWdvdG8gb3V0OworCX0KKwor CURSTV9ERUJVR19LTVMoIlJldHJhaW5pbmcgZmFpbGVkIHdpdGggJWQsIG1hcmtpbmcgbGluayBz dGF0dXMgYXMgYmFkXG4iLAorCQkgICAgICByZXQpOworCisJLyogV2UgcmFuIG91dCBvZiByZXRy aWVzLCBpZiB0aGUgc2luayBoYXNuJ3QgY2hhbmdlZCB0aGUgbGluayByYXRlIGluCisJICogaXQn cyBkcGNkIHlldCBmb3JjZSB1cyB0byBmYWxsYmFjayB0byBhIGxvd2VyIGxpbmsgcmF0ZS9jb3Vu dCAqLworCWlmIChyZXQgPT0gLUVJTlZBTCkgeworCQlyZXQgPSBpbnRlbF9kcF9nZXRfZHBjZChp bnRlbF9kcCk7CisJCWlmICghcmV0KSB7CisJCQlEUk1fRVJST1IoIklPIGVycm9yIHdoaWxlIHJl YWRpbmcgZHBjZCBmcm9tIHNpbmtcbiIpOworCQkJaGFkX2Vycm9yID0gdHJ1ZTsKKwkJCWdvdG8g b3V0OworCQl9CisKKwkJaWYgKGludGVsX2RwLT5saW5rX3JhdGUgPT0gaW50ZWxfZHBfbWF4X2xp bmtfcmF0ZShpbnRlbF9kcCkgJiYKKwkJICAgIGludGVsX2RwLT5sYW5lX2NvdW50ID09IGludGVs X2RwX21heF9sYW5lX2NvdW50KGludGVsX2RwKSkgeworCQkJaW50ZWxfZHBfZ2V0X2xpbmtfdHJh aW5fZmFsbGJhY2tfdmFsdWVzKAorCQkJICAgIGludGVsX2RwLCBpbnRlbF9kcF9tYXhfbGlua19y YXRlKGludGVsX2RwKSwKKwkJCSAgICBpbnRlbF9kcF9tYXhfbGFuZV9jb3VudChpbnRlbF9kcCkp OworCQl9CisJfQorCisJaW50ZWxfZHAtPm1zdF9saW5rX2lzX2JhZCA9IHRydWU7CisJaW50ZWxf ZHAtPm1zdF9id19sb2NrZWQgPSBmYWxzZTsKKwlzY2hlZHVsZV93b3JrKCZpbnRlbF9kcC0+bW9k ZXNldF9yZXRyeV93b3JrKTsKK291dDoKKwlkcm1fbW9kZXNldF9kcm9wX2xvY2tzKCZjdHgpOwor CWRybV9tb2Rlc2V0X2FjcXVpcmVfZmluaSgmY3R4KTsKKwlpZiAoaGFkX2Vycm9yKQorCQlkcm1f a21zX2hlbHBlcl9ob3RwbHVnX2V2ZW50KGRldik7Cit9CisKIHN0YXRpYyB2b2lkIGludGVsX2Rw X21vZGVzZXRfcmV0cnlfd29ya19mbihzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCiB7CiAJc3Ry dWN0IGludGVsX2RwICppbnRlbF9kcCA9IGNvbnRhaW5lcl9vZih3b3JrLCB0eXBlb2YoKmludGVs X2RwKSwKIAkJCQkJCSBtb2Rlc2V0X3JldHJ5X3dvcmspOwotCXN0cnVjdCBkcm1fY29ubmVjdG9y ICpjb25uZWN0b3IgPSAmaW50ZWxfZHAtPmF0dGFjaGVkX2Nvbm5lY3Rvci0+YmFzZTsKKwlzdHJ1 Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCA9IGRwX3RvX2RpZ19wb3J0KGlu dGVsX2RwKTsKKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gaW50ZWxfZGlnX3BvcnQtPmJhc2Uu YmFzZS5kZXY7CisJc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcjsKIAotCURSTV9ERUJV R19LTVMoIltDT05ORUNUT1I6JWQ6JXNdXG4iLCBjb25uZWN0b3ItPmJhc2UuaWQsCi0JCSAgICAg IGNvbm5lY3Rvci0+bmFtZSk7CisJbXV0ZXhfbG9jaygmZGV2LT5tb2RlX2NvbmZpZy5tdXRleCk7 CiAKLQkvKiBHcmFiIHRoZSBsb2NrcyBiZWZvcmUgY2hhbmdpbmcgY29ubmVjdG9yIHByb3BlcnR5 Ki8KLQltdXRleF9sb2NrKCZjb25uZWN0b3ItPmRldi0+bW9kZV9jb25maWcubXV0ZXgpOwotCS8q IFNldCBjb25uZWN0b3IgbGluayBzdGF0dXMgdG8gQkFEIGFuZCBzZW5kIGEgVWV2ZW50IHRvIG5v dGlmeQotCSAqIHVzZXJzcGFjZSB0byBkbyBhIG1vZGVzZXQuCisJLyogU2V0IHRoZSBjb25uZWN0 b3IgbGluayBzdGF0dXMgb2YgYWxsIChwb3NzaWJseSBkb3duc3RyZWFtKSBwb3J0cyB0bworCSAq IEJBRCBhbmQgc2VuZCBhIFVldmVudCB0byBub3RpZnkgdXNlcnNwYWNlIHRvIGRvIGEgbW9kZXNl dC4KIAkgKi8KLQlkcm1fbW9kZV9jb25uZWN0b3Jfc2V0X2xpbmtfc3RhdHVzX3Byb3BlcnR5KGNv bm5lY3RvciwKLQkJCQkJCSAgICBEUk1fTU9ERV9MSU5LX1NUQVRVU19CQUQpOwotCW11dGV4X3Vu bG9jaygmY29ubmVjdG9yLT5kZXYtPm1vZGVfY29uZmlnLm11dGV4KTsKKwlpZiAoaW50ZWxfZHAt PmlzX21zdCkgeworCQlkcm1fZHBfbXN0X3RvcG9sb2d5X21ncl9sb3dlcl9saW5rX3JhdGUoCisJ CSAgICAmaW50ZWxfZHAtPm1zdF9tZ3IsCisJCSAgICBpbnRlbF9kcF9tYXhfbGlua19yYXRlKGlu dGVsX2RwKSwKKwkJICAgIGludGVsX2RwX21heF9sYW5lX2NvdW50KGludGVsX2RwKSk7CisJfSBl bHNlIHsKKwkJY29ubmVjdG9yID0gJmludGVsX2RwLT5hdHRhY2hlZF9jb25uZWN0b3ItPmJhc2U7 CisKKwkJRFJNX0RFQlVHX0tNUygiW0NPTk5FQ1RPUjolZDolc11cbiIsCisJCQkgICAgICBjb25u ZWN0b3ItPmJhc2UuaWQsIGNvbm5lY3Rvci0+bmFtZSk7CisJCWRybV9tb2RlX2Nvbm5lY3Rvcl9z ZXRfbGlua19zdGF0dXNfcHJvcGVydHkoCisJCSAgICBjb25uZWN0b3IsIERSTV9NT0RFX0xJTktf U1RBVFVTX0JBRCk7CisJfQorCisJbXV0ZXhfdW5sb2NrKCZkZXYtPm1vZGVfY29uZmlnLm11dGV4 KTsKKwogCS8qIFNlbmQgSG90cGx1ZyB1ZXZlbnQgc28gdXNlcnNwYWNlIGNhbiByZXByb2JlICov Ci0JZHJtX2ttc19oZWxwZXJfaG90cGx1Z19ldmVudChjb25uZWN0b3ItPmRldik7CisJZHJtX2tt c19oZWxwZXJfaG90cGx1Z19ldmVudChkZXYpOwogfQogCiBib29sCkBAIC02MzAyLDYgKzY0Nzcs OSBAQCBpbnRlbF9kcF9pbml0X2Nvbm5lY3RvcihzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICpp bnRlbF9kaWdfcG9ydCwKIAkvKiBJbml0aWFsaXplIHRoZSB3b3JrIGZvciBtb2Rlc2V0IGluIGNh c2Ugb2YgbGluayB0cmFpbiBmYWlsdXJlICovCiAJSU5JVF9XT1JLKCZpbnRlbF9kcC0+bW9kZXNl dF9yZXRyeV93b3JrLAogCQkgIGludGVsX2RwX21vZGVzZXRfcmV0cnlfd29ya19mbik7CisJSU5J VF9XT1JLKCZpbnRlbF9kcC0+bXN0X3JldHJhaW5fd29yaywKKwkJICBpbnRlbF9kcF9tc3RfcmV0 cmFpbl9saW5rX3dvcmspOworCWluaXRfY29tcGxldGlvbigmaW50ZWxfZHAtPm1zdF9yZXRyYWlu X2NvbXBsZXRpb24pOwogCiAJaWYgKFdBUk4oaW50ZWxfZGlnX3BvcnQtPm1heF9sYW5lcyA8IDEs CiAJCSAiTm90IGVub3VnaCBsYW5lcyAoJWQpIGZvciBEUCBvbiBwb3J0ICVjXG4iLApkaWZmIC0t Z2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHBfbXN0LmMgYi9kcml2ZXJzL2dwdS9k cm0vaTkxNS9pbnRlbF9kcF9tc3QuYwppbmRleCBjMDU1MzQ1NmIxOGUuLjMxMjAyZjgzOGU4OSAx MDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHBfbXN0LmMKKysrIGIvZHJp dmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHBfbXN0LmMKQEAgLTExMCwyMSArMTEwLDMyIEBAIHN0 YXRpYyBpbnQgaW50ZWxfZHBfbXN0X2F0b21pY19jaGVjayhzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAq Y29ubmVjdG9yLAogCXN0cnVjdCBkcm1fY29ubmVjdG9yX3N0YXRlICpvbGRfY29ubl9zdGF0ZTsK IAlzdHJ1Y3QgZHJtX2NydGMgKm9sZF9jcnRjOwogCXN0cnVjdCBkcm1fY3J0Y19zdGF0ZSAqY3J0 Y19zdGF0ZTsKKwlzdHJ1Y3QgZHJtX2RwX21zdF90b3BvbG9neV9tZ3IgKm1ncjsKKwlzdHJ1Y3Qg ZHJtX2VuY29kZXIgKmVuY29kZXI7CiAJaW50IHNsb3RzLCByZXQgPSAwOworCWJvb2wgY291bGRf cmV0cmFpbiA9IGZhbHNlOworCisJaWYgKG5ld19jb25uX3N0YXRlLT5jcnRjKSB7CisJCWNydGNf c3RhdGUgPSBkcm1fYXRvbWljX2dldF9uZXdfY3J0Y19zdGF0ZSgKKwkJICAgIHN0YXRlLCBuZXdf Y29ubl9zdGF0ZS0+Y3J0Yyk7CisJCWlmIChjcnRjX3N0YXRlICYmIGRybV9hdG9taWNfY3J0Y19u ZWVkc19tb2Rlc2V0KGNydGNfc3RhdGUpKQorCQkJY291bGRfcmV0cmFpbiA9IHRydWU7CisJfQog CiAJb2xkX2Nvbm5fc3RhdGUgPSBkcm1fYXRvbWljX2dldF9vbGRfY29ubmVjdG9yX3N0YXRlKHN0 YXRlLCBjb25uZWN0b3IpOwogCW9sZF9jcnRjID0gb2xkX2Nvbm5fc3RhdGUtPmNydGM7CiAJaWYg KCFvbGRfY3J0YykKLQkJcmV0dXJuIHJldDsKKwkJZ290byBvdXQ7CiAKIAljcnRjX3N0YXRlID0g ZHJtX2F0b21pY19nZXRfbmV3X2NydGNfc3RhdGUoc3RhdGUsIG9sZF9jcnRjKTsKLQlzbG90cyA9 IHRvX2ludGVsX2NydGNfc3RhdGUoY3J0Y19zdGF0ZSktPmRwX21fbi50dTsKLQlpZiAoZHJtX2F0 b21pY19jcnRjX25lZWRzX21vZGVzZXQoY3J0Y19zdGF0ZSkgJiYgc2xvdHMgPiAwKSB7Ci0JCXN0 cnVjdCBkcm1fZHBfbXN0X3RvcG9sb2d5X21nciAqbWdyOwotCQlzdHJ1Y3QgZHJtX2VuY29kZXIg Km9sZF9lbmNvZGVyOworCWlmICghZHJtX2F0b21pY19jcnRjX25lZWRzX21vZGVzZXQoY3J0Y19z dGF0ZSkpCisJCWdvdG8gb3V0OworCWNvdWxkX3JldHJhaW4gPSB0cnVlOwogCi0JCW9sZF9lbmNv ZGVyID0gb2xkX2Nvbm5fc3RhdGUtPmJlc3RfZW5jb2RlcjsKLQkJbWdyID0gJmVuY190b19tc3Qo b2xkX2VuY29kZXIpLT5wcmltYXJ5LT5kcC5tc3RfbWdyOworCXNsb3RzID0gdG9faW50ZWxfY3J0 Y19zdGF0ZShjcnRjX3N0YXRlKS0+ZHBfbV9uLnR1OworCWlmIChzbG90cyA+IDApIHsKKwkJZW5j b2RlciA9IG9sZF9jb25uX3N0YXRlLT5iZXN0X2VuY29kZXI7CisJCW1nciA9ICZlbmNfdG9fbXN0 KGVuY29kZXIpLT5wcmltYXJ5LT5kcC5tc3RfbWdyOwogCiAJCXJldCA9IGRybV9kcF9hdG9taWNf cmVsZWFzZV92Y3BpX3Nsb3RzKHN0YXRlLCBtZ3IsIHNsb3RzKTsKIAkJaWYgKHJldCkKQEAgLTEz Miw2ICsxNDMsMTggQEAgc3RhdGljIGludCBpbnRlbF9kcF9tc3RfYXRvbWljX2NoZWNrKHN0cnVj dCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IsCiAJCWVsc2UKIAkJCXRvX2ludGVsX2NydGNfc3Rh dGUoY3J0Y19zdGF0ZSktPmRwX21fbi50dSA9IDA7CiAJfQorCitvdXQ6CisJaWYgKGNvdWxkX3Jl dHJhaW4gJiYKKwkgICAgb2xkX2Nvbm5fc3RhdGUtPmxpbmtfc3RhdHVzID09IERSTV9NT0RFX0xJ TktfU1RBVFVTX0JBRCkgeworCQlpZiAobmV3X2Nvbm5fc3RhdGUtPmJlc3RfZW5jb2RlcikKKwkJ CWVuY29kZXIgPSBuZXdfY29ubl9zdGF0ZS0+YmVzdF9lbmNvZGVyOworCQllbHNlCisJCQllbmNv ZGVyID0gb2xkX2Nvbm5fc3RhdGUtPmJlc3RfZW5jb2RlcjsKKworCQltZ3IgPSAmZW5jX3RvX21z dChlbmNvZGVyKS0+cHJpbWFyeS0+ZHAubXN0X21ncjsKKwkJcmV0ID0gZHJtX2F0b21pY19kcF9t c3RfcmV0cmFpbl90b3BvbG9neShzdGF0ZSwgbWdyKTsKKwl9CiAJcmV0dXJuIHJldDsKIH0KIApA QCAtMTg2LDkgKzIwOSwxMiBAQCBzdGF0aWMgdm9pZCBpbnRlbF9tc3RfcG9zdF9kaXNhYmxlX2Rw KHN0cnVjdCBpbnRlbF9lbmNvZGVyICplbmNvZGVyLAogCWludGVsX2RwLT5hY3RpdmVfbXN0X2xp bmtzLS07CiAKIAlpbnRlbF9tc3QtPmNvbm5lY3RvciA9IE5VTEw7Ci0JaWYgKGludGVsX2RwLT5h Y3RpdmVfbXN0X2xpbmtzID09IDApCisJaWYgKGludGVsX2RwLT5hY3RpdmVfbXN0X2xpbmtzID09 IDApIHsKKwkJaW50ZWxfZHAtPm1zdF9saW5rX2lzX2JhZCA9IGZhbHNlOworCiAJCWludGVsX2Rp Z19wb3J0LT5iYXNlLnBvc3RfZGlzYWJsZSgmaW50ZWxfZGlnX3BvcnQtPmJhc2UsCiAJCQkJCQkg IG9sZF9jcnRjX3N0YXRlLCBOVUxMKTsKKwl9CiAKIAlEUk1fREVCVUdfS01TKCJhY3RpdmUgbGlu a3MgJWRcbiIsIGludGVsX2RwLT5hY3RpdmVfbXN0X2xpbmtzKTsKIH0KZGlmZiAtLWdpdCBhL2Ry aXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rydi5oIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50 ZWxfZHJ2LmgKaW5kZXggZTVkM2VmNjc1NGE1Li5jNjNjNjU5MjNjM2UgMTAwNjQ0Ci0tLSBhL2Ry aXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rydi5oCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1 L2ludGVsX2Rydi5oCkBAIC0xMTIyLDYgKzExMjIsMTMgQEAgc3RydWN0IGludGVsX2RwIHsKIAkv KiBtc3QgY29ubmVjdG9yIGxpc3QgKi8KIAlzdHJ1Y3QgaW50ZWxfZHBfbXN0X2VuY29kZXIgKm1z dF9lbmNvZGVyc1tJOTE1X01BWF9QSVBFU107CiAJc3RydWN0IGRybV9kcF9tc3RfdG9wb2xvZ3lf bWdyIG1zdF9tZ3I7CisJLyogV2UgY2FuJ3QgaGFuZGxlIHJldHJhaW5pbmcgZnJvbSB0aGUgZGln IHdvcmtxdWV1ZSwgc28uLi4gKi8KKwlzdHJ1Y3Qgd29ya19zdHJ1Y3QgbXN0X3JldHJhaW5fd29y azsKKwlzdHJ1Y3QgY29tcGxldGlvbiBtc3RfcmV0cmFpbl9jb21wbGV0aW9uOworCS8qIFNldCB3 aGVuIHJldHJhaW5pbmcgdGhlIGxpbmsgYXQgdGhlIGN1cnJlbnQgcGFyYW1ldGVycyBpcworCSAq IGltcG9zc2libGUgZm9yIGFuIE1TVCBjb25uZWN0aW9uCisJICovCisJYm9vbCBtc3RfbGlua19p c19iYWQ7CiAKIAl1aW50MzJfdCAoKmdldF9hdXhfY2xvY2tfZGl2aWRlcikoc3RydWN0IGludGVs X2RwICpkcCwgaW50IGluZGV4KTsKIAkvKgpAQCAtMTY4OSw2ICsxNjk2LDcgQEAgdm9pZCBpbnRl bF9kcF9jb21wdXRlX3JhdGUoc3RydWN0IGludGVsX2RwICppbnRlbF9kcCwgaW50IHBvcnRfY2xv Y2ssCiBib29sIGludGVsX2RwX3NvdXJjZV9zdXBwb3J0c19oYnIyKHN0cnVjdCBpbnRlbF9kcCAq aW50ZWxfZHApOwogYm9vbAogaW50ZWxfZHBfZ2V0X2xpbmtfc3RhdHVzKHN0cnVjdCBpbnRlbF9k cCAqaW50ZWxfZHAsIHVpbnQ4X3QgbGlua19zdGF0dXNbRFBfTElOS19TVEFUVVNfU0laRV0pOwor aW50IGludGVsX2RwX2dldF9jcnRjX21hc2soc3RydWN0IGludGVsX2RwICppbnRlbF9kcCk7CiAK IHN0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IGludGVsX2RwX3VudXNlZF9sYW5lX21hc2soaW50 IGxhbmVfY291bnQpCiB7Ci0tIAoyLjE0LjMKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCkludGVsLWdmeCBtYWlsaW5nIGxpc3QKSW50ZWwtZ2Z4QGxpc3Rz LmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2ludGVsLWdmeAo=