From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753339AbeCYLBY (ORCPT ); Sun, 25 Mar 2018 07:01:24 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:34301 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752628AbeCYLAJ (ORCPT ); Sun, 25 Mar 2018 07:00:09 -0400 X-Google-Smtp-Source: AG47ELsOZ9Ydq1wIiE0JCserkJHrsbI+bITXVu1k40u3tWKOMcOcf801yBJmyCNje998sBbGVT50lw== From: "=?UTF-8?q?Christian=20K=C3=B6nig?=" X-Google-Original-From: =?UTF-8?q?Christian=20K=C3=B6nig?= To: linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [PATCH 8/8] drm/amdgpu: add support for exporting VRAM using DMA-buf Date: Sun, 25 Mar 2018 13:00:00 +0200 Message-Id: <20180325110000.2238-8-christian.koenig@amd.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180325110000.2238-1-christian.koenig@amd.com> References: <20180325110000.2238-1-christian.koenig@amd.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We should be able to do this now after checking all the prerequisites. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 44 +++++++++++--- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 9 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 91 ++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 133596df0775..86d983a0678b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -197,23 +197,44 @@ amdgpu_gem_map_dma_buf(struct dma_buf_attachment *attach, } else { /* move buffer into GTT */ struct ttm_operation_ctx ctx = { false, false }; + unsigned domains = AMDGPU_GEM_DOMAIN_GTT; - amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT); + if (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM && + attach->peer2peer) { + bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED; + domains |= AMDGPU_GEM_DOMAIN_VRAM; + } + amdgpu_ttm_placement_from_domain(bo, domains); r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx); if (r) goto error_unreserve; } - sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, bo->tbo.num_pages); - if (IS_ERR(sgt)) { - r = PTR_ERR(sgt); + switch (bo->tbo.mem.mem_type) { + case TTM_PL_TT: + sgt = drm_prime_pages_to_sg(bo->tbo.ttm->pages, + bo->tbo.num_pages); + if (IS_ERR(sgt)) { + r = PTR_ERR(sgt); + goto error_unreserve; + } + + if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, + DMA_ATTR_SKIP_CPU_SYNC)) + goto error_free; + break; + + case TTM_PL_VRAM: + r = amdgpu_vram_mgr_alloc_sgt(adev, &bo->tbo.mem, attach->dev, + dir, &sgt); + if (r) + goto error_unreserve; + break; + default: + r = -EINVAL; goto error_unreserve; } - if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir, - DMA_ATTR_SKIP_CPU_SYNC)) - goto error_free; - if (attach->dev->driver != adev->dev->driver) bo->prime_shared_count++; @@ -254,10 +275,15 @@ static void amdgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach, if (!attach->invalidate) amdgpu_bo_unreserve(bo); - if (sgt) { + if (!sgt) + return; + + if (sgt->sgl->page_link) { dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); sg_free_table(sgt); kfree(sgt); + } else { + amdgpu_vram_mgr_free_sgt(adev, attach->dev, dir, sgt); } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 6ea7de863041..b483900abed2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -73,6 +73,15 @@ bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem); uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man); int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man); +int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, + struct ttm_mem_reg *mem, + struct device *dev, + enum dma_data_direction dir, + struct sg_table **sgt); +void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev, + struct device *dev, + enum dma_data_direction dir, + struct sg_table *sgt); uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man); uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 9aca653bec07..eb8f75525a81 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -233,6 +233,97 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, mem->mm_node = NULL; } +/** + * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table + * + * @adev: amdgpu device pointer + * @mem: TTM memory object + * @dev: the other device + * @dir: dma direction + * @sgt: resulting sg table + * + * Allocate and fill a sg table from a VRAM allocation. + */ +int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, + struct ttm_mem_reg *mem, + struct device *dev, + enum dma_data_direction dir, + struct sg_table **sgt) +{ + struct drm_mm_node *node = mem->mm_node; + struct scatterlist *sg; + int num_entries; + int i, r; + + *sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + if (!*sgt) + return -ENOMEM; + + num_entries = DIV_ROUND_UP(mem->num_pages, node->size); + r = sg_alloc_table(*sgt, num_entries, GFP_KERNEL); + if (r) + goto error_free; + + for_each_sg((*sgt)->sgl, sg, num_entries, i) + sg->length = 0; + + for_each_sg((*sgt)->sgl, sg, num_entries, i) { + phys_addr_t phys = (node->start << PAGE_SHIFT) + + adev->gmc.aper_base; + size_t size = node->size << PAGE_SHIFT; + dma_addr_t addr; + + ++node; + addr = dma_map_resource(dev, phys, size, dir, + DMA_ATTR_SKIP_CPU_SYNC); + r = dma_mapping_error(dev, addr); + if (r) + goto error_unmap; + + sg_set_dma_addr(sg, addr, size, 0); + } + return 0; + +error_unmap: + for_each_sg((*sgt)->sgl, sg, num_entries, i) { + if (!sg->length) + continue; + + dma_unmap_resource(dev, sg->dma_address, + sg->length, dir, + DMA_ATTR_SKIP_CPU_SYNC); + } + sg_free_table(*sgt); + +error_free: + kfree(*sgt); + return r; +} + +/** + * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table + * + * @adev: amdgpu device pointer + * @sgt: sg table to free + * + * Free a previously allocate sg table. + */ +void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev, + struct device *dev, + enum dma_data_direction dir, + struct sg_table *sgt) +{ + struct scatterlist *sg; + int i; + + for_each_sg(sgt->sgl, sg, sgt->nents, i) + dma_unmap_resource(dev, sg->dma_address, + sg->length, dir, + DMA_ATTR_SKIP_CPU_SYNC); + sg_free_table(sgt); + kfree(sgt); +} + /** * amdgpu_vram_mgr_usage - how many bytes are used in this domain * -- 2.14.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: "=?UTF-8?q?Christian=20K=C3=B6nig?=" Subject: [PATCH 8/8] drm/amdgpu: add support for exporting VRAM using DMA-buf Date: Sun, 25 Mar 2018 13:00:00 +0200 Message-ID: <20180325110000.2238-8-christian.koenig@amd.com> References: <20180325110000.2238-1-christian.koenig@amd.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20180325110000.2238-1-christian.koenig-5C7GfCeVMHo@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: amd-gfx-bounces-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org Sender: "amd-gfx" To: linaro-mm-sig-cunTk1MwBs8s++Sfvej+rw@public.gmane.org, linux-media-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org List-Id: dri-devel@lists.freedesktop.org V2Ugc2hvdWxkIGJlIGFibGUgdG8gZG8gdGhpcyBub3cgYWZ0ZXIgY2hlY2tpbmcgYWxsIHRoZSBw cmVyZXF1aXNpdGVzLgoKU2lnbmVkLW9mZi1ieTogQ2hyaXN0aWFuIEvDtm5pZyA8Y2hyaXN0aWFu LmtvZW5pZ0BhbWQuY29tPgotLS0KIGRyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9w cmltZS5jICAgIHwgNDQgKysrKysrKysrKystLS0KIGRyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1 L2FtZGdwdV90dG0uaCAgICAgIHwgIDkgKysrCiBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9h bWRncHVfdnJhbV9tZ3IuYyB8IDkxICsrKysrKysrKysrKysrKysrKysrKysrKysrKysKIDMgZmls ZXMgY2hhbmdlZCwgMTM1IGluc2VydGlvbnMoKyksIDkgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ByaW1lLmMgYi9kcml2ZXJzL2dw dS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfcHJpbWUuYwppbmRleCAxMzM1OTZkZjA3NzUuLjg2ZDk4 M2EwNjc4YiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3By aW1lLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ByaW1lLmMKQEAg LTE5NywyMyArMTk3LDQ0IEBAIGFtZGdwdV9nZW1fbWFwX2RtYV9idWYoc3RydWN0IGRtYV9idWZf YXR0YWNobWVudCAqYXR0YWNoLAogCX0gZWxzZSB7CiAJCS8qIG1vdmUgYnVmZmVyIGludG8gR1RU ICovCiAJCXN0cnVjdCB0dG1fb3BlcmF0aW9uX2N0eCBjdHggPSB7IGZhbHNlLCBmYWxzZSB9Owor CQl1bnNpZ25lZCBkb21haW5zID0gQU1ER1BVX0dFTV9ET01BSU5fR1RUOwogCi0JCWFtZGdwdV90 dG1fcGxhY2VtZW50X2Zyb21fZG9tYWluKGJvLCBBTURHUFVfR0VNX0RPTUFJTl9HVFQpOworCQlp ZiAoYm8tPnByZWZlcnJlZF9kb21haW5zICYgQU1ER1BVX0dFTV9ET01BSU5fVlJBTSAmJgorCQkg ICAgYXR0YWNoLT5wZWVyMnBlZXIpIHsKKwkJCWJvLT5mbGFncyB8PSBBTURHUFVfR0VNX0NSRUFU RV9DUFVfQUNDRVNTX1JFUVVJUkVEOworCQkJZG9tYWlucyB8PSBBTURHUFVfR0VNX0RPTUFJTl9W UkFNOworCQl9CisJCWFtZGdwdV90dG1fcGxhY2VtZW50X2Zyb21fZG9tYWluKGJvLCBkb21haW5z KTsKIAkJciA9IHR0bV9ib192YWxpZGF0ZSgmYm8tPnRibywgJmJvLT5wbGFjZW1lbnQsICZjdHgp OwogCQlpZiAocikKIAkJCWdvdG8gZXJyb3JfdW5yZXNlcnZlOwogCX0KIAotCXNndCA9IGRybV9w cmltZV9wYWdlc190b19zZyhiby0+dGJvLnR0bS0+cGFnZXMsIGJvLT50Ym8ubnVtX3BhZ2VzKTsK LQlpZiAoSVNfRVJSKHNndCkpIHsKLQkJciA9IFBUUl9FUlIoc2d0KTsKKwlzd2l0Y2ggKGJvLT50 Ym8ubWVtLm1lbV90eXBlKSB7CisJY2FzZSBUVE1fUExfVFQ6CisJCXNndCA9IGRybV9wcmltZV9w YWdlc190b19zZyhiby0+dGJvLnR0bS0+cGFnZXMsCisJCQkJCSAgICBiby0+dGJvLm51bV9wYWdl cyk7CisJCWlmIChJU19FUlIoc2d0KSkgeworCQkJciA9IFBUUl9FUlIoc2d0KTsKKwkJCWdvdG8g ZXJyb3JfdW5yZXNlcnZlOworCQl9CisKKwkJaWYgKCFkbWFfbWFwX3NnX2F0dHJzKGF0dGFjaC0+ ZGV2LCBzZ3QtPnNnbCwgc2d0LT5uZW50cywgZGlyLAorCQkJCSAgICAgIERNQV9BVFRSX1NLSVBf Q1BVX1NZTkMpKQorCQkJZ290byBlcnJvcl9mcmVlOworCQlicmVhazsKKworCWNhc2UgVFRNX1BM X1ZSQU06CisJCXIgPSBhbWRncHVfdnJhbV9tZ3JfYWxsb2Nfc2d0KGFkZXYsICZiby0+dGJvLm1l bSwgYXR0YWNoLT5kZXYsCisJCQkJCSAgICAgIGRpciwgJnNndCk7CisJCWlmIChyKQorCQkJZ290 byBlcnJvcl91bnJlc2VydmU7CisJCWJyZWFrOworCWRlZmF1bHQ6CisJCXIgPSAtRUlOVkFMOwog CQlnb3RvIGVycm9yX3VucmVzZXJ2ZTsKIAl9CiAKLQlpZiAoIWRtYV9tYXBfc2dfYXR0cnMoYXR0 YWNoLT5kZXYsIHNndC0+c2dsLCBzZ3QtPm5lbnRzLCBkaXIsCi0JCQkgICAgICBETUFfQVRUUl9T S0lQX0NQVV9TWU5DKSkKLQkJZ290byBlcnJvcl9mcmVlOwotCiAJaWYgKGF0dGFjaC0+ZGV2LT5k cml2ZXIgIT0gYWRldi0+ZGV2LT5kcml2ZXIpCiAJCWJvLT5wcmltZV9zaGFyZWRfY291bnQrKzsK IApAQCAtMjU0LDEwICsyNzUsMTUgQEAgc3RhdGljIHZvaWQgYW1kZ3B1X2dlbV91bm1hcF9kbWFf YnVmKHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQgKmF0dGFjaCwKIAlpZiAoIWF0dGFjaC0+aW52 YWxpZGF0ZSkKIAkJYW1kZ3B1X2JvX3VucmVzZXJ2ZShibyk7CiAKLQlpZiAoc2d0KSB7CisJaWYg KCFzZ3QpCisJCXJldHVybjsKKworCWlmIChzZ3QtPnNnbC0+cGFnZV9saW5rKSB7CiAJCWRtYV91 bm1hcF9zZyhhdHRhY2gtPmRldiwgc2d0LT5zZ2wsIHNndC0+bmVudHMsIGRpcik7CiAJCXNnX2Zy ZWVfdGFibGUoc2d0KTsKIAkJa2ZyZWUoc2d0KTsKKwl9IGVsc2UgeworCQlhbWRncHVfdnJhbV9t Z3JfZnJlZV9zZ3QoYWRldiwgYXR0YWNoLT5kZXYsIGRpciwgc2d0KTsKIAl9CiB9CiAKZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV90dG0uaCBiL2RyaXZlcnMv Z3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV90dG0uaAppbmRleCA2ZWE3ZGU4NjMwNDEuLmI0ODM5 MDBhYmVkMiAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3R0 bS5oCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV90dG0uaApAQCAtNzMs NiArNzMsMTUgQEAgYm9vbCBhbWRncHVfZ3R0X21ncl9oYXNfZ2FydF9hZGRyKHN0cnVjdCB0dG1f bWVtX3JlZyAqbWVtKTsKIHVpbnQ2NF90IGFtZGdwdV9ndHRfbWdyX3VzYWdlKHN0cnVjdCB0dG1f bWVtX3R5cGVfbWFuYWdlciAqbWFuKTsKIGludCBhbWRncHVfZ3R0X21ncl9yZWNvdmVyKHN0cnVj dCB0dG1fbWVtX3R5cGVfbWFuYWdlciAqbWFuKTsKIAoraW50IGFtZGdwdV92cmFtX21ncl9hbGxv Y19zZ3Qoc3RydWN0IGFtZGdwdV9kZXZpY2UgKmFkZXYsCisJCQkgICAgICBzdHJ1Y3QgdHRtX21l bV9yZWcgKm1lbSwKKwkJCSAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCSAgICAgIGVudW0g ZG1hX2RhdGFfZGlyZWN0aW9uIGRpciwKKwkJCSAgICAgIHN0cnVjdCBzZ190YWJsZSAqKnNndCk7 Cit2b2lkIGFtZGdwdV92cmFtX21ncl9mcmVlX3NndChzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRl diwKKwkJCSAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCSAgICAgIGVudW0gZG1hX2RhdGFf ZGlyZWN0aW9uIGRpciwKKwkJCSAgICAgIHN0cnVjdCBzZ190YWJsZSAqc2d0KTsKIHVpbnQ2NF90 IGFtZGdwdV92cmFtX21ncl91c2FnZShzdHJ1Y3QgdHRtX21lbV90eXBlX21hbmFnZXIgKm1hbik7 CiB1aW50NjRfdCBhbWRncHVfdnJhbV9tZ3JfdmlzX3VzYWdlKHN0cnVjdCB0dG1fbWVtX3R5cGVf bWFuYWdlciAqbWFuKTsKIApkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUv YW1kZ3B1X3ZyYW1fbWdyLmMgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdnJh bV9tZ3IuYwppbmRleCA5YWNhNjUzYmVjMDcuLmViOGY3NTUyNWE4MSAxMDA2NDQKLS0tIGEvZHJp dmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ZyYW1fbWdyLmMKKysrIGIvZHJpdmVycy9n cHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ZyYW1fbWdyLmMKQEAgLTIzMyw2ICsyMzMsOTcgQEAg c3RhdGljIHZvaWQgYW1kZ3B1X3ZyYW1fbWdyX2RlbChzdHJ1Y3QgdHRtX21lbV90eXBlX21hbmFn ZXIgKm1hbiwKIAltZW0tPm1tX25vZGUgPSBOVUxMOwogfQogCisvKioKKyAqIGFtZGdwdV92cmFt X21ncl9hbGxvY19zZ3QgLSBhbGxvY2F0ZSBhbmQgZmlsbCBhIHNnIHRhYmxlCisgKgorICogQGFk ZXY6IGFtZGdwdSBkZXZpY2UgcG9pbnRlcgorICogQG1lbTogVFRNIG1lbW9yeSBvYmplY3QKKyAq IEBkZXY6IHRoZSBvdGhlciBkZXZpY2UKKyAqIEBkaXI6IGRtYSBkaXJlY3Rpb24KKyAqIEBzZ3Q6 IHJlc3VsdGluZyBzZyB0YWJsZQorICoKKyAqIEFsbG9jYXRlIGFuZCBmaWxsIGEgc2cgdGFibGUg ZnJvbSBhIFZSQU0gYWxsb2NhdGlvbi4KKyAqLworaW50IGFtZGdwdV92cmFtX21ncl9hbGxvY19z Z3Qoc3RydWN0IGFtZGdwdV9kZXZpY2UgKmFkZXYsCisJCQkgICAgICBzdHJ1Y3QgdHRtX21lbV9y ZWcgKm1lbSwKKwkJCSAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCSAgICAgIGVudW0gZG1h X2RhdGFfZGlyZWN0aW9uIGRpciwKKwkJCSAgICAgIHN0cnVjdCBzZ190YWJsZSAqKnNndCkKK3sK KwlzdHJ1Y3QgZHJtX21tX25vZGUgKm5vZGUgPSBtZW0tPm1tX25vZGU7CisJc3RydWN0IHNjYXR0 ZXJsaXN0ICpzZzsKKwlpbnQgbnVtX2VudHJpZXM7CisJaW50IGksIHI7CisKKwkqc2d0ID0ga21h bGxvYyhzaXplb2YoKnNndCksIEdGUF9LRVJORUwpOworCWlmICghKnNndCkKKwkJcmV0dXJuIC1F Tk9NRU07CisKKwludW1fZW50cmllcyA9IERJVl9ST1VORF9VUChtZW0tPm51bV9wYWdlcywgbm9k ZS0+c2l6ZSk7CisJciA9IHNnX2FsbG9jX3RhYmxlKCpzZ3QsIG51bV9lbnRyaWVzLCBHRlBfS0VS TkVMKTsKKwlpZiAocikKKwkJZ290byBlcnJvcl9mcmVlOworCisJZm9yX2VhY2hfc2coKCpzZ3Qp LT5zZ2wsIHNnLCBudW1fZW50cmllcywgaSkKKwkJc2ctPmxlbmd0aCA9IDA7CisKKwlmb3JfZWFj aF9zZygoKnNndCktPnNnbCwgc2csIG51bV9lbnRyaWVzLCBpKSB7CisJCXBoeXNfYWRkcl90IHBo eXMgPSAobm9kZS0+c3RhcnQgPDwgUEFHRV9TSElGVCkgKworCQkJYWRldi0+Z21jLmFwZXJfYmFz ZTsKKwkJc2l6ZV90IHNpemUgPSBub2RlLT5zaXplIDw8IFBBR0VfU0hJRlQ7CisJCWRtYV9hZGRy X3QgYWRkcjsKKworCQkrK25vZGU7CisJCWFkZHIgPSBkbWFfbWFwX3Jlc291cmNlKGRldiwgcGh5 cywgc2l6ZSwgZGlyLAorCQkJCQlETUFfQVRUUl9TS0lQX0NQVV9TWU5DKTsKKwkJciA9IGRtYV9t YXBwaW5nX2Vycm9yKGRldiwgYWRkcik7CisJCWlmIChyKQorCQkJZ290byBlcnJvcl91bm1hcDsK KworCQlzZ19zZXRfZG1hX2FkZHIoc2csIGFkZHIsIHNpemUsIDApOworCX0KKwlyZXR1cm4gMDsK KworZXJyb3JfdW5tYXA6CisJZm9yX2VhY2hfc2coKCpzZ3QpLT5zZ2wsIHNnLCBudW1fZW50cmll cywgaSkgeworCQlpZiAoIXNnLT5sZW5ndGgpCisJCQljb250aW51ZTsKKworCQlkbWFfdW5tYXBf cmVzb3VyY2UoZGV2LCBzZy0+ZG1hX2FkZHJlc3MsCisJCQkJICAgc2ctPmxlbmd0aCwgZGlyLAor CQkJCSAgIERNQV9BVFRSX1NLSVBfQ1BVX1NZTkMpOworCX0KKwlzZ19mcmVlX3RhYmxlKCpzZ3Qp OworCitlcnJvcl9mcmVlOgorCWtmcmVlKCpzZ3QpOworCXJldHVybiByOworfQorCisvKioKKyAq IGFtZGdwdV92cmFtX21ncl9hbGxvY19zZ3QgLSBhbGxvY2F0ZSBhbmQgZmlsbCBhIHNnIHRhYmxl CisgKgorICogQGFkZXY6IGFtZGdwdSBkZXZpY2UgcG9pbnRlcgorICogQHNndDogc2cgdGFibGUg dG8gZnJlZQorICoKKyAqIEZyZWUgYSBwcmV2aW91c2x5IGFsbG9jYXRlIHNnIHRhYmxlLgorICov Cit2b2lkIGFtZGdwdV92cmFtX21ncl9mcmVlX3NndChzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRl diwKKwkJCSAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJCSAgICAgIGVudW0gZG1hX2RhdGFf ZGlyZWN0aW9uIGRpciwKKwkJCSAgICAgIHN0cnVjdCBzZ190YWJsZSAqc2d0KQoreworCXN0cnVj dCBzY2F0dGVybGlzdCAqc2c7CisJaW50IGk7CisKKwlmb3JfZWFjaF9zZyhzZ3QtPnNnbCwgc2cs IHNndC0+bmVudHMsIGkpCisJCWRtYV91bm1hcF9yZXNvdXJjZShkZXYsIHNnLT5kbWFfYWRkcmVz cywKKwkJCQkgICBzZy0+bGVuZ3RoLCBkaXIsCisJCQkJICAgRE1BX0FUVFJfU0tJUF9DUFVfU1lO Qyk7CisJc2dfZnJlZV90YWJsZShzZ3QpOworCWtmcmVlKHNndCk7Cit9CisKIC8qKgogICogYW1k Z3B1X3ZyYW1fbWdyX3VzYWdlIC0gaG93IG1hbnkgYnl0ZXMgYXJlIHVzZWQgaW4gdGhpcyBkb21h aW4KICAqCi0tIAoyLjE0LjEKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fCmFtZC1nZnggbWFpbGluZyBsaXN0CmFtZC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Au b3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vYW1kLWdm eAo=