From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933780AbeCENqN (ORCPT ); Mon, 5 Mar 2018 08:46:13 -0500 Received: from mail-lf0-f65.google.com ([209.85.215.65]:41298 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933237AbeCENqM (ORCPT ); Mon, 5 Mar 2018 08:46:12 -0500 X-Google-Smtp-Source: AG47ELsYkbibGRUv86n1qBG43n/snsPcAGMLgwk+4ZNygBbCLfQBH43EBABXyot3D+zej83GphGjrw== Subject: Re: [PATCH 8/9] drm/xen-front: Implement GEM operations To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com, Oleksandr Andrushchenko References: <1519200222-20623-1-git-send-email-andr2000@gmail.com> <1519200222-20623-9-git-send-email-andr2000@gmail.com> <20180305093225.GK22212@phenom.ffwll.local> From: Oleksandr Andrushchenko Message-ID: Date: Mon, 5 Mar 2018 15:46:07 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <20180305093225.GK22212@phenom.ffwll.local> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 03/05/2018 11:32 AM, Daniel Vetter wrote: > On Wed, Feb 21, 2018 at 10:03:41AM +0200, Oleksandr Andrushchenko wrote: >> From: Oleksandr Andrushchenko >> >> Implement GEM handling depending on driver mode of operation: >> depending on the requirements for the para-virtualized environment, namely >> requirements dictated by the accompanying DRM/(v)GPU drivers running in both >> host and guest environments, number of operating modes of para-virtualized >> display driver are supported: >> - display buffers can be allocated by either frontend driver or backend >> - display buffers can be allocated to be contiguous in memory or not >> >> Note! Frontend driver itself has no dependency on contiguous memory for >> its operation. >> >> 1. Buffers allocated by the frontend driver. >> >> The below modes of operation are configured at compile-time via >> frontend driver's kernel configuration. >> >> 1.1. Front driver configured to use GEM CMA helpers >> This use-case is useful when used with accompanying DRM/vGPU driver in >> guest domain which was designed to only work with contiguous buffers, >> e.g. DRM driver based on GEM CMA helpers: such drivers can only import >> contiguous PRIME buffers, thus requiring frontend driver to provide >> such. In order to implement this mode of operation para-virtualized >> frontend driver can be configured to use GEM CMA helpers. >> >> 1.2. Front driver doesn't use GEM CMA >> If accompanying drivers can cope with non-contiguous memory then, to >> lower pressure on CMA subsystem of the kernel, driver can allocate >> buffers from system memory. >> >> Note! If used with accompanying DRM/(v)GPU drivers this mode of operation >> may require IOMMU support on the platform, so accompanying DRM/vGPU >> hardware can still reach display buffer memory while importing PRIME >> buffers from the frontend driver. >> >> 2. Buffers allocated by the backend >> >> This mode of operation is run-time configured via guest domain configuration >> through XenStore entries. >> >> For systems which do not provide IOMMU support, but having specific >> requirements for display buffers it is possible to allocate such buffers >> at backend side and share those with the frontend. >> For example, if host domain is 1:1 mapped and has DRM/GPU hardware expecting >> physically contiguous memory, this allows implementing zero-copying >> use-cases. >> >> Note! Configuration options 1.1 (contiguous display buffers) and 2 (backend >> allocated buffers) are not supported at the same time. >> >> Signed-off-by: Oleksandr Andrushchenko > Some suggestions below for some larger cleanup work. > -Daniel > >> --- >> drivers/gpu/drm/xen/Kconfig | 13 + >> drivers/gpu/drm/xen/Makefile | 6 + >> drivers/gpu/drm/xen/xen_drm_front.h | 74 ++++++ >> drivers/gpu/drm/xen/xen_drm_front_drv.c | 80 ++++++- >> drivers/gpu/drm/xen/xen_drm_front_drv.h | 1 + >> drivers/gpu/drm/xen/xen_drm_front_gem.c | 360 ++++++++++++++++++++++++++++ >> drivers/gpu/drm/xen/xen_drm_front_gem.h | 46 ++++ >> drivers/gpu/drm/xen/xen_drm_front_gem_cma.c | 93 +++++++ >> 8 files changed, 667 insertions(+), 6 deletions(-) >> create mode 100644 drivers/gpu/drm/xen/xen_drm_front_gem.c >> create mode 100644 drivers/gpu/drm/xen/xen_drm_front_gem.h >> create mode 100644 drivers/gpu/drm/xen/xen_drm_front_gem_cma.c >> >> diff --git a/drivers/gpu/drm/xen/Kconfig b/drivers/gpu/drm/xen/Kconfig >> index 4cca160782ab..4f4abc91f3b6 100644 >> --- a/drivers/gpu/drm/xen/Kconfig >> +++ b/drivers/gpu/drm/xen/Kconfig >> @@ -15,3 +15,16 @@ config DRM_XEN_FRONTEND >> help >> Choose this option if you want to enable a para-virtualized >> frontend DRM/KMS driver for Xen guest OSes. >> + >> +config DRM_XEN_FRONTEND_CMA >> + bool "Use DRM CMA to allocate dumb buffers" >> + depends on DRM_XEN_FRONTEND >> + select DRM_KMS_CMA_HELPER >> + select DRM_GEM_CMA_HELPER >> + help >> + Use DRM CMA helpers to allocate display buffers. >> + This is useful for the use-cases when guest driver needs to >> + share or export buffers to other drivers which only expect >> + contiguous buffers. >> + Note: in this mode driver cannot use buffers allocated >> + by the backend. >> diff --git a/drivers/gpu/drm/xen/Makefile b/drivers/gpu/drm/xen/Makefile >> index 4fcb0da1a9c5..12376ec78fbc 100644 >> --- a/drivers/gpu/drm/xen/Makefile >> +++ b/drivers/gpu/drm/xen/Makefile >> @@ -8,4 +8,10 @@ drm_xen_front-objs := xen_drm_front.o \ >> xen_drm_front_shbuf.o \ >> xen_drm_front_cfg.o >> >> +ifeq ($(CONFIG_DRM_XEN_FRONTEND_CMA),y) >> + drm_xen_front-objs += xen_drm_front_gem_cma.o >> +else >> + drm_xen_front-objs += xen_drm_front_gem.o >> +endif >> + >> obj-$(CONFIG_DRM_XEN_FRONTEND) += drm_xen_front.o >> diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h >> index 9ed5bfb248d0..c6f52c892434 100644 >> --- a/drivers/gpu/drm/xen/xen_drm_front.h >> +++ b/drivers/gpu/drm/xen/xen_drm_front.h >> @@ -34,6 +34,80 @@ >> >> struct xen_drm_front_drm_pipeline; >> >> +/* >> + ******************************************************************************* >> + * Para-virtualized DRM/KMS frontend driver >> + ******************************************************************************* >> + * This frontend driver implements Xen para-virtualized display >> + * according to the display protocol described at >> + * include/xen/interface/io/displif.h >> + * >> + ******************************************************************************* >> + * Driver modes of operation in terms of display buffers used >> + ******************************************************************************* >> + * Depending on the requirements for the para-virtualized environment, namely >> + * requirements dictated by the accompanying DRM/(v)GPU drivers running in both >> + * host and guest environments, number of operating modes of para-virtualized >> + * display driver are supported: >> + * - display buffers can be allocated by either frontend driver or backend >> + * - display buffers can be allocated to be contiguous in memory or not >> + * >> + * Note! Frontend driver itself has no dependency on contiguous memory for >> + * its operation. >> + * >> + ******************************************************************************* >> + * 1. Buffers allocated by the frontend driver. >> + ******************************************************************************* >> + * >> + * The below modes of operation are configured at compile-time via >> + * frontend driver's kernel configuration. >> + * >> + * 1.1. Front driver configured to use GEM CMA helpers >> + * This use-case is useful when used with accompanying DRM/vGPU driver in >> + * guest domain which was designed to only work with contiguous buffers, >> + * e.g. DRM driver based on GEM CMA helpers: such drivers can only import >> + * contiguous PRIME buffers, thus requiring frontend driver to provide >> + * such. In order to implement this mode of operation para-virtualized >> + * frontend driver can be configured to use GEM CMA helpers. >> + * >> + * 1.2. Front driver doesn't use GEM CMA >> + * If accompanying drivers can cope with non-contiguous memory then, to >> + * lower pressure on CMA subsystem of the kernel, driver can allocate >> + * buffers from system memory. >> + * >> + * Note! If used with accompanying DRM/(v)GPU drivers this mode of operation >> + * may require IOMMU support on the platform, so accompanying DRM/vGPU >> + * hardware can still reach display buffer memory while importing PRIME >> + * buffers from the frontend driver. >> + * >> + ******************************************************************************* >> + * 2. Buffers allocated by the backend >> + ******************************************************************************* >> + * >> + * This mode of operation is run-time configured via guest domain configuration >> + * through XenStore entries. >> + * >> + * For systems which do not provide IOMMU support, but having specific >> + * requirements for display buffers it is possible to allocate such buffers >> + * at backend side and share those with the frontend. >> + * For example, if host domain is 1:1 mapped and has DRM/GPU hardware expecting >> + * physically contiguous memory, this allows implementing zero-copying >> + * use-cases. >> + * >> + ******************************************************************************* >> + * Driver limitations >> + ******************************************************************************* >> + * 1. Configuration options 1.1 (contiguous display buffers) and 2 (backend >> + * allocated buffers) are not supported at the same time. >> + * >> + * 2. Only primary plane without additional properties is supported. >> + * >> + * 3. Only one video mode supported which is configured via XenStore. >> + * >> + * 4. All CRTCs operate at fixed frequency of 60Hz. >> + * >> + ******************************************************************************/ > Since you've typed this all up, pls convert it to kernel-doc and pull it > into a xen-front.rst driver section in Documentation/gpu/ There's a few > examples for i915 and vc4 already. Do you mean to move or to keep in the driver and add in the Documentation? I would prefer to move to have the description at single place. > >> + >> struct xen_drm_front_ops { >> int (*mode_set)(struct xen_drm_front_drm_pipeline *pipeline, >> uint32_t x, uint32_t y, uint32_t width, uint32_t height, >> diff --git a/drivers/gpu/drm/xen/xen_drm_front_drv.c b/drivers/gpu/drm/xen/xen_drm_front_drv.c >> index e8862d26ba27..35e7e9cda9d1 100644 >> --- a/drivers/gpu/drm/xen/xen_drm_front_drv.c >> +++ b/drivers/gpu/drm/xen/xen_drm_front_drv.c >> @@ -23,12 +23,58 @@ >> #include "xen_drm_front.h" >> #include "xen_drm_front_cfg.h" >> #include "xen_drm_front_drv.h" >> +#include "xen_drm_front_gem.h" >> #include "xen_drm_front_kms.h" >> >> static int dumb_create(struct drm_file *filp, >> struct drm_device *dev, struct drm_mode_create_dumb *args) >> { >> - return -EINVAL; >> + struct xen_drm_front_drm_info *drm_info = dev->dev_private; >> + struct drm_gem_object *obj; >> + int ret; >> + >> + ret = drm_info->gem_ops->dumb_create(filp, dev, args); >> + if (ret) >> + goto fail; >> + >> + obj = drm_gem_object_lookup(filp, args->handle); >> + if (!obj) { >> + ret = -ENOENT; >> + goto fail_destroy; >> + } >> + >> + drm_gem_object_unreference_unlocked(obj); >> + >> + /* >> + * In case of CONFIG_DRM_XEN_FRONTEND_CMA gem_obj is constructed >> + * via DRM CMA helpers and doesn't have ->pages allocated >> + * (xendrm_gem_get_pages will return NULL), but instead can provide >> + * sg table >> + */ > My recommendation is to use an sg table for everything if you deal with > mixed objects (CMA, special blocks 1:1 mapped from host, normal pages). > That avoids the constant get_pages vs. get_sgt differences. For examples > see how e.g. i915 handles the various gem object backends. Indeed, I tried to do that this way before, e.g. have all sgt based. But at the end of the day Xen shared buffer code in the driver works with pages (Xen API is page based there), so sgt then will anyway need to be converted into page array. For that reason I prefer to work with pages from the beginning, not sgt. As to constant get_pages etc. - this is the only expected place in the driver for that, so the _from_sgt/_from_pages API is only used here. > >> + if (drm_info->gem_ops->get_pages(obj)) >> + ret = drm_info->front_ops->dbuf_create_from_pages( >> + drm_info->front_info, >> + xen_drm_front_dbuf_to_cookie(obj), >> + args->width, args->height, args->bpp, >> + args->size, >> + drm_info->gem_ops->get_pages(obj)); >> + else >> + ret = drm_info->front_ops->dbuf_create_from_sgt( >> + drm_info->front_info, >> + xen_drm_front_dbuf_to_cookie(obj), >> + args->width, args->height, args->bpp, >> + args->size, >> + drm_info->gem_ops->prime_get_sg_table(obj)); >> + if (ret) >> + goto fail_destroy; >> + >> + return 0; >> + >> +fail_destroy: >> + drm_gem_dumb_destroy(filp, dev, args->handle); >> +fail: >> + DRM_ERROR("Failed to create dumb buffer: %d\n", ret); >> + return ret; >> } >> >> static void free_object(struct drm_gem_object *obj) >> @@ -37,6 +83,7 @@ static void free_object(struct drm_gem_object *obj) >> >> drm_info->front_ops->dbuf_destroy(drm_info->front_info, >> xen_drm_front_dbuf_to_cookie(obj)); >> + drm_info->gem_ops->free_object_unlocked(obj); >> } >> >> static void on_frame_done(struct platform_device *pdev, >> @@ -60,32 +107,52 @@ static void lastclose(struct drm_device *dev) >> >> static int gem_mmap(struct file *filp, struct vm_area_struct *vma) >> { >> - return -EINVAL; >> + struct drm_file *file_priv = filp->private_data; >> + struct drm_device *dev = file_priv->minor->dev; >> + struct xen_drm_front_drm_info *drm_info = dev->dev_private; >> + >> + return drm_info->gem_ops->mmap(filp, vma); > Uh, so 1 midlayer for the kms stuff and another midlayer for the gem > stuff. That's way too much indirection. If by KMS you mean front_ops then -1: I will remove front_ops. As to gem_ops, please see below >> } >> >> static struct sg_table *prime_get_sg_table(struct drm_gem_object *obj) >> { >> - return NULL; >> + struct xen_drm_front_drm_info *drm_info; >> + >> + drm_info = obj->dev->dev_private; >> + return drm_info->gem_ops->prime_get_sg_table(obj); >> } >> >> static struct drm_gem_object *prime_import_sg_table(struct drm_device *dev, >> struct dma_buf_attachment *attach, struct sg_table *sgt) >> { >> - return NULL; >> + struct xen_drm_front_drm_info *drm_info; >> + >> + drm_info = dev->dev_private; >> + return drm_info->gem_ops->prime_import_sg_table(dev, attach, sgt); >> } >> >> static void *prime_vmap(struct drm_gem_object *obj) >> { >> - return NULL; >> + struct xen_drm_front_drm_info *drm_info; >> + >> + drm_info = obj->dev->dev_private; >> + return drm_info->gem_ops->prime_vmap(obj); >> } >> >> static void prime_vunmap(struct drm_gem_object *obj, void *vaddr) >> { >> + struct xen_drm_front_drm_info *drm_info; >> + >> + drm_info = obj->dev->dev_private; >> + drm_info->gem_ops->prime_vunmap(obj, vaddr); >> } >> >> static int prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) >> { >> - return -EINVAL; >> + struct xen_drm_front_drm_info *drm_info; >> + >> + drm_info = obj->dev->dev_private; >> + return drm_info->gem_ops->prime_mmap(obj, vma); >> } >> >> static const struct file_operations xendrm_fops = { >> @@ -147,6 +214,7 @@ int xen_drm_front_drv_probe(struct platform_device *pdev, >> >> drm_info->front_ops = front_ops; >> drm_info->front_ops->on_frame_done = on_frame_done; >> + drm_info->gem_ops = xen_drm_front_gem_get_ops(); >> drm_info->front_info = cfg->front_info; >> >> dev = drm_dev_alloc(&xen_drm_driver, &pdev->dev); >> diff --git a/drivers/gpu/drm/xen/xen_drm_front_drv.h b/drivers/gpu/drm/xen/xen_drm_front_drv.h >> index 563318b19f34..34228eb86255 100644 >> --- a/drivers/gpu/drm/xen/xen_drm_front_drv.h >> +++ b/drivers/gpu/drm/xen/xen_drm_front_drv.h >> @@ -43,6 +43,7 @@ struct xen_drm_front_drm_pipeline { >> struct xen_drm_front_drm_info { >> struct xen_drm_front_info *front_info; >> struct xen_drm_front_ops *front_ops; >> + const struct xen_drm_front_gem_ops *gem_ops; >> struct drm_device *drm_dev; >> struct xen_drm_front_cfg *cfg; >> >> diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c >> new file mode 100644 >> index 000000000000..367e08f6a9ef >> --- /dev/null >> +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c >> @@ -0,0 +1,360 @@ >> +/* >> + * Xen para-virtual DRM device >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * Copyright (C) 2016-2018 EPAM Systems Inc. >> + * >> + * Author: Oleksandr Andrushchenko >> + */ >> + >> +#include "xen_drm_front_gem.h" >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#include "xen_drm_front.h" >> +#include "xen_drm_front_drv.h" >> +#include "xen_drm_front_shbuf.h" >> + >> +struct xen_gem_object { >> + struct drm_gem_object base; >> + >> + size_t num_pages; >> + struct page **pages; >> + >> + /* set for buffers allocated by the backend */ >> + bool be_alloc; >> + >> + /* this is for imported PRIME buffer */ >> + struct sg_table *sgt_imported; >> +}; >> + >> +static inline struct xen_gem_object *to_xen_gem_obj( >> + struct drm_gem_object *gem_obj) >> +{ >> + return container_of(gem_obj, struct xen_gem_object, base); >> +} >> + >> +static int gem_alloc_pages_array(struct xen_gem_object *xen_obj, >> + size_t buf_size) >> +{ >> + xen_obj->num_pages = DIV_ROUND_UP(buf_size, PAGE_SIZE); >> + xen_obj->pages = kvmalloc_array(xen_obj->num_pages, >> + sizeof(struct page *), GFP_KERNEL); >> + return xen_obj->pages == NULL ? -ENOMEM : 0; >> +} >> + >> +static void gem_free_pages_array(struct xen_gem_object *xen_obj) >> +{ >> + kvfree(xen_obj->pages); >> + xen_obj->pages = NULL; >> +} >> + >> +static struct xen_gem_object *gem_create_obj(struct drm_device *dev, >> + size_t size) >> +{ >> + struct xen_gem_object *xen_obj; >> + int ret; >> + >> + xen_obj = kzalloc(sizeof(*xen_obj), GFP_KERNEL); >> + if (!xen_obj) >> + return ERR_PTR(-ENOMEM); >> + >> + ret = drm_gem_object_init(dev, &xen_obj->base, size); >> + if (ret < 0) { >> + kfree(xen_obj); >> + return ERR_PTR(ret); >> + } >> + >> + return xen_obj; >> +} >> + >> +static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size) >> +{ >> + struct xen_drm_front_drm_info *drm_info = dev->dev_private; >> + struct xen_gem_object *xen_obj; >> + int ret; >> + >> + size = round_up(size, PAGE_SIZE); >> + xen_obj = gem_create_obj(dev, size); >> + if (IS_ERR_OR_NULL(xen_obj)) >> + return xen_obj; >> + >> + if (drm_info->cfg->be_alloc) { >> + /* >> + * backend will allocate space for this buffer, so >> + * only allocate array of pointers to pages >> + */ >> + xen_obj->be_alloc = true; >> + ret = gem_alloc_pages_array(xen_obj, size); >> + if (ret < 0) { >> + gem_free_pages_array(xen_obj); >> + goto fail; >> + } >> + >> + ret = alloc_xenballooned_pages(xen_obj->num_pages, >> + xen_obj->pages); >> + if (ret < 0) { >> + DRM_ERROR("Cannot allocate %zu ballooned pages: %d\n", >> + xen_obj->num_pages, ret); >> + goto fail; >> + } >> + >> + return xen_obj; >> + } >> + /* >> + * need to allocate backing pages now, so we can share those >> + * with the backend >> + */ >> + xen_obj->num_pages = DIV_ROUND_UP(size, PAGE_SIZE); >> + xen_obj->pages = drm_gem_get_pages(&xen_obj->base); >> + if (IS_ERR_OR_NULL(xen_obj->pages)) { >> + ret = PTR_ERR(xen_obj->pages); >> + xen_obj->pages = NULL; >> + goto fail; >> + } >> + >> + return xen_obj; >> + >> +fail: >> + DRM_ERROR("Failed to allocate buffer with size %zu\n", size); >> + return ERR_PTR(ret); >> +} >> + >> +static struct xen_gem_object *gem_create_with_handle(struct drm_file *filp, >> + struct drm_device *dev, size_t size, uint32_t *handle) >> +{ >> + struct xen_gem_object *xen_obj; >> + struct drm_gem_object *gem_obj; >> + int ret; >> + >> + xen_obj = gem_create(dev, size); >> + if (IS_ERR_OR_NULL(xen_obj)) >> + return xen_obj; >> + >> + gem_obj = &xen_obj->base; >> + ret = drm_gem_handle_create(filp, gem_obj, handle); >> + /* handle holds the reference */ >> + drm_gem_object_unreference_unlocked(gem_obj); >> + if (ret < 0) >> + return ERR_PTR(ret); >> + >> + return xen_obj; >> +} >> + >> +static int gem_dumb_create(struct drm_file *filp, struct drm_device *dev, >> + struct drm_mode_create_dumb *args) >> +{ >> + struct xen_gem_object *xen_obj; >> + >> + args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8); >> + args->size = args->pitch * args->height; >> + >> + xen_obj = gem_create_with_handle(filp, dev, args->size, &args->handle); >> + if (IS_ERR_OR_NULL(xen_obj)) >> + return xen_obj == NULL ? -ENOMEM : PTR_ERR(xen_obj); >> + >> + return 0; >> +} >> + >> +static void gem_free_object(struct drm_gem_object *gem_obj) >> +{ >> + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); >> + >> + if (xen_obj->base.import_attach) { >> + drm_prime_gem_destroy(&xen_obj->base, xen_obj->sgt_imported); >> + gem_free_pages_array(xen_obj); >> + } else { >> + if (xen_obj->pages) { >> + if (xen_obj->be_alloc) { >> + free_xenballooned_pages(xen_obj->num_pages, >> + xen_obj->pages); >> + gem_free_pages_array(xen_obj); >> + } else >> + drm_gem_put_pages(&xen_obj->base, >> + xen_obj->pages, true, false); >> + } >> + } >> + drm_gem_object_release(gem_obj); >> + kfree(xen_obj); >> +} >> + >> +static struct page **gem_get_pages(struct drm_gem_object *gem_obj) >> +{ >> + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); >> + >> + return xen_obj->pages; >> +} >> + >> +static struct sg_table *gem_get_sg_table(struct drm_gem_object *gem_obj) >> +{ >> + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); >> + >> + if (!xen_obj->pages) >> + return NULL; >> + >> + return drm_prime_pages_to_sg(xen_obj->pages, xen_obj->num_pages); >> +} >> + >> +static struct drm_gem_object *gem_import_sg_table(struct drm_device *dev, >> + struct dma_buf_attachment *attach, struct sg_table *sgt) >> +{ >> + struct xen_drm_front_drm_info *drm_info = dev->dev_private; >> + struct xen_gem_object *xen_obj; >> + size_t size; >> + int ret; >> + >> + size = attach->dmabuf->size; >> + xen_obj = gem_create_obj(dev, size); >> + if (IS_ERR_OR_NULL(xen_obj)) >> + return ERR_CAST(xen_obj); >> + >> + ret = gem_alloc_pages_array(xen_obj, size); >> + if (ret < 0) >> + return ERR_PTR(ret); >> + >> + xen_obj->sgt_imported = sgt; >> + >> + ret = drm_prime_sg_to_page_addr_arrays(sgt, xen_obj->pages, >> + NULL, xen_obj->num_pages); >> + if (ret < 0) >> + return ERR_PTR(ret); >> + >> + /* >> + * N.B. Although we have an API to create display buffer from sgt >> + * we use pages API, because we still need those for GEM handling, >> + * e.g. for mapping etc. >> + */ >> + ret = drm_info->front_ops->dbuf_create_from_pages( >> + drm_info->front_info, >> + xen_drm_front_dbuf_to_cookie(&xen_obj->base), >> + 0, 0, 0, size, xen_obj->pages); >> + if (ret < 0) >> + return ERR_PTR(ret); >> + >> + DRM_DEBUG("Imported buffer of size %zu with nents %u\n", >> + size, sgt->nents); >> + >> + return &xen_obj->base; >> +} >> + >> +static int gem_mmap_obj(struct xen_gem_object *xen_obj, >> + struct vm_area_struct *vma) >> +{ >> + unsigned long addr = vma->vm_start; >> + int i; >> + >> + /* >> + * clear the VM_PFNMAP flag that was set by drm_gem_mmap(), and set the >> + * vm_pgoff (used as a fake buffer offset by DRM) to 0 as we want to map >> + * the whole buffer. >> + */ >> + vma->vm_flags &= ~VM_PFNMAP; >> + vma->vm_flags |= VM_MIXEDMAP; >> + vma->vm_pgoff = 0; >> + vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); >> + >> + /* >> + * vm_operations_struct.fault handler will be called if CPU access >> + * to VM is here. For GPUs this isn't the case, because CPU >> + * doesn't touch the memory. Insert pages now, so both CPU and GPU are >> + * happy. >> + * FIXME: as we insert all the pages now then no .fault handler must >> + * be called, so don't provide one >> + */ >> + for (i = 0; i < xen_obj->num_pages; i++) { >> + int ret; >> + >> + ret = vm_insert_page(vma, addr, xen_obj->pages[i]); >> + if (ret < 0) { >> + DRM_ERROR("Failed to insert pages into vma: %d\n", ret); >> + return ret; >> + } >> + >> + addr += PAGE_SIZE; >> + } >> + return 0; >> +} >> + >> +static int gem_mmap(struct file *filp, struct vm_area_struct *vma) >> +{ >> + struct xen_gem_object *xen_obj; >> + struct drm_gem_object *gem_obj; >> + int ret; >> + >> + ret = drm_gem_mmap(filp, vma); >> + if (ret < 0) >> + return ret; >> + >> + gem_obj = vma->vm_private_data; >> + xen_obj = to_xen_gem_obj(gem_obj); >> + return gem_mmap_obj(xen_obj, vma); >> +} >> + >> +static void *gem_prime_vmap(struct drm_gem_object *gem_obj) >> +{ >> + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); >> + >> + if (!xen_obj->pages) >> + return NULL; >> + >> + return vmap(xen_obj->pages, xen_obj->num_pages, >> + VM_MAP, pgprot_writecombine(PAGE_KERNEL)); >> +} >> + >> +static void gem_prime_vunmap(struct drm_gem_object *gem_obj, void *vaddr) >> +{ >> + vunmap(vaddr); >> +} >> + >> +static int gem_prime_mmap(struct drm_gem_object *gem_obj, >> + struct vm_area_struct *vma) >> +{ >> + struct xen_gem_object *xen_obj; >> + int ret; >> + >> + ret = drm_gem_mmap_obj(gem_obj, gem_obj->size, vma); >> + if (ret < 0) >> + return ret; >> + >> + xen_obj = to_xen_gem_obj(gem_obj); >> + return gem_mmap_obj(xen_obj, vma); >> +} >> + >> +static const struct xen_drm_front_gem_ops xen_drm_gem_ops = { >> + .free_object_unlocked = gem_free_object, >> + .prime_get_sg_table = gem_get_sg_table, >> + .prime_import_sg_table = gem_import_sg_table, >> + >> + .prime_vmap = gem_prime_vmap, >> + .prime_vunmap = gem_prime_vunmap, >> + .prime_mmap = gem_prime_mmap, >> + >> + .dumb_create = gem_dumb_create, >> + >> + .mmap = gem_mmap, >> + >> + .get_pages = gem_get_pages, >> +}; >> + >> +const struct xen_drm_front_gem_ops *xen_drm_front_gem_get_ops(void) >> +{ >> + return &xen_drm_gem_ops; >> +} >> diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.h b/drivers/gpu/drm/xen/xen_drm_front_gem.h >> new file mode 100644 >> index 000000000000..d1e1711cc3fc >> --- /dev/null >> +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.h >> @@ -0,0 +1,46 @@ >> +/* >> + * Xen para-virtual DRM device >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * Copyright (C) 2016-2018 EPAM Systems Inc. >> + * >> + * Author: Oleksandr Andrushchenko >> + */ >> + >> +#ifndef __XEN_DRM_FRONT_GEM_H >> +#define __XEN_DRM_FRONT_GEM_H >> + >> +#include >> + >> +struct xen_drm_front_gem_ops { >> + void (*free_object_unlocked)(struct drm_gem_object *obj); >> + >> + struct sg_table *(*prime_get_sg_table)(struct drm_gem_object *obj); >> + struct drm_gem_object *(*prime_import_sg_table)(struct drm_device *dev, >> + struct dma_buf_attachment *attach, >> + struct sg_table *sgt); >> + void *(*prime_vmap)(struct drm_gem_object *obj); >> + void (*prime_vunmap)(struct drm_gem_object *obj, void *vaddr); >> + int (*prime_mmap)(struct drm_gem_object *obj, >> + struct vm_area_struct *vma); >> + >> + int (*dumb_create)(struct drm_file *file_priv, struct drm_device *dev, >> + struct drm_mode_create_dumb *args); >> + >> + int (*mmap)(struct file *filp, struct vm_area_struct *vma); >> + >> + struct page **(*get_pages)(struct drm_gem_object *obj); >> +}; >> + >> +const struct xen_drm_front_gem_ops *xen_drm_front_gem_get_ops(void); >> + >> +#endif /* __XEN_DRM_FRONT_GEM_H */ >> diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem_cma.c b/drivers/gpu/drm/xen/xen_drm_front_gem_cma.c >> new file mode 100644 >> index 000000000000..5ffcbfa652d5 >> --- /dev/null >> +++ b/drivers/gpu/drm/xen/xen_drm_front_gem_cma.c >> @@ -0,0 +1,93 @@ >> +/* >> + * Xen para-virtual DRM device >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * Copyright (C) 2016-2018 EPAM Systems Inc. >> + * >> + * Author: Oleksandr Andrushchenko >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +#include "xen_drm_front.h" >> +#include "xen_drm_front_drv.h" >> +#include "xen_drm_front_gem.h" >> + >> +static struct drm_gem_object *gem_import_sg_table(struct drm_device *dev, >> + struct dma_buf_attachment *attach, struct sg_table *sgt) >> +{ >> + struct xen_drm_front_drm_info *drm_info = dev->dev_private; >> + struct drm_gem_object *gem_obj; >> + struct drm_gem_cma_object *cma_obj; >> + int ret; >> + >> + gem_obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt); >> + if (IS_ERR_OR_NULL(gem_obj)) >> + return gem_obj; >> + >> + cma_obj = to_drm_gem_cma_obj(gem_obj); >> + >> + ret = drm_info->front_ops->dbuf_create_from_sgt( >> + drm_info->front_info, >> + xen_drm_front_dbuf_to_cookie(gem_obj), >> + 0, 0, 0, gem_obj->size, >> + drm_gem_cma_prime_get_sg_table(gem_obj)); >> + if (ret < 0) >> + return ERR_PTR(ret); >> + >> + DRM_DEBUG("Imported CMA buffer of size %zu\n", gem_obj->size); >> + >> + return gem_obj; >> +} >> + >> +static int gem_dumb_create(struct drm_file *filp, struct drm_device *dev, >> + struct drm_mode_create_dumb *args) >> +{ >> + struct xen_drm_front_drm_info *drm_info = dev->dev_private; >> + >> + if (drm_info->cfg->be_alloc) { >> + /* This use-case is not yet supported and probably won't be */ >> + DRM_ERROR("Backend allocated buffers and CMA helpers are not supported at the same time\n"); >> + return -EINVAL; >> + } >> + >> + return drm_gem_cma_dumb_create(filp, dev, args); >> +} >> + >> +static struct page **gem_get_pages(struct drm_gem_object *gem_obj) >> +{ >> + return NULL; >> +} >> + >> +static const struct xen_drm_front_gem_ops xen_drm_front_gem_cma_ops = { >> + .free_object_unlocked = drm_gem_cma_free_object, >> + .prime_get_sg_table = drm_gem_cma_prime_get_sg_table, >> + .prime_import_sg_table = gem_import_sg_table, >> + >> + .prime_vmap = drm_gem_cma_prime_vmap, >> + .prime_vunmap = drm_gem_cma_prime_vunmap, >> + .prime_mmap = drm_gem_cma_prime_mmap, >> + >> + .dumb_create = gem_dumb_create, >> + >> + .mmap = drm_gem_cma_mmap, >> + >> + .get_pages = gem_get_pages, >> +}; > Again quite a midlayer you have here. Please inline this to avoid > confusion for other people (since it looks like you only have 1 > implementation). There are 2 implementations depending on driver compile time options: you can have the GEM operations implemented with DRM CMA helpers or driver's cooked GEMs. For this reason this midlayer exists, e.g. to eliminate the need for something like #ifdef DRM_XEN_FRONTEND_CMA drm_gem_cma_...() #else xen_drm_front_gem_...() #endif So, I would prefer to have ops rather then having ifdefs > >> + >> +const struct xen_drm_front_gem_ops *xen_drm_front_gem_get_ops(void) >> +{ >> + return &xen_drm_front_gem_cma_ops; >> +} >> -- >> 2.7.4 >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/dri-devel From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: Re: [PATCH 8/9] drm/xen-front: Implement GEM operations Date: Mon, 5 Mar 2018 15:46:07 +0200 Message-ID: References: <1519200222-20623-1-git-send-email-andr2000@gmail.com> <1519200222-20623-9-git-send-email-andr2000@gmail.com> <20180305093225.GK22212@phenom.ffwll.local> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x244.google.com (mail-lf0-x244.google.com [IPv6:2a00:1450:4010:c07::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 178076E103 for ; Mon, 5 Mar 2018 13:46:11 +0000 (UTC) Received: by mail-lf0-x244.google.com with SMTP id 70so23184424lfw.2 for ; Mon, 05 Mar 2018 05:46:11 -0800 (PST) In-Reply-To: <20180305093225.GK22212@phenom.ffwll.local> Content-Language: en-US List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, airlied@linux.ie, daniel.vetter@intel.com, seanpaul@chromium.org, gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com, Oleksandr Andrushchenko List-Id: dri-devel@lists.freedesktop.org T24gMDMvMDUvMjAxOCAxMTozMiBBTSwgRGFuaWVsIFZldHRlciB3cm90ZToKPiBPbiBXZWQsIEZl YiAyMSwgMjAxOCBhdCAxMDowMzo0MUFNICswMjAwLCBPbGVrc2FuZHIgQW5kcnVzaGNoZW5rbyB3 cm90ZToKPj4gRnJvbTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNo Y2hlbmtvQGVwYW0uY29tPgo+Pgo+PiBJbXBsZW1lbnQgR0VNIGhhbmRsaW5nIGRlcGVuZGluZyBv biBkcml2ZXIgbW9kZSBvZiBvcGVyYXRpb246Cj4+IGRlcGVuZGluZyBvbiB0aGUgcmVxdWlyZW1l bnRzIGZvciB0aGUgcGFyYS12aXJ0dWFsaXplZCBlbnZpcm9ubWVudCwgbmFtZWx5Cj4+IHJlcXVp cmVtZW50cyBkaWN0YXRlZCBieSB0aGUgYWNjb21wYW55aW5nIERSTS8odilHUFUgZHJpdmVycyBy dW5uaW5nIGluIGJvdGgKPj4gaG9zdCBhbmQgZ3Vlc3QgZW52aXJvbm1lbnRzLCBudW1iZXIgb2Yg b3BlcmF0aW5nIG1vZGVzIG9mIHBhcmEtdmlydHVhbGl6ZWQKPj4gZGlzcGxheSBkcml2ZXIgYXJl IHN1cHBvcnRlZDoKPj4gICAtIGRpc3BsYXkgYnVmZmVycyBjYW4gYmUgYWxsb2NhdGVkIGJ5IGVp dGhlciBmcm9udGVuZCBkcml2ZXIgb3IgYmFja2VuZAo+PiAgIC0gZGlzcGxheSBidWZmZXJzIGNh biBiZSBhbGxvY2F0ZWQgdG8gYmUgY29udGlndW91cyBpbiBtZW1vcnkgb3Igbm90Cj4+Cj4+IE5v dGUhIEZyb250ZW5kIGRyaXZlciBpdHNlbGYgaGFzIG5vIGRlcGVuZGVuY3kgb24gY29udGlndW91 cyBtZW1vcnkgZm9yCj4+IGl0cyBvcGVyYXRpb24uCj4+Cj4+IDEuIEJ1ZmZlcnMgYWxsb2NhdGVk IGJ5IHRoZSBmcm9udGVuZCBkcml2ZXIuCj4+Cj4+IFRoZSBiZWxvdyBtb2RlcyBvZiBvcGVyYXRp b24gYXJlIGNvbmZpZ3VyZWQgYXQgY29tcGlsZS10aW1lIHZpYQo+PiBmcm9udGVuZCBkcml2ZXIn cyBrZXJuZWwgY29uZmlndXJhdGlvbi4KPj4KPj4gMS4xLiBGcm9udCBkcml2ZXIgY29uZmlndXJl ZCB0byB1c2UgR0VNIENNQSBoZWxwZXJzCj4+ICAgICAgIFRoaXMgdXNlLWNhc2UgaXMgdXNlZnVs IHdoZW4gdXNlZCB3aXRoIGFjY29tcGFueWluZyBEUk0vdkdQVSBkcml2ZXIgaW4KPj4gICAgICAg Z3Vlc3QgZG9tYWluIHdoaWNoIHdhcyBkZXNpZ25lZCB0byBvbmx5IHdvcmsgd2l0aCBjb250aWd1 b3VzIGJ1ZmZlcnMsCj4+ICAgICAgIGUuZy4gRFJNIGRyaXZlciBiYXNlZCBvbiBHRU0gQ01BIGhl bHBlcnM6IHN1Y2ggZHJpdmVycyBjYW4gb25seSBpbXBvcnQKPj4gICAgICAgY29udGlndW91cyBQ UklNRSBidWZmZXJzLCB0aHVzIHJlcXVpcmluZyBmcm9udGVuZCBkcml2ZXIgdG8gcHJvdmlkZQo+ PiAgICAgICBzdWNoLiBJbiBvcmRlciB0byBpbXBsZW1lbnQgdGhpcyBtb2RlIG9mIG9wZXJhdGlv biBwYXJhLXZpcnR1YWxpemVkCj4+ICAgICAgIGZyb250ZW5kIGRyaXZlciBjYW4gYmUgY29uZmln dXJlZCB0byB1c2UgR0VNIENNQSBoZWxwZXJzLgo+Pgo+PiAxLjIuIEZyb250IGRyaXZlciBkb2Vz bid0IHVzZSBHRU0gQ01BCj4+ICAgICAgIElmIGFjY29tcGFueWluZyBkcml2ZXJzIGNhbiBjb3Bl IHdpdGggbm9uLWNvbnRpZ3VvdXMgbWVtb3J5IHRoZW4sIHRvCj4+ICAgICAgIGxvd2VyIHByZXNz dXJlIG9uIENNQSBzdWJzeXN0ZW0gb2YgdGhlIGtlcm5lbCwgZHJpdmVyIGNhbiBhbGxvY2F0ZQo+ PiAgICAgICBidWZmZXJzIGZyb20gc3lzdGVtIG1lbW9yeS4KPj4KPj4gTm90ZSEgSWYgdXNlZCB3 aXRoIGFjY29tcGFueWluZyBEUk0vKHYpR1BVIGRyaXZlcnMgdGhpcyBtb2RlIG9mIG9wZXJhdGlv bgo+PiBtYXkgcmVxdWlyZSBJT01NVSBzdXBwb3J0IG9uIHRoZSBwbGF0Zm9ybSwgc28gYWNjb21w YW55aW5nIERSTS92R1BVCj4+IGhhcmR3YXJlIGNhbiBzdGlsbCByZWFjaCBkaXNwbGF5IGJ1ZmZl ciBtZW1vcnkgd2hpbGUgaW1wb3J0aW5nIFBSSU1FCj4+IGJ1ZmZlcnMgZnJvbSB0aGUgZnJvbnRl bmQgZHJpdmVyLgo+Pgo+PiAyLiBCdWZmZXJzIGFsbG9jYXRlZCBieSB0aGUgYmFja2VuZAo+Pgo+ PiBUaGlzIG1vZGUgb2Ygb3BlcmF0aW9uIGlzIHJ1bi10aW1lIGNvbmZpZ3VyZWQgdmlhIGd1ZXN0 IGRvbWFpbiBjb25maWd1cmF0aW9uCj4+IHRocm91Z2ggWGVuU3RvcmUgZW50cmllcy4KPj4KPj4g Rm9yIHN5c3RlbXMgd2hpY2ggZG8gbm90IHByb3ZpZGUgSU9NTVUgc3VwcG9ydCwgYnV0IGhhdmlu ZyBzcGVjaWZpYwo+PiByZXF1aXJlbWVudHMgZm9yIGRpc3BsYXkgYnVmZmVycyBpdCBpcyBwb3Nz aWJsZSB0byBhbGxvY2F0ZSBzdWNoIGJ1ZmZlcnMKPj4gYXQgYmFja2VuZCBzaWRlIGFuZCBzaGFy ZSB0aG9zZSB3aXRoIHRoZSBmcm9udGVuZC4KPj4gRm9yIGV4YW1wbGUsIGlmIGhvc3QgZG9tYWlu IGlzIDE6MSBtYXBwZWQgYW5kIGhhcyBEUk0vR1BVIGhhcmR3YXJlIGV4cGVjdGluZwo+PiBwaHlz aWNhbGx5IGNvbnRpZ3VvdXMgbWVtb3J5LCB0aGlzIGFsbG93cyBpbXBsZW1lbnRpbmcgemVyby1j b3B5aW5nCj4+IHVzZS1jYXNlcy4KPj4KPj4gTm90ZSEgQ29uZmlndXJhdGlvbiBvcHRpb25zIDEu MSAoY29udGlndW91cyBkaXNwbGF5IGJ1ZmZlcnMpIGFuZCAyIChiYWNrZW5kCj4+IGFsbG9jYXRl ZCBidWZmZXJzKSBhcmUgbm90IHN1cHBvcnRlZCBhdCB0aGUgc2FtZSB0aW1lLgo+Pgo+PiBTaWdu ZWQtb2ZmLWJ5OiBPbGVrc2FuZHIgQW5kcnVzaGNoZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVu a29AZXBhbS5jb20+Cj4gU29tZSBzdWdnZXN0aW9ucyBiZWxvdyBmb3Igc29tZSBsYXJnZXIgY2xl YW51cCB3b3JrLgo+IC1EYW5pZWwKPgo+PiAtLS0KPj4gICBkcml2ZXJzL2dwdS9kcm0veGVuL0tj b25maWcgICAgICAgICAgICAgICAgIHwgIDEzICsKPj4gICBkcml2ZXJzL2dwdS9kcm0veGVuL01h a2VmaWxlICAgICAgICAgICAgICAgIHwgICA2ICsKPj4gICBkcml2ZXJzL2dwdS9kcm0veGVuL3hl bl9kcm1fZnJvbnQuaCAgICAgICAgIHwgIDc0ICsrKysrKwo+PiAgIGRyaXZlcnMvZ3B1L2RybS94 ZW4veGVuX2RybV9mcm9udF9kcnYuYyAgICAgfCAgODAgKysrKysrLQo+PiAgIGRyaXZlcnMvZ3B1 L2RybS94ZW4veGVuX2RybV9mcm9udF9kcnYuaCAgICAgfCAgIDEgKwo+PiAgIGRyaXZlcnMvZ3B1 L2RybS94ZW4veGVuX2RybV9mcm9udF9nZW0uYyAgICAgfCAzNjAgKysrKysrKysrKysrKysrKysr KysrKysrKysrKwo+PiAgIGRyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV9mcm9udF9nZW0uaCAg ICAgfCAgNDYgKysrKwo+PiAgIGRyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV9mcm9udF9nZW1f Y21hLmMgfCAgOTMgKysrKysrKwo+PiAgIDggZmlsZXMgY2hhbmdlZCwgNjY3IGluc2VydGlvbnMo KyksIDYgZGVsZXRpb25zKC0pCj4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2Ry bS94ZW4veGVuX2RybV9mcm9udF9nZW0uYwo+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz L2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnRfZ2VtLmgKPj4gICBjcmVhdGUgbW9kZSAxMDA2NDQg ZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250X2dlbV9jbWEuYwo+Pgo+PiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9ncHUvZHJtL3hlbi9LY29uZmlnIGIvZHJpdmVycy9ncHUvZHJtL3hlbi9L Y29uZmlnCj4+IGluZGV4IDRjY2ExNjA3ODJhYi4uNGY0YWJjOTFmM2I2IDEwMDY0NAo+PiAtLS0g YS9kcml2ZXJzL2dwdS9kcm0veGVuL0tjb25maWcKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3hl bi9LY29uZmlnCj4+IEBAIC0xNSwzICsxNSwxNiBAQCBjb25maWcgRFJNX1hFTl9GUk9OVEVORAo+ PiAgIAloZWxwCj4+ICAgCSAgQ2hvb3NlIHRoaXMgb3B0aW9uIGlmIHlvdSB3YW50IHRvIGVuYWJs ZSBhIHBhcmEtdmlydHVhbGl6ZWQKPj4gICAJICBmcm9udGVuZCBEUk0vS01TIGRyaXZlciBmb3Ig WGVuIGd1ZXN0IE9TZXMuCj4+ICsKPj4gK2NvbmZpZyBEUk1fWEVOX0ZST05URU5EX0NNQQo+PiAr CWJvb2wgIlVzZSBEUk0gQ01BIHRvIGFsbG9jYXRlIGR1bWIgYnVmZmVycyIKPj4gKwlkZXBlbmRz IG9uIERSTV9YRU5fRlJPTlRFTkQKPj4gKwlzZWxlY3QgRFJNX0tNU19DTUFfSEVMUEVSCj4+ICsJ c2VsZWN0IERSTV9HRU1fQ01BX0hFTFBFUgo+PiArCWhlbHAKPj4gKwkgIFVzZSBEUk0gQ01BIGhl bHBlcnMgdG8gYWxsb2NhdGUgZGlzcGxheSBidWZmZXJzLgo+PiArCSAgVGhpcyBpcyB1c2VmdWwg Zm9yIHRoZSB1c2UtY2FzZXMgd2hlbiBndWVzdCBkcml2ZXIgbmVlZHMgdG8KPj4gKwkgIHNoYXJl IG9yIGV4cG9ydCBidWZmZXJzIHRvIG90aGVyIGRyaXZlcnMgd2hpY2ggb25seSBleHBlY3QKPj4g KwkgIGNvbnRpZ3VvdXMgYnVmZmVycy4KPj4gKwkgIE5vdGU6IGluIHRoaXMgbW9kZSBkcml2ZXIg Y2Fubm90IHVzZSBidWZmZXJzIGFsbG9jYXRlZAo+PiArCSAgYnkgdGhlIGJhY2tlbmQuCj4+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0veGVuL01ha2VmaWxlIGIvZHJpdmVycy9ncHUvZHJt L3hlbi9NYWtlZmlsZQo+PiBpbmRleCA0ZmNiMGRhMWE5YzUuLjEyMzc2ZWM3OGZiYyAxMDA2NDQK Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3hlbi9NYWtlZmlsZQo+PiArKysgYi9kcml2ZXJzL2dw dS9kcm0veGVuL01ha2VmaWxlCj4+IEBAIC04LDQgKzgsMTAgQEAgZHJtX3hlbl9mcm9udC1vYmpz IDo9IHhlbl9kcm1fZnJvbnQubyBcCj4+ICAgCQkgICAgICB4ZW5fZHJtX2Zyb250X3NoYnVmLm8g XAo+PiAgIAkJICAgICAgeGVuX2RybV9mcm9udF9jZmcubwo+PiAgIAo+PiAraWZlcSAoJChDT05G SUdfRFJNX1hFTl9GUk9OVEVORF9DTUEpLHkpCj4+ICsJZHJtX3hlbl9mcm9udC1vYmpzICs9IHhl bl9kcm1fZnJvbnRfZ2VtX2NtYS5vCj4+ICtlbHNlCj4+ICsJZHJtX3hlbl9mcm9udC1vYmpzICs9 IHhlbl9kcm1fZnJvbnRfZ2VtLm8KPj4gK2VuZGlmCj4+ICsKPj4gICBvYmotJChDT05GSUdfRFJN X1hFTl9GUk9OVEVORCkgKz0gZHJtX3hlbl9mcm9udC5vCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuaCBiL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2Ry bV9mcm9udC5oCj4+IGluZGV4IDllZDViZmIyNDhkMC4uYzZmNTJjODkyNDM0IDEwMDY0NAo+PiAt LS0gYS9kcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuaAo+PiArKysgYi9kcml2ZXJz L2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnQuaAo+PiBAQCAtMzQsNiArMzQsODAgQEAKPj4gICAK Pj4gICBzdHJ1Y3QgeGVuX2RybV9mcm9udF9kcm1fcGlwZWxpbmU7Cj4+ICAgCj4+ICsvKgo+PiAr ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioKPj4gKyAqIFBhcmEtdmlydHVhbGl6ZWQgRFJNL0tNUyBm cm9udGVuZCBkcml2ZXIKPj4gKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCj4+ICsgKiBUaGlzIGZy b250ZW5kIGRyaXZlciBpbXBsZW1lbnRzIFhlbiBwYXJhLXZpcnR1YWxpemVkIGRpc3BsYXkKPj4g KyAqIGFjY29yZGluZyB0byB0aGUgZGlzcGxheSBwcm90b2NvbCBkZXNjcmliZWQgYXQKPj4gKyAq IGluY2x1ZGUveGVuL2ludGVyZmFjZS9pby9kaXNwbGlmLmgKPj4gKyAqCj4+ICsgKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKgo+PiArICogRHJpdmVyIG1vZGVzIG9mIG9wZXJhdGlvbiBpbiB0ZXJtcyBv ZiBkaXNwbGF5IGJ1ZmZlcnMgdXNlZAo+PiArICoqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKPj4gKyAq IERlcGVuZGluZyBvbiB0aGUgcmVxdWlyZW1lbnRzIGZvciB0aGUgcGFyYS12aXJ0dWFsaXplZCBl bnZpcm9ubWVudCwgbmFtZWx5Cj4+ICsgKiByZXF1aXJlbWVudHMgZGljdGF0ZWQgYnkgdGhlIGFj Y29tcGFueWluZyBEUk0vKHYpR1BVIGRyaXZlcnMgcnVubmluZyBpbiBib3RoCj4+ICsgKiBob3N0 IGFuZCBndWVzdCBlbnZpcm9ubWVudHMsIG51bWJlciBvZiBvcGVyYXRpbmcgbW9kZXMgb2YgcGFy YS12aXJ0dWFsaXplZAo+PiArICogZGlzcGxheSBkcml2ZXIgYXJlIHN1cHBvcnRlZDoKPj4gKyAq ICAtIGRpc3BsYXkgYnVmZmVycyBjYW4gYmUgYWxsb2NhdGVkIGJ5IGVpdGhlciBmcm9udGVuZCBk cml2ZXIgb3IgYmFja2VuZAo+PiArICogIC0gZGlzcGxheSBidWZmZXJzIGNhbiBiZSBhbGxvY2F0 ZWQgdG8gYmUgY29udGlndW91cyBpbiBtZW1vcnkgb3Igbm90Cj4+ICsgKgo+PiArICogTm90ZSEg RnJvbnRlbmQgZHJpdmVyIGl0c2VsZiBoYXMgbm8gZGVwZW5kZW5jeSBvbiBjb250aWd1b3VzIG1l bW9yeSBmb3IKPj4gKyAqICAgICAgIGl0cyBvcGVyYXRpb24uCj4+ICsgKgo+PiArICoqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioKPj4gKyAqIDEuIEJ1ZmZlcnMgYWxsb2NhdGVkIGJ5IHRoZSBmcm9udGVu ZCBkcml2ZXIuCj4+ICsgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgo+PiArICoKPj4gKyAqIFRoZSBi ZWxvdyBtb2RlcyBvZiBvcGVyYXRpb24gYXJlIGNvbmZpZ3VyZWQgYXQgY29tcGlsZS10aW1lIHZp YQo+PiArICogZnJvbnRlbmQgZHJpdmVyJ3Mga2VybmVsIGNvbmZpZ3VyYXRpb24uCj4+ICsgKgo+ PiArICogMS4xLiBGcm9udCBkcml2ZXIgY29uZmlndXJlZCB0byB1c2UgR0VNIENNQSBoZWxwZXJz Cj4+ICsgKiAgICAgIFRoaXMgdXNlLWNhc2UgaXMgdXNlZnVsIHdoZW4gdXNlZCB3aXRoIGFjY29t cGFueWluZyBEUk0vdkdQVSBkcml2ZXIgaW4KPj4gKyAqICAgICAgZ3Vlc3QgZG9tYWluIHdoaWNo IHdhcyBkZXNpZ25lZCB0byBvbmx5IHdvcmsgd2l0aCBjb250aWd1b3VzIGJ1ZmZlcnMsCj4+ICsg KiAgICAgIGUuZy4gRFJNIGRyaXZlciBiYXNlZCBvbiBHRU0gQ01BIGhlbHBlcnM6IHN1Y2ggZHJp dmVycyBjYW4gb25seSBpbXBvcnQKPj4gKyAqICAgICAgY29udGlndW91cyBQUklNRSBidWZmZXJz LCB0aHVzIHJlcXVpcmluZyBmcm9udGVuZCBkcml2ZXIgdG8gcHJvdmlkZQo+PiArICogICAgICBz dWNoLiBJbiBvcmRlciB0byBpbXBsZW1lbnQgdGhpcyBtb2RlIG9mIG9wZXJhdGlvbiBwYXJhLXZp cnR1YWxpemVkCj4+ICsgKiAgICAgIGZyb250ZW5kIGRyaXZlciBjYW4gYmUgY29uZmlndXJlZCB0 byB1c2UgR0VNIENNQSBoZWxwZXJzLgo+PiArICoKPj4gKyAqIDEuMi4gRnJvbnQgZHJpdmVyIGRv ZXNuJ3QgdXNlIEdFTSBDTUEKPj4gKyAqICAgICAgSWYgYWNjb21wYW55aW5nIGRyaXZlcnMgY2Fu IGNvcGUgd2l0aCBub24tY29udGlndW91cyBtZW1vcnkgdGhlbiwgdG8KPj4gKyAqICAgICAgbG93 ZXIgcHJlc3N1cmUgb24gQ01BIHN1YnN5c3RlbSBvZiB0aGUga2VybmVsLCBkcml2ZXIgY2FuIGFs bG9jYXRlCj4+ICsgKiAgICAgIGJ1ZmZlcnMgZnJvbSBzeXN0ZW0gbWVtb3J5Lgo+PiArICoKPj4g KyAqIE5vdGUhIElmIHVzZWQgd2l0aCBhY2NvbXBhbnlpbmcgRFJNLyh2KUdQVSBkcml2ZXJzIHRo aXMgbW9kZSBvZiBvcGVyYXRpb24KPj4gKyAqICAgbWF5IHJlcXVpcmUgSU9NTVUgc3VwcG9ydCBv biB0aGUgcGxhdGZvcm0sIHNvIGFjY29tcGFueWluZyBEUk0vdkdQVQo+PiArICogICBoYXJkd2Fy ZSBjYW4gc3RpbGwgcmVhY2ggZGlzcGxheSBidWZmZXIgbWVtb3J5IHdoaWxlIGltcG9ydGluZyBQ UklNRQo+PiArICogICBidWZmZXJzIGZyb20gdGhlIGZyb250ZW5kIGRyaXZlci4KPj4gKyAqCj4+ ICsgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKgo+PiArICogMi4gQnVmZmVycyBhbGxvY2F0ZWQgYnkg dGhlIGJhY2tlbmQKPj4gKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCj4+ICsgKgo+PiArICogVGhp cyBtb2RlIG9mIG9wZXJhdGlvbiBpcyBydW4tdGltZSBjb25maWd1cmVkIHZpYSBndWVzdCBkb21h aW4gY29uZmlndXJhdGlvbgo+PiArICogdGhyb3VnaCBYZW5TdG9yZSBlbnRyaWVzLgo+PiArICoK Pj4gKyAqIEZvciBzeXN0ZW1zIHdoaWNoIGRvIG5vdCBwcm92aWRlIElPTU1VIHN1cHBvcnQsIGJ1 dCBoYXZpbmcgc3BlY2lmaWMKPj4gKyAqIHJlcXVpcmVtZW50cyBmb3IgZGlzcGxheSBidWZmZXJz IGl0IGlzIHBvc3NpYmxlIHRvIGFsbG9jYXRlIHN1Y2ggYnVmZmVycwo+PiArICogYXQgYmFja2Vu ZCBzaWRlIGFuZCBzaGFyZSB0aG9zZSB3aXRoIHRoZSBmcm9udGVuZC4KPj4gKyAqIEZvciBleGFt cGxlLCBpZiBob3N0IGRvbWFpbiBpcyAxOjEgbWFwcGVkIGFuZCBoYXMgRFJNL0dQVSBoYXJkd2Fy ZSBleHBlY3RpbmcKPj4gKyAqIHBoeXNpY2FsbHkgY29udGlndW91cyBtZW1vcnksIHRoaXMgYWxs b3dzIGltcGxlbWVudGluZyB6ZXJvLWNvcHlpbmcKPj4gKyAqIHVzZS1jYXNlcy4KPj4gKyAqCj4+ ICsgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKgo+PiArICogRHJpdmVyIGxpbWl0YXRpb25zCj4+ICsg KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKgo+PiArICogMS4gQ29uZmlndXJhdGlvbiBvcHRpb25zIDEu MSAoY29udGlndW91cyBkaXNwbGF5IGJ1ZmZlcnMpIGFuZCAyIChiYWNrZW5kCj4+ICsgKiAgICBh bGxvY2F0ZWQgYnVmZmVycykgYXJlIG5vdCBzdXBwb3J0ZWQgYXQgdGhlIHNhbWUgdGltZS4KPj4g KyAqCj4+ICsgKiAyLiBPbmx5IHByaW1hcnkgcGxhbmUgd2l0aG91dCBhZGRpdGlvbmFsIHByb3Bl cnRpZXMgaXMgc3VwcG9ydGVkLgo+PiArICoKPj4gKyAqIDMuIE9ubHkgb25lIHZpZGVvIG1vZGUg c3VwcG9ydGVkIHdoaWNoIGlzIGNvbmZpZ3VyZWQgdmlhIFhlblN0b3JlLgo+PiArICoKPj4gKyAq IDQuIEFsbCBDUlRDcyBvcGVyYXRlIGF0IGZpeGVkIGZyZXF1ZW5jeSBvZiA2MEh6Lgo+PiArICoK Pj4gKyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKioqKioqKioqKiovCj4gU2luY2UgeW91J3ZlIHR5cGVkIHRoaXMgYWxs IHVwLCBwbHMgY29udmVydCBpdCB0byBrZXJuZWwtZG9jIGFuZCBwdWxsIGl0Cj4gaW50byBhIHhl bi1mcm9udC5yc3QgZHJpdmVyIHNlY3Rpb24gaW4gRG9jdW1lbnRhdGlvbi9ncHUvIFRoZXJlJ3Mg YSBmZXcKPiBleGFtcGxlcyBmb3IgaTkxNSBhbmQgdmM0IGFscmVhZHkuCkRvIHlvdSBtZWFuIHRv IG1vdmUgb3IgdG8ga2VlcCBpbiB0aGUgZHJpdmVyIGFuZCBhZGQgaW4gdGhlCkRvY3VtZW50YXRp b24/IEkgd291bGQgcHJlZmVyIHRvIG1vdmUgdG8gaGF2ZSB0aGUgZGVzY3JpcHRpb24KYXQgc2lu Z2xlIHBsYWNlLgo+Cj4+ICsKPj4gICBzdHJ1Y3QgeGVuX2RybV9mcm9udF9vcHMgewo+PiAgIAlp bnQgKCptb2RlX3NldCkoc3RydWN0IHhlbl9kcm1fZnJvbnRfZHJtX3BpcGVsaW5lICpwaXBlbGlu ZSwKPj4gICAJCQl1aW50MzJfdCB4LCB1aW50MzJfdCB5LCB1aW50MzJfdCB3aWR0aCwgdWludDMy X3QgaGVpZ2h0LAo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zy b250X2Rydi5jIGIvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250X2Rydi5jCj4+IGlu ZGV4IGU4ODYyZDI2YmEyNy4uMzVlN2U5Y2RhOWQxIDEwMDY0NAo+PiAtLS0gYS9kcml2ZXJzL2dw dS9kcm0veGVuL3hlbl9kcm1fZnJvbnRfZHJ2LmMKPj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3hl bi94ZW5fZHJtX2Zyb250X2Rydi5jCj4+IEBAIC0yMywxMiArMjMsNTggQEAKPj4gICAjaW5jbHVk ZSAieGVuX2RybV9mcm9udC5oIgo+PiAgICNpbmNsdWRlICJ4ZW5fZHJtX2Zyb250X2NmZy5oIgo+ PiAgICNpbmNsdWRlICJ4ZW5fZHJtX2Zyb250X2Rydi5oIgo+PiArI2luY2x1ZGUgInhlbl9kcm1f ZnJvbnRfZ2VtLmgiCj4+ICAgI2luY2x1ZGUgInhlbl9kcm1fZnJvbnRfa21zLmgiCj4+ICAgCj4+ ICAgc3RhdGljIGludCBkdW1iX2NyZWF0ZShzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHAsCj4+ICAgCQlz dHJ1Y3QgZHJtX2RldmljZSAqZGV2LCBzdHJ1Y3QgZHJtX21vZGVfY3JlYXRlX2R1bWIgKmFyZ3Mp Cj4+ICAgewo+PiAtCXJldHVybiAtRUlOVkFMOwo+PiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2Ry bV9pbmZvICpkcm1faW5mbyA9IGRldi0+ZGV2X3ByaXZhdGU7Cj4+ICsJc3RydWN0IGRybV9nZW1f b2JqZWN0ICpvYmo7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCXJldCA9IGRybV9pbmZvLT5nZW1f b3BzLT5kdW1iX2NyZWF0ZShmaWxwLCBkZXYsIGFyZ3MpOwo+PiArCWlmIChyZXQpCj4+ICsJCWdv dG8gZmFpbDsKPj4gKwo+PiArCW9iaiA9IGRybV9nZW1fb2JqZWN0X2xvb2t1cChmaWxwLCBhcmdz LT5oYW5kbGUpOwo+PiArCWlmICghb2JqKSB7Cj4+ICsJCXJldCA9IC1FTk9FTlQ7Cj4+ICsJCWdv dG8gZmFpbF9kZXN0cm95Owo+PiArCX0KPj4gKwo+PiArCWRybV9nZW1fb2JqZWN0X3VucmVmZXJl bmNlX3VubG9ja2VkKG9iaik7Cj4+ICsKPj4gKwkvKgo+PiArCSAqIEluIGNhc2Ugb2YgQ09ORklH X0RSTV9YRU5fRlJPTlRFTkRfQ01BIGdlbV9vYmogaXMgY29uc3RydWN0ZWQKPj4gKwkgKiB2aWEg RFJNIENNQSBoZWxwZXJzIGFuZCBkb2Vzbid0IGhhdmUgLT5wYWdlcyBhbGxvY2F0ZWQKPj4gKwkg KiAoeGVuZHJtX2dlbV9nZXRfcGFnZXMgd2lsbCByZXR1cm4gTlVMTCksIGJ1dCBpbnN0ZWFkIGNh biBwcm92aWRlCj4+ICsJICogc2cgdGFibGUKPj4gKwkgKi8KPiBNeSByZWNvbW1lbmRhdGlvbiBp cyB0byB1c2UgYW4gc2cgdGFibGUgZm9yIGV2ZXJ5dGhpbmcgaWYgeW91IGRlYWwgd2l0aAo+IG1p eGVkIG9iamVjdHMgKENNQSwgc3BlY2lhbCBibG9ja3MgMToxIG1hcHBlZCBmcm9tIGhvc3QsIG5v cm1hbCBwYWdlcykuCj4gVGhhdCBhdm9pZHMgdGhlIGNvbnN0YW50IGdldF9wYWdlcyB2cy4gZ2V0 X3NndCBkaWZmZXJlbmNlcy4gRm9yIGV4YW1wbGVzCj4gc2VlIGhvdyBlLmcuIGk5MTUgaGFuZGxl cyB0aGUgdmFyaW91cyBnZW0gb2JqZWN0IGJhY2tlbmRzLgpJbmRlZWQsIEkgdHJpZWQgdG8gZG8g dGhhdCB0aGlzIHdheSBiZWZvcmUsIGUuZy4gaGF2ZSBhbGwgc2d0IGJhc2VkLgpCdXQgYXQgdGhl IGVuZCBvZiB0aGUgZGF5IFhlbiBzaGFyZWQgYnVmZmVyIGNvZGUgaW4gdGhlIGRyaXZlciB3b3Jr cwp3aXRoIHBhZ2VzIChYZW4gQVBJIGlzIHBhZ2UgYmFzZWQgdGhlcmUpLCBzbyBzZ3QgdGhlbiB3 aWxsIGFueXdheSBuZWVkCnRvIGJlIGNvbnZlcnRlZCBpbnRvIHBhZ2UgYXJyYXkuCkZvciB0aGF0 IHJlYXNvbiBJIHByZWZlciB0byB3b3JrIHdpdGggcGFnZXMgZnJvbSB0aGUgYmVnaW5uaW5nLCBu b3Qgc2d0LgpBcyB0byBjb25zdGFudCBnZXRfcGFnZXMgZXRjLiAtIHRoaXMgaXMgdGhlIG9ubHkg ZXhwZWN0ZWQgcGxhY2UgaW4gdGhlCmRyaXZlciBmb3IgdGhhdCwgc28gdGhlIF9mcm9tX3NndC9f ZnJvbV9wYWdlcyBBUEkgaXMgb25seSB1c2VkIGhlcmUuCgo+Cj4+ICsJaWYgKGRybV9pbmZvLT5n ZW1fb3BzLT5nZXRfcGFnZXMob2JqKSkKPj4gKwkJcmV0ID0gZHJtX2luZm8tPmZyb250X29wcy0+ ZGJ1Zl9jcmVhdGVfZnJvbV9wYWdlcygKPj4gKwkJCQlkcm1faW5mby0+ZnJvbnRfaW5mbywKPj4g KwkJCQl4ZW5fZHJtX2Zyb250X2RidWZfdG9fY29va2llKG9iaiksCj4+ICsJCQkJYXJncy0+d2lk dGgsIGFyZ3MtPmhlaWdodCwgYXJncy0+YnBwLAo+PiArCQkJCWFyZ3MtPnNpemUsCj4+ICsJCQkJ ZHJtX2luZm8tPmdlbV9vcHMtPmdldF9wYWdlcyhvYmopKTsKPj4gKwllbHNlCj4+ICsJCXJldCA9 IGRybV9pbmZvLT5mcm9udF9vcHMtPmRidWZfY3JlYXRlX2Zyb21fc2d0KAo+PiArCQkJCWRybV9p bmZvLT5mcm9udF9pbmZvLAo+PiArCQkJCXhlbl9kcm1fZnJvbnRfZGJ1Zl90b19jb29raWUob2Jq KSwKPj4gKwkJCQlhcmdzLT53aWR0aCwgYXJncy0+aGVpZ2h0LCBhcmdzLT5icHAsCj4+ICsJCQkJ YXJncy0+c2l6ZSwKPj4gKwkJCQlkcm1faW5mby0+Z2VtX29wcy0+cHJpbWVfZ2V0X3NnX3RhYmxl KG9iaikpOwo+PiArCWlmIChyZXQpCj4+ICsJCWdvdG8gZmFpbF9kZXN0cm95Owo+PiArCj4+ICsJ cmV0dXJuIDA7Cj4+ICsKPj4gK2ZhaWxfZGVzdHJveToKPj4gKwlkcm1fZ2VtX2R1bWJfZGVzdHJv eShmaWxwLCBkZXYsIGFyZ3MtPmhhbmRsZSk7Cj4+ICtmYWlsOgo+PiArCURSTV9FUlJPUigiRmFp bGVkIHRvIGNyZWF0ZSBkdW1iIGJ1ZmZlcjogJWRcbiIsIHJldCk7Cj4+ICsJcmV0dXJuIHJldDsK Pj4gICB9Cj4+ICAgCj4+ICAgc3RhdGljIHZvaWQgZnJlZV9vYmplY3Qoc3RydWN0IGRybV9nZW1f b2JqZWN0ICpvYmopCj4+IEBAIC0zNyw2ICs4Myw3IEBAIHN0YXRpYyB2b2lkIGZyZWVfb2JqZWN0 KHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKQo+PiAgIAo+PiAgIAlkcm1faW5mby0+ZnJvbnRf b3BzLT5kYnVmX2Rlc3Ryb3koZHJtX2luZm8tPmZyb250X2luZm8sCj4+ICAgCQkJeGVuX2RybV9m cm9udF9kYnVmX3RvX2Nvb2tpZShvYmopKTsKPj4gKwlkcm1faW5mby0+Z2VtX29wcy0+ZnJlZV9v YmplY3RfdW5sb2NrZWQob2JqKTsKPj4gICB9Cj4+ICAgCj4+ICAgc3RhdGljIHZvaWQgb25fZnJh bWVfZG9uZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LAo+PiBAQCAtNjAsMzIgKzEwNyw1 MiBAQCBzdGF0aWMgdm9pZCBsYXN0Y2xvc2Uoc3RydWN0IGRybV9kZXZpY2UgKmRldikKPj4gICAK Pj4gICBzdGF0aWMgaW50IGdlbV9tbWFwKHN0cnVjdCBmaWxlICpmaWxwLCBzdHJ1Y3Qgdm1fYXJl YV9zdHJ1Y3QgKnZtYSkKPj4gICB7Cj4+IC0JcmV0dXJuIC1FSU5WQUw7Cj4+ICsJc3RydWN0IGRy bV9maWxlICpmaWxlX3ByaXYgPSBmaWxwLT5wcml2YXRlX2RhdGE7Cj4+ICsJc3RydWN0IGRybV9k ZXZpY2UgKmRldiA9IGZpbGVfcHJpdi0+bWlub3ItPmRldjsKPj4gKwlzdHJ1Y3QgeGVuX2RybV9m cm9udF9kcm1faW5mbyAqZHJtX2luZm8gPSBkZXYtPmRldl9wcml2YXRlOwo+PiArCj4+ICsJcmV0 dXJuIGRybV9pbmZvLT5nZW1fb3BzLT5tbWFwKGZpbHAsIHZtYSk7Cj4gVWgsIHNvIDEgbWlkbGF5 ZXIgZm9yIHRoZSBrbXMgc3R1ZmYgYW5kIGFub3RoZXIgbWlkbGF5ZXIgZm9yIHRoZSBnZW0KPiBz dHVmZi4gVGhhdCdzIHdheSB0b28gbXVjaCBpbmRpcmVjdGlvbi4KSWYgYnkgS01TIHlvdSBtZWFu IGZyb250X29wcyB0aGVuIC0xOiBJIHdpbGwgcmVtb3ZlIGZyb250X29wcy4KQXMgdG8gZ2VtX29w cywgcGxlYXNlIHNlZSBiZWxvdwo+PiAgIH0KPj4gICAKPj4gICBzdGF0aWMgc3RydWN0IHNnX3Rh YmxlICpwcmltZV9nZXRfc2dfdGFibGUoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopCj4+ICAg ewo+PiAtCXJldHVybiBOVUxMOwo+PiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2RybV9pbmZvICpk cm1faW5mbzsKPj4gKwo+PiArCWRybV9pbmZvID0gb2JqLT5kZXYtPmRldl9wcml2YXRlOwo+PiAr CXJldHVybiBkcm1faW5mby0+Z2VtX29wcy0+cHJpbWVfZ2V0X3NnX3RhYmxlKG9iaik7Cj4+ICAg fQo+PiAgIAo+PiAgIHN0YXRpYyBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKnByaW1lX2ltcG9ydF9z Z190YWJsZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+PiAgIAkJc3RydWN0IGRtYV9idWZfYXR0 YWNobWVudCAqYXR0YWNoLCBzdHJ1Y3Qgc2dfdGFibGUgKnNndCkKPj4gICB7Cj4+IC0JcmV0dXJu IE5VTEw7Cj4+ICsJc3RydWN0IHhlbl9kcm1fZnJvbnRfZHJtX2luZm8gKmRybV9pbmZvOwo+PiAr Cj4+ICsJZHJtX2luZm8gPSBkZXYtPmRldl9wcml2YXRlOwo+PiArCXJldHVybiBkcm1faW5mby0+ Z2VtX29wcy0+cHJpbWVfaW1wb3J0X3NnX3RhYmxlKGRldiwgYXR0YWNoLCBzZ3QpOwo+PiAgIH0K Pj4gICAKPj4gICBzdGF0aWMgdm9pZCAqcHJpbWVfdm1hcChzdHJ1Y3QgZHJtX2dlbV9vYmplY3Qg Km9iaikKPj4gICB7Cj4+IC0JcmV0dXJuIE5VTEw7Cj4+ICsJc3RydWN0IHhlbl9kcm1fZnJvbnRf ZHJtX2luZm8gKmRybV9pbmZvOwo+PiArCj4+ICsJZHJtX2luZm8gPSBvYmotPmRldi0+ZGV2X3By aXZhdGU7Cj4+ICsJcmV0dXJuIGRybV9pbmZvLT5nZW1fb3BzLT5wcmltZV92bWFwKG9iaik7Cj4+ ICAgfQo+PiAgIAo+PiAgIHN0YXRpYyB2b2lkIHByaW1lX3Z1bm1hcChzdHJ1Y3QgZHJtX2dlbV9v YmplY3QgKm9iaiwgdm9pZCAqdmFkZHIpCj4+ICAgewo+PiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250 X2RybV9pbmZvICpkcm1faW5mbzsKPj4gKwo+PiArCWRybV9pbmZvID0gb2JqLT5kZXYtPmRldl9w cml2YXRlOwo+PiArCWRybV9pbmZvLT5nZW1fb3BzLT5wcmltZV92dW5tYXAob2JqLCB2YWRkcik7 Cj4+ICAgfQo+PiAgIAo+PiAgIHN0YXRpYyBpbnQgcHJpbWVfbW1hcChzdHJ1Y3QgZHJtX2dlbV9v YmplY3QgKm9iaiwgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpCj4+ICAgewo+PiAtCXJldHVy biAtRUlOVkFMOwo+PiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2RybV9pbmZvICpkcm1faW5mbzsK Pj4gKwo+PiArCWRybV9pbmZvID0gb2JqLT5kZXYtPmRldl9wcml2YXRlOwo+PiArCXJldHVybiBk cm1faW5mby0+Z2VtX29wcy0+cHJpbWVfbW1hcChvYmosIHZtYSk7Cj4+ICAgfQo+PiAgIAo+PiAg IHN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHhlbmRybV9mb3BzID0gewo+PiBA QCAtMTQ3LDYgKzIxNCw3IEBAIGludCB4ZW5fZHJtX2Zyb250X2Rydl9wcm9iZShzdHJ1Y3QgcGxh dGZvcm1fZGV2aWNlICpwZGV2LAo+PiAgIAo+PiAgIAlkcm1faW5mby0+ZnJvbnRfb3BzID0gZnJv bnRfb3BzOwo+PiAgIAlkcm1faW5mby0+ZnJvbnRfb3BzLT5vbl9mcmFtZV9kb25lID0gb25fZnJh bWVfZG9uZTsKPj4gKwlkcm1faW5mby0+Z2VtX29wcyA9IHhlbl9kcm1fZnJvbnRfZ2VtX2dldF9v cHMoKTsKPj4gICAJZHJtX2luZm8tPmZyb250X2luZm8gPSBjZmctPmZyb250X2luZm87Cj4+ICAg Cj4+ICAgCWRldiA9IGRybV9kZXZfYWxsb2MoJnhlbl9kcm1fZHJpdmVyLCAmcGRldi0+ZGV2KTsK Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV9mcm9udF9kcnYuaCBi L2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV9mcm9udF9kcnYuaAo+PiBpbmRleCA1NjMzMThi MTlmMzQuLjM0MjI4ZWI4NjI1NSAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3hlbi94 ZW5fZHJtX2Zyb250X2Rydi5oCj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV9m cm9udF9kcnYuaAo+PiBAQCAtNDMsNiArNDMsNyBAQCBzdHJ1Y3QgeGVuX2RybV9mcm9udF9kcm1f cGlwZWxpbmUgewo+PiAgIHN0cnVjdCB4ZW5fZHJtX2Zyb250X2RybV9pbmZvIHsKPj4gICAJc3Ry dWN0IHhlbl9kcm1fZnJvbnRfaW5mbyAqZnJvbnRfaW5mbzsKPj4gICAJc3RydWN0IHhlbl9kcm1f ZnJvbnRfb3BzICpmcm9udF9vcHM7Cj4+ICsJY29uc3Qgc3RydWN0IHhlbl9kcm1fZnJvbnRfZ2Vt X29wcyAqZ2VtX29wczsKPj4gICAJc3RydWN0IGRybV9kZXZpY2UgKmRybV9kZXY7Cj4+ICAgCXN0 cnVjdCB4ZW5fZHJtX2Zyb250X2NmZyAqY2ZnOwo+PiAgIAo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVy cy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250X2dlbS5jIGIvZHJpdmVycy9ncHUvZHJtL3hlbi94 ZW5fZHJtX2Zyb250X2dlbS5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAw MDAwMDAwMC4uMzY3ZTA4ZjZhOWVmCj4+IC0tLSAvZGV2L251bGwKPj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250X2dlbS5jCj4+IEBAIC0wLDAgKzEsMzYwIEBACj4+ICsv Kgo+PiArICogIFhlbiBwYXJhLXZpcnR1YWwgRFJNIGRldmljZQo+PiArICoKPj4gKyAqICAgVGhp cyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9v ciBtb2RpZnkKPj4gKyAqICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQ dWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKPj4gKyAqICAgdGhlIEZyZWUgU29mdHdhcmUg Rm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKPj4gKyAqICAg KGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KPj4gKyAqCj4+ICsgKiAgIFRoaXMg cHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVs LAo+PiArICogICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1w bGllZCB3YXJyYW50eSBvZgo+PiArICogICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1Ig QSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCj4+ICsgKiAgIEdOVSBHZW5lcmFsIFB1Ymxp YyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCj4+ICsgKgo+PiArICogQ29weXJpZ2h0IChDKSAy MDE2LTIwMTggRVBBTSBTeXN0ZW1zIEluYy4KPj4gKyAqCj4+ICsgKiBBdXRob3I6IE9sZWtzYW5k ciBBbmRydXNoY2hlbmtvIDxvbGVrc2FuZHJfYW5kcnVzaGNoZW5rb0BlcGFtLmNvbT4KPj4gKyAq Lwo+PiArCj4+ICsjaW5jbHVkZSAieGVuX2RybV9mcm9udF9nZW0uaCIKPj4gKwo+PiArI2luY2x1 ZGUgPGRybS9kcm1QLmg+Cj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBlci5oPgo+PiAr I2luY2x1ZGUgPGRybS9kcm1fZmJfaGVscGVyLmg+Cj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9nZW0u aD4KPj4gKwo+PiArI2luY2x1ZGUgPGxpbnV4L2RtYS1idWYuaD4KPj4gKyNpbmNsdWRlIDxsaW51 eC9zY2F0dGVybGlzdC5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L3NobWVtX2ZzLmg+Cj4+ICsKPj4g KyNpbmNsdWRlIDx4ZW4vYmFsbG9vbi5oPgo+PiArCj4+ICsjaW5jbHVkZSAieGVuX2RybV9mcm9u dC5oIgo+PiArI2luY2x1ZGUgInhlbl9kcm1fZnJvbnRfZHJ2LmgiCj4+ICsjaW5jbHVkZSAieGVu X2RybV9mcm9udF9zaGJ1Zi5oIgo+PiArCj4+ICtzdHJ1Y3QgeGVuX2dlbV9vYmplY3Qgewo+PiAr CXN0cnVjdCBkcm1fZ2VtX29iamVjdCBiYXNlOwo+PiArCj4+ICsJc2l6ZV90IG51bV9wYWdlczsK Pj4gKwlzdHJ1Y3QgcGFnZSAqKnBhZ2VzOwo+PiArCj4+ICsJLyogc2V0IGZvciBidWZmZXJzIGFs bG9jYXRlZCBieSB0aGUgYmFja2VuZCAqLwo+PiArCWJvb2wgYmVfYWxsb2M7Cj4+ICsKPj4gKwkv KiB0aGlzIGlzIGZvciBpbXBvcnRlZCBQUklNRSBidWZmZXIgKi8KPj4gKwlzdHJ1Y3Qgc2dfdGFi bGUgKnNndF9pbXBvcnRlZDsKPj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IHhl bl9nZW1fb2JqZWN0ICp0b194ZW5fZ2VtX29iaigKPj4gKwkJc3RydWN0IGRybV9nZW1fb2JqZWN0 ICpnZW1fb2JqKQo+PiArewo+PiArCXJldHVybiBjb250YWluZXJfb2YoZ2VtX29iaiwgc3RydWN0 IHhlbl9nZW1fb2JqZWN0LCBiYXNlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBnZW1fYWxs b2NfcGFnZXNfYXJyYXkoc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqLAo+PiArCQlzaXpl X3QgYnVmX3NpemUpCj4+ICt7Cj4+ICsJeGVuX29iai0+bnVtX3BhZ2VzID0gRElWX1JPVU5EX1VQ KGJ1Zl9zaXplLCBQQUdFX1NJWkUpOwo+PiArCXhlbl9vYmotPnBhZ2VzID0ga3ZtYWxsb2NfYXJy YXkoeGVuX29iai0+bnVtX3BhZ2VzLAo+PiArCQkJc2l6ZW9mKHN0cnVjdCBwYWdlICopLCBHRlBf S0VSTkVMKTsKPj4gKwlyZXR1cm4geGVuX29iai0+cGFnZXMgPT0gTlVMTCA/IC1FTk9NRU0gOiAw Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBnZW1fZnJlZV9wYWdlc19hcnJheShzdHJ1Y3Qg eGVuX2dlbV9vYmplY3QgKnhlbl9vYmopCj4+ICt7Cj4+ICsJa3ZmcmVlKHhlbl9vYmotPnBhZ2Vz KTsKPj4gKwl4ZW5fb2JqLT5wYWdlcyA9IE5VTEw7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1 Y3QgeGVuX2dlbV9vYmplY3QgKmdlbV9jcmVhdGVfb2JqKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYs Cj4+ICsJc2l6ZV90IHNpemUpCj4+ICt7Cj4+ICsJc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5f b2JqOwo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwl4ZW5fb2JqID0ga3phbGxvYyhzaXplb2YoKnhl bl9vYmopLCBHRlBfS0VSTkVMKTsKPj4gKwlpZiAoIXhlbl9vYmopCj4+ICsJCXJldHVybiBFUlJf UFRSKC1FTk9NRU0pOwo+PiArCj4+ICsJcmV0ID0gZHJtX2dlbV9vYmplY3RfaW5pdChkZXYsICZ4 ZW5fb2JqLT5iYXNlLCBzaXplKTsKPj4gKwlpZiAocmV0IDwgMCkgewo+PiArCQlrZnJlZSh4ZW5f b2JqKTsKPj4gKwkJcmV0dXJuIEVSUl9QVFIocmV0KTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXR1cm4g eGVuX29iajsKPj4gK30KPj4gKwo+PiArc3RhdGljIHN0cnVjdCB4ZW5fZ2VtX29iamVjdCAqZ2Vt X2NyZWF0ZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LCBzaXplX3Qgc2l6ZSkKPj4gK3sKPj4gKwlz dHJ1Y3QgeGVuX2RybV9mcm9udF9kcm1faW5mbyAqZHJtX2luZm8gPSBkZXYtPmRldl9wcml2YXRl Owo+PiArCXN0cnVjdCB4ZW5fZ2VtX29iamVjdCAqeGVuX29iajsKPj4gKwlpbnQgcmV0Owo+PiAr Cj4+ICsJc2l6ZSA9IHJvdW5kX3VwKHNpemUsIFBBR0VfU0laRSk7Cj4+ICsJeGVuX29iaiA9IGdl bV9jcmVhdGVfb2JqKGRldiwgc2l6ZSk7Cj4+ICsJaWYgKElTX0VSUl9PUl9OVUxMKHhlbl9vYmop KQo+PiArCQlyZXR1cm4geGVuX29iajsKPj4gKwo+PiArCWlmIChkcm1faW5mby0+Y2ZnLT5iZV9h bGxvYykgewo+PiArCQkvKgo+PiArCQkgKiBiYWNrZW5kIHdpbGwgYWxsb2NhdGUgc3BhY2UgZm9y IHRoaXMgYnVmZmVyLCBzbwo+PiArCQkgKiBvbmx5IGFsbG9jYXRlIGFycmF5IG9mIHBvaW50ZXJz IHRvIHBhZ2VzCj4+ICsJCSAqLwo+PiArCQl4ZW5fb2JqLT5iZV9hbGxvYyA9IHRydWU7Cj4+ICsJ CXJldCA9IGdlbV9hbGxvY19wYWdlc19hcnJheSh4ZW5fb2JqLCBzaXplKTsKPj4gKwkJaWYgKHJl dCA8IDApIHsKPj4gKwkJCWdlbV9mcmVlX3BhZ2VzX2FycmF5KHhlbl9vYmopOwo+PiArCQkJZ290 byBmYWlsOwo+PiArCQl9Cj4+ICsKPj4gKwkJcmV0ID0gYWxsb2NfeGVuYmFsbG9vbmVkX3BhZ2Vz KHhlbl9vYmotPm51bV9wYWdlcywKPj4gKwkJCQl4ZW5fb2JqLT5wYWdlcyk7Cj4+ICsJCWlmIChy ZXQgPCAwKSB7Cj4+ICsJCQlEUk1fRVJST1IoIkNhbm5vdCBhbGxvY2F0ZSAlenUgYmFsbG9vbmVk IHBhZ2VzOiAlZFxuIiwKPj4gKwkJCQkJeGVuX29iai0+bnVtX3BhZ2VzLCByZXQpOwo+PiArCQkJ Z290byBmYWlsOwo+PiArCQl9Cj4+ICsKPj4gKwkJcmV0dXJuIHhlbl9vYmo7Cj4+ICsJfQo+PiAr CS8qCj4+ICsJICogbmVlZCB0byBhbGxvY2F0ZSBiYWNraW5nIHBhZ2VzIG5vdywgc28gd2UgY2Fu IHNoYXJlIHRob3NlCj4+ICsJICogd2l0aCB0aGUgYmFja2VuZAo+PiArCSAqLwo+PiArCXhlbl9v YmotPm51bV9wYWdlcyA9IERJVl9ST1VORF9VUChzaXplLCBQQUdFX1NJWkUpOwo+PiArCXhlbl9v YmotPnBhZ2VzID0gZHJtX2dlbV9nZXRfcGFnZXMoJnhlbl9vYmotPmJhc2UpOwo+PiArCWlmIChJ U19FUlJfT1JfTlVMTCh4ZW5fb2JqLT5wYWdlcykpIHsKPj4gKwkJcmV0ID0gUFRSX0VSUih4ZW5f b2JqLT5wYWdlcyk7Cj4+ICsJCXhlbl9vYmotPnBhZ2VzID0gTlVMTDsKPj4gKwkJZ290byBmYWls Owo+PiArCX0KPj4gKwo+PiArCXJldHVybiB4ZW5fb2JqOwo+PiArCj4+ICtmYWlsOgo+PiArCURS TV9FUlJPUigiRmFpbGVkIHRvIGFsbG9jYXRlIGJ1ZmZlciB3aXRoIHNpemUgJXp1XG4iLCBzaXpl KTsKPj4gKwlyZXR1cm4gRVJSX1BUUihyZXQpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgc3RydWN0 IHhlbl9nZW1fb2JqZWN0ICpnZW1fY3JlYXRlX3dpdGhfaGFuZGxlKHN0cnVjdCBkcm1fZmlsZSAq ZmlscCwKPj4gKwkJc3RydWN0IGRybV9kZXZpY2UgKmRldiwgc2l6ZV90IHNpemUsIHVpbnQzMl90 ICpoYW5kbGUpCj4+ICt7Cj4+ICsJc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqOwo+PiAr CXN0cnVjdCBkcm1fZ2VtX29iamVjdCAqZ2VtX29iajsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJ eGVuX29iaiA9IGdlbV9jcmVhdGUoZGV2LCBzaXplKTsKPj4gKwlpZiAoSVNfRVJSX09SX05VTEwo eGVuX29iaikpCj4+ICsJCXJldHVybiB4ZW5fb2JqOwo+PiArCj4+ICsJZ2VtX29iaiA9ICZ4ZW5f b2JqLT5iYXNlOwo+PiArCXJldCA9IGRybV9nZW1faGFuZGxlX2NyZWF0ZShmaWxwLCBnZW1fb2Jq LCBoYW5kbGUpOwo+PiArCS8qIGhhbmRsZSBob2xkcyB0aGUgcmVmZXJlbmNlICovCj4+ICsJZHJt X2dlbV9vYmplY3RfdW5yZWZlcmVuY2VfdW5sb2NrZWQoZ2VtX29iaik7Cj4+ICsJaWYgKHJldCA8 IDApCj4+ICsJCXJldHVybiBFUlJfUFRSKHJldCk7Cj4+ICsKPj4gKwlyZXR1cm4geGVuX29iajsK Pj4gK30KPj4gKwo+PiArc3RhdGljIGludCBnZW1fZHVtYl9jcmVhdGUoc3RydWN0IGRybV9maWxl ICpmaWxwLCBzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+PiArCQlzdHJ1Y3QgZHJtX21vZGVfY3Jl YXRlX2R1bWIgKmFyZ3MpCj4+ICt7Cj4+ICsJc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2Jq Owo+PiArCj4+ICsJYXJncy0+cGl0Y2ggPSBESVZfUk9VTkRfVVAoYXJncy0+d2lkdGggKiBhcmdz LT5icHAsIDgpOwo+PiArCWFyZ3MtPnNpemUgPSBhcmdzLT5waXRjaCAqIGFyZ3MtPmhlaWdodDsK Pj4gKwo+PiArCXhlbl9vYmogPSBnZW1fY3JlYXRlX3dpdGhfaGFuZGxlKGZpbHAsIGRldiwgYXJn cy0+c2l6ZSwgJmFyZ3MtPmhhbmRsZSk7Cj4+ICsJaWYgKElTX0VSUl9PUl9OVUxMKHhlbl9vYmop KQo+PiArCQlyZXR1cm4geGVuX29iaiA9PSBOVUxMID8gLUVOT01FTSA6IFBUUl9FUlIoeGVuX29i aik7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIHZvaWQgZ2VtX2Zy ZWVfb2JqZWN0KHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqZ2VtX29iaikKPj4gK3sKPj4gKwlzdHJ1 Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmogPSB0b194ZW5fZ2VtX29iaihnZW1fb2JqKTsKPj4g Kwo+PiArCWlmICh4ZW5fb2JqLT5iYXNlLmltcG9ydF9hdHRhY2gpIHsKPj4gKwkJZHJtX3ByaW1l X2dlbV9kZXN0cm95KCZ4ZW5fb2JqLT5iYXNlLCB4ZW5fb2JqLT5zZ3RfaW1wb3J0ZWQpOwo+PiAr CQlnZW1fZnJlZV9wYWdlc19hcnJheSh4ZW5fb2JqKTsKPj4gKwl9IGVsc2Ugewo+PiArCQlpZiAo eGVuX29iai0+cGFnZXMpIHsKPj4gKwkJCWlmICh4ZW5fb2JqLT5iZV9hbGxvYykgewo+PiArCQkJ CWZyZWVfeGVuYmFsbG9vbmVkX3BhZ2VzKHhlbl9vYmotPm51bV9wYWdlcywKPj4gKwkJCQkJCXhl bl9vYmotPnBhZ2VzKTsKPj4gKwkJCQlnZW1fZnJlZV9wYWdlc19hcnJheSh4ZW5fb2JqKTsKPj4g KwkJCX0gZWxzZQo+PiArCQkJCWRybV9nZW1fcHV0X3BhZ2VzKCZ4ZW5fb2JqLT5iYXNlLAo+PiAr CQkJCQkJeGVuX29iai0+cGFnZXMsIHRydWUsIGZhbHNlKTsKPj4gKwkJfQo+PiArCX0KPj4gKwlk cm1fZ2VtX29iamVjdF9yZWxlYXNlKGdlbV9vYmopOwo+PiArCWtmcmVlKHhlbl9vYmopOwo+PiAr fQo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHBhZ2UgKipnZW1fZ2V0X3BhZ2VzKHN0cnVjdCBkcm1f Z2VtX29iamVjdCAqZ2VtX29iaikKPj4gK3sKPj4gKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhl bl9vYmogPSB0b194ZW5fZ2VtX29iaihnZW1fb2JqKTsKPj4gKwo+PiArCXJldHVybiB4ZW5fb2Jq LT5wYWdlczsKPj4gK30KPj4gKwo+PiArc3RhdGljIHN0cnVjdCBzZ190YWJsZSAqZ2VtX2dldF9z Z190YWJsZShzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKmdlbV9vYmopCj4+ICt7Cj4+ICsJc3RydWN0 IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqID0gdG9feGVuX2dlbV9vYmooZ2VtX29iaik7Cj4+ICsK Pj4gKwlpZiAoIXhlbl9vYmotPnBhZ2VzKQo+PiArCQlyZXR1cm4gTlVMTDsKPj4gKwo+PiArCXJl dHVybiBkcm1fcHJpbWVfcGFnZXNfdG9fc2coeGVuX29iai0+cGFnZXMsIHhlbl9vYmotPm51bV9w YWdlcyk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKmdlbV9p bXBvcnRfc2dfdGFibGUoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gKwkJc3RydWN0IGRtYV9i dWZfYXR0YWNobWVudCAqYXR0YWNoLCBzdHJ1Y3Qgc2dfdGFibGUgKnNndCkKPj4gK3sKPj4gKwlz dHJ1Y3QgeGVuX2RybV9mcm9udF9kcm1faW5mbyAqZHJtX2luZm8gPSBkZXYtPmRldl9wcml2YXRl Owo+PiArCXN0cnVjdCB4ZW5fZ2VtX29iamVjdCAqeGVuX29iajsKPj4gKwlzaXplX3Qgc2l6ZTsK Pj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJc2l6ZSA9IGF0dGFjaC0+ZG1hYnVmLT5zaXplOwo+PiAr CXhlbl9vYmogPSBnZW1fY3JlYXRlX29iaihkZXYsIHNpemUpOwo+PiArCWlmIChJU19FUlJfT1Jf TlVMTCh4ZW5fb2JqKSkKPj4gKwkJcmV0dXJuIEVSUl9DQVNUKHhlbl9vYmopOwo+PiArCj4+ICsJ cmV0ID0gZ2VtX2FsbG9jX3BhZ2VzX2FycmF5KHhlbl9vYmosIHNpemUpOwo+PiArCWlmIChyZXQg PCAwKQo+PiArCQlyZXR1cm4gRVJSX1BUUihyZXQpOwo+PiArCj4+ICsJeGVuX29iai0+c2d0X2lt cG9ydGVkID0gc2d0Owo+PiArCj4+ICsJcmV0ID0gZHJtX3ByaW1lX3NnX3RvX3BhZ2VfYWRkcl9h cnJheXMoc2d0LCB4ZW5fb2JqLT5wYWdlcywKPj4gKwkJCU5VTEwsIHhlbl9vYmotPm51bV9wYWdl cyk7Cj4+ICsJaWYgKHJldCA8IDApCj4+ICsJCXJldHVybiBFUlJfUFRSKHJldCk7Cj4+ICsKPj4g KwkvKgo+PiArCSAqIE4uQi4gQWx0aG91Z2ggd2UgaGF2ZSBhbiBBUEkgdG8gY3JlYXRlIGRpc3Bs YXkgYnVmZmVyIGZyb20gc2d0Cj4+ICsJICogd2UgdXNlIHBhZ2VzIEFQSSwgYmVjYXVzZSB3ZSBz dGlsbCBuZWVkIHRob3NlIGZvciBHRU0gaGFuZGxpbmcsCj4+ICsJICogZS5nLiBmb3IgbWFwcGlu ZyBldGMuCj4+ICsJICovCj4+ICsJcmV0ID0gZHJtX2luZm8tPmZyb250X29wcy0+ZGJ1Zl9jcmVh dGVfZnJvbV9wYWdlcygKPj4gKwkJCWRybV9pbmZvLT5mcm9udF9pbmZvLAo+PiArCQkJeGVuX2Ry bV9mcm9udF9kYnVmX3RvX2Nvb2tpZSgmeGVuX29iai0+YmFzZSksCj4+ICsJCQkwLCAwLCAwLCBz aXplLCB4ZW5fb2JqLT5wYWdlcyk7Cj4+ICsJaWYgKHJldCA8IDApCj4+ICsJCXJldHVybiBFUlJf UFRSKHJldCk7Cj4+ICsKPj4gKwlEUk1fREVCVUcoIkltcG9ydGVkIGJ1ZmZlciBvZiBzaXplICV6 dSB3aXRoIG5lbnRzICV1XG4iLAo+PiArCQlzaXplLCBzZ3QtPm5lbnRzKTsKPj4gKwo+PiArCXJl dHVybiAmeGVuX29iai0+YmFzZTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBnZW1fbW1hcF9v Ymooc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqLAo+PiArCQlzdHJ1Y3Qgdm1fYXJlYV9z dHJ1Y3QgKnZtYSkKPj4gK3sKPj4gKwl1bnNpZ25lZCBsb25nIGFkZHIgPSB2bWEtPnZtX3N0YXJ0 Owo+PiArCWludCBpOwo+PiArCj4+ICsJLyoKPj4gKwkgKiBjbGVhciB0aGUgVk1fUEZOTUFQIGZs YWcgdGhhdCB3YXMgc2V0IGJ5IGRybV9nZW1fbW1hcCgpLCBhbmQgc2V0IHRoZQo+PiArCSAqIHZt X3Bnb2ZmICh1c2VkIGFzIGEgZmFrZSBidWZmZXIgb2Zmc2V0IGJ5IERSTSkgdG8gMCBhcyB3ZSB3 YW50IHRvIG1hcAo+PiArCSAqIHRoZSB3aG9sZSBidWZmZXIuCj4+ICsJICovCj4+ICsJdm1hLT52 bV9mbGFncyAmPSB+Vk1fUEZOTUFQOwo+PiArCXZtYS0+dm1fZmxhZ3MgfD0gVk1fTUlYRURNQVA7 Cj4+ICsJdm1hLT52bV9wZ29mZiA9IDA7Cj4+ICsJdm1hLT52bV9wYWdlX3Byb3QgPSBwZ3Byb3Rf d3JpdGVjb21iaW5lKHZtX2dldF9wYWdlX3Byb3Qodm1hLT52bV9mbGFncykpOwo+PiArCj4+ICsJ LyoKPj4gKwkgKiB2bV9vcGVyYXRpb25zX3N0cnVjdC5mYXVsdCBoYW5kbGVyIHdpbGwgYmUgY2Fs bGVkIGlmIENQVSBhY2Nlc3MKPj4gKwkgKiB0byBWTSBpcyBoZXJlLiBGb3IgR1BVcyB0aGlzIGlz bid0IHRoZSBjYXNlLCBiZWNhdXNlIENQVQo+PiArCSAqIGRvZXNuJ3QgdG91Y2ggdGhlIG1lbW9y eS4gSW5zZXJ0IHBhZ2VzIG5vdywgc28gYm90aCBDUFUgYW5kIEdQVSBhcmUKPj4gKwkgKiBoYXBw eS4KPj4gKwkgKiBGSVhNRTogYXMgd2UgaW5zZXJ0IGFsbCB0aGUgcGFnZXMgbm93IHRoZW4gbm8g LmZhdWx0IGhhbmRsZXIgbXVzdAo+PiArCSAqIGJlIGNhbGxlZCwgc28gZG9uJ3QgcHJvdmlkZSBv bmUKPj4gKwkgKi8KPj4gKwlmb3IgKGkgPSAwOyBpIDwgeGVuX29iai0+bnVtX3BhZ2VzOyBpKysp IHsKPj4gKwkJaW50IHJldDsKPj4gKwo+PiArCQlyZXQgPSB2bV9pbnNlcnRfcGFnZSh2bWEsIGFk ZHIsIHhlbl9vYmotPnBhZ2VzW2ldKTsKPj4gKwkJaWYgKHJldCA8IDApIHsKPj4gKwkJCURSTV9F UlJPUigiRmFpbGVkIHRvIGluc2VydCBwYWdlcyBpbnRvIHZtYTogJWRcbiIsIHJldCk7Cj4+ICsJ CQlyZXR1cm4gcmV0Owo+PiArCQl9Cj4+ICsKPj4gKwkJYWRkciArPSBQQUdFX1NJWkU7Cj4+ICsJ fQo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGdlbV9tbWFwKHN0cnVj dCBmaWxlICpmaWxwLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKPj4gK3sKPj4gKwlzdHJ1 Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmo7Cj4+ICsJc3RydWN0IGRybV9nZW1fb2JqZWN0ICpn ZW1fb2JqOwo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwlyZXQgPSBkcm1fZ2VtX21tYXAoZmlscCwg dm1hKTsKPj4gKwlpZiAocmV0IDwgMCkKPj4gKwkJcmV0dXJuIHJldDsKPj4gKwo+PiArCWdlbV9v YmogPSB2bWEtPnZtX3ByaXZhdGVfZGF0YTsKPj4gKwl4ZW5fb2JqID0gdG9feGVuX2dlbV9vYmoo Z2VtX29iaik7Cj4+ICsJcmV0dXJuIGdlbV9tbWFwX29iaih4ZW5fb2JqLCB2bWEpOwo+PiArfQo+ PiArCj4+ICtzdGF0aWMgdm9pZCAqZ2VtX3ByaW1lX3ZtYXAoc3RydWN0IGRybV9nZW1fb2JqZWN0 ICpnZW1fb2JqKQo+PiArewo+PiArCXN0cnVjdCB4ZW5fZ2VtX29iamVjdCAqeGVuX29iaiA9IHRv X3hlbl9nZW1fb2JqKGdlbV9vYmopOwo+PiArCj4+ICsJaWYgKCF4ZW5fb2JqLT5wYWdlcykKPj4g KwkJcmV0dXJuIE5VTEw7Cj4+ICsKPj4gKwlyZXR1cm4gdm1hcCh4ZW5fb2JqLT5wYWdlcywgeGVu X29iai0+bnVtX3BhZ2VzLAo+PiArCQkJVk1fTUFQLCBwZ3Byb3Rfd3JpdGVjb21iaW5lKFBBR0Vf S0VSTkVMKSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGdlbV9wcmltZV92dW5tYXAoc3Ry dWN0IGRybV9nZW1fb2JqZWN0ICpnZW1fb2JqLCB2b2lkICp2YWRkcikKPj4gK3sKPj4gKwl2dW5t YXAodmFkZHIpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGdlbV9wcmltZV9tbWFwKHN0cnVj dCBkcm1fZ2VtX29iamVjdCAqZ2VtX29iaiwKPj4gKwlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZt YSkKPj4gK3sKPj4gKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmo7Cj4+ICsJaW50IHJl dDsKPj4gKwo+PiArCXJldCA9IGRybV9nZW1fbW1hcF9vYmooZ2VtX29iaiwgZ2VtX29iai0+c2l6 ZSwgdm1hKTsKPj4gKwlpZiAocmV0IDwgMCkKPj4gKwkJcmV0dXJuIHJldDsKPj4gKwo+PiArCXhl bl9vYmogPSB0b194ZW5fZ2VtX29iaihnZW1fb2JqKTsKPj4gKwlyZXR1cm4gZ2VtX21tYXBfb2Jq KHhlbl9vYmosIHZtYSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgeGVuX2Ry bV9mcm9udF9nZW1fb3BzIHhlbl9kcm1fZ2VtX29wcyA9IHsKPj4gKwkuZnJlZV9vYmplY3RfdW5s b2NrZWQgID0gZ2VtX2ZyZWVfb2JqZWN0LAo+PiArCS5wcmltZV9nZXRfc2dfdGFibGUgICAgPSBn ZW1fZ2V0X3NnX3RhYmxlLAo+PiArCS5wcmltZV9pbXBvcnRfc2dfdGFibGUgPSBnZW1faW1wb3J0 X3NnX3RhYmxlLAo+PiArCj4+ICsJLnByaW1lX3ZtYXAgICAgICAgICAgICA9IGdlbV9wcmltZV92 bWFwLAo+PiArCS5wcmltZV92dW5tYXAgICAgICAgICAgPSBnZW1fcHJpbWVfdnVubWFwLAo+PiAr CS5wcmltZV9tbWFwICAgICAgICAgICAgPSBnZW1fcHJpbWVfbW1hcCwKPj4gKwo+PiArCS5kdW1i X2NyZWF0ZSAgICAgICAgICAgPSBnZW1fZHVtYl9jcmVhdGUsCj4+ICsKPj4gKwkubW1hcCAgICAg ICAgICAgICAgICAgID0gZ2VtX21tYXAsCj4+ICsKPj4gKwkuZ2V0X3BhZ2VzICAgICAgICAgICAg ID0gZ2VtX2dldF9wYWdlcywKPj4gK307Cj4+ICsKPj4gK2NvbnN0IHN0cnVjdCB4ZW5fZHJtX2Zy b250X2dlbV9vcHMgKnhlbl9kcm1fZnJvbnRfZ2VtX2dldF9vcHModm9pZCkKPj4gK3sKPj4gKwly ZXR1cm4gJnhlbl9kcm1fZ2VtX29wczsKPj4gK30KPj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1 L2RybS94ZW4veGVuX2RybV9mcm9udF9nZW0uaCBiL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2Ry bV9mcm9udF9nZW0uaAo+PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+PiBpbmRleCAwMDAwMDAwMDAw MDAuLmQxZTE3MTFjYzNmYwo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2Ry bS94ZW4veGVuX2RybV9mcm9udF9nZW0uaAo+PiBAQCAtMCwwICsxLDQ2IEBACj4+ICsvKgo+PiAr ICogIFhlbiBwYXJhLXZpcnR1YWwgRFJNIGRldmljZQo+PiArICoKPj4gKyAqICAgVGhpcyBwcm9n cmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2Rp ZnkKPj4gKyAqICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMg TGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKPj4gKyAqICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRh dGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKPj4gKyAqICAgKGF0IHlv dXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KPj4gKyAqCj4+ICsgKiAgIFRoaXMgcHJvZ3Jh bSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAo+PiAr ICogICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3 YXJyYW50eSBvZgo+PiArICogICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJU SUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCj4+ICsgKiAgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNl bnNlIGZvciBtb3JlIGRldGFpbHMuCj4+ICsgKgo+PiArICogQ29weXJpZ2h0IChDKSAyMDE2LTIw MTggRVBBTSBTeXN0ZW1zIEluYy4KPj4gKyAqCj4+ICsgKiBBdXRob3I6IE9sZWtzYW5kciBBbmRy dXNoY2hlbmtvIDxvbGVrc2FuZHJfYW5kcnVzaGNoZW5rb0BlcGFtLmNvbT4KPj4gKyAqLwo+PiAr Cj4+ICsjaWZuZGVmIF9fWEVOX0RSTV9GUk9OVF9HRU1fSAo+PiArI2RlZmluZSBfX1hFTl9EUk1f RlJPTlRfR0VNX0gKPj4gKwo+PiArI2luY2x1ZGUgPGRybS9kcm1QLmg+Cj4+ICsKPj4gK3N0cnVj dCB4ZW5fZHJtX2Zyb250X2dlbV9vcHMgewo+PiArCXZvaWQgKCpmcmVlX29iamVjdF91bmxvY2tl ZCkoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopOwo+PiArCj4+ICsJc3RydWN0IHNnX3RhYmxl ICooKnByaW1lX2dldF9zZ190YWJsZSkoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopOwo+PiAr CXN0cnVjdCBkcm1fZ2VtX29iamVjdCAqKCpwcmltZV9pbXBvcnRfc2dfdGFibGUpKHN0cnVjdCBk cm1fZGV2aWNlICpkZXYsCj4+ICsJCQlzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICphdHRhY2gs Cj4+ICsJCQlzdHJ1Y3Qgc2dfdGFibGUgKnNndCk7Cj4+ICsJdm9pZCAqKCpwcmltZV92bWFwKShz dHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaik7Cj4+ICsJdm9pZCAoKnByaW1lX3Z1bm1hcCkoc3Ry dWN0IGRybV9nZW1fb2JqZWN0ICpvYmosIHZvaWQgKnZhZGRyKTsKPj4gKwlpbnQgKCpwcmltZV9t bWFwKShzdHJ1Y3QgZHJtX2dlbV9vYmplY3QgKm9iaiwKPj4gKwkJCXN0cnVjdCB2bV9hcmVhX3N0 cnVjdCAqdm1hKTsKPj4gKwo+PiArCWludCAoKmR1bWJfY3JlYXRlKShzdHJ1Y3QgZHJtX2ZpbGUg KmZpbGVfcHJpdiwgc3RydWN0IGRybV9kZXZpY2UgKmRldiwKPj4gKwkJCXN0cnVjdCBkcm1fbW9k ZV9jcmVhdGVfZHVtYiAqYXJncyk7Cj4+ICsKPj4gKwlpbnQgKCptbWFwKShzdHJ1Y3QgZmlsZSAq ZmlscCwgc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEpOwo+PiArCj4+ICsJc3RydWN0IHBhZ2Ug KiooKmdldF9wYWdlcykoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmopOwo+PiArfTsKPj4gKwo+ PiArY29uc3Qgc3RydWN0IHhlbl9kcm1fZnJvbnRfZ2VtX29wcyAqeGVuX2RybV9mcm9udF9nZW1f Z2V0X29wcyh2b2lkKTsKPj4gKwo+PiArI2VuZGlmIC8qIF9fWEVOX0RSTV9GUk9OVF9HRU1fSCAq Lwo+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX2Zyb250X2dlbV9j bWEuYyBiL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV9mcm9udF9nZW1fY21hLmMKPj4gbmV3 IGZpbGUgbW9kZSAxMDA2NDQKPj4gaW5kZXggMDAwMDAwMDAwMDAwLi41ZmZjYmZhNjUyZDUKPj4g LS0tIC9kZXYvbnVsbAo+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1fZnJvbnRf Z2VtX2NtYS5jCj4+IEBAIC0wLDAgKzEsOTMgQEAKPj4gKy8qCj4+ICsgKiAgWGVuIHBhcmEtdmly dHVhbCBEUk0gZGV2aWNlCj4+ICsgKgo+PiArICogICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0 d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQo+PiArICogICBpdCB1 bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxp c2hlZCBieQo+PiArICogICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVy c2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgo+PiArICogICAoYXQgeW91ciBvcHRpb24pIGFueSBs YXRlciB2ZXJzaW9uLgo+PiArICoKPj4gKyAqICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVk IGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCj4+ICsgKiAgIGJ1dCBXSVRIT1VU IEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCj4+ICsg KiAgIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4g IFNlZSB0aGUKPj4gKyAqICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0 YWlscy4KPj4gKyAqCj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTYtMjAxOCBFUEFNIFN5c3RlbXMg SW5jLgo+PiArICoKPj4gKyAqIEF1dGhvcjogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtz YW5kcl9hbmRydXNoY2hlbmtvQGVwYW0uY29tPgo+PiArICovCj4+ICsKPj4gKyNpbmNsdWRlIDxk cm0vZHJtUC5oPgo+PiArI2luY2x1ZGUgPGRybS9kcm1fZ2VtLmg+Cj4+ICsjaW5jbHVkZSA8ZHJt L2RybV9mYl9jbWFfaGVscGVyLmg+Cj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9nZW1fY21hX2hlbHBl ci5oPgo+PiArCj4+ICsjaW5jbHVkZSAieGVuX2RybV9mcm9udC5oIgo+PiArI2luY2x1ZGUgInhl bl9kcm1fZnJvbnRfZHJ2LmgiCj4+ICsjaW5jbHVkZSAieGVuX2RybV9mcm9udF9nZW0uaCIKPj4g Kwo+PiArc3RhdGljIHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqZ2VtX2ltcG9ydF9zZ190YWJsZShz dHJ1Y3QgZHJtX2RldmljZSAqZGV2LAo+PiArCQlzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICph dHRhY2gsIHN0cnVjdCBzZ190YWJsZSAqc2d0KQo+PiArewo+PiArCXN0cnVjdCB4ZW5fZHJtX2Zy b250X2RybV9pbmZvICpkcm1faW5mbyA9IGRldi0+ZGV2X3ByaXZhdGU7Cj4+ICsJc3RydWN0IGRy bV9nZW1fb2JqZWN0ICpnZW1fb2JqOwo+PiArCXN0cnVjdCBkcm1fZ2VtX2NtYV9vYmplY3QgKmNt YV9vYmo7Cj4+ICsJaW50IHJldDsKPj4gKwo+PiArCWdlbV9vYmogPSBkcm1fZ2VtX2NtYV9wcmlt ZV9pbXBvcnRfc2dfdGFibGUoZGV2LCBhdHRhY2gsIHNndCk7Cj4+ICsJaWYgKElTX0VSUl9PUl9O VUxMKGdlbV9vYmopKQo+PiArCQlyZXR1cm4gZ2VtX29iajsKPj4gKwo+PiArCWNtYV9vYmogPSB0 b19kcm1fZ2VtX2NtYV9vYmooZ2VtX29iaik7Cj4+ICsKPj4gKwlyZXQgPSBkcm1faW5mby0+ZnJv bnRfb3BzLT5kYnVmX2NyZWF0ZV9mcm9tX3NndCgKPj4gKwkJCWRybV9pbmZvLT5mcm9udF9pbmZv LAo+PiArCQkJeGVuX2RybV9mcm9udF9kYnVmX3RvX2Nvb2tpZShnZW1fb2JqKSwKPj4gKwkJCTAs IDAsIDAsIGdlbV9vYmotPnNpemUsCj4+ICsJCQlkcm1fZ2VtX2NtYV9wcmltZV9nZXRfc2dfdGFi bGUoZ2VtX29iaikpOwo+PiArCWlmIChyZXQgPCAwKQo+PiArCQlyZXR1cm4gRVJSX1BUUihyZXQp Owo+PiArCj4+ICsJRFJNX0RFQlVHKCJJbXBvcnRlZCBDTUEgYnVmZmVyIG9mIHNpemUgJXp1XG4i LCBnZW1fb2JqLT5zaXplKTsKPj4gKwo+PiArCXJldHVybiBnZW1fb2JqOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgaW50IGdlbV9kdW1iX2NyZWF0ZShzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHAsIHN0cnVj dCBkcm1fZGV2aWNlICpkZXYsCj4+ICsJc3RydWN0IGRybV9tb2RlX2NyZWF0ZV9kdW1iICphcmdz KQo+PiArewo+PiArCXN0cnVjdCB4ZW5fZHJtX2Zyb250X2RybV9pbmZvICpkcm1faW5mbyA9IGRl di0+ZGV2X3ByaXZhdGU7Cj4+ICsKPj4gKwlpZiAoZHJtX2luZm8tPmNmZy0+YmVfYWxsb2MpIHsK Pj4gKwkJLyogVGhpcyB1c2UtY2FzZSBpcyBub3QgeWV0IHN1cHBvcnRlZCBhbmQgcHJvYmFibHkg d29uJ3QgYmUgKi8KPj4gKwkJRFJNX0VSUk9SKCJCYWNrZW5kIGFsbG9jYXRlZCBidWZmZXJzIGFu ZCBDTUEgaGVscGVycyBhcmUgbm90IHN1cHBvcnRlZCBhdCB0aGUgc2FtZSB0aW1lXG4iKTsKPj4g KwkJcmV0dXJuIC1FSU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJcmV0dXJuIGRybV9nZW1fY21hX2R1 bWJfY3JlYXRlKGZpbHAsIGRldiwgYXJncyk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3Qg cGFnZSAqKmdlbV9nZXRfcGFnZXMoc3RydWN0IGRybV9nZW1fb2JqZWN0ICpnZW1fb2JqKQo+PiAr ewo+PiArCXJldHVybiBOVUxMOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHhl bl9kcm1fZnJvbnRfZ2VtX29wcyB4ZW5fZHJtX2Zyb250X2dlbV9jbWFfb3BzID0gewo+PiArCS5m cmVlX29iamVjdF91bmxvY2tlZCAgPSBkcm1fZ2VtX2NtYV9mcmVlX29iamVjdCwKPj4gKwkucHJp bWVfZ2V0X3NnX3RhYmxlICAgID0gZHJtX2dlbV9jbWFfcHJpbWVfZ2V0X3NnX3RhYmxlLAo+PiAr CS5wcmltZV9pbXBvcnRfc2dfdGFibGUgPSBnZW1faW1wb3J0X3NnX3RhYmxlLAo+PiArCj4+ICsJ LnByaW1lX3ZtYXAgICAgICAgICAgICA9IGRybV9nZW1fY21hX3ByaW1lX3ZtYXAsCj4+ICsJLnBy aW1lX3Z1bm1hcCAgICAgICAgICA9IGRybV9nZW1fY21hX3ByaW1lX3Z1bm1hcCwKPj4gKwkucHJp bWVfbW1hcCAgICAgICAgICAgID0gZHJtX2dlbV9jbWFfcHJpbWVfbW1hcCwKPj4gKwo+PiArCS5k dW1iX2NyZWF0ZSAgICAgICAgICAgPSBnZW1fZHVtYl9jcmVhdGUsCj4+ICsKPj4gKwkubW1hcCAg ICAgICAgICAgICAgICAgID0gZHJtX2dlbV9jbWFfbW1hcCwKPj4gKwo+PiArCS5nZXRfcGFnZXMg ICAgICAgICAgICAgPSBnZW1fZ2V0X3BhZ2VzLAo+PiArfTsKPiBBZ2FpbiBxdWl0ZSBhIG1pZGxh eWVyIHlvdSBoYXZlIGhlcmUuIFBsZWFzZSBpbmxpbmUgdGhpcyB0byBhdm9pZAo+IGNvbmZ1c2lv biBmb3Igb3RoZXIgcGVvcGxlIChzaW5jZSBpdCBsb29rcyBsaWtlIHlvdSBvbmx5IGhhdmUgMQo+ IGltcGxlbWVudGF0aW9uKS4KVGhlcmUgYXJlIDIgaW1wbGVtZW50YXRpb25zIGRlcGVuZGluZyBv biBkcml2ZXIgY29tcGlsZSB0aW1lIG9wdGlvbnM6CnlvdSBjYW4gaGF2ZSB0aGUgR0VNIG9wZXJh dGlvbnMgaW1wbGVtZW50ZWQgd2l0aCBEUk0gQ01BIGhlbHBlcnMKb3IgZHJpdmVyJ3MgY29va2Vk IEdFTXMuIEZvciB0aGlzIHJlYXNvbiB0aGlzIG1pZGxheWVyIGV4aXN0cywgZS5nLgp0byBlbGlt aW5hdGUgdGhlIG5lZWQgZm9yIHNvbWV0aGluZyBsaWtlCiNpZmRlZiBEUk1fWEVOX0ZST05URU5E X0NNQQpkcm1fZ2VtX2NtYV8uLi4oKQojZWxzZQp4ZW5fZHJtX2Zyb250X2dlbV8uLi4oKQojZW5k aWYKU28sIEkgd291bGQgcHJlZmVyIHRvIGhhdmUgb3BzIHJhdGhlciB0aGVuIGhhdmluZyBpZmRl ZnMKPgo+PiArCj4+ICtjb25zdCBzdHJ1Y3QgeGVuX2RybV9mcm9udF9nZW1fb3BzICp4ZW5fZHJt X2Zyb250X2dlbV9nZXRfb3BzKHZvaWQpCj4+ICt7Cj4+ICsJcmV0dXJuICZ4ZW5fZHJtX2Zyb250 X2dlbV9jbWFfb3BzOwo+PiArfQo+PiAtLSAKPj4gMi43LjQKPj4KPj4gX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KPj4gZHJpLWRldmVsIG1haWxpbmcgbGlz dAo+PiBkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCj4+IGh0dHBzOi8vbGlzdHMuZnJl ZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCgpfX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRy aS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5v cmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK