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.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT 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 0ADB2C4360F for ; Wed, 13 Mar 2019 23:52:30 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B322E21019 for ; Wed, 13 Mar 2019 23:52:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727314AbfCMXw2 (ORCPT ); Wed, 13 Mar 2019 19:52:28 -0400 Received: from anholt.net ([50.246.234.109]:53774 "EHLO anholt.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726721AbfCMXw0 (ORCPT ); Wed, 13 Mar 2019 19:52:26 -0400 Received: from localhost (localhost [127.0.0.1]) by anholt.net (Postfix) with ESMTP id 5058810A1128; Wed, 13 Mar 2019 16:52:25 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at anholt.net Received: from anholt.net ([127.0.0.1]) by localhost (kingsolver.anholt.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 74E6g_cgrRHB; Wed, 13 Mar 2019 16:52:17 -0700 (PDT) Received: from eliezer.anholt.net (localhost [127.0.0.1]) by anholt.net (Postfix) with ESMTP id 8755A10A2A54; Wed, 13 Mar 2019 16:52:12 -0700 (PDT) Received: by eliezer.anholt.net (Postfix, from userid 1000) id 843342FE4655; Wed, 13 Mar 2019 16:52:11 -0700 (PDT) From: Eric Anholt To: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, david.emett@broadcom.com, thomas.spurden@broadcom.com, Eric Anholt Subject: [PATCH 3/4] drm/v3d: Refactor job management. Date: Wed, 13 Mar 2019 16:52:10 -0700 Message-Id: <20190313235211.28995-3-eric@anholt.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190313235211.28995-1-eric@anholt.net> References: <20190313235211.28995-1-eric@anholt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The CL submission had two jobs embedded in an exec struct. When I added TFU support, I had to replicate some of the exec stuff and some of the job stuff. As I went to add CSD, it became clear that actually what was in exec should just be in the two CL jobs, and it would let us share a lot more code between the 4 queues. Signed-off-by: Eric Anholt --- drivers/gpu/drm/v3d/v3d_drv.h | 77 +++---- drivers/gpu/drm/v3d/v3d_gem.c | 344 ++++++++++++++++---------------- drivers/gpu/drm/v3d/v3d_irq.c | 8 +- drivers/gpu/drm/v3d/v3d_sched.c | 259 ++++++++++++++---------- 4 files changed, 370 insertions(+), 318 deletions(-) diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 284ced85ff02..04cad5a62191 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -73,8 +73,8 @@ struct v3d_dev { struct work_struct overflow_mem_work; - struct v3d_exec_info *bin_job; - struct v3d_exec_info *render_job; + struct v3d_bin_job *bin_job; + struct v3d_render_job *render_job; struct v3d_tfu_job *tfu_job; struct v3d_queue_state queue[V3D_MAX_QUEUES]; @@ -123,7 +123,7 @@ struct v3d_bo { struct drm_mm_node node; /* List entry for the BO's position in - * v3d_exec_info->unref_list + * v3d_render_job->unref_list */ struct list_head unref_head; }; @@ -163,7 +163,15 @@ to_v3d_fence(struct dma_fence *fence) struct v3d_job { struct drm_sched_job base; - struct v3d_exec_info *exec; + struct kref refcount; + + struct v3d_dev *v3d; + + /* This is the array of BOs that were looked up at the start + * of submission. + */ + struct v3d_bo **bo; + u32 bo_count; /* An optional fence userspace can pass in for the job to depend on. */ struct dma_fence *in_fence; @@ -171,59 +179,53 @@ struct v3d_job { /* v3d fence to be signaled by IRQ handler when the job is complete. */ struct dma_fence *irq_fence; + /* scheduler fence for when the job is considered complete and + * the BO reservations can be released. + */ + struct dma_fence *done_fence; + + /* Callback for the freeing of the job on refcount going to 0. */ + void (*free)(struct kref *ref); +}; + +struct v3d_bin_job { + struct v3d_job base; + /* GPU virtual addresses of the start/end of the CL job. */ u32 start, end; u32 timedout_ctca, timedout_ctra; -}; -struct v3d_exec_info { - struct v3d_dev *v3d; + /* Corresponding render job, for attaching our overflow memory. */ + struct v3d_render_job *render; + + /* Submitted tile memory allocation start/size, tile state. */ + u32 qma, qms, qts; +}; - struct v3d_job bin, render; +struct v3d_render_job { + struct v3d_job base; - /* Fence for when the scheduler considers the binner to be - * done, for render to depend on. + /* Optional fence for the binner, to depend on before starting + * our job. */ struct dma_fence *bin_done_fence; - /* Fence for when the scheduler considers the render to be - * done, for when the BOs reservations should be complete. - */ - struct dma_fence *render_done_fence; - - struct kref refcount; + /* GPU virtual addresses of the start/end of the CL job. */ + u32 start, end; - /* This is the array of BOs that were looked up at the start of exec. */ - struct v3d_bo **bo; - u32 bo_count; + u32 timedout_ctca, timedout_ctra; /* List of overflow BOs used in the job that need to be * released once the job is complete. */ struct list_head unref_list; - - /* Submitted tile memory allocation start/size, tile state. */ - u32 qma, qms, qts; }; struct v3d_tfu_job { - struct drm_sched_job base; + struct v3d_job base; struct drm_v3d_submit_tfu args; - - /* An optional fence userspace can pass in for the job to depend on. */ - struct dma_fence *in_fence; - - /* v3d fence to be signaled by IRQ handler when the job is complete. */ - struct dma_fence *irq_fence; - - struct v3d_dev *v3d; - - struct kref refcount; - - /* This is the array of BOs that were looked up at the start of exec. */ - struct v3d_bo *bo[4]; }; /** @@ -289,8 +291,7 @@ int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int v3d_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -void v3d_exec_put(struct v3d_exec_info *exec); -void v3d_tfu_job_put(struct v3d_tfu_job *exec); +void v3d_job_put(struct v3d_job *job); void v3d_reset(struct v3d_dev *v3d); void v3d_invalidate_caches(struct v3d_dev *v3d); diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c index b06bed0835c9..2cdc914d477e 100644 --- a/drivers/gpu/drm/v3d/v3d_gem.c +++ b/drivers/gpu/drm/v3d/v3d_gem.c @@ -250,11 +250,11 @@ v3d_lock_bo_reservations(struct v3d_bo **bos, } /** - * v3d_cl_lookup_bos() - Sets up exec->bo[] with the GEM objects + * v3d_lookup_bos() - Sets up job->bo[] with the GEM objects * referenced by the job. * @dev: DRM device * @file_priv: DRM file for this fd - * @exec: V3D job being set up + * @job: V3D job being set up * * The command validator needs to reference BOs by their index within * the submitted job's BO list. This does the validation of the job's @@ -264,18 +264,19 @@ v3d_lock_bo_reservations(struct v3d_bo **bos, * failure, because that will happen at v3d_exec_cleanup() time. */ static int -v3d_cl_lookup_bos(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_v3d_submit_cl *args, - struct v3d_exec_info *exec) +v3d_lookup_bos(struct drm_device *dev, + struct drm_file *file_priv, + struct v3d_job *job, + u64 bo_handles, + u32 bo_count) { u32 *handles; int ret = 0; int i; - exec->bo_count = args->bo_handle_count; + job->bo_count = bo_count; - if (!exec->bo_count) { + if (!job->bo_count) { /* See comment on bo_index for why we have to check * this. */ @@ -283,15 +284,15 @@ v3d_cl_lookup_bos(struct drm_device *dev, return -EINVAL; } - exec->bo = kvmalloc_array(exec->bo_count, - sizeof(struct drm_gem_cma_object *), - GFP_KERNEL | __GFP_ZERO); - if (!exec->bo) { + job->bo = kvmalloc_array(job->bo_count, + sizeof(struct drm_gem_cma_object *), + GFP_KERNEL | __GFP_ZERO); + if (!job->bo) { DRM_DEBUG("Failed to allocate validated BO pointers\n"); return -ENOMEM; } - handles = kvmalloc_array(exec->bo_count, sizeof(u32), GFP_KERNEL); + handles = kvmalloc_array(job->bo_count, sizeof(u32), GFP_KERNEL); if (!handles) { ret = -ENOMEM; DRM_DEBUG("Failed to allocate incoming GEM handles\n"); @@ -299,15 +300,15 @@ v3d_cl_lookup_bos(struct drm_device *dev, } if (copy_from_user(handles, - (void __user *)(uintptr_t)args->bo_handles, - exec->bo_count * sizeof(u32))) { + (void __user *)(uintptr_t)bo_handles, + job->bo_count * sizeof(u32))) { ret = -EFAULT; DRM_DEBUG("Failed to copy in GEM handles\n"); goto fail; } spin_lock(&file_priv->table_lock); - for (i = 0; i < exec->bo_count; i++) { + for (i = 0; i < job->bo_count; i++) { struct drm_gem_object *bo = idr_find(&file_priv->object_idr, handles[i]); if (!bo) { @@ -318,7 +319,7 @@ v3d_cl_lookup_bos(struct drm_device *dev, goto fail; } drm_gem_object_get(bo); - exec->bo[i] = to_v3d_bo(bo); + job->bo[i] = to_v3d_bo(bo); } spin_unlock(&file_priv->table_lock); @@ -328,67 +329,44 @@ v3d_cl_lookup_bos(struct drm_device *dev, } static void -v3d_exec_cleanup(struct kref *ref) +v3d_job_free(struct kref *ref) { - struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info, - refcount); - struct v3d_dev *v3d = exec->v3d; - unsigned int i; - struct v3d_bo *bo, *save; - - dma_fence_put(exec->bin.in_fence); - dma_fence_put(exec->render.in_fence); - - dma_fence_put(exec->bin.irq_fence); - dma_fence_put(exec->render.irq_fence); - - dma_fence_put(exec->bin_done_fence); - dma_fence_put(exec->render_done_fence); - - for (i = 0; i < exec->bo_count; i++) - drm_gem_object_put_unlocked(&exec->bo[i]->base.base); - kvfree(exec->bo); + struct v3d_job *job = container_of(ref, struct v3d_job, refcount); + int i; - list_for_each_entry_safe(bo, save, &exec->unref_list, unref_head) { - drm_gem_object_put_unlocked(&bo->base.base); + for (i = 0; i < job->bo_count; i++) { + if (job->bo[i]) + drm_gem_object_put_unlocked(&job->bo[i]->base.base); } + kvfree(job->bo); - pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); + dma_fence_put(job->in_fence); + dma_fence_put(job->irq_fence); + dma_fence_put(job->done_fence); - kfree(exec); -} + pm_runtime_mark_last_busy(job->v3d->dev); + pm_runtime_put_autosuspend(job->v3d->dev); -void v3d_exec_put(struct v3d_exec_info *exec) -{ - kref_put(&exec->refcount, v3d_exec_cleanup); + kfree(job); } static void -v3d_tfu_job_cleanup(struct kref *ref) +v3d_render_job_free(struct kref *ref) { - struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job, - refcount); - struct v3d_dev *v3d = job->v3d; - unsigned int i; - - dma_fence_put(job->in_fence); - dma_fence_put(job->irq_fence); + struct v3d_render_job *job = container_of(ref, struct v3d_render_job, + base.refcount); + struct v3d_bo *bo, *save; - for (i = 0; i < ARRAY_SIZE(job->bo); i++) { - if (job->bo[i]) - drm_gem_object_put_unlocked(&job->bo[i]->base.base); + list_for_each_entry_safe(bo, save, &job->unref_list, unref_head) { + drm_gem_object_put_unlocked(&bo->base.base); } - pm_runtime_mark_last_busy(v3d->dev); - pm_runtime_put_autosuspend(v3d->dev); - - kfree(job); + v3d_job_free(ref); } -void v3d_tfu_job_put(struct v3d_tfu_job *job) +void v3d_job_put(struct v3d_job *job) { - kref_put(&job->refcount, v3d_tfu_job_cleanup); + kref_put(&job->refcount, job->free); } int @@ -424,6 +402,71 @@ v3d_wait_bo_ioctl(struct drm_device *dev, void *data, return ret; } +static int +v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv, + struct v3d_job *job, void (*free)(struct kref *ref), + u32 in_sync) +{ + int ret; + + job->v3d = v3d; + job->free = free; + + ret = pm_runtime_get_sync(v3d->dev); + if (ret < 0) + return ret; + + ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &job->in_fence); + if (ret == -EINVAL) { + pm_runtime_put_autosuspend(v3d->dev); + return ret; + } + + kref_init(&job->refcount); + + return 0; +} + +static int +v3d_push_job(struct v3d_file_priv *v3d_priv, + struct v3d_job *job, enum v3d_queue queue) +{ + int ret; + + ret = drm_sched_job_init(&job->base, &v3d_priv->sched_entity[queue], + v3d_priv); + if (ret) + return ret; + + job->done_fence = dma_fence_get(&job->base.s_fence->finished); + + /* put by scheduler job completion */ + kref_get(&job->refcount); + + drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[queue]); + + return 0; +} + +static void +v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv, + struct v3d_job *job, + struct ww_acquire_ctx *acquire_ctx, + u32 out_sync) +{ + struct drm_syncobj *sync_out; + + v3d_attach_object_fences(job->bo, job->bo_count, job->done_fence); + v3d_unlock_bo_reservations(job->bo, job->bo_count, acquire_ctx); + + /* Update the return sync object for the job */ + sync_out = drm_syncobj_find(file_priv, out_sync); + if (sync_out) { + drm_syncobj_replace_fence(sync_out, job->done_fence); + drm_syncobj_put(sync_out); + } +} + /** * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D. * @dev: DRM device @@ -443,9 +486,9 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, struct v3d_dev *v3d = to_v3d_dev(dev); struct v3d_file_priv *v3d_priv = file_priv->driver_priv; struct drm_v3d_submit_cl *args = data; - struct v3d_exec_info *exec; + struct v3d_bin_job *bin = NULL; + struct v3d_render_job *render; struct ww_acquire_ctx acquire_ctx; - struct drm_syncobj *sync_out; int ret = 0; trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end); @@ -455,100 +498,83 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); - if (!exec) + render = kcalloc(1, sizeof(*render), GFP_KERNEL); + if (!render) return -ENOMEM; - ret = pm_runtime_get_sync(v3d->dev); - if (ret < 0) { - kfree(exec); + render->start = args->rcl_start; + render->end = args->rcl_end; + INIT_LIST_HEAD(&render->unref_list); + + ret = v3d_job_init(v3d, file_priv, &render->base, + v3d_render_job_free, args->in_sync_rcl); + if (ret) { + kfree(render); return ret; } - kref_init(&exec->refcount); + if (args->bcl_start != args->bcl_end) { + bin = kcalloc(1, sizeof(*bin), GFP_KERNEL); + if (!bin) + return -ENOMEM; - ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl, - 0, 0, &exec->bin.in_fence); - if (ret == -EINVAL) - goto fail; + ret = v3d_job_init(v3d, file_priv, &bin->base, + v3d_job_free, args->in_sync_bcl); + if (ret) { + v3d_job_put(&render->base); + return ret; + } - ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl, - 0, 0, &exec->render.in_fence); - if (ret == -EINVAL) - goto fail; + bin->start = args->bcl_start; + bin->end = args->bcl_end; + bin->qma = args->qma; + bin->qms = args->qms; + bin->qts = args->qts; + bin->render = render; + } - exec->qma = args->qma; - exec->qms = args->qms; - exec->qts = args->qts; - exec->bin.exec = exec; - exec->bin.start = args->bcl_start; - exec->bin.end = args->bcl_end; - exec->render.exec = exec; - exec->render.start = args->rcl_start; - exec->render.end = args->rcl_end; - exec->v3d = v3d; - INIT_LIST_HEAD(&exec->unref_list); - - ret = v3d_cl_lookup_bos(dev, file_priv, args, exec); + ret = v3d_lookup_bos(dev, file_priv, &render->base, + args->bo_handles, args->bo_handle_count); if (ret) goto fail; - ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count, + ret = v3d_lock_bo_reservations(render->base.bo, render->base.bo_count, &acquire_ctx); if (ret) goto fail; mutex_lock(&v3d->sched_lock); - if (exec->bin.start != exec->bin.end) { - ret = drm_sched_job_init(&exec->bin.base, - &v3d_priv->sched_entity[V3D_BIN], - v3d_priv); + if (bin) { + ret = v3d_push_job(v3d_priv, &bin->base, V3D_BIN); if (ret) goto fail_unreserve; - exec->bin_done_fence = - dma_fence_get(&exec->bin.base.s_fence->finished); - - kref_get(&exec->refcount); /* put by scheduler job completion */ - drm_sched_entity_push_job(&exec->bin.base, - &v3d_priv->sched_entity[V3D_BIN]); + render->bin_done_fence = dma_fence_get(bin->base.done_fence); } - ret = drm_sched_job_init(&exec->render.base, - &v3d_priv->sched_entity[V3D_RENDER], - v3d_priv); + ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER); if (ret) goto fail_unreserve; - - exec->render_done_fence = - dma_fence_get(&exec->render.base.s_fence->finished); - - kref_get(&exec->refcount); /* put by scheduler job completion */ - drm_sched_entity_push_job(&exec->render.base, - &v3d_priv->sched_entity[V3D_RENDER]); mutex_unlock(&v3d->sched_lock); - v3d_attach_object_fences(exec->bo, exec->bo_count, - exec->render_done_fence); - - v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); + v3d_attach_fences_and_unlock_reservation(file_priv, + &render->base, &acquire_ctx, + args->out_sync); - /* Update the return sync object for the */ - sync_out = drm_syncobj_find(file_priv, args->out_sync); - if (sync_out) { - drm_syncobj_replace_fence(sync_out, exec->render_done_fence); - drm_syncobj_put(sync_out); - } - - v3d_exec_put(exec); + if (bin) + v3d_job_put(&bin->base); + v3d_job_put(&render->base); return 0; fail_unreserve: mutex_unlock(&v3d->sched_lock); - v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx); + v3d_unlock_bo_reservations(render->base.bo, + render->base.bo_count, &acquire_ctx); fail: - v3d_exec_put(exec); + if (bin) + v3d_job_put(&bin->base); + v3d_job_put(&render->base); return ret; } @@ -571,10 +597,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, struct drm_v3d_submit_tfu *args = data; struct v3d_tfu_job *job; struct ww_acquire_ctx acquire_ctx; - struct drm_syncobj *sync_out; - struct dma_fence *sched_done_fence; int ret = 0; - int bo_count; trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia); @@ -582,81 +605,66 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, if (!job) return -ENOMEM; - ret = pm_runtime_get_sync(v3d->dev); - if (ret < 0) { + ret = v3d_job_init(v3d, file_priv, &job->base, + v3d_job_free, args->in_sync); + if (ret) { kfree(job); return ret; } - kref_init(&job->refcount); - - ret = drm_syncobj_find_fence(file_priv, args->in_sync, - 0, 0, &job->in_fence); - if (ret == -EINVAL) - goto fail; - + job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles), + sizeof(*job->base.bo), GFP_KERNEL); job->args = *args; - job->v3d = v3d; spin_lock(&file_priv->table_lock); - for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) { + for (job->base.bo_count = 0; + job->base.bo_count < ARRAY_SIZE(args->bo_handles); + job->base.bo_count++) { struct drm_gem_object *bo; - if (!args->bo_handles[bo_count]) + if (!args->bo_handles[job->base.bo_count]) break; bo = idr_find(&file_priv->object_idr, - args->bo_handles[bo_count]); + args->bo_handles[job->base.bo_count]); if (!bo) { DRM_DEBUG("Failed to look up GEM BO %d: %d\n", - bo_count, args->bo_handles[bo_count]); + job->base.bo_count, + args->bo_handles[job->base.bo_count]); ret = -ENOENT; spin_unlock(&file_priv->table_lock); goto fail; } drm_gem_object_get(bo); - job->bo[bo_count] = to_v3d_bo(bo); + job->base.bo[job->base.bo_count] = to_v3d_bo(bo); } spin_unlock(&file_priv->table_lock); - ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx); + ret = v3d_lock_bo_reservations(job->base.bo, job->base.bo_count, + &acquire_ctx); if (ret) goto fail; mutex_lock(&v3d->sched_lock); - ret = drm_sched_job_init(&job->base, - &v3d_priv->sched_entity[V3D_TFU], - v3d_priv); + ret = v3d_push_job(v3d_priv, &job->base, V3D_TFU); if (ret) goto fail_unreserve; - - sched_done_fence = dma_fence_get(&job->base.s_fence->finished); - - kref_get(&job->refcount); /* put by scheduler job completion */ - drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]); mutex_unlock(&v3d->sched_lock); - v3d_attach_object_fences(job->bo, bo_count, sched_done_fence); - - v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); - - /* Update the return sync object */ - sync_out = drm_syncobj_find(file_priv, args->out_sync); - if (sync_out) { - drm_syncobj_replace_fence(sync_out, sched_done_fence); - drm_syncobj_put(sync_out); - } - dma_fence_put(sched_done_fence); + v3d_attach_fences_and_unlock_reservation(file_priv, + &job->base, &acquire_ctx, + args->out_sync); - v3d_tfu_job_put(job); + v3d_job_put(&job->base); return 0; fail_unreserve: mutex_unlock(&v3d->sched_lock); - v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx); + v3d_unlock_bo_reservations(job->base.bo, job->base.bo_count, + &acquire_ctx); fail: - v3d_tfu_job_put(job); + v3d_job_put(&job->base); return ret; } @@ -714,7 +722,7 @@ v3d_gem_destroy(struct drm_device *dev) v3d_sched_fini(v3d); - /* Waiting for exec to finish would need to be done before + /* Waiting for jobs to finish would need to be done before * unregistering V3D. */ WARN_ON(v3d->bin_job); diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index 044062607577..480ba6666a4d 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -62,7 +62,7 @@ v3d_overflow_mem_work(struct work_struct *work) } drm_gem_object_get(obj); - list_add_tail(&bo->unref_head, &v3d->bin_job->unref_list); + list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list); spin_unlock_irqrestore(&v3d->job_lock, irqflags); V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT); @@ -96,7 +96,7 @@ v3d_irq(int irq, void *arg) if (intsts & V3D_INT_FLDONE) { struct v3d_fence *fence = - to_v3d_fence(v3d->bin_job->bin.irq_fence); + to_v3d_fence(v3d->bin_job->base.irq_fence); trace_v3d_bcl_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); @@ -105,7 +105,7 @@ v3d_irq(int irq, void *arg) if (intsts & V3D_INT_FRDONE) { struct v3d_fence *fence = - to_v3d_fence(v3d->render_job->render.irq_fence); + to_v3d_fence(v3d->render_job->base.irq_fence); trace_v3d_rcl_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); @@ -141,7 +141,7 @@ v3d_hub_irq(int irq, void *arg) if (intsts & V3D_HUB_INT_TFUC) { struct v3d_fence *fence = - to_v3d_fence(v3d->tfu_job->irq_fence); + to_v3d_fence(v3d->tfu_job->base.irq_fence); trace_v3d_tfu_irq(&v3d->drm, fence->seqno); dma_fence_signal(&fence->base); diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c index e740f3b99aa5..884f00f5edf4 100644 --- a/drivers/gpu/drm/v3d/v3d_sched.c +++ b/drivers/gpu/drm/v3d/v3d_sched.c @@ -30,43 +30,44 @@ to_v3d_job(struct drm_sched_job *sched_job) return container_of(sched_job, struct v3d_job, base); } -static struct v3d_tfu_job * -to_tfu_job(struct drm_sched_job *sched_job) +static struct v3d_bin_job * +to_bin_job(struct drm_sched_job *sched_job) { - return container_of(sched_job, struct v3d_tfu_job, base); + return container_of(sched_job, struct v3d_bin_job, base.base); } -static void -v3d_job_free(struct drm_sched_job *sched_job) +static struct v3d_render_job * +to_render_job(struct drm_sched_job *sched_job) { - struct v3d_job *job = to_v3d_job(sched_job); - - drm_sched_job_cleanup(sched_job); + return container_of(sched_job, struct v3d_render_job, base.base); +} - v3d_exec_put(job->exec); +static struct v3d_tfu_job * +to_tfu_job(struct drm_sched_job *sched_job) +{ + return container_of(sched_job, struct v3d_tfu_job, base.base); } static void -v3d_tfu_job_free(struct drm_sched_job *sched_job) +v3d_job_free(struct drm_sched_job *sched_job) { - struct v3d_tfu_job *job = to_tfu_job(sched_job); + struct v3d_job *job = to_v3d_job(sched_job); drm_sched_job_cleanup(sched_job); - - v3d_tfu_job_put(job); + v3d_job_put(job); } /** - * Returns the fences that the bin or render job depends on, one by one. - * v3d_job_run() won't be called until all of them have been signaled. + * Returns the fences that the job depends on, one by one. + * + * If placed in the scheduler's .dependency method, the corresponding + * .run_job won't be called until all of them have been signaled. */ static struct dma_fence * v3d_job_dependency(struct drm_sched_job *sched_job, struct drm_sched_entity *s_entity) { struct v3d_job *job = to_v3d_job(sched_job); - struct v3d_exec_info *exec = job->exec; - enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER; struct dma_fence *fence; fence = job->in_fence; @@ -75,113 +76,132 @@ v3d_job_dependency(struct drm_sched_job *sched_job, return fence; } - if (q == V3D_RENDER) { - /* If we had a bin job, the render job definitely depends on - * it. We first have to wait for bin to be scheduled, so that - * its done_fence is created. - */ - fence = exec->bin_done_fence; - if (fence) { - exec->bin_done_fence = NULL; - return fence; - } - } - /* XXX: Wait on a fence for switching the GMP if necessary, * and then do so. */ - return fence; + return NULL; } /** - * Returns the fences that the TFU job depends on, one by one. - * v3d_tfu_job_run() won't be called until all of them have been - * signaled. + * Returns the fences that the render job depends on, one by one. + * v3d_job_run() won't be called until all of them have been signaled. */ static struct dma_fence * -v3d_tfu_job_dependency(struct drm_sched_job *sched_job, - struct drm_sched_entity *s_entity) +v3d_render_job_dependency(struct drm_sched_job *sched_job, + struct drm_sched_entity *s_entity) { - struct v3d_tfu_job *job = to_tfu_job(sched_job); + struct v3d_render_job *job = to_render_job(sched_job); struct dma_fence *fence; - fence = job->in_fence; + fence = v3d_job_dependency(sched_job, s_entity); + if (fence) + return fence; + + /* If we had a bin job, the render job definitely depends on + * it. We first have to wait for bin to be scheduled, so that + * its done_fence is created. + */ + fence = job->bin_done_fence; if (fence) { - job->in_fence = NULL; + job->bin_done_fence = NULL; return fence; } - return NULL; + return fence; } -static struct dma_fence *v3d_job_run(struct drm_sched_job *sched_job) +static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job) { - struct v3d_job *job = to_v3d_job(sched_job); - struct v3d_exec_info *exec = job->exec; - enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER; - struct v3d_dev *v3d = exec->v3d; + struct v3d_bin_job *job = to_bin_job(sched_job); + struct v3d_dev *v3d = job->base.v3d; struct drm_device *dev = &v3d->drm; struct dma_fence *fence; unsigned long irqflags; - if (unlikely(job->base.s_fence->finished.error)) + if (unlikely(job->base.base.s_fence->finished.error)) return NULL; /* Lock required around bin_job update vs * v3d_overflow_mem_work(). */ spin_lock_irqsave(&v3d->job_lock, irqflags); - if (q == V3D_BIN) { - v3d->bin_job = job->exec; - - /* Clear out the overflow allocation, so we don't - * reuse the overflow attached to a previous job. - */ - V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0); - } else { - v3d->render_job = job->exec; - } + v3d->bin_job = job; + /* Clear out the overflow allocation, so we don't + * reuse the overflow attached to a previous job. + */ + V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0); spin_unlock_irqrestore(&v3d->job_lock, irqflags); - /* Can we avoid this flush when q==RENDER? We need to be - * careful of scheduling, though -- imagine job0 rendering to - * texture and job1 reading, and them being executed as bin0, - * bin1, render0, render1, so that render1's flush at bin time + v3d_invalidate_caches(v3d); + + fence = v3d_fence_create(v3d, V3D_BIN); + if (IS_ERR(fence)) + return NULL; + + if (job->base.irq_fence) + dma_fence_put(job->base.irq_fence); + job->base.irq_fence = dma_fence_get(fence); + + trace_v3d_submit_cl(dev, false, to_v3d_fence(fence)->seqno, + job->start, job->end); + + /* Set the current and end address of the control list. + * Writing the end register is what starts the job. + */ + if (job->qma) { + V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, job->qma); + V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, job->qms); + } + if (job->qts) { + V3D_CORE_WRITE(0, V3D_CLE_CT0QTS, + V3D_CLE_CT0QTS_ENABLE | + job->qts); + } + V3D_CORE_WRITE(0, V3D_CLE_CT0QBA, job->start); + V3D_CORE_WRITE(0, V3D_CLE_CT0QEA, job->end); + + return fence; +} + +static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job) +{ + struct v3d_render_job *job = to_render_job(sched_job); + struct v3d_dev *v3d = job->base.v3d; + struct drm_device *dev = &v3d->drm; + struct dma_fence *fence; + + if (unlikely(job->base.base.s_fence->finished.error)) + return NULL; + + v3d->render_job = job; + + /* Can we avoid this flush? We need to be careful of + * scheduling, though -- imagine job0 rendering to texture and + * job1 reading, and them being executed as bin0, bin1, + * render0, render1, so that render1's flush at bin time * wasn't enough. */ v3d_invalidate_caches(v3d); - fence = v3d_fence_create(v3d, q); + fence = v3d_fence_create(v3d, V3D_RENDER); if (IS_ERR(fence)) return NULL; - if (job->irq_fence) - dma_fence_put(job->irq_fence); - job->irq_fence = dma_fence_get(fence); + if (job->base.irq_fence) + dma_fence_put(job->base.irq_fence); + job->base.irq_fence = dma_fence_get(fence); - trace_v3d_submit_cl(dev, q == V3D_RENDER, to_v3d_fence(fence)->seqno, + trace_v3d_submit_cl(dev, true, to_v3d_fence(fence)->seqno, job->start, job->end); - if (q == V3D_BIN) { - if (exec->qma) { - V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, exec->qma); - V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, exec->qms); - } - if (exec->qts) { - V3D_CORE_WRITE(0, V3D_CLE_CT0QTS, - V3D_CLE_CT0QTS_ENABLE | - exec->qts); - } - } else { - /* XXX: Set the QCFG */ - } + /* XXX: Set the QCFG */ /* Set the current and end address of the control list. * Writing the end register is what starts the job. */ - V3D_CORE_WRITE(0, V3D_CLE_CTNQBA(q), job->start); - V3D_CORE_WRITE(0, V3D_CLE_CTNQEA(q), job->end); + V3D_CORE_WRITE(0, V3D_CLE_CT1QBA, job->start); + V3D_CORE_WRITE(0, V3D_CLE_CT1QEA, job->end); return fence; } @@ -190,7 +210,7 @@ static struct dma_fence * v3d_tfu_job_run(struct drm_sched_job *sched_job) { struct v3d_tfu_job *job = to_tfu_job(sched_job); - struct v3d_dev *v3d = job->v3d; + struct v3d_dev *v3d = job->base.v3d; struct drm_device *dev = &v3d->drm; struct dma_fence *fence; @@ -199,9 +219,9 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job) return NULL; v3d->tfu_job = job; - if (job->irq_fence) - dma_fence_put(job->irq_fence); - job->irq_fence = dma_fence_get(fence); + if (job->base.irq_fence) + dma_fence_put(job->base.irq_fence); + job->base.irq_fence = dma_fence_get(fence); trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno); @@ -251,51 +271,74 @@ v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) mutex_unlock(&v3d->reset_lock); } +/* If the current address or return address have changed, then the GPU + * has probably made progress and we should delay the reset. This + * could fail if the GPU got in an infinite loop in the CL, but that + * is pretty unlikely outside of an i-g-t testcase. + */ static void -v3d_job_timedout(struct drm_sched_job *sched_job) +v3d_cl_job_timedout(struct drm_sched_job *sched_job, enum v3d_queue q, + u32 *timedout_ctca, u32 *timedout_ctra) { struct v3d_job *job = to_v3d_job(sched_job); - struct v3d_exec_info *exec = job->exec; - struct v3d_dev *v3d = exec->v3d; - enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER; - u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q)); - u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q)); - - /* If the current address or return address have changed, then - * the GPU has probably made progress and we should delay the - * reset. This could fail if the GPU got in an infinite loop - * in the CL, but that is pretty unlikely outside of an i-g-t - * testcase. - */ - if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) { - job->timedout_ctca = ctca; - job->timedout_ctra = ctra; + struct v3d_dev *v3d = job->v3d; + u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(q)); + u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(q)); + + if (*timedout_ctca != ctca || *timedout_ctra != ctra) { + *timedout_ctca = ctca; + *timedout_ctra = ctra; return; } v3d_gpu_reset_for_timeout(v3d, sched_job); } +static void +v3d_bin_job_timedout(struct drm_sched_job *sched_job) +{ + struct v3d_bin_job *job = to_bin_job(sched_job); + + v3d_cl_job_timedout(sched_job, V3D_BIN, + &job->timedout_ctca, &job->timedout_ctra); +} + +static void +v3d_render_job_timedout(struct drm_sched_job *sched_job) +{ + struct v3d_render_job *job = to_render_job(sched_job); + + v3d_cl_job_timedout(sched_job, V3D_RENDER, + &job->timedout_ctca, &job->timedout_ctra); +} + static void v3d_tfu_job_timedout(struct drm_sched_job *sched_job) { - struct v3d_tfu_job *job = to_tfu_job(sched_job); + struct v3d_job *job = to_v3d_job(sched_job); v3d_gpu_reset_for_timeout(job->v3d, sched_job); } -static const struct drm_sched_backend_ops v3d_sched_ops = { +static const struct drm_sched_backend_ops v3d_bin_sched_ops = { .dependency = v3d_job_dependency, - .run_job = v3d_job_run, - .timedout_job = v3d_job_timedout, - .free_job = v3d_job_free + .run_job = v3d_bin_job_run, + .timedout_job = v3d_bin_job_timedout, + .free_job = v3d_job_free, +}; + +static const struct drm_sched_backend_ops v3d_render_sched_ops = { + .dependency = v3d_render_job_dependency, + .run_job = v3d_render_job_run, + .timedout_job = v3d_render_job_timedout, + .free_job = v3d_job_free, }; static const struct drm_sched_backend_ops v3d_tfu_sched_ops = { - .dependency = v3d_tfu_job_dependency, + .dependency = v3d_job_dependency, .run_job = v3d_tfu_job_run, .timedout_job = v3d_tfu_job_timedout, - .free_job = v3d_tfu_job_free + .free_job = v3d_job_free, }; int @@ -307,7 +350,7 @@ v3d_sched_init(struct v3d_dev *v3d) int ret; ret = drm_sched_init(&v3d->queue[V3D_BIN].sched, - &v3d_sched_ops, + &v3d_bin_sched_ops, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), "v3d_bin"); @@ -317,7 +360,7 @@ v3d_sched_init(struct v3d_dev *v3d) } ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched, - &v3d_sched_ops, + &v3d_render_sched_ops, hw_jobs_limit, job_hang_limit, msecs_to_jiffies(hang_limit_ms), "v3d_render"); -- 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Anholt Subject: [PATCH 3/4] drm/v3d: Refactor job management. Date: Wed, 13 Mar 2019 16:52:10 -0700 Message-ID: <20190313235211.28995-3-eric@anholt.net> References: <20190313235211.28995-1-eric@anholt.net> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from anholt.net (anholt.net [50.246.234.109]) by gabe.freedesktop.org (Postfix) with ESMTP id 845C16E116 for ; Wed, 13 Mar 2019 23:52:25 +0000 (UTC) In-Reply-To: <20190313235211.28995-1-eric@anholt.net> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: dri-devel@lists.freedesktop.org Cc: david.emett@broadcom.com, thomas.spurden@broadcom.com, linux-kernel@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org VGhlIENMIHN1Ym1pc3Npb24gaGFkIHR3byBqb2JzIGVtYmVkZGVkIGluIGFuIGV4ZWMgc3RydWN0 LiAgV2hlbiBJCmFkZGVkIFRGVSBzdXBwb3J0LCBJIGhhZCB0byByZXBsaWNhdGUgc29tZSBvZiB0 aGUgZXhlYyBzdHVmZiBhbmQgc29tZQpvZiB0aGUgam9iIHN0dWZmLiAgQXMgSSB3ZW50IHRvIGFk ZCBDU0QsIGl0IGJlY2FtZSBjbGVhciB0aGF0IGFjdHVhbGx5CndoYXQgd2FzIGluIGV4ZWMgc2hv dWxkIGp1c3QgYmUgaW4gdGhlIHR3byBDTCBqb2JzLCBhbmQgaXQgd291bGQgbGV0CnVzIHNoYXJl IGEgbG90IG1vcmUgY29kZSBiZXR3ZWVuIHRoZSA0IHF1ZXVlcy4KClNpZ25lZC1vZmYtYnk6IEVy aWMgQW5ob2x0IDxlcmljQGFuaG9sdC5uZXQ+Ci0tLQogZHJpdmVycy9ncHUvZHJtL3YzZC92M2Rf ZHJ2LmggICB8ICA3NyArKystLS0tCiBkcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9nZW0uYyAgIHwg MzQ0ICsrKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tLS0tCiBkcml2ZXJzL2dwdS9kcm0vdjNk L3YzZF9pcnEuYyAgIHwgICA4ICstCiBkcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9zY2hlZC5jIHwg MjU5ICsrKysrKysrKysrKysrLS0tLS0tLS0tLQogNCBmaWxlcyBjaGFuZ2VkLCAzNzAgaW5zZXJ0 aW9ucygrKSwgMzE4IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS92 M2QvdjNkX2Rydi5oIGIvZHJpdmVycy9ncHUvZHJtL3YzZC92M2RfZHJ2LmgKaW5kZXggMjg0Y2Vk ODVmZjAyLi4wNGNhZDVhNjIxOTEgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS92M2QvdjNk X2Rydi5oCisrKyBiL2RyaXZlcnMvZ3B1L2RybS92M2QvdjNkX2Rydi5oCkBAIC03Myw4ICs3Myw4 IEBAIHN0cnVjdCB2M2RfZGV2IHsKIAogCXN0cnVjdCB3b3JrX3N0cnVjdCBvdmVyZmxvd19tZW1f d29yazsKIAotCXN0cnVjdCB2M2RfZXhlY19pbmZvICpiaW5fam9iOwotCXN0cnVjdCB2M2RfZXhl Y19pbmZvICpyZW5kZXJfam9iOworCXN0cnVjdCB2M2RfYmluX2pvYiAqYmluX2pvYjsKKwlzdHJ1 Y3QgdjNkX3JlbmRlcl9qb2IgKnJlbmRlcl9qb2I7CiAJc3RydWN0IHYzZF90ZnVfam9iICp0ZnVf am9iOwogCiAJc3RydWN0IHYzZF9xdWV1ZV9zdGF0ZSBxdWV1ZVtWM0RfTUFYX1FVRVVFU107CkBA IC0xMjMsNyArMTIzLDcgQEAgc3RydWN0IHYzZF9ibyB7CiAJc3RydWN0IGRybV9tbV9ub2RlIG5v ZGU7CiAKIAkvKiBMaXN0IGVudHJ5IGZvciB0aGUgQk8ncyBwb3NpdGlvbiBpbgotCSAqIHYzZF9l eGVjX2luZm8tPnVucmVmX2xpc3QKKwkgKiB2M2RfcmVuZGVyX2pvYi0+dW5yZWZfbGlzdAogCSAq LwogCXN0cnVjdCBsaXN0X2hlYWQgdW5yZWZfaGVhZDsKIH07CkBAIC0xNjMsNyArMTYzLDE1IEBA IHRvX3YzZF9mZW5jZShzdHJ1Y3QgZG1hX2ZlbmNlICpmZW5jZSkKIHN0cnVjdCB2M2Rfam9iIHsK IAlzdHJ1Y3QgZHJtX3NjaGVkX2pvYiBiYXNlOwogCi0Jc3RydWN0IHYzZF9leGVjX2luZm8gKmV4 ZWM7CisJc3RydWN0IGtyZWYgcmVmY291bnQ7CisKKwlzdHJ1Y3QgdjNkX2RldiAqdjNkOworCisJ LyogVGhpcyBpcyB0aGUgYXJyYXkgb2YgQk9zIHRoYXQgd2VyZSBsb29rZWQgdXAgYXQgdGhlIHN0 YXJ0CisJICogb2Ygc3VibWlzc2lvbi4KKwkgKi8KKwlzdHJ1Y3QgdjNkX2JvICoqYm87CisJdTMy IGJvX2NvdW50OwogCiAJLyogQW4gb3B0aW9uYWwgZmVuY2UgdXNlcnNwYWNlIGNhbiBwYXNzIGlu IGZvciB0aGUgam9iIHRvIGRlcGVuZCBvbi4gKi8KIAlzdHJ1Y3QgZG1hX2ZlbmNlICppbl9mZW5j ZTsKQEAgLTE3MSw1OSArMTc5LDUzIEBAIHN0cnVjdCB2M2Rfam9iIHsKIAkvKiB2M2QgZmVuY2Ug dG8gYmUgc2lnbmFsZWQgYnkgSVJRIGhhbmRsZXIgd2hlbiB0aGUgam9iIGlzIGNvbXBsZXRlLiAq LwogCXN0cnVjdCBkbWFfZmVuY2UgKmlycV9mZW5jZTsKIAorCS8qIHNjaGVkdWxlciBmZW5jZSBm b3Igd2hlbiB0aGUgam9iIGlzIGNvbnNpZGVyZWQgY29tcGxldGUgYW5kCisJICogdGhlIEJPIHJl c2VydmF0aW9ucyBjYW4gYmUgcmVsZWFzZWQuCisJICovCisJc3RydWN0IGRtYV9mZW5jZSAqZG9u ZV9mZW5jZTsKKworCS8qIENhbGxiYWNrIGZvciB0aGUgZnJlZWluZyBvZiB0aGUgam9iIG9uIHJl ZmNvdW50IGdvaW5nIHRvIDAuICovCisJdm9pZCAoKmZyZWUpKHN0cnVjdCBrcmVmICpyZWYpOwor fTsKKworc3RydWN0IHYzZF9iaW5fam9iIHsKKwlzdHJ1Y3QgdjNkX2pvYiBiYXNlOworCiAJLyog R1BVIHZpcnR1YWwgYWRkcmVzc2VzIG9mIHRoZSBzdGFydC9lbmQgb2YgdGhlIENMIGpvYi4gKi8K IAl1MzIgc3RhcnQsIGVuZDsKIAogCXUzMiB0aW1lZG91dF9jdGNhLCB0aW1lZG91dF9jdHJhOwot fTsKIAotc3RydWN0IHYzZF9leGVjX2luZm8gewotCXN0cnVjdCB2M2RfZGV2ICp2M2Q7CisJLyog Q29ycmVzcG9uZGluZyByZW5kZXIgam9iLCBmb3IgYXR0YWNoaW5nIG91ciBvdmVyZmxvdyBtZW1v cnkuICovCisJc3RydWN0IHYzZF9yZW5kZXJfam9iICpyZW5kZXI7CisKKwkvKiBTdWJtaXR0ZWQg dGlsZSBtZW1vcnkgYWxsb2NhdGlvbiBzdGFydC9zaXplLCB0aWxlIHN0YXRlLiAqLworCXUzMiBx bWEsIHFtcywgcXRzOworfTsKIAotCXN0cnVjdCB2M2Rfam9iIGJpbiwgcmVuZGVyOworc3RydWN0 IHYzZF9yZW5kZXJfam9iIHsKKwlzdHJ1Y3QgdjNkX2pvYiBiYXNlOwogCi0JLyogRmVuY2UgZm9y IHdoZW4gdGhlIHNjaGVkdWxlciBjb25zaWRlcnMgdGhlIGJpbm5lciB0byBiZQotCSAqIGRvbmUs IGZvciByZW5kZXIgdG8gZGVwZW5kIG9uLgorCS8qIE9wdGlvbmFsIGZlbmNlIGZvciB0aGUgYmlu bmVyLCB0byBkZXBlbmQgb24gYmVmb3JlIHN0YXJ0aW5nCisJICogb3VyIGpvYi4KIAkgKi8KIAlz dHJ1Y3QgZG1hX2ZlbmNlICpiaW5fZG9uZV9mZW5jZTsKIAotCS8qIEZlbmNlIGZvciB3aGVuIHRo ZSBzY2hlZHVsZXIgY29uc2lkZXJzIHRoZSByZW5kZXIgdG8gYmUKLQkgKiBkb25lLCBmb3Igd2hl biB0aGUgQk9zIHJlc2VydmF0aW9ucyBzaG91bGQgYmUgY29tcGxldGUuCi0JICovCi0Jc3RydWN0 IGRtYV9mZW5jZSAqcmVuZGVyX2RvbmVfZmVuY2U7Ci0KLQlzdHJ1Y3Qga3JlZiByZWZjb3VudDsK KwkvKiBHUFUgdmlydHVhbCBhZGRyZXNzZXMgb2YgdGhlIHN0YXJ0L2VuZCBvZiB0aGUgQ0wgam9i LiAqLworCXUzMiBzdGFydCwgZW5kOwogCi0JLyogVGhpcyBpcyB0aGUgYXJyYXkgb2YgQk9zIHRo YXQgd2VyZSBsb29rZWQgdXAgYXQgdGhlIHN0YXJ0IG9mIGV4ZWMuICovCi0Jc3RydWN0IHYzZF9i byAqKmJvOwotCXUzMiBib19jb3VudDsKKwl1MzIgdGltZWRvdXRfY3RjYSwgdGltZWRvdXRfY3Ry YTsKIAogCS8qIExpc3Qgb2Ygb3ZlcmZsb3cgQk9zIHVzZWQgaW4gdGhlIGpvYiB0aGF0IG5lZWQg dG8gYmUKIAkgKiByZWxlYXNlZCBvbmNlIHRoZSBqb2IgaXMgY29tcGxldGUuCiAJICovCiAJc3Ry dWN0IGxpc3RfaGVhZCB1bnJlZl9saXN0OwotCi0JLyogU3VibWl0dGVkIHRpbGUgbWVtb3J5IGFs bG9jYXRpb24gc3RhcnQvc2l6ZSwgdGlsZSBzdGF0ZS4gKi8KLQl1MzIgcW1hLCBxbXMsIHF0czsK IH07CiAKIHN0cnVjdCB2M2RfdGZ1X2pvYiB7Ci0Jc3RydWN0IGRybV9zY2hlZF9qb2IgYmFzZTsK KwlzdHJ1Y3QgdjNkX2pvYiBiYXNlOwogCiAJc3RydWN0IGRybV92M2Rfc3VibWl0X3RmdSBhcmdz OwotCi0JLyogQW4gb3B0aW9uYWwgZmVuY2UgdXNlcnNwYWNlIGNhbiBwYXNzIGluIGZvciB0aGUg am9iIHRvIGRlcGVuZCBvbi4gKi8KLQlzdHJ1Y3QgZG1hX2ZlbmNlICppbl9mZW5jZTsKLQotCS8q IHYzZCBmZW5jZSB0byBiZSBzaWduYWxlZCBieSBJUlEgaGFuZGxlciB3aGVuIHRoZSBqb2IgaXMg Y29tcGxldGUuICovCi0Jc3RydWN0IGRtYV9mZW5jZSAqaXJxX2ZlbmNlOwotCi0Jc3RydWN0IHYz ZF9kZXYgKnYzZDsKLQotCXN0cnVjdCBrcmVmIHJlZmNvdW50OwotCi0JLyogVGhpcyBpcyB0aGUg YXJyYXkgb2YgQk9zIHRoYXQgd2VyZSBsb29rZWQgdXAgYXQgdGhlIHN0YXJ0IG9mIGV4ZWMuICov Ci0Jc3RydWN0IHYzZF9ibyAqYm9bNF07CiB9OwogCiAvKioKQEAgLTI4OSw4ICsyOTEsNyBAQCBp bnQgdjNkX3N1Ym1pdF90ZnVfaW9jdGwoc3RydWN0IGRybV9kZXZpY2UgKmRldiwgdm9pZCAqZGF0 YSwKIAkJCSBzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVfcHJpdik7CiBpbnQgdjNkX3dhaXRfYm9faW9j dGwoc3RydWN0IGRybV9kZXZpY2UgKmRldiwgdm9pZCAqZGF0YSwKIAkJICAgICAgc3RydWN0IGRy bV9maWxlICpmaWxlX3ByaXYpOwotdm9pZCB2M2RfZXhlY19wdXQoc3RydWN0IHYzZF9leGVjX2lu Zm8gKmV4ZWMpOwotdm9pZCB2M2RfdGZ1X2pvYl9wdXQoc3RydWN0IHYzZF90ZnVfam9iICpleGVj KTsKK3ZvaWQgdjNkX2pvYl9wdXQoc3RydWN0IHYzZF9qb2IgKmpvYik7CiB2b2lkIHYzZF9yZXNl dChzdHJ1Y3QgdjNkX2RldiAqdjNkKTsKIHZvaWQgdjNkX2ludmFsaWRhdGVfY2FjaGVzKHN0cnVj dCB2M2RfZGV2ICp2M2QpOwogCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9n ZW0uYyBiL2RyaXZlcnMvZ3B1L2RybS92M2QvdjNkX2dlbS5jCmluZGV4IGIwNmJlZDA4MzVjOS4u MmNkYzkxNGQ0NzdlIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9nZW0uYwor KysgYi9kcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9nZW0uYwpAQCAtMjUwLDExICsyNTAsMTEgQEAg djNkX2xvY2tfYm9fcmVzZXJ2YXRpb25zKHN0cnVjdCB2M2RfYm8gKipib3MsCiB9CiAKIC8qKgot ICogdjNkX2NsX2xvb2t1cF9ib3MoKSAtIFNldHMgdXAgZXhlYy0+Ym9bXSB3aXRoIHRoZSBHRU0g b2JqZWN0cworICogdjNkX2xvb2t1cF9ib3MoKSAtIFNldHMgdXAgam9iLT5ib1tdIHdpdGggdGhl IEdFTSBvYmplY3RzCiAgKiByZWZlcmVuY2VkIGJ5IHRoZSBqb2IuCiAgKiBAZGV2OiBEUk0gZGV2 aWNlCiAgKiBAZmlsZV9wcml2OiBEUk0gZmlsZSBmb3IgdGhpcyBmZAotICogQGV4ZWM6IFYzRCBq b2IgYmVpbmcgc2V0IHVwCisgKiBAam9iOiBWM0Qgam9iIGJlaW5nIHNldCB1cAogICoKICAqIFRo ZSBjb21tYW5kIHZhbGlkYXRvciBuZWVkcyB0byByZWZlcmVuY2UgQk9zIGJ5IHRoZWlyIGluZGV4 IHdpdGhpbgogICogdGhlIHN1Ym1pdHRlZCBqb2IncyBCTyBsaXN0LiAgVGhpcyBkb2VzIHRoZSB2 YWxpZGF0aW9uIG9mIHRoZSBqb2IncwpAQCAtMjY0LDE4ICsyNjQsMTkgQEAgdjNkX2xvY2tfYm9f cmVzZXJ2YXRpb25zKHN0cnVjdCB2M2RfYm8gKipib3MsCiAgKiBmYWlsdXJlLCBiZWNhdXNlIHRo YXQgd2lsbCBoYXBwZW4gYXQgdjNkX2V4ZWNfY2xlYW51cCgpIHRpbWUuCiAgKi8KIHN0YXRpYyBp bnQKLXYzZF9jbF9sb29rdXBfYm9zKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCi0JCSAgc3RydWN0 IGRybV9maWxlICpmaWxlX3ByaXYsCi0JCSAgc3RydWN0IGRybV92M2Rfc3VibWl0X2NsICphcmdz LAotCQkgIHN0cnVjdCB2M2RfZXhlY19pbmZvICpleGVjKQordjNkX2xvb2t1cF9ib3Moc3RydWN0 IGRybV9kZXZpY2UgKmRldiwKKwkgICAgICAgc3RydWN0IGRybV9maWxlICpmaWxlX3ByaXYsCisJ ICAgICAgIHN0cnVjdCB2M2Rfam9iICpqb2IsCisJICAgICAgIHU2NCBib19oYW5kbGVzLAorCSAg ICAgICB1MzIgYm9fY291bnQpCiB7CiAJdTMyICpoYW5kbGVzOwogCWludCByZXQgPSAwOwogCWlu dCBpOwogCi0JZXhlYy0+Ym9fY291bnQgPSBhcmdzLT5ib19oYW5kbGVfY291bnQ7CisJam9iLT5i b19jb3VudCA9IGJvX2NvdW50OwogCi0JaWYgKCFleGVjLT5ib19jb3VudCkgeworCWlmICgham9i LT5ib19jb3VudCkgewogCQkvKiBTZWUgY29tbWVudCBvbiBib19pbmRleCBmb3Igd2h5IHdlIGhh dmUgdG8gY2hlY2sKIAkJICogdGhpcy4KIAkJICovCkBAIC0yODMsMTUgKzI4NCwxNSBAQCB2M2Rf Y2xfbG9va3VwX2JvcyhzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAogCQlyZXR1cm4gLUVJTlZBTDsK IAl9CiAKLQlleGVjLT5ibyA9IGt2bWFsbG9jX2FycmF5KGV4ZWMtPmJvX2NvdW50LAotCQkJCSAg c2l6ZW9mKHN0cnVjdCBkcm1fZ2VtX2NtYV9vYmplY3QgKiksCi0JCQkJICBHRlBfS0VSTkVMIHwg X19HRlBfWkVSTyk7Ci0JaWYgKCFleGVjLT5ibykgeworCWpvYi0+Ym8gPSBrdm1hbGxvY19hcnJh eShqb2ItPmJvX2NvdW50LAorCQkJCSBzaXplb2Yoc3RydWN0IGRybV9nZW1fY21hX29iamVjdCAq KSwKKwkJCQkgR0ZQX0tFUk5FTCB8IF9fR0ZQX1pFUk8pOworCWlmICgham9iLT5ibykgewogCQlE Uk1fREVCVUcoIkZhaWxlZCB0byBhbGxvY2F0ZSB2YWxpZGF0ZWQgQk8gcG9pbnRlcnNcbiIpOwog CQlyZXR1cm4gLUVOT01FTTsKIAl9CiAKLQloYW5kbGVzID0ga3ZtYWxsb2NfYXJyYXkoZXhlYy0+ Ym9fY291bnQsIHNpemVvZih1MzIpLCBHRlBfS0VSTkVMKTsKKwloYW5kbGVzID0ga3ZtYWxsb2Nf YXJyYXkoam9iLT5ib19jb3VudCwgc2l6ZW9mKHUzMiksIEdGUF9LRVJORUwpOwogCWlmICghaGFu ZGxlcykgewogCQlyZXQgPSAtRU5PTUVNOwogCQlEUk1fREVCVUcoIkZhaWxlZCB0byBhbGxvY2F0 ZSBpbmNvbWluZyBHRU0gaGFuZGxlc1xuIik7CkBAIC0yOTksMTUgKzMwMCwxNSBAQCB2M2RfY2xf bG9va3VwX2JvcyhzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAogCX0KIAogCWlmIChjb3B5X2Zyb21f dXNlcihoYW5kbGVzLAotCQkJICAgKHZvaWQgX191c2VyICopKHVpbnRwdHJfdClhcmdzLT5ib19o YW5kbGVzLAotCQkJICAgZXhlYy0+Ym9fY291bnQgKiBzaXplb2YodTMyKSkpIHsKKwkJCSAgICh2 b2lkIF9fdXNlciAqKSh1aW50cHRyX3QpYm9faGFuZGxlcywKKwkJCSAgIGpvYi0+Ym9fY291bnQg KiBzaXplb2YodTMyKSkpIHsKIAkJcmV0ID0gLUVGQVVMVDsKIAkJRFJNX0RFQlVHKCJGYWlsZWQg dG8gY29weSBpbiBHRU0gaGFuZGxlc1xuIik7CiAJCWdvdG8gZmFpbDsKIAl9CiAKIAlzcGluX2xv Y2soJmZpbGVfcHJpdi0+dGFibGVfbG9jayk7Ci0JZm9yIChpID0gMDsgaSA8IGV4ZWMtPmJvX2Nv dW50OyBpKyspIHsKKwlmb3IgKGkgPSAwOyBpIDwgam9iLT5ib19jb3VudDsgaSsrKSB7CiAJCXN0 cnVjdCBkcm1fZ2VtX29iamVjdCAqYm8gPSBpZHJfZmluZCgmZmlsZV9wcml2LT5vYmplY3RfaWRy LAogCQkJCQkJICAgICBoYW5kbGVzW2ldKTsKIAkJaWYgKCFibykgewpAQCAtMzE4LDcgKzMxOSw3 IEBAIHYzZF9jbF9sb29rdXBfYm9zKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCiAJCQlnb3RvIGZh aWw7CiAJCX0KIAkJZHJtX2dlbV9vYmplY3RfZ2V0KGJvKTsKLQkJZXhlYy0+Ym9baV0gPSB0b192 M2RfYm8oYm8pOworCQlqb2ItPmJvW2ldID0gdG9fdjNkX2JvKGJvKTsKIAl9CiAJc3Bpbl91bmxv Y2soJmZpbGVfcHJpdi0+dGFibGVfbG9jayk7CiAKQEAgLTMyOCw2NyArMzI5LDQ0IEBAIHYzZF9j bF9sb29rdXBfYm9zKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCiB9CiAKIHN0YXRpYyB2b2lkCi12 M2RfZXhlY19jbGVhbnVwKHN0cnVjdCBrcmVmICpyZWYpCit2M2Rfam9iX2ZyZWUoc3RydWN0IGty ZWYgKnJlZikKIHsKLQlzdHJ1Y3QgdjNkX2V4ZWNfaW5mbyAqZXhlYyA9IGNvbnRhaW5lcl9vZihy ZWYsIHN0cnVjdCB2M2RfZXhlY19pbmZvLAotCQkJCQkJICByZWZjb3VudCk7Ci0Jc3RydWN0IHYz ZF9kZXYgKnYzZCA9IGV4ZWMtPnYzZDsKLQl1bnNpZ25lZCBpbnQgaTsKLQlzdHJ1Y3QgdjNkX2Jv ICpibywgKnNhdmU7Ci0KLQlkbWFfZmVuY2VfcHV0KGV4ZWMtPmJpbi5pbl9mZW5jZSk7Ci0JZG1h X2ZlbmNlX3B1dChleGVjLT5yZW5kZXIuaW5fZmVuY2UpOwotCi0JZG1hX2ZlbmNlX3B1dChleGVj LT5iaW4uaXJxX2ZlbmNlKTsKLQlkbWFfZmVuY2VfcHV0KGV4ZWMtPnJlbmRlci5pcnFfZmVuY2Up OwotCi0JZG1hX2ZlbmNlX3B1dChleGVjLT5iaW5fZG9uZV9mZW5jZSk7Ci0JZG1hX2ZlbmNlX3B1 dChleGVjLT5yZW5kZXJfZG9uZV9mZW5jZSk7Ci0KLQlmb3IgKGkgPSAwOyBpIDwgZXhlYy0+Ym9f Y291bnQ7IGkrKykKLQkJZHJtX2dlbV9vYmplY3RfcHV0X3VubG9ja2VkKCZleGVjLT5ib1tpXS0+ YmFzZS5iYXNlKTsKLQlrdmZyZWUoZXhlYy0+Ym8pOworCXN0cnVjdCB2M2Rfam9iICpqb2IgPSBj b250YWluZXJfb2YocmVmLCBzdHJ1Y3QgdjNkX2pvYiwgcmVmY291bnQpOworCWludCBpOwogCi0J bGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGJvLCBzYXZlLCAmZXhlYy0+dW5yZWZfbGlzdCwgdW5y ZWZfaGVhZCkgewotCQlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2NrZWQoJmJvLT5iYXNlLmJhc2Up OworCWZvciAoaSA9IDA7IGkgPCBqb2ItPmJvX2NvdW50OyBpKyspIHsKKwkJaWYgKGpvYi0+Ym9b aV0pCisJCQlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2NrZWQoJmpvYi0+Ym9baV0tPmJhc2UuYmFz ZSk7CiAJfQorCWt2ZnJlZShqb2ItPmJvKTsKIAotCXBtX3J1bnRpbWVfbWFya19sYXN0X2J1c3ko djNkLT5kZXYpOwotCXBtX3J1bnRpbWVfcHV0X2F1dG9zdXNwZW5kKHYzZC0+ZGV2KTsKKwlkbWFf ZmVuY2VfcHV0KGpvYi0+aW5fZmVuY2UpOworCWRtYV9mZW5jZV9wdXQoam9iLT5pcnFfZmVuY2Up OworCWRtYV9mZW5jZV9wdXQoam9iLT5kb25lX2ZlbmNlKTsKIAotCWtmcmVlKGV4ZWMpOwotfQor CXBtX3J1bnRpbWVfbWFya19sYXN0X2J1c3koam9iLT52M2QtPmRldik7CisJcG1fcnVudGltZV9w dXRfYXV0b3N1c3BlbmQoam9iLT52M2QtPmRldik7CiAKLXZvaWQgdjNkX2V4ZWNfcHV0KHN0cnVj dCB2M2RfZXhlY19pbmZvICpleGVjKQotewotCWtyZWZfcHV0KCZleGVjLT5yZWZjb3VudCwgdjNk X2V4ZWNfY2xlYW51cCk7CisJa2ZyZWUoam9iKTsKIH0KIAogc3RhdGljIHZvaWQKLXYzZF90ZnVf am9iX2NsZWFudXAoc3RydWN0IGtyZWYgKnJlZikKK3YzZF9yZW5kZXJfam9iX2ZyZWUoc3RydWN0 IGtyZWYgKnJlZikKIHsKLQlzdHJ1Y3QgdjNkX3RmdV9qb2IgKmpvYiA9IGNvbnRhaW5lcl9vZihy ZWYsIHN0cnVjdCB2M2RfdGZ1X2pvYiwKLQkJCQkJICAgICAgIHJlZmNvdW50KTsKLQlzdHJ1Y3Qg djNkX2RldiAqdjNkID0gam9iLT52M2Q7Ci0JdW5zaWduZWQgaW50IGk7Ci0KLQlkbWFfZmVuY2Vf cHV0KGpvYi0+aW5fZmVuY2UpOwotCWRtYV9mZW5jZV9wdXQoam9iLT5pcnFfZmVuY2UpOworCXN0 cnVjdCB2M2RfcmVuZGVyX2pvYiAqam9iID0gY29udGFpbmVyX29mKHJlZiwgc3RydWN0IHYzZF9y ZW5kZXJfam9iLAorCQkJCQkJICBiYXNlLnJlZmNvdW50KTsKKwlzdHJ1Y3QgdjNkX2JvICpibywg KnNhdmU7CiAKLQlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShqb2ItPmJvKTsgaSsrKSB7Ci0J CWlmIChqb2ItPmJvW2ldKQotCQkJZHJtX2dlbV9vYmplY3RfcHV0X3VubG9ja2VkKCZqb2ItPmJv W2ldLT5iYXNlLmJhc2UpOworCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShibywgc2F2ZSwgJmpv Yi0+dW5yZWZfbGlzdCwgdW5yZWZfaGVhZCkgeworCQlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2Nr ZWQoJmJvLT5iYXNlLmJhc2UpOwogCX0KIAotCXBtX3J1bnRpbWVfbWFya19sYXN0X2J1c3kodjNk LT5kZXYpOwotCXBtX3J1bnRpbWVfcHV0X2F1dG9zdXNwZW5kKHYzZC0+ZGV2KTsKLQotCWtmcmVl KGpvYik7CisJdjNkX2pvYl9mcmVlKHJlZik7CiB9CiAKLXZvaWQgdjNkX3RmdV9qb2JfcHV0KHN0 cnVjdCB2M2RfdGZ1X2pvYiAqam9iKQordm9pZCB2M2Rfam9iX3B1dChzdHJ1Y3QgdjNkX2pvYiAq am9iKQogewotCWtyZWZfcHV0KCZqb2ItPnJlZmNvdW50LCB2M2RfdGZ1X2pvYl9jbGVhbnVwKTsK KwlrcmVmX3B1dCgmam9iLT5yZWZjb3VudCwgam9iLT5mcmVlKTsKIH0KIAogaW50CkBAIC00MjQs NiArNDAyLDcxIEBAIHYzZF93YWl0X2JvX2lvY3RsKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHZv aWQgKmRhdGEsCiAJcmV0dXJuIHJldDsKIH0KIAorc3RhdGljIGludAordjNkX2pvYl9pbml0KHN0 cnVjdCB2M2RfZGV2ICp2M2QsIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9wcml2LAorCSAgICAgc3Ry dWN0IHYzZF9qb2IgKmpvYiwgdm9pZCAoKmZyZWUpKHN0cnVjdCBrcmVmICpyZWYpLAorCSAgICAg dTMyIGluX3N5bmMpCit7CisJaW50IHJldDsKKworCWpvYi0+djNkID0gdjNkOworCWpvYi0+ZnJl ZSA9IGZyZWU7CisKKwlyZXQgPSBwbV9ydW50aW1lX2dldF9zeW5jKHYzZC0+ZGV2KTsKKwlpZiAo cmV0IDwgMCkKKwkJcmV0dXJuIHJldDsKKworCXJldCA9IGRybV9zeW5jb2JqX2ZpbmRfZmVuY2Uo ZmlsZV9wcml2LCBpbl9zeW5jLCAwLCAwLCAmam9iLT5pbl9mZW5jZSk7CisJaWYgKHJldCA9PSAt RUlOVkFMKSB7CisJCXBtX3J1bnRpbWVfcHV0X2F1dG9zdXNwZW5kKHYzZC0+ZGV2KTsKKwkJcmV0 dXJuIHJldDsKKwl9CisKKwlrcmVmX2luaXQoJmpvYi0+cmVmY291bnQpOworCisJcmV0dXJuIDA7 Cit9CisKK3N0YXRpYyBpbnQKK3YzZF9wdXNoX2pvYihzdHJ1Y3QgdjNkX2ZpbGVfcHJpdiAqdjNk X3ByaXYsCisJICAgICBzdHJ1Y3QgdjNkX2pvYiAqam9iLCBlbnVtIHYzZF9xdWV1ZSBxdWV1ZSkK K3sKKwlpbnQgcmV0OworCisJcmV0ID0gZHJtX3NjaGVkX2pvYl9pbml0KCZqb2ItPmJhc2UsICZ2 M2RfcHJpdi0+c2NoZWRfZW50aXR5W3F1ZXVlXSwKKwkJCQkgdjNkX3ByaXYpOworCWlmIChyZXQp CisJCXJldHVybiByZXQ7CisKKwlqb2ItPmRvbmVfZmVuY2UgPSBkbWFfZmVuY2VfZ2V0KCZqb2It PmJhc2Uuc19mZW5jZS0+ZmluaXNoZWQpOworCisJLyogcHV0IGJ5IHNjaGVkdWxlciBqb2IgY29t cGxldGlvbiAqLworCWtyZWZfZ2V0KCZqb2ItPnJlZmNvdW50KTsKKworCWRybV9zY2hlZF9lbnRp dHlfcHVzaF9qb2IoJmpvYi0+YmFzZSwgJnYzZF9wcml2LT5zY2hlZF9lbnRpdHlbcXVldWVdKTsK KworCXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZAordjNkX2F0dGFjaF9mZW5jZXNfYW5kX3Vu bG9ja19yZXNlcnZhdGlvbihzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVfcHJpdiwKKwkJCQkJIHN0cnVj dCB2M2Rfam9iICpqb2IsCisJCQkJCSBzdHJ1Y3Qgd3dfYWNxdWlyZV9jdHggKmFjcXVpcmVfY3R4 LAorCQkJCQkgdTMyIG91dF9zeW5jKQoreworCXN0cnVjdCBkcm1fc3luY29iaiAqc3luY19vdXQ7 CisKKwl2M2RfYXR0YWNoX29iamVjdF9mZW5jZXMoam9iLT5ibywgam9iLT5ib19jb3VudCwgam9i LT5kb25lX2ZlbmNlKTsKKwl2M2RfdW5sb2NrX2JvX3Jlc2VydmF0aW9ucyhqb2ItPmJvLCBqb2It PmJvX2NvdW50LCBhY3F1aXJlX2N0eCk7CisKKwkvKiBVcGRhdGUgdGhlIHJldHVybiBzeW5jIG9i amVjdCBmb3IgdGhlIGpvYiAqLworCXN5bmNfb3V0ID0gZHJtX3N5bmNvYmpfZmluZChmaWxlX3By aXYsIG91dF9zeW5jKTsKKwlpZiAoc3luY19vdXQpIHsKKwkJZHJtX3N5bmNvYmpfcmVwbGFjZV9m ZW5jZShzeW5jX291dCwgam9iLT5kb25lX2ZlbmNlKTsKKwkJZHJtX3N5bmNvYmpfcHV0KHN5bmNf b3V0KTsKKwl9Cit9CisKIC8qKgogICogdjNkX3N1Ym1pdF9jbF9pb2N0bCgpIC0gU3VibWl0cyBh IGpvYiAoZnJhbWUpIHRvIHRoZSBWM0QuCiAgKiBAZGV2OiBEUk0gZGV2aWNlCkBAIC00NDMsOSAr NDg2LDkgQEAgdjNkX3N1Ym1pdF9jbF9pb2N0bChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LCB2b2lk ICpkYXRhLAogCXN0cnVjdCB2M2RfZGV2ICp2M2QgPSB0b192M2RfZGV2KGRldik7CiAJc3RydWN0 IHYzZF9maWxlX3ByaXYgKnYzZF9wcml2ID0gZmlsZV9wcml2LT5kcml2ZXJfcHJpdjsKIAlzdHJ1 Y3QgZHJtX3YzZF9zdWJtaXRfY2wgKmFyZ3MgPSBkYXRhOwotCXN0cnVjdCB2M2RfZXhlY19pbmZv ICpleGVjOworCXN0cnVjdCB2M2RfYmluX2pvYiAqYmluID0gTlVMTDsKKwlzdHJ1Y3QgdjNkX3Jl bmRlcl9qb2IgKnJlbmRlcjsKIAlzdHJ1Y3Qgd3dfYWNxdWlyZV9jdHggYWNxdWlyZV9jdHg7Ci0J c3RydWN0IGRybV9zeW5jb2JqICpzeW5jX291dDsKIAlpbnQgcmV0ID0gMDsKIAogCXRyYWNlX3Yz ZF9zdWJtaXRfY2xfaW9jdGwoJnYzZC0+ZHJtLCBhcmdzLT5yY2xfc3RhcnQsIGFyZ3MtPnJjbF9l bmQpOwpAQCAtNDU1LDEwMCArNDk4LDgzIEBAIHYzZF9zdWJtaXRfY2xfaW9jdGwoc3RydWN0IGRy bV9kZXZpY2UgKmRldiwgdm9pZCAqZGF0YSwKIAkJcmV0dXJuIC1FSU5WQUw7CiAJfQogCi0JZXhl YyA9IGtjYWxsb2MoMSwgc2l6ZW9mKCpleGVjKSwgR0ZQX0tFUk5FTCk7Ci0JaWYgKCFleGVjKQor CXJlbmRlciA9IGtjYWxsb2MoMSwgc2l6ZW9mKCpyZW5kZXIpLCBHRlBfS0VSTkVMKTsKKwlpZiAo IXJlbmRlcikKIAkJcmV0dXJuIC1FTk9NRU07CiAKLQlyZXQgPSBwbV9ydW50aW1lX2dldF9zeW5j KHYzZC0+ZGV2KTsKLQlpZiAocmV0IDwgMCkgewotCQlrZnJlZShleGVjKTsKKwlyZW5kZXItPnN0 YXJ0ID0gYXJncy0+cmNsX3N0YXJ0OworCXJlbmRlci0+ZW5kID0gYXJncy0+cmNsX2VuZDsKKwlJ TklUX0xJU1RfSEVBRCgmcmVuZGVyLT51bnJlZl9saXN0KTsKKworCXJldCA9IHYzZF9qb2JfaW5p dCh2M2QsIGZpbGVfcHJpdiwgJnJlbmRlci0+YmFzZSwKKwkJCSAgIHYzZF9yZW5kZXJfam9iX2Zy ZWUsIGFyZ3MtPmluX3N5bmNfcmNsKTsKKwlpZiAocmV0KSB7CisJCWtmcmVlKHJlbmRlcik7CiAJ CXJldHVybiByZXQ7CiAJfQogCi0Ja3JlZl9pbml0KCZleGVjLT5yZWZjb3VudCk7CisJaWYgKGFy Z3MtPmJjbF9zdGFydCAhPSBhcmdzLT5iY2xfZW5kKSB7CisJCWJpbiA9IGtjYWxsb2MoMSwgc2l6 ZW9mKCpiaW4pLCBHRlBfS0VSTkVMKTsKKwkJaWYgKCFiaW4pCisJCQlyZXR1cm4gLUVOT01FTTsK IAotCXJldCA9IGRybV9zeW5jb2JqX2ZpbmRfZmVuY2UoZmlsZV9wcml2LCBhcmdzLT5pbl9zeW5j X2JjbCwKLQkJCQkgICAgIDAsIDAsICZleGVjLT5iaW4uaW5fZmVuY2UpOwotCWlmIChyZXQgPT0g LUVJTlZBTCkKLQkJZ290byBmYWlsOworCQlyZXQgPSB2M2Rfam9iX2luaXQodjNkLCBmaWxlX3By aXYsICZiaW4tPmJhc2UsCisJCQkJICAgdjNkX2pvYl9mcmVlLCBhcmdzLT5pbl9zeW5jX2JjbCk7 CisJCWlmIChyZXQpIHsKKwkJCXYzZF9qb2JfcHV0KCZyZW5kZXItPmJhc2UpOworCQkJcmV0dXJu IHJldDsKKwkJfQogCi0JcmV0ID0gZHJtX3N5bmNvYmpfZmluZF9mZW5jZShmaWxlX3ByaXYsIGFy Z3MtPmluX3N5bmNfcmNsLAotCQkJCSAgICAgMCwgMCwgJmV4ZWMtPnJlbmRlci5pbl9mZW5jZSk7 Ci0JaWYgKHJldCA9PSAtRUlOVkFMKQotCQlnb3RvIGZhaWw7CisJCWJpbi0+c3RhcnQgPSBhcmdz LT5iY2xfc3RhcnQ7CisJCWJpbi0+ZW5kID0gYXJncy0+YmNsX2VuZDsKKwkJYmluLT5xbWEgPSBh cmdzLT5xbWE7CisJCWJpbi0+cW1zID0gYXJncy0+cW1zOworCQliaW4tPnF0cyA9IGFyZ3MtPnF0 czsKKwkJYmluLT5yZW5kZXIgPSByZW5kZXI7CisJfQogCi0JZXhlYy0+cW1hID0gYXJncy0+cW1h OwotCWV4ZWMtPnFtcyA9IGFyZ3MtPnFtczsKLQlleGVjLT5xdHMgPSBhcmdzLT5xdHM7Ci0JZXhl Yy0+YmluLmV4ZWMgPSBleGVjOwotCWV4ZWMtPmJpbi5zdGFydCA9IGFyZ3MtPmJjbF9zdGFydDsK LQlleGVjLT5iaW4uZW5kID0gYXJncy0+YmNsX2VuZDsKLQlleGVjLT5yZW5kZXIuZXhlYyA9IGV4 ZWM7Ci0JZXhlYy0+cmVuZGVyLnN0YXJ0ID0gYXJncy0+cmNsX3N0YXJ0OwotCWV4ZWMtPnJlbmRl ci5lbmQgPSBhcmdzLT5yY2xfZW5kOwotCWV4ZWMtPnYzZCA9IHYzZDsKLQlJTklUX0xJU1RfSEVB RCgmZXhlYy0+dW5yZWZfbGlzdCk7Ci0KLQlyZXQgPSB2M2RfY2xfbG9va3VwX2JvcyhkZXYsIGZp bGVfcHJpdiwgYXJncywgZXhlYyk7CisJcmV0ID0gdjNkX2xvb2t1cF9ib3MoZGV2LCBmaWxlX3By aXYsICZyZW5kZXItPmJhc2UsCisJCQkgICAgIGFyZ3MtPmJvX2hhbmRsZXMsIGFyZ3MtPmJvX2hh bmRsZV9jb3VudCk7CiAJaWYgKHJldCkKIAkJZ290byBmYWlsOwogCi0JcmV0ID0gdjNkX2xvY2tf Ym9fcmVzZXJ2YXRpb25zKGV4ZWMtPmJvLCBleGVjLT5ib19jb3VudCwKKwlyZXQgPSB2M2RfbG9j a19ib19yZXNlcnZhdGlvbnMocmVuZGVyLT5iYXNlLmJvLCByZW5kZXItPmJhc2UuYm9fY291bnQs CiAJCQkJICAgICAgICZhY3F1aXJlX2N0eCk7CiAJaWYgKHJldCkKIAkJZ290byBmYWlsOwogCiAJ bXV0ZXhfbG9jaygmdjNkLT5zY2hlZF9sb2NrKTsKLQlpZiAoZXhlYy0+YmluLnN0YXJ0ICE9IGV4 ZWMtPmJpbi5lbmQpIHsKLQkJcmV0ID0gZHJtX3NjaGVkX2pvYl9pbml0KCZleGVjLT5iaW4uYmFz ZSwKLQkJCQkJICZ2M2RfcHJpdi0+c2NoZWRfZW50aXR5W1YzRF9CSU5dLAotCQkJCQkgdjNkX3By aXYpOworCWlmIChiaW4pIHsKKwkJcmV0ID0gdjNkX3B1c2hfam9iKHYzZF9wcml2LCAmYmluLT5i YXNlLCBWM0RfQklOKTsKIAkJaWYgKHJldCkKIAkJCWdvdG8gZmFpbF91bnJlc2VydmU7CiAKLQkJ ZXhlYy0+YmluX2RvbmVfZmVuY2UgPQotCQkJZG1hX2ZlbmNlX2dldCgmZXhlYy0+YmluLmJhc2Uu c19mZW5jZS0+ZmluaXNoZWQpOwotCi0JCWtyZWZfZ2V0KCZleGVjLT5yZWZjb3VudCk7IC8qIHB1 dCBieSBzY2hlZHVsZXIgam9iIGNvbXBsZXRpb24gKi8KLQkJZHJtX3NjaGVkX2VudGl0eV9wdXNo X2pvYigmZXhlYy0+YmluLmJhc2UsCi0JCQkJCSAgJnYzZF9wcml2LT5zY2hlZF9lbnRpdHlbVjNE X0JJTl0pOworCQlyZW5kZXItPmJpbl9kb25lX2ZlbmNlID0gZG1hX2ZlbmNlX2dldChiaW4tPmJh c2UuZG9uZV9mZW5jZSk7CiAJfQogCi0JcmV0ID0gZHJtX3NjaGVkX2pvYl9pbml0KCZleGVjLT5y ZW5kZXIuYmFzZSwKLQkJCQkgJnYzZF9wcml2LT5zY2hlZF9lbnRpdHlbVjNEX1JFTkRFUl0sCi0J CQkJIHYzZF9wcml2KTsKKwlyZXQgPSB2M2RfcHVzaF9qb2IodjNkX3ByaXYsICZyZW5kZXItPmJh c2UsIFYzRF9SRU5ERVIpOwogCWlmIChyZXQpCiAJCWdvdG8gZmFpbF91bnJlc2VydmU7Ci0KLQll eGVjLT5yZW5kZXJfZG9uZV9mZW5jZSA9Ci0JCWRtYV9mZW5jZV9nZXQoJmV4ZWMtPnJlbmRlci5i YXNlLnNfZmVuY2UtPmZpbmlzaGVkKTsKLQotCWtyZWZfZ2V0KCZleGVjLT5yZWZjb3VudCk7IC8q IHB1dCBieSBzY2hlZHVsZXIgam9iIGNvbXBsZXRpb24gKi8KLQlkcm1fc2NoZWRfZW50aXR5X3B1 c2hfam9iKCZleGVjLT5yZW5kZXIuYmFzZSwKLQkJCQkgICZ2M2RfcHJpdi0+c2NoZWRfZW50aXR5 W1YzRF9SRU5ERVJdKTsKIAltdXRleF91bmxvY2soJnYzZC0+c2NoZWRfbG9jayk7CiAKLQl2M2Rf YXR0YWNoX29iamVjdF9mZW5jZXMoZXhlYy0+Ym8sIGV4ZWMtPmJvX2NvdW50LAotCQkJCSBleGVj LT5yZW5kZXJfZG9uZV9mZW5jZSk7Ci0KLQl2M2RfdW5sb2NrX2JvX3Jlc2VydmF0aW9ucyhleGVj LT5ibywgZXhlYy0+Ym9fY291bnQsICZhY3F1aXJlX2N0eCk7CisJdjNkX2F0dGFjaF9mZW5jZXNf YW5kX3VubG9ja19yZXNlcnZhdGlvbihmaWxlX3ByaXYsCisJCQkJCQkgJnJlbmRlci0+YmFzZSwg JmFjcXVpcmVfY3R4LAorCQkJCQkJIGFyZ3MtPm91dF9zeW5jKTsKIAotCS8qIFVwZGF0ZSB0aGUg cmV0dXJuIHN5bmMgb2JqZWN0IGZvciB0aGUgKi8KLQlzeW5jX291dCA9IGRybV9zeW5jb2JqX2Zp bmQoZmlsZV9wcml2LCBhcmdzLT5vdXRfc3luYyk7Ci0JaWYgKHN5bmNfb3V0KSB7Ci0JCWRybV9z eW5jb2JqX3JlcGxhY2VfZmVuY2Uoc3luY19vdXQsIGV4ZWMtPnJlbmRlcl9kb25lX2ZlbmNlKTsK LQkJZHJtX3N5bmNvYmpfcHV0KHN5bmNfb3V0KTsKLQl9Ci0KLQl2M2RfZXhlY19wdXQoZXhlYyk7 CisJaWYgKGJpbikKKwkJdjNkX2pvYl9wdXQoJmJpbi0+YmFzZSk7CisJdjNkX2pvYl9wdXQoJnJl bmRlci0+YmFzZSk7CiAKIAlyZXR1cm4gMDsKIAogZmFpbF91bnJlc2VydmU6CiAJbXV0ZXhfdW5s b2NrKCZ2M2QtPnNjaGVkX2xvY2spOwotCXYzZF91bmxvY2tfYm9fcmVzZXJ2YXRpb25zKGV4ZWMt PmJvLCBleGVjLT5ib19jb3VudCwgJmFjcXVpcmVfY3R4KTsKKwl2M2RfdW5sb2NrX2JvX3Jlc2Vy dmF0aW9ucyhyZW5kZXItPmJhc2UuYm8sCisJCQkJICAgcmVuZGVyLT5iYXNlLmJvX2NvdW50LCAm YWNxdWlyZV9jdHgpOwogZmFpbDoKLQl2M2RfZXhlY19wdXQoZXhlYyk7CisJaWYgKGJpbikKKwkJ djNkX2pvYl9wdXQoJmJpbi0+YmFzZSk7CisJdjNkX2pvYl9wdXQoJnJlbmRlci0+YmFzZSk7CiAK IAlyZXR1cm4gcmV0OwogfQpAQCAtNTcxLDEwICs1OTcsNyBAQCB2M2Rfc3VibWl0X3RmdV9pb2N0 bChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LCB2b2lkICpkYXRhLAogCXN0cnVjdCBkcm1fdjNkX3N1 Ym1pdF90ZnUgKmFyZ3MgPSBkYXRhOwogCXN0cnVjdCB2M2RfdGZ1X2pvYiAqam9iOwogCXN0cnVj dCB3d19hY3F1aXJlX2N0eCBhY3F1aXJlX2N0eDsKLQlzdHJ1Y3QgZHJtX3N5bmNvYmogKnN5bmNf b3V0OwotCXN0cnVjdCBkbWFfZmVuY2UgKnNjaGVkX2RvbmVfZmVuY2U7CiAJaW50IHJldCA9IDA7 Ci0JaW50IGJvX2NvdW50OwogCiAJdHJhY2VfdjNkX3N1Ym1pdF90ZnVfaW9jdGwoJnYzZC0+ZHJt LCBhcmdzLT5paWEpOwogCkBAIC01ODIsODEgKzYwNSw2NiBAQCB2M2Rfc3VibWl0X3RmdV9pb2N0 bChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LCB2b2lkICpkYXRhLAogCWlmICgham9iKQogCQlyZXR1 cm4gLUVOT01FTTsKIAotCXJldCA9IHBtX3J1bnRpbWVfZ2V0X3N5bmModjNkLT5kZXYpOwotCWlm IChyZXQgPCAwKSB7CisJcmV0ID0gdjNkX2pvYl9pbml0KHYzZCwgZmlsZV9wcml2LCAmam9iLT5i YXNlLAorCQkJICAgdjNkX2pvYl9mcmVlLCBhcmdzLT5pbl9zeW5jKTsKKwlpZiAocmV0KSB7CiAJ CWtmcmVlKGpvYik7CiAJCXJldHVybiByZXQ7CiAJfQogCi0Ja3JlZl9pbml0KCZqb2ItPnJlZmNv dW50KTsKLQotCXJldCA9IGRybV9zeW5jb2JqX2ZpbmRfZmVuY2UoZmlsZV9wcml2LCBhcmdzLT5p bl9zeW5jLAotCQkJCSAgICAgMCwgMCwgJmpvYi0+aW5fZmVuY2UpOwotCWlmIChyZXQgPT0gLUVJ TlZBTCkKLQkJZ290byBmYWlsOwotCisJam9iLT5iYXNlLmJvID0ga2NhbGxvYyhBUlJBWV9TSVpF KGFyZ3MtPmJvX2hhbmRsZXMpLAorCQkJICAgICAgIHNpemVvZigqam9iLT5iYXNlLmJvKSwgR0ZQ X0tFUk5FTCk7CiAJam9iLT5hcmdzID0gKmFyZ3M7Ci0Jam9iLT52M2QgPSB2M2Q7CiAKIAlzcGlu X2xvY2soJmZpbGVfcHJpdi0+dGFibGVfbG9jayk7Ci0JZm9yIChib19jb3VudCA9IDA7IGJvX2Nv dW50IDwgQVJSQVlfU0laRShqb2ItPmJvKTsgYm9fY291bnQrKykgeworCWZvciAoam9iLT5iYXNl LmJvX2NvdW50ID0gMDsKKwkgICAgIGpvYi0+YmFzZS5ib19jb3VudCA8IEFSUkFZX1NJWkUoYXJn cy0+Ym9faGFuZGxlcyk7CisJICAgICBqb2ItPmJhc2UuYm9fY291bnQrKykgewogCQlzdHJ1Y3Qg ZHJtX2dlbV9vYmplY3QgKmJvOwogCi0JCWlmICghYXJncy0+Ym9faGFuZGxlc1tib19jb3VudF0p CisJCWlmICghYXJncy0+Ym9faGFuZGxlc1tqb2ItPmJhc2UuYm9fY291bnRdKQogCQkJYnJlYWs7 CiAKIAkJYm8gPSBpZHJfZmluZCgmZmlsZV9wcml2LT5vYmplY3RfaWRyLAotCQkJICAgICAgYXJn cy0+Ym9faGFuZGxlc1tib19jb3VudF0pOworCQkJICAgICAgYXJncy0+Ym9faGFuZGxlc1tqb2It PmJhc2UuYm9fY291bnRdKTsKIAkJaWYgKCFibykgewogCQkJRFJNX0RFQlVHKCJGYWlsZWQgdG8g bG9vayB1cCBHRU0gQk8gJWQ6ICVkXG4iLAotCQkJCSAgYm9fY291bnQsIGFyZ3MtPmJvX2hhbmRs ZXNbYm9fY291bnRdKTsKKwkJCQkgIGpvYi0+YmFzZS5ib19jb3VudCwKKwkJCQkgIGFyZ3MtPmJv X2hhbmRsZXNbam9iLT5iYXNlLmJvX2NvdW50XSk7CiAJCQlyZXQgPSAtRU5PRU5UOwogCQkJc3Bp bl91bmxvY2soJmZpbGVfcHJpdi0+dGFibGVfbG9jayk7CiAJCQlnb3RvIGZhaWw7CiAJCX0KIAkJ ZHJtX2dlbV9vYmplY3RfZ2V0KGJvKTsKLQkJam9iLT5ib1tib19jb3VudF0gPSB0b192M2RfYm8o Ym8pOworCQlqb2ItPmJhc2UuYm9bam9iLT5iYXNlLmJvX2NvdW50XSA9IHRvX3YzZF9ibyhibyk7 CiAJfQogCXNwaW5fdW5sb2NrKCZmaWxlX3ByaXYtPnRhYmxlX2xvY2spOwogCi0JcmV0ID0gdjNk X2xvY2tfYm9fcmVzZXJ2YXRpb25zKGpvYi0+Ym8sIGJvX2NvdW50LCAmYWNxdWlyZV9jdHgpOwor CXJldCA9IHYzZF9sb2NrX2JvX3Jlc2VydmF0aW9ucyhqb2ItPmJhc2UuYm8sIGpvYi0+YmFzZS5i b19jb3VudCwKKwkJCQkgICAgICAgJmFjcXVpcmVfY3R4KTsKIAlpZiAocmV0KQogCQlnb3RvIGZh aWw7CiAKIAltdXRleF9sb2NrKCZ2M2QtPnNjaGVkX2xvY2spOwotCXJldCA9IGRybV9zY2hlZF9q b2JfaW5pdCgmam9iLT5iYXNlLAotCQkJCSAmdjNkX3ByaXYtPnNjaGVkX2VudGl0eVtWM0RfVEZV XSwKLQkJCQkgdjNkX3ByaXYpOworCXJldCA9IHYzZF9wdXNoX2pvYih2M2RfcHJpdiwgJmpvYi0+ YmFzZSwgVjNEX1RGVSk7CiAJaWYgKHJldCkKIAkJZ290byBmYWlsX3VucmVzZXJ2ZTsKLQotCXNj aGVkX2RvbmVfZmVuY2UgPSBkbWFfZmVuY2VfZ2V0KCZqb2ItPmJhc2Uuc19mZW5jZS0+ZmluaXNo ZWQpOwotCi0Ja3JlZl9nZXQoJmpvYi0+cmVmY291bnQpOyAvKiBwdXQgYnkgc2NoZWR1bGVyIGpv YiBjb21wbGV0aW9uICovCi0JZHJtX3NjaGVkX2VudGl0eV9wdXNoX2pvYigmam9iLT5iYXNlLCAm djNkX3ByaXYtPnNjaGVkX2VudGl0eVtWM0RfVEZVXSk7CiAJbXV0ZXhfdW5sb2NrKCZ2M2QtPnNj aGVkX2xvY2spOwogCi0JdjNkX2F0dGFjaF9vYmplY3RfZmVuY2VzKGpvYi0+Ym8sIGJvX2NvdW50 LCBzY2hlZF9kb25lX2ZlbmNlKTsKLQotCXYzZF91bmxvY2tfYm9fcmVzZXJ2YXRpb25zKGpvYi0+ Ym8sIGJvX2NvdW50LCAmYWNxdWlyZV9jdHgpOwotCi0JLyogVXBkYXRlIHRoZSByZXR1cm4gc3lu YyBvYmplY3QgKi8KLQlzeW5jX291dCA9IGRybV9zeW5jb2JqX2ZpbmQoZmlsZV9wcml2LCBhcmdz LT5vdXRfc3luYyk7Ci0JaWYgKHN5bmNfb3V0KSB7Ci0JCWRybV9zeW5jb2JqX3JlcGxhY2VfZmVu Y2Uoc3luY19vdXQsIHNjaGVkX2RvbmVfZmVuY2UpOwotCQlkcm1fc3luY29ial9wdXQoc3luY19v dXQpOwotCX0KLQlkbWFfZmVuY2VfcHV0KHNjaGVkX2RvbmVfZmVuY2UpOworCXYzZF9hdHRhY2hf ZmVuY2VzX2FuZF91bmxvY2tfcmVzZXJ2YXRpb24oZmlsZV9wcml2LAorCQkJCQkJICZqb2ItPmJh c2UsICZhY3F1aXJlX2N0eCwKKwkJCQkJCSBhcmdzLT5vdXRfc3luYyk7CiAKLQl2M2RfdGZ1X2pv Yl9wdXQoam9iKTsKKwl2M2Rfam9iX3B1dCgmam9iLT5iYXNlKTsKIAogCXJldHVybiAwOwogCiBm YWlsX3VucmVzZXJ2ZToKIAltdXRleF91bmxvY2soJnYzZC0+c2NoZWRfbG9jayk7Ci0JdjNkX3Vu bG9ja19ib19yZXNlcnZhdGlvbnMoam9iLT5ibywgYm9fY291bnQsICZhY3F1aXJlX2N0eCk7CisJ djNkX3VubG9ja19ib19yZXNlcnZhdGlvbnMoam9iLT5iYXNlLmJvLCBqb2ItPmJhc2UuYm9fY291 bnQsCisJCQkJICAgJmFjcXVpcmVfY3R4KTsKIGZhaWw6Ci0JdjNkX3RmdV9qb2JfcHV0KGpvYik7 CisJdjNkX2pvYl9wdXQoJmpvYi0+YmFzZSk7CiAKIAlyZXR1cm4gcmV0OwogfQpAQCAtNzE0LDcg KzcyMiw3IEBAIHYzZF9nZW1fZGVzdHJveShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KQogCiAJdjNk X3NjaGVkX2ZpbmkodjNkKTsKIAotCS8qIFdhaXRpbmcgZm9yIGV4ZWMgdG8gZmluaXNoIHdvdWxk IG5lZWQgdG8gYmUgZG9uZSBiZWZvcmUKKwkvKiBXYWl0aW5nIGZvciBqb2JzIHRvIGZpbmlzaCB3 b3VsZCBuZWVkIHRvIGJlIGRvbmUgYmVmb3JlCiAJICogdW5yZWdpc3RlcmluZyBWM0QuCiAJICov CiAJV0FSTl9PTih2M2QtPmJpbl9qb2IpOwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3Yz ZC92M2RfaXJxLmMgYi9kcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9pcnEuYwppbmRleCAwNDQwNjI2 MDc1NzcuLjQ4MGJhNjY2NmE0ZCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3YzZC92M2Rf aXJxLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL3YzZC92M2RfaXJxLmMKQEAgLTYyLDcgKzYyLDcg QEAgdjNkX292ZXJmbG93X21lbV93b3JrKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKIAl9CiAK IAlkcm1fZ2VtX29iamVjdF9nZXQob2JqKTsKLQlsaXN0X2FkZF90YWlsKCZiby0+dW5yZWZfaGVh ZCwgJnYzZC0+YmluX2pvYi0+dW5yZWZfbGlzdCk7CisJbGlzdF9hZGRfdGFpbCgmYm8tPnVucmVm X2hlYWQsICZ2M2QtPmJpbl9qb2ItPnJlbmRlci0+dW5yZWZfbGlzdCk7CiAJc3Bpbl91bmxvY2tf aXJxcmVzdG9yZSgmdjNkLT5qb2JfbG9jaywgaXJxZmxhZ3MpOwogCiAJVjNEX0NPUkVfV1JJVEUo MCwgVjNEX1BUQl9CUE9BLCBiby0+bm9kZS5zdGFydCA8PCBQQUdFX1NISUZUKTsKQEAgLTk2LDcg Kzk2LDcgQEAgdjNkX2lycShpbnQgaXJxLCB2b2lkICphcmcpCiAKIAlpZiAoaW50c3RzICYgVjNE X0lOVF9GTERPTkUpIHsKIAkJc3RydWN0IHYzZF9mZW5jZSAqZmVuY2UgPQotCQkJdG9fdjNkX2Zl bmNlKHYzZC0+YmluX2pvYi0+YmluLmlycV9mZW5jZSk7CisJCQl0b192M2RfZmVuY2UodjNkLT5i aW5fam9iLT5iYXNlLmlycV9mZW5jZSk7CiAKIAkJdHJhY2VfdjNkX2JjbF9pcnEoJnYzZC0+ZHJt LCBmZW5jZS0+c2Vxbm8pOwogCQlkbWFfZmVuY2Vfc2lnbmFsKCZmZW5jZS0+YmFzZSk7CkBAIC0x MDUsNyArMTA1LDcgQEAgdjNkX2lycShpbnQgaXJxLCB2b2lkICphcmcpCiAKIAlpZiAoaW50c3Rz ICYgVjNEX0lOVF9GUkRPTkUpIHsKIAkJc3RydWN0IHYzZF9mZW5jZSAqZmVuY2UgPQotCQkJdG9f djNkX2ZlbmNlKHYzZC0+cmVuZGVyX2pvYi0+cmVuZGVyLmlycV9mZW5jZSk7CisJCQl0b192M2Rf ZmVuY2UodjNkLT5yZW5kZXJfam9iLT5iYXNlLmlycV9mZW5jZSk7CiAKIAkJdHJhY2VfdjNkX3Jj bF9pcnEoJnYzZC0+ZHJtLCBmZW5jZS0+c2Vxbm8pOwogCQlkbWFfZmVuY2Vfc2lnbmFsKCZmZW5j ZS0+YmFzZSk7CkBAIC0xNDEsNyArMTQxLDcgQEAgdjNkX2h1Yl9pcnEoaW50IGlycSwgdm9pZCAq YXJnKQogCiAJaWYgKGludHN0cyAmIFYzRF9IVUJfSU5UX1RGVUMpIHsKIAkJc3RydWN0IHYzZF9m ZW5jZSAqZmVuY2UgPQotCQkJdG9fdjNkX2ZlbmNlKHYzZC0+dGZ1X2pvYi0+aXJxX2ZlbmNlKTsK KwkJCXRvX3YzZF9mZW5jZSh2M2QtPnRmdV9qb2ItPmJhc2UuaXJxX2ZlbmNlKTsKIAogCQl0cmFj ZV92M2RfdGZ1X2lycSgmdjNkLT5kcm0sIGZlbmNlLT5zZXFubyk7CiAJCWRtYV9mZW5jZV9zaWdu YWwoJmZlbmNlLT5iYXNlKTsKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS92M2QvdjNkX3Nj aGVkLmMgYi9kcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9zY2hlZC5jCmluZGV4IGU3NDBmM2I5OWFh NS4uODg0ZjAwZjVlZGY0IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vdjNkL3YzZF9zY2hl ZC5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS92M2QvdjNkX3NjaGVkLmMKQEAgLTMwLDQzICszMCw0 NCBAQCB0b192M2Rfam9iKHN0cnVjdCBkcm1fc2NoZWRfam9iICpzY2hlZF9qb2IpCiAJcmV0dXJu IGNvbnRhaW5lcl9vZihzY2hlZF9qb2IsIHN0cnVjdCB2M2Rfam9iLCBiYXNlKTsKIH0KIAotc3Rh dGljIHN0cnVjdCB2M2RfdGZ1X2pvYiAqCi10b190ZnVfam9iKHN0cnVjdCBkcm1fc2NoZWRfam9i ICpzY2hlZF9qb2IpCitzdGF0aWMgc3RydWN0IHYzZF9iaW5fam9iICoKK3RvX2Jpbl9qb2Ioc3Ry dWN0IGRybV9zY2hlZF9qb2IgKnNjaGVkX2pvYikKIHsKLQlyZXR1cm4gY29udGFpbmVyX29mKHNj aGVkX2pvYiwgc3RydWN0IHYzZF90ZnVfam9iLCBiYXNlKTsKKwlyZXR1cm4gY29udGFpbmVyX29m KHNjaGVkX2pvYiwgc3RydWN0IHYzZF9iaW5fam9iLCBiYXNlLmJhc2UpOwogfQogCi1zdGF0aWMg dm9pZAotdjNkX2pvYl9mcmVlKHN0cnVjdCBkcm1fc2NoZWRfam9iICpzY2hlZF9qb2IpCitzdGF0 aWMgc3RydWN0IHYzZF9yZW5kZXJfam9iICoKK3RvX3JlbmRlcl9qb2Ioc3RydWN0IGRybV9zY2hl ZF9qb2IgKnNjaGVkX2pvYikKIHsKLQlzdHJ1Y3QgdjNkX2pvYiAqam9iID0gdG9fdjNkX2pvYihz Y2hlZF9qb2IpOwotCi0JZHJtX3NjaGVkX2pvYl9jbGVhbnVwKHNjaGVkX2pvYik7CisJcmV0dXJu IGNvbnRhaW5lcl9vZihzY2hlZF9qb2IsIHN0cnVjdCB2M2RfcmVuZGVyX2pvYiwgYmFzZS5iYXNl KTsKK30KIAotCXYzZF9leGVjX3B1dChqb2ItPmV4ZWMpOworc3RhdGljIHN0cnVjdCB2M2RfdGZ1 X2pvYiAqCit0b190ZnVfam9iKHN0cnVjdCBkcm1fc2NoZWRfam9iICpzY2hlZF9qb2IpCit7CisJ cmV0dXJuIGNvbnRhaW5lcl9vZihzY2hlZF9qb2IsIHN0cnVjdCB2M2RfdGZ1X2pvYiwgYmFzZS5i YXNlKTsKIH0KIAogc3RhdGljIHZvaWQKLXYzZF90ZnVfam9iX2ZyZWUoc3RydWN0IGRybV9zY2hl ZF9qb2IgKnNjaGVkX2pvYikKK3YzZF9qb2JfZnJlZShzdHJ1Y3QgZHJtX3NjaGVkX2pvYiAqc2No ZWRfam9iKQogewotCXN0cnVjdCB2M2RfdGZ1X2pvYiAqam9iID0gdG9fdGZ1X2pvYihzY2hlZF9q b2IpOworCXN0cnVjdCB2M2Rfam9iICpqb2IgPSB0b192M2Rfam9iKHNjaGVkX2pvYik7CiAKIAlk cm1fc2NoZWRfam9iX2NsZWFudXAoc2NoZWRfam9iKTsKLQotCXYzZF90ZnVfam9iX3B1dChqb2Ip OworCXYzZF9qb2JfcHV0KGpvYik7CiB9CiAKIC8qKgotICogUmV0dXJucyB0aGUgZmVuY2VzIHRo YXQgdGhlIGJpbiBvciByZW5kZXIgam9iIGRlcGVuZHMgb24sIG9uZSBieSBvbmUuCi0gKiB2M2Rf am9iX3J1bigpIHdvbid0IGJlIGNhbGxlZCB1bnRpbCBhbGwgb2YgdGhlbSBoYXZlIGJlZW4gc2ln bmFsZWQuCisgKiBSZXR1cm5zIHRoZSBmZW5jZXMgdGhhdCB0aGUgam9iIGRlcGVuZHMgb24sIG9u ZSBieSBvbmUuCisgKgorICogSWYgcGxhY2VkIGluIHRoZSBzY2hlZHVsZXIncyAuZGVwZW5kZW5j eSBtZXRob2QsIHRoZSBjb3JyZXNwb25kaW5nCisgKiAucnVuX2pvYiB3b24ndCBiZSBjYWxsZWQg dW50aWwgYWxsIG9mIHRoZW0gaGF2ZSBiZWVuIHNpZ25hbGVkLgogICovCiBzdGF0aWMgc3RydWN0 IGRtYV9mZW5jZSAqCiB2M2Rfam9iX2RlcGVuZGVuY3koc3RydWN0IGRybV9zY2hlZF9qb2IgKnNj aGVkX2pvYiwKIAkJICAgc3RydWN0IGRybV9zY2hlZF9lbnRpdHkgKnNfZW50aXR5KQogewogCXN0 cnVjdCB2M2Rfam9iICpqb2IgPSB0b192M2Rfam9iKHNjaGVkX2pvYik7Ci0Jc3RydWN0IHYzZF9l eGVjX2luZm8gKmV4ZWMgPSBqb2ItPmV4ZWM7Ci0JZW51bSB2M2RfcXVldWUgcSA9IGpvYiA9PSAm ZXhlYy0+YmluID8gVjNEX0JJTiA6IFYzRF9SRU5ERVI7CiAJc3RydWN0IGRtYV9mZW5jZSAqZmVu Y2U7CiAKIAlmZW5jZSA9IGpvYi0+aW5fZmVuY2U7CkBAIC03NSwxMTMgKzc2LDEzMiBAQCB2M2Rf am9iX2RlcGVuZGVuY3koc3RydWN0IGRybV9zY2hlZF9qb2IgKnNjaGVkX2pvYiwKIAkJcmV0dXJu IGZlbmNlOwogCX0KIAotCWlmIChxID09IFYzRF9SRU5ERVIpIHsKLQkJLyogSWYgd2UgaGFkIGEg YmluIGpvYiwgdGhlIHJlbmRlciBqb2IgZGVmaW5pdGVseSBkZXBlbmRzIG9uCi0JCSAqIGl0LiBX ZSBmaXJzdCBoYXZlIHRvIHdhaXQgZm9yIGJpbiB0byBiZSBzY2hlZHVsZWQsIHNvIHRoYXQKLQkJ ICogaXRzIGRvbmVfZmVuY2UgaXMgY3JlYXRlZC4KLQkJICovCi0JCWZlbmNlID0gZXhlYy0+Ymlu X2RvbmVfZmVuY2U7Ci0JCWlmIChmZW5jZSkgewotCQkJZXhlYy0+YmluX2RvbmVfZmVuY2UgPSBO VUxMOwotCQkJcmV0dXJuIGZlbmNlOwotCQl9Ci0JfQotCiAJLyogWFhYOiBXYWl0IG9uIGEgZmVu Y2UgZm9yIHN3aXRjaGluZyB0aGUgR01QIGlmIG5lY2Vzc2FyeSwKIAkgKiBhbmQgdGhlbiBkbyBz by4KIAkgKi8KIAotCXJldHVybiBmZW5jZTsKKwlyZXR1cm4gTlVMTDsKIH0KIAogLyoqCi0gKiBS ZXR1cm5zIHRoZSBmZW5jZXMgdGhhdCB0aGUgVEZVIGpvYiBkZXBlbmRzIG9uLCBvbmUgYnkgb25l LgotICogdjNkX3RmdV9qb2JfcnVuKCkgd29uJ3QgYmUgY2FsbGVkIHVudGlsIGFsbCBvZiB0aGVt IGhhdmUgYmVlbgotICogc2lnbmFsZWQuCisgKiBSZXR1cm5zIHRoZSBmZW5jZXMgdGhhdCB0aGUg cmVuZGVyIGpvYiBkZXBlbmRzIG9uLCBvbmUgYnkgb25lLgorICogdjNkX2pvYl9ydW4oKSB3b24n dCBiZSBjYWxsZWQgdW50aWwgYWxsIG9mIHRoZW0gaGF2ZSBiZWVuIHNpZ25hbGVkLgogICovCiBz dGF0aWMgc3RydWN0IGRtYV9mZW5jZSAqCi12M2RfdGZ1X2pvYl9kZXBlbmRlbmN5KHN0cnVjdCBk cm1fc2NoZWRfam9iICpzY2hlZF9qb2IsCi0JCSAgICAgICBzdHJ1Y3QgZHJtX3NjaGVkX2VudGl0 eSAqc19lbnRpdHkpCit2M2RfcmVuZGVyX2pvYl9kZXBlbmRlbmN5KHN0cnVjdCBkcm1fc2NoZWRf am9iICpzY2hlZF9qb2IsCisJCQkgIHN0cnVjdCBkcm1fc2NoZWRfZW50aXR5ICpzX2VudGl0eSkK IHsKLQlzdHJ1Y3QgdjNkX3RmdV9qb2IgKmpvYiA9IHRvX3RmdV9qb2Ioc2NoZWRfam9iKTsKKwlz dHJ1Y3QgdjNkX3JlbmRlcl9qb2IgKmpvYiA9IHRvX3JlbmRlcl9qb2Ioc2NoZWRfam9iKTsKIAlz dHJ1Y3QgZG1hX2ZlbmNlICpmZW5jZTsKIAotCWZlbmNlID0gam9iLT5pbl9mZW5jZTsKKwlmZW5j ZSA9IHYzZF9qb2JfZGVwZW5kZW5jeShzY2hlZF9qb2IsIHNfZW50aXR5KTsKKwlpZiAoZmVuY2Up CisJCXJldHVybiBmZW5jZTsKKworCS8qIElmIHdlIGhhZCBhIGJpbiBqb2IsIHRoZSByZW5kZXIg am9iIGRlZmluaXRlbHkgZGVwZW5kcyBvbgorCSAqIGl0LiBXZSBmaXJzdCBoYXZlIHRvIHdhaXQg Zm9yIGJpbiB0byBiZSBzY2hlZHVsZWQsIHNvIHRoYXQKKwkgKiBpdHMgZG9uZV9mZW5jZSBpcyBj cmVhdGVkLgorCSAqLworCWZlbmNlID0gam9iLT5iaW5fZG9uZV9mZW5jZTsKIAlpZiAoZmVuY2Up IHsKLQkJam9iLT5pbl9mZW5jZSA9IE5VTEw7CisJCWpvYi0+YmluX2RvbmVfZmVuY2UgPSBOVUxM OwogCQlyZXR1cm4gZmVuY2U7CiAJfQogCi0JcmV0dXJuIE5VTEw7CisJcmV0dXJuIGZlbmNlOwog fQogCi1zdGF0aWMgc3RydWN0IGRtYV9mZW5jZSAqdjNkX2pvYl9ydW4oc3RydWN0IGRybV9zY2hl ZF9qb2IgKnNjaGVkX2pvYikKK3N0YXRpYyBzdHJ1Y3QgZG1hX2ZlbmNlICp2M2RfYmluX2pvYl9y dW4oc3RydWN0IGRybV9zY2hlZF9qb2IgKnNjaGVkX2pvYikKIHsKLQlzdHJ1Y3QgdjNkX2pvYiAq am9iID0gdG9fdjNkX2pvYihzY2hlZF9qb2IpOwotCXN0cnVjdCB2M2RfZXhlY19pbmZvICpleGVj ID0gam9iLT5leGVjOwotCWVudW0gdjNkX3F1ZXVlIHEgPSBqb2IgPT0gJmV4ZWMtPmJpbiA/IFYz RF9CSU4gOiBWM0RfUkVOREVSOwotCXN0cnVjdCB2M2RfZGV2ICp2M2QgPSBleGVjLT52M2Q7CisJ c3RydWN0IHYzZF9iaW5fam9iICpqb2IgPSB0b19iaW5fam9iKHNjaGVkX2pvYik7CisJc3RydWN0 IHYzZF9kZXYgKnYzZCA9IGpvYi0+YmFzZS52M2Q7CiAJc3RydWN0IGRybV9kZXZpY2UgKmRldiA9 ICZ2M2QtPmRybTsKIAlzdHJ1Y3QgZG1hX2ZlbmNlICpmZW5jZTsKIAl1bnNpZ25lZCBsb25nIGly cWZsYWdzOwogCi0JaWYgKHVubGlrZWx5KGpvYi0+YmFzZS5zX2ZlbmNlLT5maW5pc2hlZC5lcnJv cikpCisJaWYgKHVubGlrZWx5KGpvYi0+YmFzZS5iYXNlLnNfZmVuY2UtPmZpbmlzaGVkLmVycm9y KSkKIAkJcmV0dXJuIE5VTEw7CiAKIAkvKiBMb2NrIHJlcXVpcmVkIGFyb3VuZCBiaW5fam9iIHVw ZGF0ZSB2cwogCSAqIHYzZF9vdmVyZmxvd19tZW1fd29yaygpLgogCSAqLwogCXNwaW5fbG9ja19p cnFzYXZlKCZ2M2QtPmpvYl9sb2NrLCBpcnFmbGFncyk7Ci0JaWYgKHEgPT0gVjNEX0JJTikgewot CQl2M2QtPmJpbl9qb2IgPSBqb2ItPmV4ZWM7Ci0KLQkJLyogQ2xlYXIgb3V0IHRoZSBvdmVyZmxv dyBhbGxvY2F0aW9uLCBzbyB3ZSBkb24ndAotCQkgKiByZXVzZSB0aGUgb3ZlcmZsb3cgYXR0YWNo ZWQgdG8gYSBwcmV2aW91cyBqb2IuCi0JCSAqLwotCQlWM0RfQ09SRV9XUklURSgwLCBWM0RfUFRC X0JQT1MsIDApOwotCX0gZWxzZSB7Ci0JCXYzZC0+cmVuZGVyX2pvYiA9IGpvYi0+ZXhlYzsKLQl9 CisJdjNkLT5iaW5fam9iID0gam9iOworCS8qIENsZWFyIG91dCB0aGUgb3ZlcmZsb3cgYWxsb2Nh dGlvbiwgc28gd2UgZG9uJ3QKKwkgKiByZXVzZSB0aGUgb3ZlcmZsb3cgYXR0YWNoZWQgdG8gYSBw cmV2aW91cyBqb2IuCisJICovCisJVjNEX0NPUkVfV1JJVEUoMCwgVjNEX1BUQl9CUE9TLCAwKTsK IAlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZ2M2QtPmpvYl9sb2NrLCBpcnFmbGFncyk7CiAKLQkv KiBDYW4gd2UgYXZvaWQgdGhpcyBmbHVzaCB3aGVuIHE9PVJFTkRFUj8gIFdlIG5lZWQgdG8gYmUK LQkgKiBjYXJlZnVsIG9mIHNjaGVkdWxpbmcsIHRob3VnaCAtLSBpbWFnaW5lIGpvYjAgcmVuZGVy aW5nIHRvCi0JICogdGV4dHVyZSBhbmQgam9iMSByZWFkaW5nLCBhbmQgdGhlbSBiZWluZyBleGVj dXRlZCBhcyBiaW4wLAotCSAqIGJpbjEsIHJlbmRlcjAsIHJlbmRlcjEsIHNvIHRoYXQgcmVuZGVy MSdzIGZsdXNoIGF0IGJpbiB0aW1lCisJdjNkX2ludmFsaWRhdGVfY2FjaGVzKHYzZCk7CisKKwlm ZW5jZSA9IHYzZF9mZW5jZV9jcmVhdGUodjNkLCBWM0RfQklOKTsKKwlpZiAoSVNfRVJSKGZlbmNl KSkKKwkJcmV0dXJuIE5VTEw7CisKKwlpZiAoam9iLT5iYXNlLmlycV9mZW5jZSkKKwkJZG1hX2Zl bmNlX3B1dChqb2ItPmJhc2UuaXJxX2ZlbmNlKTsKKwlqb2ItPmJhc2UuaXJxX2ZlbmNlID0gZG1h X2ZlbmNlX2dldChmZW5jZSk7CisKKwl0cmFjZV92M2Rfc3VibWl0X2NsKGRldiwgZmFsc2UsIHRv X3YzZF9mZW5jZShmZW5jZSktPnNlcW5vLAorCQkJICAgIGpvYi0+c3RhcnQsIGpvYi0+ZW5kKTsK KworCS8qIFNldCB0aGUgY3VycmVudCBhbmQgZW5kIGFkZHJlc3Mgb2YgdGhlIGNvbnRyb2wgbGlz dC4KKwkgKiBXcml0aW5nIHRoZSBlbmQgcmVnaXN0ZXIgaXMgd2hhdCBzdGFydHMgdGhlIGpvYi4K KwkgKi8KKwlpZiAoam9iLT5xbWEpIHsKKwkJVjNEX0NPUkVfV1JJVEUoMCwgVjNEX0NMRV9DVDBR TUEsIGpvYi0+cW1hKTsKKwkJVjNEX0NPUkVfV1JJVEUoMCwgVjNEX0NMRV9DVDBRTVMsIGpvYi0+ cW1zKTsKKwl9CisJaWYgKGpvYi0+cXRzKSB7CisJCVYzRF9DT1JFX1dSSVRFKDAsIFYzRF9DTEVf Q1QwUVRTLAorCQkJICAgICAgIFYzRF9DTEVfQ1QwUVRTX0VOQUJMRSB8CisJCQkgICAgICAgam9i LT5xdHMpOworCX0KKwlWM0RfQ09SRV9XUklURSgwLCBWM0RfQ0xFX0NUMFFCQSwgam9iLT5zdGFy dCk7CisJVjNEX0NPUkVfV1JJVEUoMCwgVjNEX0NMRV9DVDBRRUEsIGpvYi0+ZW5kKTsKKworCXJl dHVybiBmZW5jZTsKK30KKworc3RhdGljIHN0cnVjdCBkbWFfZmVuY2UgKnYzZF9yZW5kZXJfam9i X3J1bihzdHJ1Y3QgZHJtX3NjaGVkX2pvYiAqc2NoZWRfam9iKQoreworCXN0cnVjdCB2M2RfcmVu ZGVyX2pvYiAqam9iID0gdG9fcmVuZGVyX2pvYihzY2hlZF9qb2IpOworCXN0cnVjdCB2M2RfZGV2 ICp2M2QgPSBqb2ItPmJhc2UudjNkOworCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYgPSAmdjNkLT5k cm07CisJc3RydWN0IGRtYV9mZW5jZSAqZmVuY2U7CisKKwlpZiAodW5saWtlbHkoam9iLT5iYXNl LmJhc2Uuc19mZW5jZS0+ZmluaXNoZWQuZXJyb3IpKQorCQlyZXR1cm4gTlVMTDsKKworCXYzZC0+ cmVuZGVyX2pvYiA9IGpvYjsKKworCS8qIENhbiB3ZSBhdm9pZCB0aGlzIGZsdXNoPyAgV2UgbmVl ZCB0byBiZSBjYXJlZnVsIG9mCisJICogc2NoZWR1bGluZywgdGhvdWdoIC0tIGltYWdpbmUgam9i MCByZW5kZXJpbmcgdG8gdGV4dHVyZSBhbmQKKwkgKiBqb2IxIHJlYWRpbmcsIGFuZCB0aGVtIGJl aW5nIGV4ZWN1dGVkIGFzIGJpbjAsIGJpbjEsCisJICogcmVuZGVyMCwgcmVuZGVyMSwgc28gdGhh dCByZW5kZXIxJ3MgZmx1c2ggYXQgYmluIHRpbWUKIAkgKiB3YXNuJ3QgZW5vdWdoLgogCSAqLwog CXYzZF9pbnZhbGlkYXRlX2NhY2hlcyh2M2QpOwogCi0JZmVuY2UgPSB2M2RfZmVuY2VfY3JlYXRl KHYzZCwgcSk7CisJZmVuY2UgPSB2M2RfZmVuY2VfY3JlYXRlKHYzZCwgVjNEX1JFTkRFUik7CiAJ aWYgKElTX0VSUihmZW5jZSkpCiAJCXJldHVybiBOVUxMOwogCi0JaWYgKGpvYi0+aXJxX2ZlbmNl KQotCQlkbWFfZmVuY2VfcHV0KGpvYi0+aXJxX2ZlbmNlKTsKLQlqb2ItPmlycV9mZW5jZSA9IGRt YV9mZW5jZV9nZXQoZmVuY2UpOworCWlmIChqb2ItPmJhc2UuaXJxX2ZlbmNlKQorCQlkbWFfZmVu Y2VfcHV0KGpvYi0+YmFzZS5pcnFfZmVuY2UpOworCWpvYi0+YmFzZS5pcnFfZmVuY2UgPSBkbWFf ZmVuY2VfZ2V0KGZlbmNlKTsKIAotCXRyYWNlX3YzZF9zdWJtaXRfY2woZGV2LCBxID09IFYzRF9S RU5ERVIsIHRvX3YzZF9mZW5jZShmZW5jZSktPnNlcW5vLAorCXRyYWNlX3YzZF9zdWJtaXRfY2wo ZGV2LCB0cnVlLCB0b192M2RfZmVuY2UoZmVuY2UpLT5zZXFubywKIAkJCSAgICBqb2ItPnN0YXJ0 LCBqb2ItPmVuZCk7CiAKLQlpZiAocSA9PSBWM0RfQklOKSB7Ci0JCWlmIChleGVjLT5xbWEpIHsK LQkJCVYzRF9DT1JFX1dSSVRFKDAsIFYzRF9DTEVfQ1QwUU1BLCBleGVjLT5xbWEpOwotCQkJVjNE X0NPUkVfV1JJVEUoMCwgVjNEX0NMRV9DVDBRTVMsIGV4ZWMtPnFtcyk7Ci0JCX0KLQkJaWYgKGV4 ZWMtPnF0cykgewotCQkJVjNEX0NPUkVfV1JJVEUoMCwgVjNEX0NMRV9DVDBRVFMsCi0JCQkJICAg ICAgIFYzRF9DTEVfQ1QwUVRTX0VOQUJMRSB8Ci0JCQkJICAgICAgIGV4ZWMtPnF0cyk7Ci0JCX0K LQl9IGVsc2UgewotCQkvKiBYWFg6IFNldCB0aGUgUUNGRyAqLwotCX0KKwkvKiBYWFg6IFNldCB0 aGUgUUNGRyAqLwogCiAJLyogU2V0IHRoZSBjdXJyZW50IGFuZCBlbmQgYWRkcmVzcyBvZiB0aGUg Y29udHJvbCBsaXN0LgogCSAqIFdyaXRpbmcgdGhlIGVuZCByZWdpc3RlciBpcyB3aGF0IHN0YXJ0 cyB0aGUgam9iLgogCSAqLwotCVYzRF9DT1JFX1dSSVRFKDAsIFYzRF9DTEVfQ1ROUUJBKHEpLCBq b2ItPnN0YXJ0KTsKLQlWM0RfQ09SRV9XUklURSgwLCBWM0RfQ0xFX0NUTlFFQShxKSwgam9iLT5l bmQpOworCVYzRF9DT1JFX1dSSVRFKDAsIFYzRF9DTEVfQ1QxUUJBLCBqb2ItPnN0YXJ0KTsKKwlW M0RfQ09SRV9XUklURSgwLCBWM0RfQ0xFX0NUMVFFQSwgam9iLT5lbmQpOwogCiAJcmV0dXJuIGZl bmNlOwogfQpAQCAtMTkwLDcgKzIxMCw3IEBAIHN0YXRpYyBzdHJ1Y3QgZG1hX2ZlbmNlICoKIHYz ZF90ZnVfam9iX3J1bihzdHJ1Y3QgZHJtX3NjaGVkX2pvYiAqc2NoZWRfam9iKQogewogCXN0cnVj dCB2M2RfdGZ1X2pvYiAqam9iID0gdG9fdGZ1X2pvYihzY2hlZF9qb2IpOwotCXN0cnVjdCB2M2Rf ZGV2ICp2M2QgPSBqb2ItPnYzZDsKKwlzdHJ1Y3QgdjNkX2RldiAqdjNkID0gam9iLT5iYXNlLnYz ZDsKIAlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gJnYzZC0+ZHJtOwogCXN0cnVjdCBkbWFfZmVu Y2UgKmZlbmNlOwogCkBAIC0xOTksOSArMjE5LDkgQEAgdjNkX3RmdV9qb2JfcnVuKHN0cnVjdCBk cm1fc2NoZWRfam9iICpzY2hlZF9qb2IpCiAJCXJldHVybiBOVUxMOwogCiAJdjNkLT50ZnVfam9i ID0gam9iOwotCWlmIChqb2ItPmlycV9mZW5jZSkKLQkJZG1hX2ZlbmNlX3B1dChqb2ItPmlycV9m ZW5jZSk7Ci0Jam9iLT5pcnFfZmVuY2UgPSBkbWFfZmVuY2VfZ2V0KGZlbmNlKTsKKwlpZiAoam9i LT5iYXNlLmlycV9mZW5jZSkKKwkJZG1hX2ZlbmNlX3B1dChqb2ItPmJhc2UuaXJxX2ZlbmNlKTsK Kwlqb2ItPmJhc2UuaXJxX2ZlbmNlID0gZG1hX2ZlbmNlX2dldChmZW5jZSk7CiAKIAl0cmFjZV92 M2Rfc3VibWl0X3RmdShkZXYsIHRvX3YzZF9mZW5jZShmZW5jZSktPnNlcW5vKTsKIApAQCAtMjUx LDUxICsyNzEsNzQgQEAgdjNkX2dwdV9yZXNldF9mb3JfdGltZW91dChzdHJ1Y3QgdjNkX2RldiAq djNkLCBzdHJ1Y3QgZHJtX3NjaGVkX2pvYiAqc2NoZWRfam9iKQogCW11dGV4X3VubG9jaygmdjNk LT5yZXNldF9sb2NrKTsKIH0KIAorLyogSWYgdGhlIGN1cnJlbnQgYWRkcmVzcyBvciByZXR1cm4g YWRkcmVzcyBoYXZlIGNoYW5nZWQsIHRoZW4gdGhlIEdQVQorICogaGFzIHByb2JhYmx5IG1hZGUg cHJvZ3Jlc3MgYW5kIHdlIHNob3VsZCBkZWxheSB0aGUgcmVzZXQuICBUaGlzCisgKiBjb3VsZCBm YWlsIGlmIHRoZSBHUFUgZ290IGluIGFuIGluZmluaXRlIGxvb3AgaW4gdGhlIENMLCBidXQgdGhh dAorICogaXMgcHJldHR5IHVubGlrZWx5IG91dHNpZGUgb2YgYW4gaS1nLXQgdGVzdGNhc2UuCisg Ki8KIHN0YXRpYyB2b2lkCi12M2Rfam9iX3RpbWVkb3V0KHN0cnVjdCBkcm1fc2NoZWRfam9iICpz Y2hlZF9qb2IpCit2M2RfY2xfam9iX3RpbWVkb3V0KHN0cnVjdCBkcm1fc2NoZWRfam9iICpzY2hl ZF9qb2IsIGVudW0gdjNkX3F1ZXVlIHEsCisJCSAgICAgIHUzMiAqdGltZWRvdXRfY3RjYSwgdTMy ICp0aW1lZG91dF9jdHJhKQogewogCXN0cnVjdCB2M2Rfam9iICpqb2IgPSB0b192M2Rfam9iKHNj aGVkX2pvYik7Ci0Jc3RydWN0IHYzZF9leGVjX2luZm8gKmV4ZWMgPSBqb2ItPmV4ZWM7Ci0Jc3Ry dWN0IHYzZF9kZXYgKnYzZCA9IGV4ZWMtPnYzZDsKLQllbnVtIHYzZF9xdWV1ZSBqb2JfcSA9IGpv YiA9PSAmZXhlYy0+YmluID8gVjNEX0JJTiA6IFYzRF9SRU5ERVI7Ci0JdTMyIGN0Y2EgPSBWM0Rf Q09SRV9SRUFEKDAsIFYzRF9DTEVfQ1ROQ0Eoam9iX3EpKTsKLQl1MzIgY3RyYSA9IFYzRF9DT1JF X1JFQUQoMCwgVjNEX0NMRV9DVE5SQShqb2JfcSkpOwotCi0JLyogSWYgdGhlIGN1cnJlbnQgYWRk cmVzcyBvciByZXR1cm4gYWRkcmVzcyBoYXZlIGNoYW5nZWQsIHRoZW4KLQkgKiB0aGUgR1BVIGhh cyBwcm9iYWJseSBtYWRlIHByb2dyZXNzIGFuZCB3ZSBzaG91bGQgZGVsYXkgdGhlCi0JICogcmVz ZXQuICBUaGlzIGNvdWxkIGZhaWwgaWYgdGhlIEdQVSBnb3QgaW4gYW4gaW5maW5pdGUgbG9vcAot CSAqIGluIHRoZSBDTCwgYnV0IHRoYXQgaXMgcHJldHR5IHVubGlrZWx5IG91dHNpZGUgb2YgYW4g aS1nLXQKLQkgKiB0ZXN0Y2FzZS4KLQkgKi8KLQlpZiAoam9iLT50aW1lZG91dF9jdGNhICE9IGN0 Y2EgfHwgam9iLT50aW1lZG91dF9jdHJhICE9IGN0cmEpIHsKLQkJam9iLT50aW1lZG91dF9jdGNh ID0gY3RjYTsKLQkJam9iLT50aW1lZG91dF9jdHJhID0gY3RyYTsKKwlzdHJ1Y3QgdjNkX2RldiAq djNkID0gam9iLT52M2Q7CisJdTMyIGN0Y2EgPSBWM0RfQ09SRV9SRUFEKDAsIFYzRF9DTEVfQ1RO Q0EocSkpOworCXUzMiBjdHJhID0gVjNEX0NPUkVfUkVBRCgwLCBWM0RfQ0xFX0NUTlJBKHEpKTsK KworCWlmICgqdGltZWRvdXRfY3RjYSAhPSBjdGNhIHx8ICp0aW1lZG91dF9jdHJhICE9IGN0cmEp IHsKKwkJKnRpbWVkb3V0X2N0Y2EgPSBjdGNhOworCQkqdGltZWRvdXRfY3RyYSA9IGN0cmE7CiAJ CXJldHVybjsKIAl9CiAKIAl2M2RfZ3B1X3Jlc2V0X2Zvcl90aW1lb3V0KHYzZCwgc2NoZWRfam9i KTsKIH0KIAorc3RhdGljIHZvaWQKK3YzZF9iaW5fam9iX3RpbWVkb3V0KHN0cnVjdCBkcm1fc2No ZWRfam9iICpzY2hlZF9qb2IpCit7CisJc3RydWN0IHYzZF9iaW5fam9iICpqb2IgPSB0b19iaW5f am9iKHNjaGVkX2pvYik7CisKKwl2M2RfY2xfam9iX3RpbWVkb3V0KHNjaGVkX2pvYiwgVjNEX0JJ TiwKKwkJCSAgICAmam9iLT50aW1lZG91dF9jdGNhLCAmam9iLT50aW1lZG91dF9jdHJhKTsKK30K Kworc3RhdGljIHZvaWQKK3YzZF9yZW5kZXJfam9iX3RpbWVkb3V0KHN0cnVjdCBkcm1fc2NoZWRf am9iICpzY2hlZF9qb2IpCit7CisJc3RydWN0IHYzZF9yZW5kZXJfam9iICpqb2IgPSB0b19yZW5k ZXJfam9iKHNjaGVkX2pvYik7CisKKwl2M2RfY2xfam9iX3RpbWVkb3V0KHNjaGVkX2pvYiwgVjNE X1JFTkRFUiwKKwkJCSAgICAmam9iLT50aW1lZG91dF9jdGNhLCAmam9iLT50aW1lZG91dF9jdHJh KTsKK30KKwogc3RhdGljIHZvaWQKIHYzZF90ZnVfam9iX3RpbWVkb3V0KHN0cnVjdCBkcm1fc2No ZWRfam9iICpzY2hlZF9qb2IpCiB7Ci0Jc3RydWN0IHYzZF90ZnVfam9iICpqb2IgPSB0b190ZnVf am9iKHNjaGVkX2pvYik7CisJc3RydWN0IHYzZF9qb2IgKmpvYiA9IHRvX3YzZF9qb2Ioc2NoZWRf am9iKTsKIAogCXYzZF9ncHVfcmVzZXRfZm9yX3RpbWVvdXQoam9iLT52M2QsIHNjaGVkX2pvYik7 CiB9CiAKLXN0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX3NjaGVkX2JhY2tlbmRfb3BzIHYzZF9zY2hl ZF9vcHMgPSB7CitzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9zY2hlZF9iYWNrZW5kX29wcyB2M2Rf YmluX3NjaGVkX29wcyA9IHsKIAkuZGVwZW5kZW5jeSA9IHYzZF9qb2JfZGVwZW5kZW5jeSwKLQku cnVuX2pvYiA9IHYzZF9qb2JfcnVuLAotCS50aW1lZG91dF9qb2IgPSB2M2Rfam9iX3RpbWVkb3V0 LAotCS5mcmVlX2pvYiA9IHYzZF9qb2JfZnJlZQorCS5ydW5fam9iID0gdjNkX2Jpbl9qb2JfcnVu LAorCS50aW1lZG91dF9qb2IgPSB2M2RfYmluX2pvYl90aW1lZG91dCwKKwkuZnJlZV9qb2IgPSB2 M2Rfam9iX2ZyZWUsCit9OworCitzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9zY2hlZF9iYWNrZW5k X29wcyB2M2RfcmVuZGVyX3NjaGVkX29wcyA9IHsKKwkuZGVwZW5kZW5jeSA9IHYzZF9yZW5kZXJf am9iX2RlcGVuZGVuY3ksCisJLnJ1bl9qb2IgPSB2M2RfcmVuZGVyX2pvYl9ydW4sCisJLnRpbWVk b3V0X2pvYiA9IHYzZF9yZW5kZXJfam9iX3RpbWVkb3V0LAorCS5mcmVlX2pvYiA9IHYzZF9qb2Jf ZnJlZSwKIH07CiAKIHN0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX3NjaGVkX2JhY2tlbmRfb3BzIHYz ZF90ZnVfc2NoZWRfb3BzID0gewotCS5kZXBlbmRlbmN5ID0gdjNkX3RmdV9qb2JfZGVwZW5kZW5j eSwKKwkuZGVwZW5kZW5jeSA9IHYzZF9qb2JfZGVwZW5kZW5jeSwKIAkucnVuX2pvYiA9IHYzZF90 ZnVfam9iX3J1biwKIAkudGltZWRvdXRfam9iID0gdjNkX3RmdV9qb2JfdGltZWRvdXQsCi0JLmZy ZWVfam9iID0gdjNkX3RmdV9qb2JfZnJlZQorCS5mcmVlX2pvYiA9IHYzZF9qb2JfZnJlZSwKIH07 CiAKIGludApAQCAtMzA3LDcgKzM1MCw3IEBAIHYzZF9zY2hlZF9pbml0KHN0cnVjdCB2M2RfZGV2 ICp2M2QpCiAJaW50IHJldDsKIAogCXJldCA9IGRybV9zY2hlZF9pbml0KCZ2M2QtPnF1ZXVlW1Yz RF9CSU5dLnNjaGVkLAotCQkJICAgICAmdjNkX3NjaGVkX29wcywKKwkJCSAgICAgJnYzZF9iaW5f c2NoZWRfb3BzLAogCQkJICAgICBod19qb2JzX2xpbWl0LCBqb2JfaGFuZ19saW1pdCwKIAkJCSAg ICAgbXNlY3NfdG9famlmZmllcyhoYW5nX2xpbWl0X21zKSwKIAkJCSAgICAgInYzZF9iaW4iKTsK QEAgLTMxNyw3ICszNjAsNyBAQCB2M2Rfc2NoZWRfaW5pdChzdHJ1Y3QgdjNkX2RldiAqdjNkKQog CX0KIAogCXJldCA9IGRybV9zY2hlZF9pbml0KCZ2M2QtPnF1ZXVlW1YzRF9SRU5ERVJdLnNjaGVk LAotCQkJICAgICAmdjNkX3NjaGVkX29wcywKKwkJCSAgICAgJnYzZF9yZW5kZXJfc2NoZWRfb3Bz LAogCQkJICAgICBod19qb2JzX2xpbWl0LCBqb2JfaGFuZ19saW1pdCwKIAkJCSAgICAgbXNlY3Nf dG9famlmZmllcyhoYW5nX2xpbWl0X21zKSwKIAkJCSAgICAgInYzZF9yZW5kZXIiKTsKLS0gCjIu MjAuMQoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KZHJp LWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0dHBz Oi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVs