From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from cantor2.suse.de ([195.135.220.15]:43259 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754209AbbCQL5D (ORCPT ); Tue, 17 Mar 2015 07:57:03 -0400 From: Jan Kara To: linux-media@vger.kernel.org Cc: Hans Verkuil , Mauro Carvalho Chehab , linux-mm@kvack.org, dri-devel@lists.freedesktop.org, David Airlie , Jan Kara Subject: [PATCH 9/9] drm/exynos: Convert g2d_userptr_get_dma_addr() to use get_vaddr_pfn() Date: Tue, 17 Mar 2015 12:56:39 +0100 Message-Id: <1426593399-6549-10-git-send-email-jack@suse.cz> In-Reply-To: <1426593399-6549-1-git-send-email-jack@suse.cz> References: <1426593399-6549-1-git-send-email-jack@suse.cz> Sender: linux-media-owner@vger.kernel.org List-ID: Convert g2d_userptr_get_dma_addr() to pin pages using get_vaddr_pfn(). This removes the knowledge about vmas and mmap_sem locking from exynos driver. Also it fixes a problem that the function has been mapping user provided address without holding mmap_sem. Signed-off-by: Jan Kara --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 91 ++++++++++--------------------- drivers/gpu/drm/exynos/exynos_drm_gem.c | 97 --------------------------------- 2 files changed, 30 insertions(+), 158 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 81a250830808..8949354a85a1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -190,10 +190,8 @@ struct g2d_cmdlist_userptr { dma_addr_t dma_addr; unsigned long userptr; unsigned long size; - struct page **pages; - unsigned int npages; + struct pinned_pfns *pfns; struct sg_table *sgt; - struct vm_area_struct *vma; atomic_t refcount; bool in_pool; bool out_of_list; @@ -363,6 +361,7 @@ static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev, { struct g2d_cmdlist_userptr *g2d_userptr = (struct g2d_cmdlist_userptr *)obj; + struct page **pages; if (!obj) return; @@ -382,19 +381,21 @@ out: exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt, DMA_BIDIRECTIONAL); - exynos_gem_put_pages_to_userptr(g2d_userptr->pages, - g2d_userptr->npages, - g2d_userptr->vma); + pages = pfns_vector_pages(g2d_userptr->pfns); + if (pages) { + int i; - exynos_gem_put_vma(g2d_userptr->vma); + for (i = 0; i < pfns_vector_count(g2d_userptr->pfns); i++) + set_page_dirty_lock(pages[i]); + } + put_vaddr_pfns(g2d_userptr->pfns); + pfns_vector_destroy(g2d_userptr->pfns); if (!g2d_userptr->out_of_list) list_del_init(&g2d_userptr->list); sg_free_table(g2d_userptr->sgt); kfree(g2d_userptr->sgt); - - drm_free_large(g2d_userptr->pages); kfree(g2d_userptr); } @@ -413,6 +414,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, struct vm_area_struct *vma; unsigned long start, end; unsigned int npages, offset; + struct pinned_pfns *pfns; int ret; if (!size) { @@ -456,65 +458,37 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, return ERR_PTR(-ENOMEM); atomic_set(&g2d_userptr->refcount, 1); + g2d_userptr->size = size; start = userptr & PAGE_MASK; offset = userptr & ~PAGE_MASK; end = PAGE_ALIGN(userptr + size); npages = (end - start) >> PAGE_SHIFT; - g2d_userptr->npages = npages; + pfns = g2d_userptr->pfns = pfns_vector_create(npages); + if (!pfns) + goto out_free; - pages = drm_calloc_large(npages, sizeof(struct page *)); - if (!pages) { - DRM_ERROR("failed to allocate pages.\n"); - ret = -ENOMEM; - goto err_free; - } - - down_read(¤t->mm->mmap_sem); - vma = find_vma(current->mm, userptr); - if (!vma) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("failed to get vm region.\n"); + ret = get_vaddr_pfn(start, npages, 1, 1, pfns); + if (ret != npages) { + DRM_ERROR("failed to get user pages from userptr.\n"); + if (ret < 0) + goto err_destroy_pfns; ret = -EFAULT; - goto err_free_pages; + goto err_put_pfns; } - - if (vma->vm_end < userptr + size) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("vma is too small.\n"); + if (pfns_vector_to_pages(pfns) < 0) { ret = -EFAULT; - goto err_free_pages; + goto err_put_pfns; } - g2d_userptr->vma = exynos_gem_get_vma(vma); - if (!g2d_userptr->vma) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("failed to copy vma.\n"); - ret = -ENOMEM; - goto err_free_pages; - } - - g2d_userptr->size = size; - - ret = exynos_gem_get_pages_from_userptr(start & PAGE_MASK, - npages, pages, vma); - if (ret < 0) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("failed to get user pages from userptr.\n"); - goto err_put_vma; - } - - up_read(¤t->mm->mmap_sem); - g2d_userptr->pages = pages; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { ret = -ENOMEM; - goto err_free_userptr; + goto err_put_pfns; } - ret = sg_alloc_table_from_pages(sgt, pages, npages, offset, - size, GFP_KERNEL); + ret = sg_alloc_table_from_pages(sgt, pfns_vector_pages(pfns), npages, + offset, size, GFP_KERNEL); if (ret < 0) { DRM_ERROR("failed to get sgt from pages.\n"); goto err_free_sgt; @@ -549,16 +523,11 @@ err_sg_free_table: err_free_sgt: kfree(sgt); -err_free_userptr: - exynos_gem_put_pages_to_userptr(g2d_userptr->pages, - g2d_userptr->npages, - g2d_userptr->vma); - -err_put_vma: - exynos_gem_put_vma(g2d_userptr->vma); +err_put_pfns: + put_vaddr_pfns(pfns); -err_free_pages: - drm_free_large(pages); +err_destroy_pfns: + pfns_vector_destroy(pfns); err_free: kfree(g2d_userptr); diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 0d5b9698d384..47068ae44ced 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -378,103 +378,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, return 0; } -struct vm_area_struct *exynos_gem_get_vma(struct vm_area_struct *vma) -{ - struct vm_area_struct *vma_copy; - - vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL); - if (!vma_copy) - return NULL; - - if (vma->vm_ops && vma->vm_ops->open) - vma->vm_ops->open(vma); - - if (vma->vm_file) - get_file(vma->vm_file); - - memcpy(vma_copy, vma, sizeof(*vma)); - - vma_copy->vm_mm = NULL; - vma_copy->vm_next = NULL; - vma_copy->vm_prev = NULL; - - return vma_copy; -} - -void exynos_gem_put_vma(struct vm_area_struct *vma) -{ - if (!vma) - return; - - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - - if (vma->vm_file) - fput(vma->vm_file); - - kfree(vma); -} - -int exynos_gem_get_pages_from_userptr(unsigned long start, - unsigned int npages, - struct page **pages, - struct vm_area_struct *vma) -{ - int get_npages; - - /* the memory region mmaped with VM_PFNMAP. */ - if (vma_is_io(vma)) { - unsigned int i; - - for (i = 0; i < npages; ++i, start += PAGE_SIZE) { - unsigned long pfn; - int ret = follow_pfn(vma, start, &pfn); - if (ret) - return ret; - - pages[i] = pfn_to_page(pfn); - } - - if (i != npages) { - DRM_ERROR("failed to get user_pages.\n"); - return -EINVAL; - } - - return 0; - } - - get_npages = get_user_pages(current, current->mm, start, - npages, 1, 1, pages, NULL); - get_npages = max(get_npages, 0); - if (get_npages != npages) { - DRM_ERROR("failed to get user_pages.\n"); - while (get_npages) - put_page(pages[--get_npages]); - return -EFAULT; - } - - return 0; -} - -void exynos_gem_put_pages_to_userptr(struct page **pages, - unsigned int npages, - struct vm_area_struct *vma) -{ - if (!vma_is_io(vma)) { - unsigned int i; - - for (i = 0; i < npages; i++) { - set_page_dirty_lock(pages[i]); - - /* - * undo the reference we took when populating - * the table. - */ - put_page(pages[i]); - } - } -} - int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev, struct sg_table *sgt, enum dma_data_direction dir) -- 2.1.4 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wg0-f52.google.com (mail-wg0-f52.google.com [74.125.82.52]) by kanga.kvack.org (Postfix) with ESMTP id 6599E900016 for ; Tue, 17 Mar 2015 07:57:16 -0400 (EDT) Received: by wgbcc7 with SMTP id cc7so6433555wgb.0 for ; Tue, 17 Mar 2015 04:57:16 -0700 (PDT) Received: from mx2.suse.de (cantor2.suse.de. [195.135.220.15]) by mx.google.com with ESMTPS id v6si2848300wif.47.2015.03.17.04.57.01 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 17 Mar 2015 04:57:02 -0700 (PDT) From: Jan Kara Subject: [PATCH 9/9] drm/exynos: Convert g2d_userptr_get_dma_addr() to use get_vaddr_pfn() Date: Tue, 17 Mar 2015 12:56:39 +0100 Message-Id: <1426593399-6549-10-git-send-email-jack@suse.cz> In-Reply-To: <1426593399-6549-1-git-send-email-jack@suse.cz> References: <1426593399-6549-1-git-send-email-jack@suse.cz> Sender: owner-linux-mm@kvack.org List-ID: To: linux-media@vger.kernel.org Cc: Hans Verkuil , Mauro Carvalho Chehab , linux-mm@kvack.org, dri-devel@lists.freedesktop.org, David Airlie , Jan Kara Convert g2d_userptr_get_dma_addr() to pin pages using get_vaddr_pfn(). This removes the knowledge about vmas and mmap_sem locking from exynos driver. Also it fixes a problem that the function has been mapping user provided address without holding mmap_sem. Signed-off-by: Jan Kara --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 91 ++++++++++--------------------- drivers/gpu/drm/exynos/exynos_drm_gem.c | 97 --------------------------------- 2 files changed, 30 insertions(+), 158 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 81a250830808..8949354a85a1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -190,10 +190,8 @@ struct g2d_cmdlist_userptr { dma_addr_t dma_addr; unsigned long userptr; unsigned long size; - struct page **pages; - unsigned int npages; + struct pinned_pfns *pfns; struct sg_table *sgt; - struct vm_area_struct *vma; atomic_t refcount; bool in_pool; bool out_of_list; @@ -363,6 +361,7 @@ static void g2d_userptr_put_dma_addr(struct drm_device *drm_dev, { struct g2d_cmdlist_userptr *g2d_userptr = (struct g2d_cmdlist_userptr *)obj; + struct page **pages; if (!obj) return; @@ -382,19 +381,21 @@ out: exynos_gem_unmap_sgt_from_dma(drm_dev, g2d_userptr->sgt, DMA_BIDIRECTIONAL); - exynos_gem_put_pages_to_userptr(g2d_userptr->pages, - g2d_userptr->npages, - g2d_userptr->vma); + pages = pfns_vector_pages(g2d_userptr->pfns); + if (pages) { + int i; - exynos_gem_put_vma(g2d_userptr->vma); + for (i = 0; i < pfns_vector_count(g2d_userptr->pfns); i++) + set_page_dirty_lock(pages[i]); + } + put_vaddr_pfns(g2d_userptr->pfns); + pfns_vector_destroy(g2d_userptr->pfns); if (!g2d_userptr->out_of_list) list_del_init(&g2d_userptr->list); sg_free_table(g2d_userptr->sgt); kfree(g2d_userptr->sgt); - - drm_free_large(g2d_userptr->pages); kfree(g2d_userptr); } @@ -413,6 +414,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, struct vm_area_struct *vma; unsigned long start, end; unsigned int npages, offset; + struct pinned_pfns *pfns; int ret; if (!size) { @@ -456,65 +458,37 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, return ERR_PTR(-ENOMEM); atomic_set(&g2d_userptr->refcount, 1); + g2d_userptr->size = size; start = userptr & PAGE_MASK; offset = userptr & ~PAGE_MASK; end = PAGE_ALIGN(userptr + size); npages = (end - start) >> PAGE_SHIFT; - g2d_userptr->npages = npages; + pfns = g2d_userptr->pfns = pfns_vector_create(npages); + if (!pfns) + goto out_free; - pages = drm_calloc_large(npages, sizeof(struct page *)); - if (!pages) { - DRM_ERROR("failed to allocate pages.\n"); - ret = -ENOMEM; - goto err_free; - } - - down_read(¤t->mm->mmap_sem); - vma = find_vma(current->mm, userptr); - if (!vma) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("failed to get vm region.\n"); + ret = get_vaddr_pfn(start, npages, 1, 1, pfns); + if (ret != npages) { + DRM_ERROR("failed to get user pages from userptr.\n"); + if (ret < 0) + goto err_destroy_pfns; ret = -EFAULT; - goto err_free_pages; + goto err_put_pfns; } - - if (vma->vm_end < userptr + size) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("vma is too small.\n"); + if (pfns_vector_to_pages(pfns) < 0) { ret = -EFAULT; - goto err_free_pages; + goto err_put_pfns; } - g2d_userptr->vma = exynos_gem_get_vma(vma); - if (!g2d_userptr->vma) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("failed to copy vma.\n"); - ret = -ENOMEM; - goto err_free_pages; - } - - g2d_userptr->size = size; - - ret = exynos_gem_get_pages_from_userptr(start & PAGE_MASK, - npages, pages, vma); - if (ret < 0) { - up_read(¤t->mm->mmap_sem); - DRM_ERROR("failed to get user pages from userptr.\n"); - goto err_put_vma; - } - - up_read(¤t->mm->mmap_sem); - g2d_userptr->pages = pages; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { ret = -ENOMEM; - goto err_free_userptr; + goto err_put_pfns; } - ret = sg_alloc_table_from_pages(sgt, pages, npages, offset, - size, GFP_KERNEL); + ret = sg_alloc_table_from_pages(sgt, pfns_vector_pages(pfns), npages, + offset, size, GFP_KERNEL); if (ret < 0) { DRM_ERROR("failed to get sgt from pages.\n"); goto err_free_sgt; @@ -549,16 +523,11 @@ err_sg_free_table: err_free_sgt: kfree(sgt); -err_free_userptr: - exynos_gem_put_pages_to_userptr(g2d_userptr->pages, - g2d_userptr->npages, - g2d_userptr->vma); - -err_put_vma: - exynos_gem_put_vma(g2d_userptr->vma); +err_put_pfns: + put_vaddr_pfns(pfns); -err_free_pages: - drm_free_large(pages); +err_destroy_pfns: + pfns_vector_destroy(pfns); err_free: kfree(g2d_userptr); diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 0d5b9698d384..47068ae44ced 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -378,103 +378,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, return 0; } -struct vm_area_struct *exynos_gem_get_vma(struct vm_area_struct *vma) -{ - struct vm_area_struct *vma_copy; - - vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL); - if (!vma_copy) - return NULL; - - if (vma->vm_ops && vma->vm_ops->open) - vma->vm_ops->open(vma); - - if (vma->vm_file) - get_file(vma->vm_file); - - memcpy(vma_copy, vma, sizeof(*vma)); - - vma_copy->vm_mm = NULL; - vma_copy->vm_next = NULL; - vma_copy->vm_prev = NULL; - - return vma_copy; -} - -void exynos_gem_put_vma(struct vm_area_struct *vma) -{ - if (!vma) - return; - - if (vma->vm_ops && vma->vm_ops->close) - vma->vm_ops->close(vma); - - if (vma->vm_file) - fput(vma->vm_file); - - kfree(vma); -} - -int exynos_gem_get_pages_from_userptr(unsigned long start, - unsigned int npages, - struct page **pages, - struct vm_area_struct *vma) -{ - int get_npages; - - /* the memory region mmaped with VM_PFNMAP. */ - if (vma_is_io(vma)) { - unsigned int i; - - for (i = 0; i < npages; ++i, start += PAGE_SIZE) { - unsigned long pfn; - int ret = follow_pfn(vma, start, &pfn); - if (ret) - return ret; - - pages[i] = pfn_to_page(pfn); - } - - if (i != npages) { - DRM_ERROR("failed to get user_pages.\n"); - return -EINVAL; - } - - return 0; - } - - get_npages = get_user_pages(current, current->mm, start, - npages, 1, 1, pages, NULL); - get_npages = max(get_npages, 0); - if (get_npages != npages) { - DRM_ERROR("failed to get user_pages.\n"); - while (get_npages) - put_page(pages[--get_npages]); - return -EFAULT; - } - - return 0; -} - -void exynos_gem_put_pages_to_userptr(struct page **pages, - unsigned int npages, - struct vm_area_struct *vma) -{ - if (!vma_is_io(vma)) { - unsigned int i; - - for (i = 0; i < npages; i++) { - set_page_dirty_lock(pages[i]); - - /* - * undo the reference we took when populating - * the table. - */ - put_page(pages[i]); - } - } -} - int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev, struct sg_table *sgt, enum dma_data_direction dir) -- 2.1.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kara Subject: [PATCH 9/9] drm/exynos: Convert g2d_userptr_get_dma_addr() to use get_vaddr_pfn() Date: Tue, 17 Mar 2015 12:56:39 +0100 Message-ID: <1426593399-6549-10-git-send-email-jack@suse.cz> References: <1426593399-6549-1-git-send-email-jack@suse.cz> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTP id DAC986E694 for ; Tue, 17 Mar 2015 04:57:01 -0700 (PDT) In-Reply-To: <1426593399-6549-1-git-send-email-jack@suse.cz> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: linux-media@vger.kernel.org Cc: Jan Kara , Mauro Carvalho Chehab , dri-devel@lists.freedesktop.org, linux-mm@kvack.org, Hans Verkuil List-Id: dri-devel@lists.freedesktop.org Q29udmVydCBnMmRfdXNlcnB0cl9nZXRfZG1hX2FkZHIoKSB0byBwaW4gcGFnZXMgdXNpbmcgZ2V0 X3ZhZGRyX3BmbigpLgpUaGlzIHJlbW92ZXMgdGhlIGtub3dsZWRnZSBhYm91dCB2bWFzIGFuZCBt bWFwX3NlbSBsb2NraW5nIGZyb20gZXh5bm9zCmRyaXZlci4gQWxzbyBpdCBmaXhlcyBhIHByb2Js ZW0gdGhhdCB0aGUgZnVuY3Rpb24gaGFzIGJlZW4gbWFwcGluZyB1c2VyCnByb3ZpZGVkIGFkZHJl c3Mgd2l0aG91dCBob2xkaW5nIG1tYXBfc2VtLgoKU2lnbmVkLW9mZi1ieTogSmFuIEthcmEgPGph Y2tAc3VzZS5jej4KLS0tCiBkcml2ZXJzL2dwdS9kcm0vZXh5bm9zL2V4eW5vc19kcm1fZzJkLmMg fCA5MSArKysrKysrKysrLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiBkcml2ZXJzL2dwdS9kcm0vZXh5 bm9zL2V4eW5vc19kcm1fZ2VtLmMgfCA5NyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0KIDIgZmlsZXMgY2hhbmdlZCwgMzAgaW5zZXJ0aW9ucygrKSwgMTU4IGRlbGV0aW9ucygtKQoK ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9leHlub3MvZXh5bm9zX2RybV9nMmQuYyBiL2Ry aXZlcnMvZ3B1L2RybS9leHlub3MvZXh5bm9zX2RybV9nMmQuYwppbmRleCA4MWEyNTA4MzA4MDgu Ljg5NDkzNTRhODVhMSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2V4eW5vcy9leHlub3Nf ZHJtX2cyZC5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9leHlub3MvZXh5bm9zX2RybV9nMmQuYwpA QCAtMTkwLDEwICsxOTAsOCBAQCBzdHJ1Y3QgZzJkX2NtZGxpc3RfdXNlcnB0ciB7CiAJZG1hX2Fk ZHJfdAkJZG1hX2FkZHI7CiAJdW5zaWduZWQgbG9uZwkJdXNlcnB0cjsKIAl1bnNpZ25lZCBsb25n CQlzaXplOwotCXN0cnVjdCBwYWdlCQkqKnBhZ2VzOwotCXVuc2lnbmVkIGludAkJbnBhZ2VzOwor CXN0cnVjdCBwaW5uZWRfcGZucwkqcGZuczsKIAlzdHJ1Y3Qgc2dfdGFibGUJCSpzZ3Q7Ci0Jc3Ry dWN0IHZtX2FyZWFfc3RydWN0CSp2bWE7CiAJYXRvbWljX3QJCXJlZmNvdW50OwogCWJvb2wJCQlp bl9wb29sOwogCWJvb2wJCQlvdXRfb2ZfbGlzdDsKQEAgLTM2Myw2ICszNjEsNyBAQCBzdGF0aWMg dm9pZCBnMmRfdXNlcnB0cl9wdXRfZG1hX2FkZHIoc3RydWN0IGRybV9kZXZpY2UgKmRybV9kZXYs CiB7CiAJc3RydWN0IGcyZF9jbWRsaXN0X3VzZXJwdHIgKmcyZF91c2VycHRyID0KIAkJCQkJKHN0 cnVjdCBnMmRfY21kbGlzdF91c2VycHRyICopb2JqOworCXN0cnVjdCBwYWdlICoqcGFnZXM7CiAK IAlpZiAoIW9iaikKIAkJcmV0dXJuOwpAQCAtMzgyLDE5ICszODEsMjEgQEAgb3V0OgogCWV4eW5v c19nZW1fdW5tYXBfc2d0X2Zyb21fZG1hKGRybV9kZXYsIGcyZF91c2VycHRyLT5zZ3QsCiAJCQkJ CURNQV9CSURJUkVDVElPTkFMKTsKIAotCWV4eW5vc19nZW1fcHV0X3BhZ2VzX3RvX3VzZXJwdHIo ZzJkX3VzZXJwdHItPnBhZ2VzLAotCQkJCQlnMmRfdXNlcnB0ci0+bnBhZ2VzLAotCQkJCQlnMmRf dXNlcnB0ci0+dm1hKTsKKwlwYWdlcyA9IHBmbnNfdmVjdG9yX3BhZ2VzKGcyZF91c2VycHRyLT5w Zm5zKTsKKwlpZiAocGFnZXMpIHsKKwkJaW50IGk7CiAKLQlleHlub3NfZ2VtX3B1dF92bWEoZzJk X3VzZXJwdHItPnZtYSk7CisJCWZvciAoaSA9IDA7IGkgPCBwZm5zX3ZlY3Rvcl9jb3VudChnMmRf dXNlcnB0ci0+cGZucyk7IGkrKykKKwkJCXNldF9wYWdlX2RpcnR5X2xvY2socGFnZXNbaV0pOwor CX0KKwlwdXRfdmFkZHJfcGZucyhnMmRfdXNlcnB0ci0+cGZucyk7CisJcGZuc192ZWN0b3JfZGVz dHJveShnMmRfdXNlcnB0ci0+cGZucyk7CiAKIAlpZiAoIWcyZF91c2VycHRyLT5vdXRfb2ZfbGlz dCkKIAkJbGlzdF9kZWxfaW5pdCgmZzJkX3VzZXJwdHItPmxpc3QpOwogCiAJc2dfZnJlZV90YWJs ZShnMmRfdXNlcnB0ci0+c2d0KTsKIAlrZnJlZShnMmRfdXNlcnB0ci0+c2d0KTsKLQotCWRybV9m cmVlX2xhcmdlKGcyZF91c2VycHRyLT5wYWdlcyk7CiAJa2ZyZWUoZzJkX3VzZXJwdHIpOwogfQog CkBAIC00MTMsNiArNDE0LDcgQEAgc3RhdGljIGRtYV9hZGRyX3QgKmcyZF91c2VycHRyX2dldF9k bWFfYWRkcihzdHJ1Y3QgZHJtX2RldmljZSAqZHJtX2RldiwKIAlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1 Y3QgKnZtYTsKIAl1bnNpZ25lZCBsb25nIHN0YXJ0LCBlbmQ7CiAJdW5zaWduZWQgaW50IG5wYWdl cywgb2Zmc2V0OworCXN0cnVjdCBwaW5uZWRfcGZucyAqcGZuczsKIAlpbnQgcmV0OwogCiAJaWYg KCFzaXplKSB7CkBAIC00NTYsNjUgKzQ1OCwzNyBAQCBzdGF0aWMgZG1hX2FkZHJfdCAqZzJkX3Vz ZXJwdHJfZ2V0X2RtYV9hZGRyKHN0cnVjdCBkcm1fZGV2aWNlICpkcm1fZGV2LAogCQlyZXR1cm4g RVJSX1BUUigtRU5PTUVNKTsKIAogCWF0b21pY19zZXQoJmcyZF91c2VycHRyLT5yZWZjb3VudCwg MSk7CisJZzJkX3VzZXJwdHItPnNpemUgPSBzaXplOwogCiAJc3RhcnQgPSB1c2VycHRyICYgUEFH RV9NQVNLOwogCW9mZnNldCA9IHVzZXJwdHIgJiB+UEFHRV9NQVNLOwogCWVuZCA9IFBBR0VfQUxJ R04odXNlcnB0ciArIHNpemUpOwogCW5wYWdlcyA9IChlbmQgLSBzdGFydCkgPj4gUEFHRV9TSElG VDsKLQlnMmRfdXNlcnB0ci0+bnBhZ2VzID0gbnBhZ2VzOworCXBmbnMgPSBnMmRfdXNlcnB0ci0+ cGZucyA9IHBmbnNfdmVjdG9yX2NyZWF0ZShucGFnZXMpOworCWlmICghcGZucykKKwkJZ290byBv dXRfZnJlZTsKIAotCXBhZ2VzID0gZHJtX2NhbGxvY19sYXJnZShucGFnZXMsIHNpemVvZihzdHJ1 Y3QgcGFnZSAqKSk7Ci0JaWYgKCFwYWdlcykgewotCQlEUk1fRVJST1IoImZhaWxlZCB0byBhbGxv Y2F0ZSBwYWdlcy5cbiIpOwotCQlyZXQgPSAtRU5PTUVNOwotCQlnb3RvIGVycl9mcmVlOwotCX0K LQotCWRvd25fcmVhZCgmY3VycmVudC0+bW0tPm1tYXBfc2VtKTsKLQl2bWEgPSBmaW5kX3ZtYShj dXJyZW50LT5tbSwgdXNlcnB0cik7Ci0JaWYgKCF2bWEpIHsKLQkJdXBfcmVhZCgmY3VycmVudC0+ bW0tPm1tYXBfc2VtKTsKLQkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gZ2V0IHZtIHJlZ2lvbi5cbiIp OworCXJldCA9IGdldF92YWRkcl9wZm4oc3RhcnQsIG5wYWdlcywgMSwgMSwgcGZucyk7CisJaWYg KHJldCAhPSBucGFnZXMpIHsKKwkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gZ2V0IHVzZXIgcGFnZXMg ZnJvbSB1c2VycHRyLlxuIik7CisJCWlmIChyZXQgPCAwKQorCQkJZ290byBlcnJfZGVzdHJveV9w Zm5zOwogCQlyZXQgPSAtRUZBVUxUOwotCQlnb3RvIGVycl9mcmVlX3BhZ2VzOworCQlnb3RvIGVy cl9wdXRfcGZuczsKIAl9Ci0KLQlpZiAodm1hLT52bV9lbmQgPCB1c2VycHRyICsgc2l6ZSkgewot CQl1cF9yZWFkKCZjdXJyZW50LT5tbS0+bW1hcF9zZW0pOwotCQlEUk1fRVJST1IoInZtYSBpcyB0 b28gc21hbGwuXG4iKTsKKwlpZiAocGZuc192ZWN0b3JfdG9fcGFnZXMocGZucykgPCAwKSB7CiAJ CXJldCA9IC1FRkFVTFQ7Ci0JCWdvdG8gZXJyX2ZyZWVfcGFnZXM7CisJCWdvdG8gZXJyX3B1dF9w Zm5zOwogCX0KIAotCWcyZF91c2VycHRyLT52bWEgPSBleHlub3NfZ2VtX2dldF92bWEodm1hKTsK LQlpZiAoIWcyZF91c2VycHRyLT52bWEpIHsKLQkJdXBfcmVhZCgmY3VycmVudC0+bW0tPm1tYXBf c2VtKTsKLQkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gY29weSB2bWEuXG4iKTsKLQkJcmV0ID0gLUVO T01FTTsKLQkJZ290byBlcnJfZnJlZV9wYWdlczsKLQl9Ci0KLQlnMmRfdXNlcnB0ci0+c2l6ZSA9 IHNpemU7Ci0KLQlyZXQgPSBleHlub3NfZ2VtX2dldF9wYWdlc19mcm9tX3VzZXJwdHIoc3RhcnQg JiBQQUdFX01BU0ssCi0JCQkJCQlucGFnZXMsIHBhZ2VzLCB2bWEpOwotCWlmIChyZXQgPCAwKSB7 Ci0JCXVwX3JlYWQoJmN1cnJlbnQtPm1tLT5tbWFwX3NlbSk7Ci0JCURSTV9FUlJPUigiZmFpbGVk IHRvIGdldCB1c2VyIHBhZ2VzIGZyb20gdXNlcnB0ci5cbiIpOwotCQlnb3RvIGVycl9wdXRfdm1h OwotCX0KLQotCXVwX3JlYWQoJmN1cnJlbnQtPm1tLT5tbWFwX3NlbSk7Ci0JZzJkX3VzZXJwdHIt PnBhZ2VzID0gcGFnZXM7Ci0KIAlzZ3QgPSBremFsbG9jKHNpemVvZigqc2d0KSwgR0ZQX0tFUk5F TCk7CiAJaWYgKCFzZ3QpIHsKIAkJcmV0ID0gLUVOT01FTTsKLQkJZ290byBlcnJfZnJlZV91c2Vy cHRyOworCQlnb3RvIGVycl9wdXRfcGZuczsKIAl9CiAKLQlyZXQgPSBzZ19hbGxvY190YWJsZV9m cm9tX3BhZ2VzKHNndCwgcGFnZXMsIG5wYWdlcywgb2Zmc2V0LAotCQkJCQlzaXplLCBHRlBfS0VS TkVMKTsKKwlyZXQgPSBzZ19hbGxvY190YWJsZV9mcm9tX3BhZ2VzKHNndCwgcGZuc192ZWN0b3Jf cGFnZXMocGZucyksIG5wYWdlcywKKwkJCQkJb2Zmc2V0LCBzaXplLCBHRlBfS0VSTkVMKTsKIAlp ZiAocmV0IDwgMCkgewogCQlEUk1fRVJST1IoImZhaWxlZCB0byBnZXQgc2d0IGZyb20gcGFnZXMu XG4iKTsKIAkJZ290byBlcnJfZnJlZV9zZ3Q7CkBAIC01NDksMTYgKzUyMywxMSBAQCBlcnJfc2df ZnJlZV90YWJsZToKIGVycl9mcmVlX3NndDoKIAlrZnJlZShzZ3QpOwogCi1lcnJfZnJlZV91c2Vy cHRyOgotCWV4eW5vc19nZW1fcHV0X3BhZ2VzX3RvX3VzZXJwdHIoZzJkX3VzZXJwdHItPnBhZ2Vz LAotCQkJCQlnMmRfdXNlcnB0ci0+bnBhZ2VzLAotCQkJCQlnMmRfdXNlcnB0ci0+dm1hKTsKLQot ZXJyX3B1dF92bWE6Ci0JZXh5bm9zX2dlbV9wdXRfdm1hKGcyZF91c2VycHRyLT52bWEpOworZXJy X3B1dF9wZm5zOgorCXB1dF92YWRkcl9wZm5zKHBmbnMpOwogCi1lcnJfZnJlZV9wYWdlczoKLQlk cm1fZnJlZV9sYXJnZShwYWdlcyk7CitlcnJfZGVzdHJveV9wZm5zOgorCXBmbnNfdmVjdG9yX2Rl c3Ryb3kocGZucyk7CiAKIGVycl9mcmVlOgogCWtmcmVlKGcyZF91c2VycHRyKTsKZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS9leHlub3MvZXh5bm9zX2RybV9nZW0uYyBiL2RyaXZlcnMvZ3B1 L2RybS9leHlub3MvZXh5bm9zX2RybV9nZW0uYwppbmRleCAwZDViOTY5OGQzODQuLjQ3MDY4YWU0 NGNlZCAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL2V4eW5vcy9leHlub3NfZHJtX2dlbS5j CisrKyBiL2RyaXZlcnMvZ3B1L2RybS9leHlub3MvZXh5bm9zX2RybV9nZW0uYwpAQCAtMzc4LDEw MyArMzc4LDYgQEAgaW50IGV4eW5vc19kcm1fZ2VtX2dldF9pb2N0bChzdHJ1Y3QgZHJtX2Rldmlj ZSAqZGV2LCB2b2lkICpkYXRhLAogCXJldHVybiAwOwogfQogCi1zdHJ1Y3Qgdm1fYXJlYV9zdHJ1 Y3QgKmV4eW5vc19nZW1fZ2V0X3ZtYShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKLXsKLQlz dHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYV9jb3B5OwotCi0Jdm1hX2NvcHkgPSBrbWFsbG9jKHNp emVvZigqdm1hX2NvcHkpLCBHRlBfS0VSTkVMKTsKLQlpZiAoIXZtYV9jb3B5KQotCQlyZXR1cm4g TlVMTDsKLQotCWlmICh2bWEtPnZtX29wcyAmJiB2bWEtPnZtX29wcy0+b3BlbikKLQkJdm1hLT52 bV9vcHMtPm9wZW4odm1hKTsKLQotCWlmICh2bWEtPnZtX2ZpbGUpCi0JCWdldF9maWxlKHZtYS0+ dm1fZmlsZSk7Ci0KLQltZW1jcHkodm1hX2NvcHksIHZtYSwgc2l6ZW9mKCp2bWEpKTsKLQotCXZt YV9jb3B5LT52bV9tbSA9IE5VTEw7Ci0Jdm1hX2NvcHktPnZtX25leHQgPSBOVUxMOwotCXZtYV9j b3B5LT52bV9wcmV2ID0gTlVMTDsKLQotCXJldHVybiB2bWFfY29weTsKLX0KLQotdm9pZCBleHlu b3NfZ2VtX3B1dF92bWEoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCi17Ci0JaWYgKCF2bWEp Ci0JCXJldHVybjsKLQotCWlmICh2bWEtPnZtX29wcyAmJiB2bWEtPnZtX29wcy0+Y2xvc2UpCi0J CXZtYS0+dm1fb3BzLT5jbG9zZSh2bWEpOwotCi0JaWYgKHZtYS0+dm1fZmlsZSkKLQkJZnB1dCh2 bWEtPnZtX2ZpbGUpOwotCi0Ja2ZyZWUodm1hKTsKLX0KLQotaW50IGV4eW5vc19nZW1fZ2V0X3Bh Z2VzX2Zyb21fdXNlcnB0cih1bnNpZ25lZCBsb25nIHN0YXJ0LAotCQkJCQkJdW5zaWduZWQgaW50 IG5wYWdlcywKLQkJCQkJCXN0cnVjdCBwYWdlICoqcGFnZXMsCi0JCQkJCQlzdHJ1Y3Qgdm1fYXJl YV9zdHJ1Y3QgKnZtYSkKLXsKLQlpbnQgZ2V0X25wYWdlczsKLQotCS8qIHRoZSBtZW1vcnkgcmVn aW9uIG1tYXBlZCB3aXRoIFZNX1BGTk1BUC4gKi8KLQlpZiAodm1hX2lzX2lvKHZtYSkpIHsKLQkJ dW5zaWduZWQgaW50IGk7Ci0KLQkJZm9yIChpID0gMDsgaSA8IG5wYWdlczsgKytpLCBzdGFydCAr PSBQQUdFX1NJWkUpIHsKLQkJCXVuc2lnbmVkIGxvbmcgcGZuOwotCQkJaW50IHJldCA9IGZvbGxv d19wZm4odm1hLCBzdGFydCwgJnBmbik7Ci0JCQlpZiAocmV0KQotCQkJCXJldHVybiByZXQ7Ci0K LQkJCXBhZ2VzW2ldID0gcGZuX3RvX3BhZ2UocGZuKTsKLQkJfQotCi0JCWlmIChpICE9IG5wYWdl cykgewotCQkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gZ2V0IHVzZXJfcGFnZXMuXG4iKTsKLQkJCXJl dHVybiAtRUlOVkFMOwotCQl9Ci0KLQkJcmV0dXJuIDA7Ci0JfQotCi0JZ2V0X25wYWdlcyA9IGdl dF91c2VyX3BhZ2VzKGN1cnJlbnQsIGN1cnJlbnQtPm1tLCBzdGFydCwKLQkJCQkJbnBhZ2VzLCAx LCAxLCBwYWdlcywgTlVMTCk7Ci0JZ2V0X25wYWdlcyA9IG1heChnZXRfbnBhZ2VzLCAwKTsKLQlp ZiAoZ2V0X25wYWdlcyAhPSBucGFnZXMpIHsKLQkJRFJNX0VSUk9SKCJmYWlsZWQgdG8gZ2V0IHVz ZXJfcGFnZXMuXG4iKTsKLQkJd2hpbGUgKGdldF9ucGFnZXMpCi0JCQlwdXRfcGFnZShwYWdlc1st LWdldF9ucGFnZXNdKTsKLQkJcmV0dXJuIC1FRkFVTFQ7Ci0JfQotCi0JcmV0dXJuIDA7Ci19Ci0K LXZvaWQgZXh5bm9zX2dlbV9wdXRfcGFnZXNfdG9fdXNlcnB0cihzdHJ1Y3QgcGFnZSAqKnBhZ2Vz LAotCQkJCQl1bnNpZ25lZCBpbnQgbnBhZ2VzLAotCQkJCQlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3Qg KnZtYSkKLXsKLQlpZiAoIXZtYV9pc19pbyh2bWEpKSB7Ci0JCXVuc2lnbmVkIGludCBpOwotCi0J CWZvciAoaSA9IDA7IGkgPCBucGFnZXM7IGkrKykgewotCQkJc2V0X3BhZ2VfZGlydHlfbG9jayhw YWdlc1tpXSk7Ci0KLQkJCS8qCi0JCQkgKiB1bmRvIHRoZSByZWZlcmVuY2Ugd2UgdG9vayB3aGVu IHBvcHVsYXRpbmcKLQkJCSAqIHRoZSB0YWJsZS4KLQkJCSAqLwotCQkJcHV0X3BhZ2UocGFnZXNb aV0pOwotCQl9Ci0JfQotfQotCiBpbnQgZXh5bm9zX2dlbV9tYXBfc2d0X3dpdGhfZG1hKHN0cnVj dCBkcm1fZGV2aWNlICpkcm1fZGV2LAogCQkJCXN0cnVjdCBzZ190YWJsZSAqc2d0LAogCQkJCWVu dW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpcikKLS0gCjIuMS40CgpfX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1k ZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cDovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9t YWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=