From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2960C32750 for ; Fri, 2 Aug 2019 05:23:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 69F872171F for ; Fri, 2 Aug 2019 05:23:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387776AbfHBFXy (ORCPT ); Fri, 2 Aug 2019 01:23:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35118 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732711AbfHBFWx (ORCPT ); Fri, 2 Aug 2019 01:22:53 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1F0B83087958; Fri, 2 Aug 2019 05:22:53 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-81.ams2.redhat.com [10.36.116.81]) by smtp.corp.redhat.com (Postfix) with ESMTP id 269B4608C2; Fri, 2 Aug 2019 05:22:49 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id 72FF11750B; Fri, 2 Aug 2019 07:22:48 +0200 (CEST) From: Gerd Hoffmann To: dri-devel@lists.freedesktop.org Cc: ckoenig.leichtzumerken@gmail.com, thomas@shipmail.org, tzimmermann@suse.de, daniel@ffwll.ch, bskeggs@redhat.com, Gerd Hoffmann , Dave Airlie , David Airlie , virtualization@lists.linux-foundation.org (open list:DRM DRIVER FOR QXL VIRTUAL GPU), spice-devel@lists.freedesktop.org (open list:DRM DRIVER FOR QXL VIRTUAL GPU), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 03/17] drm/qxl: use embedded gem object Date: Fri, 2 Aug 2019 07:22:33 +0200 Message-Id: <20190802052247.18427-4-kraxel@redhat.com> In-Reply-To: <20190802052247.18427-1-kraxel@redhat.com> References: <20190802052247.18427-1-kraxel@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 02 Aug 2019 05:22:53 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Drop drm_gem_object from qxl_bo, use the ttm_buffer_object.base instead. Signed-off-by: Gerd Hoffmann Acked-by: Christian König --- drivers/gpu/drm/qxl/qxl_drv.h | 6 +++--- drivers/gpu/drm/qxl/qxl_object.h | 4 ++-- drivers/gpu/drm/qxl/qxl_cmd.c | 4 ++-- drivers/gpu/drm/qxl/qxl_debugfs.c | 2 +- drivers/gpu/drm/qxl/qxl_display.c | 8 ++++---- drivers/gpu/drm/qxl/qxl_gem.c | 2 +- drivers/gpu/drm/qxl/qxl_object.c | 20 ++++++++++---------- drivers/gpu/drm/qxl/qxl_release.c | 2 +- drivers/gpu/drm/qxl/qxl_ttm.c | 4 ++-- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index ae82e5fab09c..9e034c5fa87d 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -71,12 +71,13 @@ extern int qxl_max_ioctls; QXL_INTERRUPT_CLIENT_MONITORS_CONFIG) struct qxl_bo { + struct ttm_buffer_object tbo; + /* Protected by gem.mutex */ struct list_head list; /* Protected by tbo.reserved */ struct ttm_place placements[3]; struct ttm_placement placement; - struct ttm_buffer_object tbo; struct ttm_bo_kmap_obj kmap; unsigned int pin_count; void *kptr; @@ -84,7 +85,6 @@ struct qxl_bo { int type; /* Constant after initialization */ - struct drm_gem_object gem_base; unsigned int is_primary:1; /* is this now a primary surface */ unsigned int is_dumb:1; struct qxl_bo *shadow; @@ -93,7 +93,7 @@ struct qxl_bo { uint32_t surface_id; struct qxl_release *surf_create; }; -#define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base) +#define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, tbo.base) #define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo) struct qxl_gem { diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h index 255b914e2a7b..b812d4ae9d0d 100644 --- a/drivers/gpu/drm/qxl/qxl_object.h +++ b/drivers/gpu/drm/qxl/qxl_object.h @@ -34,7 +34,7 @@ static inline int qxl_bo_reserve(struct qxl_bo *bo, bool no_wait) r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) { - struct drm_device *ddev = bo->gem_base.dev; + struct drm_device *ddev = bo->tbo.base.dev; dev_err(ddev->dev, "%p reserve failed\n", bo); } @@ -71,7 +71,7 @@ static inline int qxl_bo_wait(struct qxl_bo *bo, u32 *mem_type, r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL); if (unlikely(r != 0)) { if (r != -ERESTARTSYS) { - struct drm_device *ddev = bo->gem_base.dev; + struct drm_device *ddev = bo->tbo.base.dev; dev_err(ddev->dev, "%p reserve failed for wait\n", bo); diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index ac1081f55b51..ef09dc6bc635 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -377,7 +377,7 @@ void qxl_io_destroy_primary(struct qxl_device *qdev) { wait_for_io_cmd(qdev, 0, QXL_IO_DESTROY_PRIMARY_ASYNC); qdev->primary_bo->is_primary = false; - drm_gem_object_put_unlocked(&qdev->primary_bo->gem_base); + drm_gem_object_put_unlocked(&qdev->primary_bo->tbo.base); qdev->primary_bo = NULL; } @@ -404,7 +404,7 @@ void qxl_io_create_primary(struct qxl_device *qdev, struct qxl_bo *bo) wait_for_io_cmd(qdev, 0, QXL_IO_CREATE_PRIMARY_ASYNC); qdev->primary_bo = bo; qdev->primary_bo->is_primary = true; - drm_gem_object_get(&qdev->primary_bo->gem_base); + drm_gem_object_get(&qdev->primary_bo->tbo.base); } void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id) diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c b/drivers/gpu/drm/qxl/qxl_debugfs.c index a85ec100b0cc..bdb5ac0987ab 100644 --- a/drivers/gpu/drm/qxl/qxl_debugfs.c +++ b/drivers/gpu/drm/qxl/qxl_debugfs.c @@ -66,7 +66,7 @@ qxl_debugfs_buffers_info(struct seq_file *m, void *data) rcu_read_unlock(); seq_printf(m, "size %ld, pc %d, num releases %d\n", - (unsigned long)bo->gem_base.size, + (unsigned long)bo->tbo.base.size, bo->pin_count, rel); } return 0; diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 023fb5a69af1..16d73b22f3f5 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -797,7 +797,7 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, qdev->dumb_shadow_bo->surf.height != surf.height) { if (qdev->dumb_shadow_bo) { drm_gem_object_put_unlocked - (&qdev->dumb_shadow_bo->gem_base); + (&qdev->dumb_shadow_bo->tbo.base); qdev->dumb_shadow_bo = NULL; } qxl_bo_create(qdev, surf.height * surf.stride, @@ -807,10 +807,10 @@ static int qxl_plane_prepare_fb(struct drm_plane *plane, if (user_bo->shadow != qdev->dumb_shadow_bo) { if (user_bo->shadow) { drm_gem_object_put_unlocked - (&user_bo->shadow->gem_base); + (&user_bo->shadow->tbo.base); user_bo->shadow = NULL; } - drm_gem_object_get(&qdev->dumb_shadow_bo->gem_base); + drm_gem_object_get(&qdev->dumb_shadow_bo->tbo.base); user_bo->shadow = qdev->dumb_shadow_bo; } } @@ -841,7 +841,7 @@ static void qxl_plane_cleanup_fb(struct drm_plane *plane, qxl_bo_unpin(user_bo); if (old_state->fb != plane->state->fb && user_bo->shadow) { - drm_gem_object_put_unlocked(&user_bo->shadow->gem_base); + drm_gem_object_put_unlocked(&user_bo->shadow->tbo.base); user_bo->shadow = NULL; } } diff --git a/drivers/gpu/drm/qxl/qxl_gem.c b/drivers/gpu/drm/qxl/qxl_gem.c index 89e4f9a7249c..69f37db1027a 100644 --- a/drivers/gpu/drm/qxl/qxl_gem.c +++ b/drivers/gpu/drm/qxl/qxl_gem.c @@ -63,7 +63,7 @@ int qxl_gem_object_create(struct qxl_device *qdev, int size, size, initial_domain, alignment, r); return r; } - *obj = &qbo->gem_base; + *obj = &qbo->tbo.base; mutex_lock(&qdev->gem.mutex); list_add_tail(&qbo->list, &qdev->gem.objects); diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 4928fa602944..548dfe6f3b26 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -33,14 +33,14 @@ static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo) struct qxl_device *qdev; bo = to_qxl_bo(tbo); - qdev = (struct qxl_device *)bo->gem_base.dev->dev_private; + qdev = (struct qxl_device *)bo->tbo.base.dev->dev_private; qxl_surface_evict(qdev, bo, false); WARN_ON_ONCE(bo->map_count > 0); mutex_lock(&qdev->gem.mutex); list_del_init(&bo->list); mutex_unlock(&qdev->gem.mutex); - drm_gem_object_release(&bo->gem_base); + drm_gem_object_release(&bo->tbo.base); kfree(bo); } @@ -95,7 +95,7 @@ int qxl_bo_create(struct qxl_device *qdev, if (bo == NULL) return -ENOMEM; size = roundup(size, PAGE_SIZE); - r = drm_gem_object_init(&qdev->ddev, &bo->gem_base, size); + r = drm_gem_object_init(&qdev->ddev, &bo->tbo.base, size); if (unlikely(r)) { kfree(bo); return r; @@ -214,20 +214,20 @@ void qxl_bo_unref(struct qxl_bo **bo) if ((*bo) == NULL) return; - drm_gem_object_put_unlocked(&(*bo)->gem_base); + drm_gem_object_put_unlocked(&(*bo)->tbo.base); *bo = NULL; } struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo) { - drm_gem_object_get(&bo->gem_base); + drm_gem_object_get(&bo->tbo.base); return bo; } static int __qxl_bo_pin(struct qxl_bo *bo) { struct ttm_operation_ctx ctx = { false, false }; - struct drm_device *ddev = bo->gem_base.dev; + struct drm_device *ddev = bo->tbo.base.dev; int r; if (bo->pin_count) { @@ -247,7 +247,7 @@ static int __qxl_bo_pin(struct qxl_bo *bo) static int __qxl_bo_unpin(struct qxl_bo *bo) { struct ttm_operation_ctx ctx = { false, false }; - struct drm_device *ddev = bo->gem_base.dev; + struct drm_device *ddev = bo->tbo.base.dev; int r, i; if (!bo->pin_count) { @@ -310,13 +310,13 @@ void qxl_bo_force_delete(struct qxl_device *qdev) dev_err(qdev->ddev.dev, "Userspace still has active objects !\n"); list_for_each_entry_safe(bo, n, &qdev->gem.objects, list) { dev_err(qdev->ddev.dev, "%p %p %lu %lu force free\n", - &bo->gem_base, bo, (unsigned long)bo->gem_base.size, - *((unsigned long *)&bo->gem_base.refcount)); + &bo->tbo.base, bo, (unsigned long)bo->tbo.base.size, + *((unsigned long *)&bo->tbo.base.refcount)); mutex_lock(&qdev->gem.mutex); list_del_init(&bo->list); mutex_unlock(&qdev->gem.mutex); /* this should unref the ttm bo */ - drm_gem_object_put_unlocked(&bo->gem_base); + drm_gem_object_put_unlocked(&bo->tbo.base); } } diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index b805bfa87b68..0022e31ba910 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -243,7 +243,7 @@ static int qxl_release_validate_bo(struct qxl_bo *bo) return ret; /* allocate a surface for reserved + validated buffers */ - ret = qxl_bo_check_id(bo->gem_base.dev->dev_private, bo); + ret = qxl_bo_check_id(bo->tbo.base.dev->dev_private, bo); if (ret) return ret; return 0; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 663e59fd1e8c..9b24514c75aa 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -155,7 +155,7 @@ static int qxl_verify_access(struct ttm_buffer_object *bo, struct file *filp) { struct qxl_bo *qbo = to_qxl_bo(bo); - return drm_vma_node_verify_access(&qbo->gem_base.vma_node, + return drm_vma_node_verify_access(&qbo->tbo.base.vma_node, filp->private_data); } @@ -297,7 +297,7 @@ static void qxl_bo_move_notify(struct ttm_buffer_object *bo, if (!qxl_ttm_bo_is_qxl_bo(bo)) return; qbo = to_qxl_bo(bo); - qdev = qbo->gem_base.dev->dev_private; + qdev = qbo->tbo.base.dev->dev_private; if (bo->mem.mem_type == TTM_PL_PRIV && qbo->surface_id) qxl_surface_evict(qdev, qbo, new_mem ? true : false); -- 2.18.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gerd Hoffmann Subject: [PATCH v4 03/17] drm/qxl: use embedded gem object Date: Fri, 2 Aug 2019 07:22:33 +0200 Message-ID: <20190802052247.18427-4-kraxel@redhat.com> References: <20190802052247.18427-1-kraxel@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20190802052247.18427-1-kraxel@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: virtualization-bounces@lists.linux-foundation.org Errors-To: virtualization-bounces@lists.linux-foundation.org To: dri-devel@lists.freedesktop.org Cc: thomas@shipmail.org, tzimmermann@suse.de, David Airlie , ckoenig.leichtzumerken@gmail.com, open list , "open list:DRM DRIVER FOR QXL VIRTUAL GPU" , daniel@ffwll.ch, "open list:DRM DRIVER FOR QXL VIRTUAL GPU" , Dave Airlie , bskeggs@redhat.com List-Id: virtualization@lists.linuxfoundation.org RHJvcCBkcm1fZ2VtX29iamVjdCBmcm9tIHF4bF9ibywgdXNlIHRoZQp0dG1fYnVmZmVyX29iamVj dC5iYXNlIGluc3RlYWQuCgpTaWduZWQtb2ZmLWJ5OiBHZXJkIEhvZmZtYW5uIDxrcmF4ZWxAcmVk aGF0LmNvbT4KQWNrZWQtYnk6IENocmlzdGlhbiBLw7ZuaWcgPGNocmlzdGlhbi5rb2VuaWdAYW1k LmNvbT4KLS0tCiBkcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kcnYuaCAgICAgfCAgNiArKystLS0K IGRyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX29iamVjdC5oICB8ICA0ICsrLS0KIGRyaXZlcnMvZ3B1 L2RybS9xeGwvcXhsX2NtZC5jICAgICB8ICA0ICsrLS0KIGRyaXZlcnMvZ3B1L2RybS9xeGwvcXhs X2RlYnVnZnMuYyB8ICAyICstCiBkcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNwbGF5LmMgfCAg OCArKysrLS0tLQogZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZ2VtLmMgICAgIHwgIDIgKy0KIGRy aXZlcnMvZ3B1L2RybS9xeGwvcXhsX29iamVjdC5jICB8IDIwICsrKysrKysrKystLS0tLS0tLS0t CiBkcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9yZWxlYXNlLmMgfCAgMiArLQogZHJpdmVycy9ncHUv ZHJtL3F4bC9xeGxfdHRtLmMgICAgIHwgIDQgKystLQogOSBmaWxlcyBjaGFuZ2VkLCAyNiBpbnNl cnRpb25zKCspLCAyNiBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0v cXhsL3F4bF9kcnYuaCBiL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Rydi5oCmluZGV4IGFlODJl NWZhYjA5Yy4uOWUwMzRjNWZhODdkIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4 bF9kcnYuaAorKysgYi9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kcnYuaApAQCAtNzEsMTIgKzcx LDEzIEBAIGV4dGVybiBpbnQgcXhsX21heF9pb2N0bHM7CiAJUVhMX0lOVEVSUlVQVF9DTElFTlRf TU9OSVRPUlNfQ09ORklHKQogCiBzdHJ1Y3QgcXhsX2JvIHsKKwlzdHJ1Y3QgdHRtX2J1ZmZlcl9v YmplY3QJdGJvOworCiAJLyogUHJvdGVjdGVkIGJ5IGdlbS5tdXRleCAqLwogCXN0cnVjdCBsaXN0 X2hlYWQJCWxpc3Q7CiAJLyogUHJvdGVjdGVkIGJ5IHRiby5yZXNlcnZlZCAqLwogCXN0cnVjdCB0 dG1fcGxhY2UJCXBsYWNlbWVudHNbM107CiAJc3RydWN0IHR0bV9wbGFjZW1lbnQJCXBsYWNlbWVu dDsKLQlzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmplY3QJdGJvOwogCXN0cnVjdCB0dG1fYm9fa21hcF9v YmoJCWttYXA7CiAJdW5zaWduZWQgaW50IHBpbl9jb3VudDsKIAl2b2lkCQkJCSprcHRyOwpAQCAt ODQsNyArODUsNiBAQCBzdHJ1Y3QgcXhsX2JvIHsKIAlpbnQgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHR5cGU7CiAKIAkvKiBDb25zdGFudCBhZnRlciBpbml0aWFsaXphdGlvbiAqLwotCXN0 cnVjdCBkcm1fZ2VtX29iamVjdAkJZ2VtX2Jhc2U7CiAJdW5zaWduZWQgaW50IGlzX3ByaW1hcnk6 MTsgLyogaXMgdGhpcyBub3cgYSBwcmltYXJ5IHN1cmZhY2UgKi8KIAl1bnNpZ25lZCBpbnQgaXNf ZHVtYjoxOwogCXN0cnVjdCBxeGxfYm8gKnNoYWRvdzsKQEAgLTkzLDcgKzkzLDcgQEAgc3RydWN0 IHF4bF9ibyB7CiAJdWludDMyX3Qgc3VyZmFjZV9pZDsKIAlzdHJ1Y3QgcXhsX3JlbGVhc2UgKnN1 cmZfY3JlYXRlOwogfTsKLSNkZWZpbmUgZ2VtX3RvX3F4bF9ibyhnb2JqKSBjb250YWluZXJfb2Yo KGdvYmopLCBzdHJ1Y3QgcXhsX2JvLCBnZW1fYmFzZSkKKyNkZWZpbmUgZ2VtX3RvX3F4bF9ibyhn b2JqKSBjb250YWluZXJfb2YoKGdvYmopLCBzdHJ1Y3QgcXhsX2JvLCB0Ym8uYmFzZSkKICNkZWZp bmUgdG9fcXhsX2JvKHRvYmopIGNvbnRhaW5lcl9vZigodG9iaiksIHN0cnVjdCBxeGxfYm8sIHRi bykKIAogc3RydWN0IHF4bF9nZW0gewpkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3F4bC9x eGxfb2JqZWN0LmggYi9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9vYmplY3QuaAppbmRleCAyNTVi OTE0ZTJhN2IuLmI4MTJkNGFlOWQwZCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3F4bC9x eGxfb2JqZWN0LmgKKysrIGIvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfb2JqZWN0LmgKQEAgLTM0 LDcgKzM0LDcgQEAgc3RhdGljIGlubGluZSBpbnQgcXhsX2JvX3Jlc2VydmUoc3RydWN0IHF4bF9i byAqYm8sIGJvb2wgbm9fd2FpdCkKIAlyID0gdHRtX2JvX3Jlc2VydmUoJmJvLT50Ym8sIHRydWUs IG5vX3dhaXQsIE5VTEwpOwogCWlmICh1bmxpa2VseShyICE9IDApKSB7CiAJCWlmIChyICE9IC1F UkVTVEFSVFNZUykgewotCQkJc3RydWN0IGRybV9kZXZpY2UgKmRkZXYgPSBiby0+Z2VtX2Jhc2Uu ZGV2OworCQkJc3RydWN0IGRybV9kZXZpY2UgKmRkZXYgPSBiby0+dGJvLmJhc2UuZGV2OwogCiAJ CQlkZXZfZXJyKGRkZXYtPmRldiwgIiVwIHJlc2VydmUgZmFpbGVkXG4iLCBibyk7CiAJCX0KQEAg LTcxLDcgKzcxLDcgQEAgc3RhdGljIGlubGluZSBpbnQgcXhsX2JvX3dhaXQoc3RydWN0IHF4bF9i byAqYm8sIHUzMiAqbWVtX3R5cGUsCiAJciA9IHR0bV9ib19yZXNlcnZlKCZiby0+dGJvLCB0cnVl LCBub193YWl0LCBOVUxMKTsKIAlpZiAodW5saWtlbHkociAhPSAwKSkgewogCQlpZiAociAhPSAt RVJFU1RBUlRTWVMpIHsKLQkJCXN0cnVjdCBkcm1fZGV2aWNlICpkZGV2ID0gYm8tPmdlbV9iYXNl LmRldjsKKwkJCXN0cnVjdCBkcm1fZGV2aWNlICpkZGV2ID0gYm8tPnRiby5iYXNlLmRldjsKIAog CQkJZGV2X2VycihkZGV2LT5kZXYsICIlcCByZXNlcnZlIGZhaWxlZCBmb3Igd2FpdFxuIiwKIAkJ CQlibyk7CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9jbWQuYyBiL2RyaXZl cnMvZ3B1L2RybS9xeGwvcXhsX2NtZC5jCmluZGV4IGFjMTA4MWY1NWI1MS4uZWYwOWRjNmJjNjM1 IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9jbWQuYworKysgYi9kcml2ZXJz L2dwdS9kcm0vcXhsL3F4bF9jbWQuYwpAQCAtMzc3LDcgKzM3Nyw3IEBAIHZvaWQgcXhsX2lvX2Rl c3Ryb3lfcHJpbWFyeShzdHJ1Y3QgcXhsX2RldmljZSAqcWRldikKIHsKIAl3YWl0X2Zvcl9pb19j bWQocWRldiwgMCwgUVhMX0lPX0RFU1RST1lfUFJJTUFSWV9BU1lOQyk7CiAJcWRldi0+cHJpbWFy eV9iby0+aXNfcHJpbWFyeSA9IGZhbHNlOwotCWRybV9nZW1fb2JqZWN0X3B1dF91bmxvY2tlZCgm cWRldi0+cHJpbWFyeV9iby0+Z2VtX2Jhc2UpOworCWRybV9nZW1fb2JqZWN0X3B1dF91bmxvY2tl ZCgmcWRldi0+cHJpbWFyeV9iby0+dGJvLmJhc2UpOwogCXFkZXYtPnByaW1hcnlfYm8gPSBOVUxM OwogfQogCkBAIC00MDQsNyArNDA0LDcgQEAgdm9pZCBxeGxfaW9fY3JlYXRlX3ByaW1hcnkoc3Ry dWN0IHF4bF9kZXZpY2UgKnFkZXYsIHN0cnVjdCBxeGxfYm8gKmJvKQogCXdhaXRfZm9yX2lvX2Nt ZChxZGV2LCAwLCBRWExfSU9fQ1JFQVRFX1BSSU1BUllfQVNZTkMpOwogCXFkZXYtPnByaW1hcnlf Ym8gPSBibzsKIAlxZGV2LT5wcmltYXJ5X2JvLT5pc19wcmltYXJ5ID0gdHJ1ZTsKLQlkcm1fZ2Vt X29iamVjdF9nZXQoJnFkZXYtPnByaW1hcnlfYm8tPmdlbV9iYXNlKTsKKwlkcm1fZ2VtX29iamVj dF9nZXQoJnFkZXYtPnByaW1hcnlfYm8tPnRiby5iYXNlKTsKIH0KIAogdm9pZCBxeGxfaW9fbWVt c2xvdF9hZGQoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYsIHVpbnQ4X3QgaWQpCmRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kZWJ1Z2ZzLmMgYi9kcml2ZXJzL2dwdS9kcm0vcXhs L3F4bF9kZWJ1Z2ZzLmMKaW5kZXggYTg1ZWMxMDBiMGNjLi5iZGI1YWMwOTg3YWIgMTAwNjQ0Ci0t LSBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2RlYnVnZnMuYworKysgYi9kcml2ZXJzL2dwdS9k cm0vcXhsL3F4bF9kZWJ1Z2ZzLmMKQEAgLTY2LDcgKzY2LDcgQEAgcXhsX2RlYnVnZnNfYnVmZmVy c19pbmZvKHN0cnVjdCBzZXFfZmlsZSAqbSwgdm9pZCAqZGF0YSkKIAkJcmN1X3JlYWRfdW5sb2Nr KCk7CiAKIAkJc2VxX3ByaW50ZihtLCAic2l6ZSAlbGQsIHBjICVkLCBudW0gcmVsZWFzZXMgJWRc biIsCi0JCQkgICAodW5zaWduZWQgbG9uZyliby0+Z2VtX2Jhc2Uuc2l6ZSwKKwkJCSAgICh1bnNp Z25lZCBsb25nKWJvLT50Ym8uYmFzZS5zaXplLAogCQkJICAgYm8tPnBpbl9jb3VudCwgcmVsKTsK IAl9CiAJcmV0dXJuIDA7CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNw bGF5LmMgYi9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNwbGF5LmMKaW5kZXggMDIzZmI1YTY5 YWYxLi4xNmQ3M2IyMmYzZjUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Rp c3BsYXkuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNwbGF5LmMKQEAgLTc5Nyw3 ICs3OTcsNyBAQCBzdGF0aWMgaW50IHF4bF9wbGFuZV9wcmVwYXJlX2ZiKHN0cnVjdCBkcm1fcGxh bmUgKnBsYW5lLAogCQkgICAgcWRldi0+ZHVtYl9zaGFkb3dfYm8tPnN1cmYuaGVpZ2h0ICE9IHN1 cmYuaGVpZ2h0KSB7CiAJCQlpZiAocWRldi0+ZHVtYl9zaGFkb3dfYm8pIHsKIAkJCQlkcm1fZ2Vt X29iamVjdF9wdXRfdW5sb2NrZWQKLQkJCQkJKCZxZGV2LT5kdW1iX3NoYWRvd19iby0+Z2VtX2Jh c2UpOworCQkJCQkoJnFkZXYtPmR1bWJfc2hhZG93X2JvLT50Ym8uYmFzZSk7CiAJCQkJcWRldi0+ ZHVtYl9zaGFkb3dfYm8gPSBOVUxMOwogCQkJfQogCQkJcXhsX2JvX2NyZWF0ZShxZGV2LCBzdXJm LmhlaWdodCAqIHN1cmYuc3RyaWRlLApAQCAtODA3LDEwICs4MDcsMTAgQEAgc3RhdGljIGludCBx eGxfcGxhbmVfcHJlcGFyZV9mYihzdHJ1Y3QgZHJtX3BsYW5lICpwbGFuZSwKIAkJaWYgKHVzZXJf Ym8tPnNoYWRvdyAhPSBxZGV2LT5kdW1iX3NoYWRvd19ibykgewogCQkJaWYgKHVzZXJfYm8tPnNo YWRvdykgewogCQkJCWRybV9nZW1fb2JqZWN0X3B1dF91bmxvY2tlZAotCQkJCQkoJnVzZXJfYm8t PnNoYWRvdy0+Z2VtX2Jhc2UpOworCQkJCQkoJnVzZXJfYm8tPnNoYWRvdy0+dGJvLmJhc2UpOwog CQkJCXVzZXJfYm8tPnNoYWRvdyA9IE5VTEw7CiAJCQl9Ci0JCQlkcm1fZ2VtX29iamVjdF9nZXQo JnFkZXYtPmR1bWJfc2hhZG93X2JvLT5nZW1fYmFzZSk7CisJCQlkcm1fZ2VtX29iamVjdF9nZXQo JnFkZXYtPmR1bWJfc2hhZG93X2JvLT50Ym8uYmFzZSk7CiAJCQl1c2VyX2JvLT5zaGFkb3cgPSBx ZGV2LT5kdW1iX3NoYWRvd19ibzsKIAkJfQogCX0KQEAgLTg0MSw3ICs4NDEsNyBAQCBzdGF0aWMg dm9pZCBxeGxfcGxhbmVfY2xlYW51cF9mYihzdHJ1Y3QgZHJtX3BsYW5lICpwbGFuZSwKIAlxeGxf Ym9fdW5waW4odXNlcl9ibyk7CiAKIAlpZiAob2xkX3N0YXRlLT5mYiAhPSBwbGFuZS0+c3RhdGUt PmZiICYmIHVzZXJfYm8tPnNoYWRvdykgewotCQlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2NrZWQo JnVzZXJfYm8tPnNoYWRvdy0+Z2VtX2Jhc2UpOworCQlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2Nr ZWQoJnVzZXJfYm8tPnNoYWRvdy0+dGJvLmJhc2UpOwogCQl1c2VyX2JvLT5zaGFkb3cgPSBOVUxM OwogCX0KIH0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2dlbS5jIGIvZHJp dmVycy9ncHUvZHJtL3F4bC9xeGxfZ2VtLmMKaW5kZXggODllNGY5YTcyNDljLi42OWYzN2RiMTAy N2EgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2dlbS5jCisrKyBiL2RyaXZl cnMvZ3B1L2RybS9xeGwvcXhsX2dlbS5jCkBAIC02Myw3ICs2Myw3IEBAIGludCBxeGxfZ2VtX29i amVjdF9jcmVhdGUoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYsIGludCBzaXplLAogCQkJCSAgc2l6 ZSwgaW5pdGlhbF9kb21haW4sIGFsaWdubWVudCwgcik7CiAJCXJldHVybiByOwogCX0KLQkqb2Jq ID0gJnFiby0+Z2VtX2Jhc2U7CisJKm9iaiA9ICZxYm8tPnRiby5iYXNlOwogCiAJbXV0ZXhfbG9j aygmcWRldi0+Z2VtLm11dGV4KTsKIAlsaXN0X2FkZF90YWlsKCZxYm8tPmxpc3QsICZxZGV2LT5n ZW0ub2JqZWN0cyk7CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9vYmplY3Qu YyBiL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX29iamVjdC5jCmluZGV4IDQ5MjhmYTYwMjk0NC4u NTQ4ZGZlNmYzYjI2IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9vYmplY3Qu YworKysgYi9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9vYmplY3QuYwpAQCAtMzMsMTQgKzMzLDE0 IEBAIHN0YXRpYyB2b2lkIHF4bF90dG1fYm9fZGVzdHJveShzdHJ1Y3QgdHRtX2J1ZmZlcl9vYmpl Y3QgKnRibykKIAlzdHJ1Y3QgcXhsX2RldmljZSAqcWRldjsKIAogCWJvID0gdG9fcXhsX2JvKHRi byk7Ci0JcWRldiA9IChzdHJ1Y3QgcXhsX2RldmljZSAqKWJvLT5nZW1fYmFzZS5kZXYtPmRldl9w cml2YXRlOworCXFkZXYgPSAoc3RydWN0IHF4bF9kZXZpY2UgKiliby0+dGJvLmJhc2UuZGV2LT5k ZXZfcHJpdmF0ZTsKIAogCXF4bF9zdXJmYWNlX2V2aWN0KHFkZXYsIGJvLCBmYWxzZSk7CiAJV0FS Tl9PTl9PTkNFKGJvLT5tYXBfY291bnQgPiAwKTsKIAltdXRleF9sb2NrKCZxZGV2LT5nZW0ubXV0 ZXgpOwogCWxpc3RfZGVsX2luaXQoJmJvLT5saXN0KTsKIAltdXRleF91bmxvY2soJnFkZXYtPmdl bS5tdXRleCk7Ci0JZHJtX2dlbV9vYmplY3RfcmVsZWFzZSgmYm8tPmdlbV9iYXNlKTsKKwlkcm1f Z2VtX29iamVjdF9yZWxlYXNlKCZiby0+dGJvLmJhc2UpOwogCWtmcmVlKGJvKTsKIH0KIApAQCAt OTUsNyArOTUsNyBAQCBpbnQgcXhsX2JvX2NyZWF0ZShzdHJ1Y3QgcXhsX2RldmljZSAqcWRldiwK IAlpZiAoYm8gPT0gTlVMTCkKIAkJcmV0dXJuIC1FTk9NRU07CiAJc2l6ZSA9IHJvdW5kdXAoc2l6 ZSwgUEFHRV9TSVpFKTsKLQlyID0gZHJtX2dlbV9vYmplY3RfaW5pdCgmcWRldi0+ZGRldiwgJmJv LT5nZW1fYmFzZSwgc2l6ZSk7CisJciA9IGRybV9nZW1fb2JqZWN0X2luaXQoJnFkZXYtPmRkZXYs ICZiby0+dGJvLmJhc2UsIHNpemUpOwogCWlmICh1bmxpa2VseShyKSkgewogCQlrZnJlZShibyk7 CiAJCXJldHVybiByOwpAQCAtMjE0LDIwICsyMTQsMjAgQEAgdm9pZCBxeGxfYm9fdW5yZWYoc3Ry dWN0IHF4bF9ibyAqKmJvKQogCWlmICgoKmJvKSA9PSBOVUxMKQogCQlyZXR1cm47CiAKLQlkcm1f Z2VtX29iamVjdF9wdXRfdW5sb2NrZWQoJigqYm8pLT5nZW1fYmFzZSk7CisJZHJtX2dlbV9vYmpl Y3RfcHV0X3VubG9ja2VkKCYoKmJvKS0+dGJvLmJhc2UpOwogCSpibyA9IE5VTEw7CiB9CiAKIHN0 cnVjdCBxeGxfYm8gKnF4bF9ib19yZWYoc3RydWN0IHF4bF9ibyAqYm8pCiB7Ci0JZHJtX2dlbV9v YmplY3RfZ2V0KCZiby0+Z2VtX2Jhc2UpOworCWRybV9nZW1fb2JqZWN0X2dldCgmYm8tPnRiby5i YXNlKTsKIAlyZXR1cm4gYm87CiB9CiAKIHN0YXRpYyBpbnQgX19xeGxfYm9fcGluKHN0cnVjdCBx eGxfYm8gKmJvKQogewogCXN0cnVjdCB0dG1fb3BlcmF0aW9uX2N0eCBjdHggPSB7IGZhbHNlLCBm YWxzZSB9OwotCXN0cnVjdCBkcm1fZGV2aWNlICpkZGV2ID0gYm8tPmdlbV9iYXNlLmRldjsKKwlz dHJ1Y3QgZHJtX2RldmljZSAqZGRldiA9IGJvLT50Ym8uYmFzZS5kZXY7CiAJaW50IHI7CiAKIAlp ZiAoYm8tPnBpbl9jb3VudCkgewpAQCAtMjQ3LDcgKzI0Nyw3IEBAIHN0YXRpYyBpbnQgX19xeGxf Ym9fcGluKHN0cnVjdCBxeGxfYm8gKmJvKQogc3RhdGljIGludCBfX3F4bF9ib191bnBpbihzdHJ1 Y3QgcXhsX2JvICpibykKIHsKIAlzdHJ1Y3QgdHRtX29wZXJhdGlvbl9jdHggY3R4ID0geyBmYWxz ZSwgZmFsc2UgfTsKLQlzdHJ1Y3QgZHJtX2RldmljZSAqZGRldiA9IGJvLT5nZW1fYmFzZS5kZXY7 CisJc3RydWN0IGRybV9kZXZpY2UgKmRkZXYgPSBiby0+dGJvLmJhc2UuZGV2OwogCWludCByLCBp OwogCiAJaWYgKCFiby0+cGluX2NvdW50KSB7CkBAIC0zMTAsMTMgKzMxMCwxMyBAQCB2b2lkIHF4 bF9ib19mb3JjZV9kZWxldGUoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYpCiAJZGV2X2VycihxZGV2 LT5kZGV2LmRldiwgIlVzZXJzcGFjZSBzdGlsbCBoYXMgYWN0aXZlIG9iamVjdHMgIVxuIik7CiAJ bGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGJvLCBuLCAmcWRldi0+Z2VtLm9iamVjdHMsIGxpc3Qp IHsKIAkJZGV2X2VycihxZGV2LT5kZGV2LmRldiwgIiVwICVwICVsdSAlbHUgZm9yY2UgZnJlZVxu IiwKLQkJCSZiby0+Z2VtX2Jhc2UsIGJvLCAodW5zaWduZWQgbG9uZyliby0+Z2VtX2Jhc2Uuc2l6 ZSwKLQkJCSooKHVuc2lnbmVkIGxvbmcgKikmYm8tPmdlbV9iYXNlLnJlZmNvdW50KSk7CisJCQkm Ym8tPnRiby5iYXNlLCBibywgKHVuc2lnbmVkIGxvbmcpYm8tPnRiby5iYXNlLnNpemUsCisJCQkq KCh1bnNpZ25lZCBsb25nICopJmJvLT50Ym8uYmFzZS5yZWZjb3VudCkpOwogCQltdXRleF9sb2Nr KCZxZGV2LT5nZW0ubXV0ZXgpOwogCQlsaXN0X2RlbF9pbml0KCZiby0+bGlzdCk7CiAJCW11dGV4 X3VubG9jaygmcWRldi0+Z2VtLm11dGV4KTsKIAkJLyogdGhpcyBzaG91bGQgdW5yZWYgdGhlIHR0 bSBibyAqLwotCQlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2NrZWQoJmJvLT5nZW1fYmFzZSk7CisJ CWRybV9nZW1fb2JqZWN0X3B1dF91bmxvY2tlZCgmYm8tPnRiby5iYXNlKTsKIAl9CiB9CiAKZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX3JlbGVhc2UuYyBiL2RyaXZlcnMvZ3B1 L2RybS9xeGwvcXhsX3JlbGVhc2UuYwppbmRleCBiODA1YmZhODdiNjguLjAwMjJlMzFiYTkxMCAx MDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfcmVsZWFzZS5jCisrKyBiL2RyaXZl cnMvZ3B1L2RybS9xeGwvcXhsX3JlbGVhc2UuYwpAQCAtMjQzLDcgKzI0Myw3IEBAIHN0YXRpYyBp bnQgcXhsX3JlbGVhc2VfdmFsaWRhdGVfYm8oc3RydWN0IHF4bF9ibyAqYm8pCiAJCXJldHVybiBy ZXQ7CiAKIAkvKiBhbGxvY2F0ZSBhIHN1cmZhY2UgZm9yIHJlc2VydmVkICsgdmFsaWRhdGVkIGJ1 ZmZlcnMgKi8KLQlyZXQgPSBxeGxfYm9fY2hlY2tfaWQoYm8tPmdlbV9iYXNlLmRldi0+ZGV2X3By aXZhdGUsIGJvKTsKKwlyZXQgPSBxeGxfYm9fY2hlY2tfaWQoYm8tPnRiby5iYXNlLmRldi0+ZGV2 X3ByaXZhdGUsIGJvKTsKIAlpZiAocmV0KQogCQlyZXR1cm4gcmV0OwogCXJldHVybiAwOwpkaWZm IC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfdHRtLmMgYi9kcml2ZXJzL2dwdS9kcm0v cXhsL3F4bF90dG0uYwppbmRleCA2NjNlNTlmZDFlOGMuLjliMjQ1MTRjNzVhYSAxMDA2NDQKLS0t IGEvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfdHRtLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL3F4 bC9xeGxfdHRtLmMKQEAgLTE1NSw3ICsxNTUsNyBAQCBzdGF0aWMgaW50IHF4bF92ZXJpZnlfYWNj ZXNzKHN0cnVjdCB0dG1fYnVmZmVyX29iamVjdCAqYm8sIHN0cnVjdCBmaWxlICpmaWxwKQogewog CXN0cnVjdCBxeGxfYm8gKnFibyA9IHRvX3F4bF9ibyhibyk7CiAKLQlyZXR1cm4gZHJtX3ZtYV9u b2RlX3ZlcmlmeV9hY2Nlc3MoJnFiby0+Z2VtX2Jhc2Uudm1hX25vZGUsCisJcmV0dXJuIGRybV92 bWFfbm9kZV92ZXJpZnlfYWNjZXNzKCZxYm8tPnRiby5iYXNlLnZtYV9ub2RlLAogCQkJCQkgIGZp bHAtPnByaXZhdGVfZGF0YSk7CiB9CiAKQEAgLTI5Nyw3ICsyOTcsNyBAQCBzdGF0aWMgdm9pZCBx eGxfYm9fbW92ZV9ub3RpZnkoc3RydWN0IHR0bV9idWZmZXJfb2JqZWN0ICpibywKIAlpZiAoIXF4 bF90dG1fYm9faXNfcXhsX2JvKGJvKSkKIAkJcmV0dXJuOwogCXFibyA9IHRvX3F4bF9ibyhibyk7 Ci0JcWRldiA9IHFiby0+Z2VtX2Jhc2UuZGV2LT5kZXZfcHJpdmF0ZTsKKwlxZGV2ID0gcWJvLT50 Ym8uYmFzZS5kZXYtPmRldl9wcml2YXRlOwogCiAJaWYgKGJvLT5tZW0ubWVtX3R5cGUgPT0gVFRN X1BMX1BSSVYgJiYgcWJvLT5zdXJmYWNlX2lkKQogCQlxeGxfc3VyZmFjZV9ldmljdChxZGV2LCBx Ym8sIG5ld19tZW0gPyB0cnVlIDogZmFsc2UpOwotLSAKMi4xOC4xCgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpWaXJ0dWFsaXphdGlvbiBtYWlsaW5nIGxp c3QKVmlydHVhbGl6YXRpb25AbGlzdHMubGludXgtZm91bmRhdGlvbi5vcmcKaHR0cHM6Ly9saXN0 cy5saW51eGZvdW5kYXRpb24ub3JnL21haWxtYW4vbGlzdGluZm8vdmlydHVhbGl6YXRpb24=