From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752710AbeC2NTv (ORCPT ); Thu, 29 Mar 2018 09:19:51 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:37573 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752319AbeC2NTp (ORCPT ); Thu, 29 Mar 2018 09:19:45 -0400 X-Google-Smtp-Source: AIpwx49PxfDtooDde3M0xnFReo6WU8ImS9yU5qpeOkLc/m9EsV4Bsfnil/Mx+FinPyKmpOYhViF1QQ== From: Oleksandr Andrushchenko 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 Cc: andr2000@gmail.com, Oleksandr Andrushchenko Subject: [PATCH 1/1] drm/xen-zcopy: Add Xen zero-copy helper DRM driver Date: Thu, 29 Mar 2018 16:19:31 +0300 Message-Id: <20180329131931.29957-2-andr2000@gmail.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180329131931.29957-1-andr2000@gmail.com> References: <20180329131931.29957-1-andr2000@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Oleksandr Andrushchenko Introduce Xen zero-copy helper DRM driver, add user-space API of the driver: 1. DRM_IOCTL_XEN_ZCOPY_DUMB_FROM_REFS This will create a DRM dumb buffer from grant references provided by the frontend. The intended usage is: - Frontend - creates a dumb/display buffer and allocates memory - grants foreign access to the buffer pages - passes granted references to the backend - Backend - issues DRM_XEN_ZCOPY_DUMB_FROM_REFS ioctl to map granted references and create a dumb buffer - requests handle to fd conversion via DRM_IOCTL_PRIME_HANDLE_TO_FD - requests real HW driver/consumer to import the PRIME buffer with DRM_IOCTL_PRIME_FD_TO_HANDLE - uses handle returned by the real HW driver - at the end: o closes real HW driver's handle with DRM_IOCTL_GEM_CLOSE o closes zero-copy driver's handle with DRM_IOCTL_GEM_CLOSE o closes file descriptor of the exported buffer 2. DRM_IOCTL_XEN_ZCOPY_DUMB_TO_REFS This will grant references to a dumb/display buffer's memory provided by the backend. The intended usage is: - Frontend - requests backend to allocate dumb/display buffer and grant references to its pages - Backend - requests real HW driver to create a dumb with DRM_IOCTL_MODE_CREATE_DUMB - requests handle to fd conversion via DRM_IOCTL_PRIME_HANDLE_TO_FD - requests zero-copy driver to import the PRIME buffer with DRM_IOCTL_PRIME_FD_TO_HANDLE - issues DRM_XEN_ZCOPY_DUMB_TO_REFS ioctl to grant references to the buffer's memory. - passes grant references to the frontend - at the end: - closes zero-copy driver's handle with DRM_IOCTL_GEM_CLOSE - closes real HW driver's handle with DRM_IOCTL_GEM_CLOSE - closes file descriptor of the imported buffer Implement GEM/IOCTL handling depending on driver mode of operation: - if GEM is created from grant references, then prepare to create a dumb from mapped pages - if GEM grant references are about to be provided for the imported PRIME buffer, then prepare for granting references and providing those to user-space Implement handling of display buffers from backend to/from front interaction point ov view: - when importing a buffer from the frontend: - allocate/free xen ballooned pages via Xen balloon driver or by manually allocating a DMA buffer - if DMA buffer is used, then increase/decrease its pages reservation accordingly - map/unmap foreign pages to the ballooned pages - when exporting a buffer to the frontend: - grant references for the pages of the imported PRIME buffer - pass the grants back to user-space, so those can be shared with the frontend Add an option to allocate DMA buffers as backing storage while importing a frontend's buffer into host's memory: for those use-cases when exported PRIME buffer will be used by a device expecting CMA buffers only, it is possible to map frontend's pages onto contiguous buffer, e.g. allocated via DMA API. Implement synchronous buffer deletion: for buffers, created from front's grant references, synchronization between backend and frontend is needed on buffer deletion as front expects us to unmap these references after XENDISPL_OP_DBUF_DESTROY response. For that reason introduce DRM_IOCTL_XEN_ZCOPY_DUMB_WAIT_FREE IOCTL: this will block until dumb buffer, with the wait handle provided, be freed. The rationale behind implementing own wait handle: - dumb buffer handle cannot be used as when the PRIME buffer gets exported there are at least 2 handles: one is for the backend and another one for the importing application, so when backend closes its handle and the other application still holds the buffer then there is no way for the backend to tell which buffer we want to wait for while calling xen_ioctl_wait_free - flink cannot be used as well as it is gone when DRM core calls .gem_free_object_unlocked Signed-off-by: Oleksandr Andrushchenko --- Documentation/gpu/drivers.rst | 1 + Documentation/gpu/xen-zcopy.rst | 32 + drivers/gpu/drm/xen/Kconfig | 25 + drivers/gpu/drm/xen/Makefile | 5 + drivers/gpu/drm/xen/xen_drm_zcopy.c | 880 ++++++++++++++++++++++++++++ drivers/gpu/drm/xen/xen_drm_zcopy_balloon.c | 154 +++++ drivers/gpu/drm/xen/xen_drm_zcopy_balloon.h | 38 ++ include/uapi/drm/xen_zcopy_drm.h | 129 ++++ 8 files changed, 1264 insertions(+) create mode 100644 Documentation/gpu/xen-zcopy.rst create mode 100644 drivers/gpu/drm/xen/xen_drm_zcopy.c create mode 100644 drivers/gpu/drm/xen/xen_drm_zcopy_balloon.c create mode 100644 drivers/gpu/drm/xen/xen_drm_zcopy_balloon.h create mode 100644 include/uapi/drm/xen_zcopy_drm.h diff --git a/Documentation/gpu/drivers.rst b/Documentation/gpu/drivers.rst index d3ab6abae838..900ff1c3d3f1 100644 --- a/Documentation/gpu/drivers.rst +++ b/Documentation/gpu/drivers.rst @@ -13,6 +13,7 @@ GPU Driver Documentation vc4 bridge/dw-hdmi xen-front + xen-zcopy .. only:: subproject and html diff --git a/Documentation/gpu/xen-zcopy.rst b/Documentation/gpu/xen-zcopy.rst new file mode 100644 index 000000000000..28d3942af2b8 --- /dev/null +++ b/Documentation/gpu/xen-zcopy.rst @@ -0,0 +1,32 @@ +=============================== +Xen zero-copy helper DRM driver +=============================== + +This helper driver allows implementing zero-copying use-cases +when using Xen para-virtualized frontend display driver: + + - a dumb buffer created on backend's side can be shared + with the Xen PV frontend driver, so it directly writes + into backend's domain memory (into the buffer exported from + DRM/KMS driver of a physical display device) + - a dumb buffer allocated by the frontend can be imported + into physical device DRM/KMS driver, thus allowing to + achieve no copying as well + +DRM_XEN_ZCOPY_DUMB_FROM_REFS IOCTL +================================== + +.. kernel-doc:: include/uapi/drm/xen_zcopy_drm.h + :doc: DRM_XEN_ZCOPY_DUMB_FROM_REFS + +DRM_XEN_ZCOPY_DUMB_TO_REFS IOCTL +================================ + +.. kernel-doc:: include/uapi/drm/xen_zcopy_drm.h + :doc: DRM_XEN_ZCOPY_DUMB_TO_REFS + +DRM_XEN_ZCOPY_DUMB_WAIT_FREE IOCTL +================================== + +.. kernel-doc:: include/uapi/drm/xen_zcopy_drm.h + :doc: DRM_XEN_ZCOPY_DUMB_WAIT_FREE diff --git a/drivers/gpu/drm/xen/Kconfig b/drivers/gpu/drm/xen/Kconfig index 4f4abc91f3b6..31eedb410829 100644 --- a/drivers/gpu/drm/xen/Kconfig +++ b/drivers/gpu/drm/xen/Kconfig @@ -5,6 +5,10 @@ config DRM_XEN Choose this option if you want to enable DRM support for Xen. +choice + prompt "Xen DRM drivers selection" + depends on DRM_XEN + config DRM_XEN_FRONTEND tristate "Para-virtualized frontend driver for Xen guest OS" depends on DRM_XEN @@ -28,3 +32,24 @@ config DRM_XEN_FRONTEND_CMA contiguous buffers. Note: in this mode driver cannot use buffers allocated by the backend. + +config DRM_XEN_ZCOPY + tristate "Zero copy helper DRM driver for Xen" + depends on DRM_XEN + depends on DRM + select DRM_KMS_HELPER + help + Choose this option if you want to enable a zero copy + helper DRM driver for Xen. This is implemented via mapping + of foreign display buffer pages into current domain and + exporting a dumb via PRIME interface. This allows + driver domains to use buffers of unpriveledged guests without + additional memory copying. + +config DRM_XEN_ZCOPY_CMA + bool "Use CMA to allocate buffers" + depends on DRM_XEN_ZCOPY + help + Use CMA to allocate display buffers. + +endchoice diff --git a/drivers/gpu/drm/xen/Makefile b/drivers/gpu/drm/xen/Makefile index 352730dc6c13..832daea761a9 100644 --- a/drivers/gpu/drm/xen/Makefile +++ b/drivers/gpu/drm/xen/Makefile @@ -14,3 +14,8 @@ else endif obj-$(CONFIG_DRM_XEN_FRONTEND) += drm_xen_front.o + +drm_xen_zcopy-objs := xen_drm_zcopy.o \ + xen_drm_zcopy_balloon.o + +obj-$(CONFIG_DRM_XEN_ZCOPY) += drm_xen_zcopy.o diff --git a/drivers/gpu/drm/xen/xen_drm_zcopy.c b/drivers/gpu/drm/xen/xen_drm_zcopy.c new file mode 100644 index 000000000000..c2fa4fcf1bf6 --- /dev/null +++ b/drivers/gpu/drm/xen/xen_drm_zcopy.c @@ -0,0 +1,880 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +/* + * Xen zero-copy helper DRM device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "xen_drm_zcopy_balloon.h" + +struct xen_gem_object { + struct drm_gem_object base; + uint32_t dumb_handle; + + int otherend_id; + + uint32_t num_pages; + grant_ref_t *grefs; + /* these are the pages from Xen balloon for allocated Xen GEM object */ + struct page **pages; + + struct xen_drm_zcopy_balloon balloon; + + /* this will be set if we have imported a PRIME buffer */ + struct sg_table *sgt; + /* map grant handles */ + grant_handle_t *map_handles; + /* + * these are used for synchronous object deletion, e.g. + * when user-space wants to know that the grefs are unmapped + */ + struct kref refcount; + int wait_handle; +}; + +struct xen_wait_obj { + struct list_head list; + struct xen_gem_object *xen_obj; + struct completion completion; +}; + +struct xen_drv_info { + struct drm_device *drm_dev; + + /* + * For buffers, created from front's grant references, synchronization + * between backend and frontend is needed on buffer deletion as front + * expects us to unmap these references after XENDISPL_OP_DBUF_DESTROY + * response. This means that when calling DRM_XEN_ZCOPY_DUMB_WAIT_FREE + * ioctl user-space has to provide some unique handle, so we can tell + * the buffer. For that reason we use IDR to allocate a unique value. + * The rationale behind implementing wait handle as IDR: + * - dumb buffer handle cannot be used as when the PRIME buffer + * gets exported there are at least 2 handles: one is for the + * backend and another one for the importing application, + * so when backend closes its handle and the other application still + * holds the buffer and then there is no way for the backend to tell + * which buffer we want to wait for while calling xen_ioctl_wait_free + * - flink cannot be used as well as it is gone when DRM core + * calls .gem_free_object_unlocked + * - sync_file can be used, but it seems to be an overhead to use it + * only to get a unique "handle" + */ + struct list_head wait_obj_list; + struct idr idr; + spinlock_t idr_lock; + spinlock_t wait_list_lock; +}; + +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 struct xen_wait_obj *wait_obj_new(struct xen_drv_info *drv_info, + struct xen_gem_object *xen_obj) +{ + struct xen_wait_obj *wait_obj; + + wait_obj = kzalloc(sizeof(*wait_obj), GFP_KERNEL); + if (!wait_obj) + return ERR_PTR(-ENOMEM); + + init_completion(&wait_obj->completion); + wait_obj->xen_obj = xen_obj; + + spin_lock(&drv_info->wait_list_lock); + list_add(&wait_obj->list, &drv_info->wait_obj_list); + spin_unlock(&drv_info->wait_list_lock); + + return wait_obj; +} + +static void wait_obj_free(struct xen_drv_info *drv_info, + struct xen_wait_obj *wait_obj) +{ + struct xen_wait_obj *cur_wait_obj, *q; + + spin_lock(&drv_info->wait_list_lock); + list_for_each_entry_safe(cur_wait_obj, q, + &drv_info->wait_obj_list, list) + if (cur_wait_obj == wait_obj) { + list_del(&wait_obj->list); + kfree(wait_obj); + break; + } + spin_unlock(&drv_info->wait_list_lock); +} + +static void wait_obj_check_pending(struct xen_drv_info *drv_info) +{ + /* + * It is intended to be called from .last_close when + * no pending wait objects should be on the list. + * make sure we don't miss a bug if this is not the case. + */ + WARN(!list_empty(&drv_info->wait_obj_list), + "Removing with pending wait objects!\n"); +} + +static int wait_obj_wait(struct xen_wait_obj *wait_obj, + uint32_t wait_to_ms) +{ + if (wait_for_completion_timeout(&wait_obj->completion, + msecs_to_jiffies(wait_to_ms)) <= 0) + return -ETIMEDOUT; + + return 0; +} + +static void wait_obj_signal(struct xen_drv_info *drv_info, + struct xen_gem_object *xen_obj) +{ + struct xen_wait_obj *wait_obj, *q; + + spin_lock(&drv_info->wait_list_lock); + list_for_each_entry_safe(wait_obj, q, &drv_info->wait_obj_list, list) + if (wait_obj->xen_obj == xen_obj) { + DRM_DEBUG("Found xen_obj in the wait list, wake\n"); + complete_all(&wait_obj->completion); + } + spin_unlock(&drv_info->wait_list_lock); +} + +static int wait_obj_handle_new(struct xen_drv_info *drv_info, + struct xen_gem_object *xen_obj) +{ + int ret; + + idr_preload(GFP_KERNEL); + spin_lock(&drv_info->idr_lock); + ret = idr_alloc(&drv_info->idr, xen_obj, 1, 0, GFP_NOWAIT); + spin_unlock(&drv_info->idr_lock); + idr_preload_end(); + return ret; +} + +static void wait_obj_handle_free(struct xen_drv_info *drv_info, + struct xen_gem_object *xen_obj) +{ + spin_lock(&drv_info->idr_lock); + idr_remove(&drv_info->idr, xen_obj->wait_handle); + spin_unlock(&drv_info->idr_lock); +} + +static struct xen_gem_object *get_obj_by_wait_handle( + struct xen_drv_info *drv_info, int wait_handle) +{ + struct xen_gem_object *xen_obj; + + spin_lock(&drv_info->idr_lock); + /* check if xen_obj still exists */ + xen_obj = idr_find(&drv_info->idr, wait_handle); + if (xen_obj) + kref_get(&xen_obj->refcount); + spin_unlock(&drv_info->idr_lock); + return xen_obj; +} + +#define xen_page_to_vaddr(page) \ + ((phys_addr_t)pfn_to_kaddr(page_to_xen_pfn(page))) + +static int from_refs_unmap(struct device *dev, + struct xen_gem_object *xen_obj) +{ + struct gnttab_unmap_grant_ref *unmap_ops; + int i, ret; + + if (!xen_obj->pages || !xen_obj->map_handles) + return 0; + + unmap_ops = kcalloc(xen_obj->num_pages, sizeof(*unmap_ops), GFP_KERNEL); + if (!unmap_ops) + return -ENOMEM; + + for (i = 0; i < xen_obj->num_pages; i++) { + phys_addr_t addr; + + /* + * When unmapping the grant entry for access by host CPUs: + * if or is zero, that + * field is ignored. If non-zero, they must refer to + * a device/host mapping that is tracked by + */ + addr = xen_page_to_vaddr(xen_obj->pages[i]); + gnttab_set_unmap_op(&unmap_ops[i], addr, +#if defined(CONFIG_X86) + GNTMAP_host_map | GNTMAP_device_map, +#else + GNTMAP_host_map, +#endif + xen_obj->map_handles[i]); + unmap_ops[i].dev_bus_addr = __pfn_to_phys(__pfn_to_mfn( + page_to_pfn(xen_obj->pages[i]))); + } + + ret = gnttab_unmap_refs(unmap_ops, NULL, xen_obj->pages, + xen_obj->num_pages); + /* + * Even if we didn't unmap properly - continue to rescue whatever + * resources we can. + */ + if (ret) + DRM_ERROR("Failed to unmap grant references, ret %d", ret); + + for (i = 0; i < xen_obj->num_pages; i++) { + if (unlikely(unmap_ops[i].status != GNTST_okay)) + DRM_ERROR("Failed to unmap page %d with ref %d: %d\n", + i, xen_obj->grefs[i], + unmap_ops[i].status); + } + + xen_drm_zcopy_ballooned_pages_free(dev, &xen_obj->balloon, + xen_obj->num_pages, xen_obj->pages); + + kfree(xen_obj->pages); + xen_obj->pages = NULL; + kfree(xen_obj->map_handles); + xen_obj->map_handles = NULL; + kfree(unmap_ops); + kfree(xen_obj->grefs); + xen_obj->grefs = NULL; + return ret; +} + +static int from_refs_map(struct device *dev, struct xen_gem_object *xen_obj) +{ + struct gnttab_map_grant_ref *map_ops = NULL; + int ret, i; + + if (xen_obj->pages) { + DRM_ERROR("Mapping already mapped pages?\n"); + return -EINVAL; + } + + xen_obj->pages = kcalloc(xen_obj->num_pages, sizeof(*xen_obj->pages), + GFP_KERNEL); + if (!xen_obj->pages) { + ret = -ENOMEM; + goto fail; + } + + xen_obj->map_handles = kcalloc(xen_obj->num_pages, + sizeof(*xen_obj->map_handles), GFP_KERNEL); + if (!xen_obj->map_handles) { + ret = -ENOMEM; + goto fail; + } + + map_ops = kcalloc(xen_obj->num_pages, sizeof(*map_ops), GFP_KERNEL); + if (!map_ops) { + ret = -ENOMEM; + goto fail; + } + + ret = xen_drm_zcopy_ballooned_pages_alloc(dev, &xen_obj->balloon, + xen_obj->num_pages, xen_obj->pages); + if (ret < 0) { + DRM_ERROR("Cannot allocate %d ballooned pages: %d\n", + xen_obj->num_pages, ret); + goto fail; + } + + for (i = 0; i < xen_obj->num_pages; i++) { + phys_addr_t addr; + + addr = xen_page_to_vaddr(xen_obj->pages[i]); + gnttab_set_map_op(&map_ops[i], addr, +#if defined(CONFIG_X86) + GNTMAP_host_map | GNTMAP_device_map, +#else + GNTMAP_host_map, +#endif + xen_obj->grefs[i], xen_obj->otherend_id); + } + ret = gnttab_map_refs(map_ops, NULL, xen_obj->pages, + xen_obj->num_pages); + + /* save handles even if error, so we can unmap */ + for (i = 0; i < xen_obj->num_pages; i++) { + xen_obj->map_handles[i] = map_ops[i].handle; + if (unlikely(map_ops[i].status != GNTST_okay)) + DRM_ERROR("Failed to map page %d with ref %d: %d\n", + i, xen_obj->grefs[i], map_ops[i].status); + } + + if (ret) { + DRM_ERROR("Failed to map grant references, ret %d", ret); + from_refs_unmap(dev, xen_obj); + goto fail; + } + + kfree(map_ops); + return 0; + +fail: + kfree(xen_obj->pages); + xen_obj->pages = NULL; + kfree(xen_obj->map_handles); + xen_obj->map_handles = NULL; + kfree(map_ops); + return ret; + +} + +static void to_refs_end_foreign_access(struct xen_gem_object *xen_obj) +{ + int i; + + if (xen_obj->grefs) + for (i = 0; i < xen_obj->num_pages; i++) + if (xen_obj->grefs[i] != GRANT_INVALID_REF) + gnttab_end_foreign_access(xen_obj->grefs[i], + 0, 0UL); + + kfree(xen_obj->grefs); + xen_obj->grefs = NULL; + xen_obj->sgt = NULL; +} + +static int to_refs_grant_foreign_access(struct xen_gem_object *xen_obj) +{ + grant_ref_t priv_gref_head; + int ret, j, cur_ref, num_pages; + struct sg_page_iter sg_iter; + + ret = gnttab_alloc_grant_references(xen_obj->num_pages, + &priv_gref_head); + if (ret < 0) { + DRM_ERROR("Cannot allocate grant references\n"); + return ret; + } + + j = 0; + num_pages = xen_obj->num_pages; + for_each_sg_page(xen_obj->sgt->sgl, &sg_iter, xen_obj->sgt->nents, 0) { + struct page *page; + + page = sg_page_iter_page(&sg_iter); + cur_ref = gnttab_claim_grant_reference(&priv_gref_head); + if (cur_ref < 0) + return cur_ref; + + gnttab_grant_foreign_access_ref(cur_ref, + xen_obj->otherend_id, xen_page_to_gfn(page), 0); + xen_obj->grefs[j++] = cur_ref; + num_pages--; + } + + WARN_ON(num_pages != 0); + + gnttab_free_grant_references(priv_gref_head); + return 0; +} + +static int gem_create_with_handle(struct xen_gem_object *xen_obj, + struct drm_file *filp, struct drm_device *dev, int size) +{ + struct drm_gem_object *gem_obj; + int ret; + + drm_gem_private_object_init(dev, &xen_obj->base, size); + gem_obj = &xen_obj->base; + ret = drm_gem_handle_create(filp, gem_obj, &xen_obj->dumb_handle); + /* drop reference from allocate - handle holds it now. */ + drm_gem_object_put_unlocked(gem_obj); + return ret; +} + +static int gem_create_obj(struct xen_gem_object *xen_obj, + struct drm_device *dev, struct drm_file *filp, int size) +{ + struct drm_gem_object *gem_obj; + int ret; + + ret = gem_create_with_handle(xen_obj, filp, dev, size); + if (ret < 0) + goto fail; + + gem_obj = drm_gem_object_lookup(filp, xen_obj->dumb_handle); + if (!gem_obj) { + DRM_ERROR("Lookup for handle %d failed\n", + xen_obj->dumb_handle); + ret = -EINVAL; + goto fail_destroy; + } + + drm_gem_object_put_unlocked(gem_obj); + return 0; + +fail_destroy: + drm_gem_dumb_destroy(filp, dev, xen_obj->dumb_handle); +fail: + DRM_ERROR("Failed to create dumb buffer: %d\n", ret); + xen_obj->dumb_handle = 0; + return ret; +} + +static int gem_init_obj(struct xen_gem_object *xen_obj, + struct drm_device *dev, int size) +{ + struct drm_gem_object *gem_obj = &xen_obj->base; + int ret; + + ret = drm_gem_object_init(dev, gem_obj, size); + if (ret < 0) + return ret; + + ret = drm_gem_create_mmap_offset(gem_obj); + if (ret < 0) { + drm_gem_object_release(gem_obj); + return ret; + } + + return 0; +} + +static void obj_release(struct kref *kref) +{ + struct xen_gem_object *xen_obj = + container_of(kref, struct xen_gem_object, refcount); + struct xen_drv_info *drv_info = xen_obj->base.dev->dev_private; + + wait_obj_signal(drv_info, xen_obj); + kfree(xen_obj); +} + +static void gem_free_object_unlocked(struct drm_gem_object *gem_obj) +{ + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); + struct xen_drv_info *drv_info = gem_obj->dev->dev_private; + + DRM_DEBUG("Freeing dumb with handle %d\n", xen_obj->dumb_handle); + if (xen_obj->grefs) { + if (xen_obj->sgt) { + drm_prime_gem_destroy(&xen_obj->base, xen_obj->sgt); + to_refs_end_foreign_access(xen_obj); + } else + from_refs_unmap(gem_obj->dev->dev, xen_obj); + } + + drm_gem_object_release(gem_obj); + + wait_obj_handle_free(drv_info, xen_obj); + kref_put(&xen_obj->refcount, obj_release); +} + +static struct sg_table *gem_prime_get_sg_table( + struct drm_gem_object *gem_obj) +{ + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); + struct sg_table *sgt = NULL; + + if (unlikely(!xen_obj->pages)) + return NULL; + + sgt = drm_prime_pages_to_sg(xen_obj->pages, xen_obj->num_pages); + + if (unlikely(!sgt)) + DRM_ERROR("Failed to export sgt\n"); + else + DRM_DEBUG("Exporting %scontiguous buffer nents %d\n", + sgt->nents == 1 ? "" : "non-", sgt->nents); + return sgt; +} + +struct drm_gem_object *gem_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, struct sg_table *sgt) +{ + struct xen_gem_object *xen_obj; + int ret; + + xen_obj = kzalloc(sizeof(*xen_obj), GFP_KERNEL); + if (!xen_obj) + return ERR_PTR(-ENOMEM); + + ret = gem_init_obj(xen_obj, dev, attach->dmabuf->size); + if (ret < 0) + goto fail; + + kref_init(&xen_obj->refcount); + xen_obj->sgt = sgt; + xen_obj->num_pages = DIV_ROUND_UP(attach->dmabuf->size, PAGE_SIZE); + + DRM_DEBUG("Imported buffer of size %zu with nents %u\n", + attach->dmabuf->size, sgt->nents); + return &xen_obj->base; + +fail: + kfree(xen_obj); + return ERR_PTR(ret); +} + +static int do_ioctl_from_refs(struct drm_device *dev, + struct drm_xen_zcopy_dumb_from_refs *req, + struct drm_file *filp) +{ + struct xen_drv_info *drv_info = dev->dev_private; + struct xen_gem_object *xen_obj; + int ret; + + xen_obj = kzalloc(sizeof(*xen_obj), GFP_KERNEL); + if (!xen_obj) + return -ENOMEM; + + kref_init(&xen_obj->refcount); + xen_obj->num_pages = req->num_grefs; + xen_obj->otherend_id = req->otherend_id; + xen_obj->grefs = kcalloc(xen_obj->num_pages, + sizeof(grant_ref_t), GFP_KERNEL); + if (!xen_obj->grefs) { + ret = -ENOMEM; + goto fail; + } + + if (copy_from_user(xen_obj->grefs, req->grefs, + xen_obj->num_pages * sizeof(grant_ref_t))) { + ret = -EINVAL; + goto fail; + } + + ret = from_refs_map(dev->dev, xen_obj); + if (ret < 0) + goto fail; + + ret = gem_create_obj(xen_obj, dev, filp, + round_up(req->dumb.size, PAGE_SIZE)); + if (ret < 0) + goto fail; + + req->dumb.handle = xen_obj->dumb_handle; + + /* + * Get user-visible handle for this GEM object. + * the wait object is not allocated at the moment, + * but if need be it will be allocated at the time of + * DRM_XEN_ZCOPY_DUMB_WAIT_FREE IOCTL + */ + ret = wait_obj_handle_new(drv_info, xen_obj); + if (ret < 0) + goto fail; + + req->wait_handle = ret; + xen_obj->wait_handle = ret; + return 0; + +fail: + kfree(xen_obj->grefs); + xen_obj->grefs = NULL; + kfree(xen_obj); + return ret; +} + +static int ioctl_from_refs(struct drm_device *dev, + void *data, struct drm_file *filp) +{ + struct drm_xen_zcopy_dumb_from_refs *req = + (struct drm_xen_zcopy_dumb_from_refs *)data; + struct drm_mode_create_dumb *args = &req->dumb; + uint32_t cpp, stride, size; + + if (!req->num_grefs || !req->grefs) + return -EINVAL; + + if (!args->width || !args->height || !args->bpp) + return -EINVAL; + + cpp = DIV_ROUND_UP(args->bpp, 8); + if (!cpp || cpp > 0xffffffffU / args->width) + return -EINVAL; + + stride = cpp * args->width; + if (args->height > 0xffffffffU / stride) + return -EINVAL; + + size = args->height * stride; + if (PAGE_ALIGN(size) == 0) + return -EINVAL; + + args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + args->size = args->pitch * args->height; + args->handle = 0; + if (req->num_grefs < DIV_ROUND_UP(args->size, PAGE_SIZE)) { + DRM_ERROR("Provided %d pages, need %d\n", req->num_grefs, + (int)DIV_ROUND_UP(args->size, PAGE_SIZE)); + return -EINVAL; + } + + return do_ioctl_from_refs(dev, req, filp); +} + +static int ioctl_to_refs(struct drm_device *dev, + void *data, struct drm_file *filp) +{ + struct xen_gem_object *xen_obj; + struct drm_gem_object *gem_obj; + struct drm_xen_zcopy_dumb_to_refs *req = + (struct drm_xen_zcopy_dumb_to_refs *)data; + int ret; + + if (!req->num_grefs || !req->grefs) + return -EINVAL; + + gem_obj = drm_gem_object_lookup(filp, req->handle); + if (!gem_obj) { + DRM_ERROR("Lookup for handle %d failed\n", req->handle); + return -EINVAL; + } + + drm_gem_object_put_unlocked(gem_obj); + xen_obj = to_xen_gem_obj(gem_obj); + + if (xen_obj->num_pages != req->num_grefs) { + DRM_ERROR("Provided %d pages, need %d\n", req->num_grefs, + xen_obj->num_pages); + return -EINVAL; + } + + xen_obj->otherend_id = req->otherend_id; + xen_obj->grefs = kcalloc(xen_obj->num_pages, + sizeof(grant_ref_t), GFP_KERNEL); + if (!xen_obj->grefs) { + ret = -ENOMEM; + goto fail; + } + + ret = to_refs_grant_foreign_access(xen_obj); + if (ret < 0) + goto fail; + + if (copy_to_user(req->grefs, xen_obj->grefs, + xen_obj->num_pages * sizeof(grant_ref_t))) { + ret = -EINVAL; + goto fail; + } + + return 0; + +fail: + to_refs_end_foreign_access(xen_obj); + return ret; +} + +static int ioctl_wait_free(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_xen_zcopy_dumb_wait_free *req = + (struct drm_xen_zcopy_dumb_wait_free *)data; + struct xen_drv_info *drv_info = dev->dev_private; + struct xen_gem_object *xen_obj; + struct xen_wait_obj *wait_obj; + int wait_handle, ret; + + wait_handle = req->wait_handle; + /* + * try to find the wait handle: if not found means that + * either the handle has already been freed or wrong + */ + xen_obj = get_obj_by_wait_handle(drv_info, wait_handle); + if (!xen_obj) + return -ENOENT; + + /* + * xen_obj still exists and is reference count locked by us now, so + * prepare to wait: allocate wait object and add it to the wait list, + * so we can find it on release + */ + wait_obj = wait_obj_new(drv_info, xen_obj); + /* put our reference and wait for xen_obj release to fire */ + kref_put(&xen_obj->refcount, obj_release); + ret = PTR_ERR_OR_ZERO(wait_obj); + if (ret < 0) { + DRM_ERROR("Failed to setup wait object, ret %d\n", ret); + return ret; + } + + ret = wait_obj_wait(wait_obj, req->wait_to_ms); + wait_obj_free(drv_info, wait_obj); + return ret; +} + +static void lastclose(struct drm_device *dev) +{ + struct xen_drv_info *drv_info = dev->dev_private; + + wait_obj_check_pending(drv_info); +} + +static const struct drm_ioctl_desc xen_drm_ioctls[] = { + DRM_IOCTL_DEF_DRV(XEN_ZCOPY_DUMB_FROM_REFS, + ioctl_from_refs, + DRM_AUTH | DRM_CONTROL_ALLOW | DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(XEN_ZCOPY_DUMB_TO_REFS, + ioctl_to_refs, + DRM_AUTH | DRM_CONTROL_ALLOW | DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(XEN_ZCOPY_DUMB_WAIT_FREE, + ioctl_wait_free, + DRM_AUTH | DRM_CONTROL_ALLOW | DRM_UNLOCKED), +}; + +static const struct file_operations xen_drm_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, +}; + +static struct drm_driver xen_drm_driver = { + .driver_features = DRIVER_GEM | DRIVER_PRIME, + .lastclose = lastclose, + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_get_sg_table = gem_prime_get_sg_table, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_import_sg_table = gem_prime_import_sg_table, + .gem_free_object_unlocked = gem_free_object_unlocked, + .fops = &xen_drm_fops, + .ioctls = xen_drm_ioctls, + .num_ioctls = ARRAY_SIZE(xen_drm_ioctls), + .name = XENDRM_ZCOPY_DRIVER_NAME, + .desc = "Xen PV DRM zero copy", + .date = "20180221", + .major = 1, + .minor = 0, +}; + +static int xen_drm_drv_remove(struct platform_device *pdev) +{ + struct xen_drv_info *drv_info = platform_get_drvdata(pdev); + + if (drv_info && drv_info->drm_dev) { + drm_dev_unregister(drv_info->drm_dev); + drm_dev_unref(drv_info->drm_dev); + idr_destroy(&drv_info->idr); + } + return 0; +} + +static int xen_drm_drv_probe(struct platform_device *pdev) +{ + struct xen_drv_info *drv_info; + int ret; + + DRM_INFO("Creating %s\n", xen_drm_driver.desc); + drv_info = kzalloc(sizeof(*drv_info), GFP_KERNEL); + if (!drv_info) + return -ENOMEM; + + idr_init(&drv_info->idr); + spin_lock_init(&drv_info->idr_lock); + spin_lock_init(&drv_info->wait_list_lock); + INIT_LIST_HEAD(&drv_info->wait_obj_list); + + /* + * The device is not spawn from a device tree, so arch_setup_dma_ops + * is not called, thus leaving the device with dummy DMA ops. + * This makes the device return error on PRIME buffer import, which + * is not correct: to fix this call of_dma_configure() with a NULL + * node to set default DMA ops. + */ + of_dma_configure(&pdev->dev, NULL); + + drv_info->drm_dev = drm_dev_alloc(&xen_drm_driver, &pdev->dev); + if (!drv_info->drm_dev) + return -ENOMEM; + + ret = drm_dev_register(drv_info->drm_dev, 0); + if (ret < 0) + goto fail; + + drv_info->drm_dev->dev_private = drv_info; + platform_set_drvdata(pdev, drv_info); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + xen_drm_driver.name, xen_drm_driver.major, + xen_drm_driver.minor, xen_drm_driver.patchlevel, + xen_drm_driver.date, drv_info->drm_dev->primary->index); + return 0; + +fail: + drm_dev_unref(drv_info->drm_dev); + kfree(drv_info); + return ret; +} + +static struct platform_driver zcopy_platform_drv_info = { + .probe = xen_drm_drv_probe, + .remove = xen_drm_drv_remove, + .driver = { + .name = XENDRM_ZCOPY_DRIVER_NAME, + }, +}; + +struct platform_device_info zcopy_dev_info = { + .name = XENDRM_ZCOPY_DRIVER_NAME, + .id = 0, + .num_res = 0, + .dma_mask = DMA_BIT_MASK(32), +}; + +static struct platform_device *xen_pdev; + +static int __init xen_drv_init(void) +{ + int ret; + + /* At the moment we only support case with XEN_PAGE_SIZE == PAGE_SIZE */ + if (XEN_PAGE_SIZE != PAGE_SIZE) { + DRM_ERROR(XENDRM_ZCOPY_DRIVER_NAME ": different kernel and Xen page sizes are not supported: XEN_PAGE_SIZE (%lu) != PAGE_SIZE (%lu)\n", + XEN_PAGE_SIZE, PAGE_SIZE); + return -ENODEV; + } + + if (!xen_domain()) + return -ENODEV; + + xen_pdev = platform_device_register_full(&zcopy_dev_info); + if (!xen_pdev) { + DRM_ERROR("Failed to register " XENDRM_ZCOPY_DRIVER_NAME " device\n"); + return -ENODEV; + } + + ret = platform_driver_register(&zcopy_platform_drv_info); + if (ret != 0) { + DRM_ERROR("Failed to register " XENDRM_ZCOPY_DRIVER_NAME " driver: %d\n", ret); + platform_device_unregister(xen_pdev); + return ret; + } + + return 0; +} + +static void __exit xen_drv_fini(void) +{ + if (xen_pdev) + platform_device_unregister(xen_pdev); + platform_driver_unregister(&zcopy_platform_drv_info); +} + +module_init(xen_drv_init); +module_exit(xen_drv_fini); + +MODULE_DESCRIPTION("Xen zero-copy helper DRM device"); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/xen/xen_drm_zcopy_balloon.c b/drivers/gpu/drm/xen/xen_drm_zcopy_balloon.c new file mode 100644 index 000000000000..2679233b9f84 --- /dev/null +++ b/drivers/gpu/drm/xen/xen_drm_zcopy_balloon.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +/* + * Xen zero-copy helper DRM device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ + +#include + +#if defined(CONFIG_DRM_XEN_ZCOPY_CMA) +#include +#include +#include +#else +#include +#endif + +#include "xen_drm_zcopy_balloon.h" + +#if defined(CONFIG_DRM_XEN_ZCOPY_CMA) +int xen_drm_zcopy_ballooned_pages_alloc(struct device *dev, + struct xen_drm_zcopy_balloon *obj, int num_pages, + struct page **pages) +{ + xen_pfn_t *frame_list; + size_t size; + int i, ret; + dma_addr_t dev_addr, cpu_addr; + void *vaddr = NULL; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + + size = num_pages * PAGE_SIZE; + DRM_DEBUG("Ballooning out %d pages, size %zu\n", num_pages, size); + frame_list = kcalloc(num_pages, sizeof(*frame_list), GFP_KERNEL); + if (!frame_list) + return -ENOMEM; + + vaddr = dma_alloc_wc(dev, size, &dev_addr, GFP_KERNEL | __GFP_NOWARN); + if (!vaddr) { + DRM_ERROR("Failed to allocate DMA buffer with size %zu\n", + size); + ret = -ENOMEM; + goto fail; + } + + cpu_addr = dev_addr; + for (i = 0; i < num_pages; i++) { + pages[i] = pfn_to_page(__phys_to_pfn(cpu_addr)); + /* + * XENMEM_populate_physmap requires a PFN based on Xen + * granularity. + */ + frame_list[i] = page_to_xen_pfn(pages[i]); + cpu_addr += PAGE_SIZE; + } + + set_xen_guest_handle(reservation.extent_start, frame_list); + reservation.nr_extents = num_pages; + /* rc will hold number of pages processed */ + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + if (ret <= 0) { + DRM_ERROR("Failed to balloon out %d pages (%d), retrying\n", + num_pages, ret); + WARN_ON(ret != num_pages); + ret = -EFAULT; + goto fail; + } + + obj->vaddr = vaddr; + obj->dev_bus_addr = dev_addr; + kfree(frame_list); + return 0; + +fail: + if (vaddr) + dma_free_wc(dev, size, vaddr, dev_addr); + + kfree(frame_list); + return ret; +} + +void xen_drm_zcopy_ballooned_pages_free(struct device *dev, + struct xen_drm_zcopy_balloon *obj, int num_pages, + struct page **pages) +{ + xen_pfn_t *frame_list; + int i, ret; + size_t size; + struct xen_memory_reservation reservation = { + .address_bits = 0, + .extent_order = 0, + .domid = DOMID_SELF + }; + + if (!pages) + return; + + if (!obj->vaddr) + return; + + frame_list = kcalloc(num_pages, sizeof(*frame_list), GFP_KERNEL); + if (!frame_list) { + DRM_ERROR("Failed to balloon in %d pages\n", num_pages); + return; + } + + DRM_DEBUG("Ballooning in %d pages\n", num_pages); + size = num_pages * PAGE_SIZE; + for (i = 0; i < num_pages; i++) { + /* + * XENMEM_populate_physmap requires a PFN based on Xen + * granularity. + */ + frame_list[i] = page_to_xen_pfn(pages[i]); + } + + set_xen_guest_handle(reservation.extent_start, frame_list); + reservation.nr_extents = num_pages; + /* rc will hold number of pages processed */ + ret = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); + if (ret <= 0) { + DRM_ERROR("Failed to balloon in %d pages\n", num_pages); + WARN_ON(ret != num_pages); + } + + if (obj->vaddr) + dma_free_wc(dev, size, obj->vaddr, obj->dev_bus_addr); + + obj->vaddr = NULL; + obj->dev_bus_addr = 0; + kfree(frame_list); +} +#else +int xen_drm_zcopy_ballooned_pages_alloc(struct device *dev, + struct xen_drm_zcopy_balloon *obj, int num_pages, + struct page **pages) +{ + return alloc_xenballooned_pages(num_pages, pages); +} + +void xen_drm_zcopy_ballooned_pages_free(struct device *dev, + struct xen_drm_zcopy_balloon *obj, int num_pages, + struct page **pages) +{ + free_xenballooned_pages(num_pages, pages); +} +#endif /* defined(CONFIG_DRM_XEN_ZCOPY_CMA) */ diff --git a/drivers/gpu/drm/xen/xen_drm_zcopy_balloon.h b/drivers/gpu/drm/xen/xen_drm_zcopy_balloon.h new file mode 100644 index 000000000000..1151f17f9339 --- /dev/null +++ b/drivers/gpu/drm/xen/xen_drm_zcopy_balloon.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ + +/* + * Xen zero-copy helper DRM device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ + +#ifndef __XEN_DRM_ZCOPY_BALLOON_H_ +#define __XEN_DRM_ZCOPY_BALLOON_H_ + +#include + +#ifndef GRANT_INVALID_REF +/* + * Note on usage of grant reference 0 as invalid grant reference: + * grant reference 0 is valid, but never exposed to a PV driver, + * because of the fact it is already in use/reserved by the PV console. + */ +#define GRANT_INVALID_REF 0 +#endif + +struct xen_drm_zcopy_balloon { + void *vaddr; + dma_addr_t dev_bus_addr; +}; + +int xen_drm_zcopy_ballooned_pages_alloc(struct device *dev, + struct xen_drm_zcopy_balloon *obj, int num_pages, + struct page **pages); + +void xen_drm_zcopy_ballooned_pages_free(struct device *dev, + struct xen_drm_zcopy_balloon *obj, int num_pages, + struct page **pages); + +#endif /* __XEN_DRM_ZCOPY_BALLOON_H_ */ diff --git a/include/uapi/drm/xen_zcopy_drm.h b/include/uapi/drm/xen_zcopy_drm.h new file mode 100644 index 000000000000..8767cfbf0350 --- /dev/null +++ b/include/uapi/drm/xen_zcopy_drm.h @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + +/* + * Xen zero-copy helper DRM device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ +#ifndef __XEN_ZCOPY_DRM_H +#define __XEN_ZCOPY_DRM_H + +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#define XENDRM_ZCOPY_DRIVER_NAME "xen_drm_zcopy" + +/** + * DOC: DRM_XEN_ZCOPY_DUMB_FROM_REFS + * + * This will create a DRM dumb buffer from grant references provided + * by the frontend: + * + * - Frontend + * + * - creates a dumb/display buffer and allocates memory. + * - grants foreign access to the buffer pages + * - passes granted references to the backend + * + * - Backend + * + * - issues DRM_XEN_ZCOPY_DUMB_FROM_REFS ioctl to map + * granted references and create a dumb buffer. + * - requests handle to fd conversion via DRM_IOCTL_PRIME_HANDLE_TO_FD + * - requests real HW driver to import the PRIME buffer with + * DRM_IOCTL_PRIME_FD_TO_HANDLE + * - uses handle returned by the real HW driver + * + * At the end: + * + * - closes real HW driver's handle with DRM_IOCTL_GEM_CLOSE + * - closes zero-copy driver's handle with DRM_IOCTL_GEM_CLOSE + * - closes file descriptor of the exported buffer + * - may wait for the object to be actually freed via wait_handle + * and DRM_XEN_ZCOPY_DUMB_WAIT_FREE + */ +#define DRM_XEN_ZCOPY_DUMB_FROM_REFS 0x00 + +struct drm_xen_zcopy_dumb_from_refs { + uint32_t num_grefs; + /* user-space uses uint32_t instead of grant_ref_t for mapping */ + uint32_t *grefs; + uint64_t otherend_id; + struct drm_mode_create_dumb dumb; + uint32_t wait_handle; +}; + +/** + * DOC: DRM_XEN_ZCOPY_DUMB_TO_REFS + * + * This will grant references to a dumb/display buffer's memory provided by the + * backend: + * + * - Frontend + * + * - requests backend to allocate dumb/display buffer and grant references + * to its pages + * + * - Backend + * + * - requests real HW driver to create a dumb with DRM_IOCTL_MODE_CREATE_DUMB + * - requests handle to fd conversion via DRM_IOCTL_PRIME_HANDLE_TO_FD + * - requests zero-copy driver to import the PRIME buffer with + * DRM_IOCTL_PRIME_FD_TO_HANDLE + * - issues DRM_XEN_ZCOPY_DUMB_TO_REFS ioctl to grant references to the + * buffer's memory. + * - passes grant references to the frontend + * + * At the end: + * + * - closes zero-copy driver's handle with DRM_IOCTL_GEM_CLOSE + * - closes real HW driver's handle with DRM_IOCTL_GEM_CLOSE + * - closes file descriptor of the imported buffer + */ +#define DRM_XEN_ZCOPY_DUMB_TO_REFS 0x01 + +struct drm_xen_zcopy_dumb_to_refs { + uint32_t num_grefs; + /* user-space uses uint32_t instead of grant_ref_t for mapping */ + uint32_t *grefs; + uint64_t otherend_id; + uint32_t handle; +}; + +/** + * DOC: DRM_XEN_ZCOPY_DUMB_WAIT_FREE + * + * This will block until the dumb buffer with the wait handle provided be freed: + * this is needed for synchronization between frontend and backend in case + * frontend provides grant references of the buffer via + * DRM_XEN_ZCOPY_DUMB_FROM_REFS IOCTL and which must be released before + * backend replies with XENDISPL_OP_DBUF_DESTROY response. + * wait_handle must be the same value returned while calling + * DRM_XEN_ZCOPY_DUMB_FROM_REFS IOCTL. + */ +#define DRM_XEN_ZCOPY_DUMB_WAIT_FREE 0x02 + +struct drm_xen_zcopy_dumb_wait_free { + uint32_t wait_handle; + uint32_t wait_to_ms; +}; + +#define DRM_IOCTL_XEN_ZCOPY_DUMB_FROM_REFS DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_XEN_ZCOPY_DUMB_FROM_REFS, struct drm_xen_zcopy_dumb_from_refs) + +#define DRM_IOCTL_XEN_ZCOPY_DUMB_TO_REFS DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_XEN_ZCOPY_DUMB_TO_REFS, struct drm_xen_zcopy_dumb_to_refs) + +#define DRM_IOCTL_XEN_ZCOPY_DUMB_WAIT_FREE DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_XEN_ZCOPY_DUMB_WAIT_FREE, struct drm_xen_zcopy_dumb_wait_free) + +#if defined(__cplusplus) +} +#endif + +#endif /* __XEN_ZCOPY_DRM_H*/ -- 2.16.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: [PATCH 1/1] drm/xen-zcopy: Add Xen zero-copy helper DRM driver Date: Thu, 29 Mar 2018 16:19:31 +0300 Message-ID: <20180329131931.29957-2-andr2000@gmail.com> References: <20180329131931.29957-1-andr2000@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x242.google.com (mail-lf0-x242.google.com [IPv6:2a00:1450:4010:c07::242]) by gabe.freedesktop.org (Postfix) with ESMTPS id 428A66E175 for ; Thu, 29 Mar 2018 13:19:45 +0000 (UTC) Received: by mail-lf0-x242.google.com with SMTP id v207-v6so8367946lfa.10 for ; Thu, 29 Mar 2018 06:19:45 -0700 (PDT) In-Reply-To: <20180329131931.29957-1-andr2000@gmail.com> 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 Cc: andr2000@gmail.com, Oleksandr Andrushchenko List-Id: dri-devel@lists.freedesktop.org RnJvbTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVw YW0uY29tPgoKSW50cm9kdWNlIFhlbiB6ZXJvLWNvcHkgaGVscGVyIERSTSBkcml2ZXIsIGFkZCB1 c2VyLXNwYWNlIEFQSSBvZiB0aGUgZHJpdmVyOgoxLiBEUk1fSU9DVExfWEVOX1pDT1BZX0RVTUJf RlJPTV9SRUZTClRoaXMgd2lsbCBjcmVhdGUgYSBEUk0gZHVtYiBidWZmZXIgZnJvbSBncmFudCBy ZWZlcmVuY2VzIHByb3ZpZGVkCmJ5IHRoZSBmcm9udGVuZC4gVGhlIGludGVuZGVkIHVzYWdlIGlz OgogIC0gRnJvbnRlbmQKICAgIC0gY3JlYXRlcyBhIGR1bWIvZGlzcGxheSBidWZmZXIgYW5kIGFs bG9jYXRlcyBtZW1vcnkKICAgIC0gZ3JhbnRzIGZvcmVpZ24gYWNjZXNzIHRvIHRoZSBidWZmZXIg cGFnZXMKICAgIC0gcGFzc2VzIGdyYW50ZWQgcmVmZXJlbmNlcyB0byB0aGUgYmFja2VuZAogIC0g QmFja2VuZAogICAgLSBpc3N1ZXMgRFJNX1hFTl9aQ09QWV9EVU1CX0ZST01fUkVGUyBpb2N0bCB0 byBtYXAKICAgICAgZ3JhbnRlZCByZWZlcmVuY2VzIGFuZCBjcmVhdGUgYSBkdW1iIGJ1ZmZlcgog ICAgLSByZXF1ZXN0cyBoYW5kbGUgdG8gZmQgY29udmVyc2lvbiB2aWEgRFJNX0lPQ1RMX1BSSU1F X0hBTkRMRV9UT19GRAogICAgLSByZXF1ZXN0cyByZWFsIEhXIGRyaXZlci9jb25zdW1lciB0byBp bXBvcnQgdGhlIFBSSU1FIGJ1ZmZlciB3aXRoCiAgICAgIERSTV9JT0NUTF9QUklNRV9GRF9UT19I QU5ETEUKICAgIC0gdXNlcyBoYW5kbGUgcmV0dXJuZWQgYnkgdGhlIHJlYWwgSFcgZHJpdmVyCiAg LSBhdCB0aGUgZW5kOgogICAgbyBjbG9zZXMgcmVhbCBIVyBkcml2ZXIncyBoYW5kbGUgd2l0aCBE Uk1fSU9DVExfR0VNX0NMT1NFCiAgICBvIGNsb3NlcyB6ZXJvLWNvcHkgZHJpdmVyJ3MgaGFuZGxl IHdpdGggRFJNX0lPQ1RMX0dFTV9DTE9TRQogICAgbyBjbG9zZXMgZmlsZSBkZXNjcmlwdG9yIG9m IHRoZSBleHBvcnRlZCBidWZmZXIKCjIuIERSTV9JT0NUTF9YRU5fWkNPUFlfRFVNQl9UT19SRUZT ClRoaXMgd2lsbCBncmFudCByZWZlcmVuY2VzIHRvIGEgZHVtYi9kaXNwbGF5IGJ1ZmZlcidzIG1l bW9yeSBwcm92aWRlZCBieSB0aGUKYmFja2VuZC4gVGhlIGludGVuZGVkIHVzYWdlIGlzOgogIC0g RnJvbnRlbmQKICAgIC0gcmVxdWVzdHMgYmFja2VuZCB0byBhbGxvY2F0ZSBkdW1iL2Rpc3BsYXkg YnVmZmVyIGFuZCBncmFudCByZWZlcmVuY2VzCiAgICAgIHRvIGl0cyBwYWdlcwogIC0gQmFja2Vu ZAogICAgLSByZXF1ZXN0cyByZWFsIEhXIGRyaXZlciB0byBjcmVhdGUgYSBkdW1iIHdpdGggRFJN X0lPQ1RMX01PREVfQ1JFQVRFX0RVTUIKICAgIC0gcmVxdWVzdHMgaGFuZGxlIHRvIGZkIGNvbnZl cnNpb24gdmlhIERSTV9JT0NUTF9QUklNRV9IQU5ETEVfVE9fRkQKICAgIC0gcmVxdWVzdHMgemVy by1jb3B5IGRyaXZlciB0byBpbXBvcnQgdGhlIFBSSU1FIGJ1ZmZlciB3aXRoCiAgICAgIERSTV9J T0NUTF9QUklNRV9GRF9UT19IQU5ETEUKICAgIC0gaXNzdWVzIERSTV9YRU5fWkNPUFlfRFVNQl9U T19SRUZTIGlvY3RsIHRvCiAgICAgIGdyYW50IHJlZmVyZW5jZXMgdG8gdGhlIGJ1ZmZlcidzIG1l bW9yeS4KICAgIC0gcGFzc2VzIGdyYW50IHJlZmVyZW5jZXMgdG8gdGhlIGZyb250ZW5kCiAtIGF0 IHRoZSBlbmQ6CiAgICAtIGNsb3NlcyB6ZXJvLWNvcHkgZHJpdmVyJ3MgaGFuZGxlIHdpdGggRFJN X0lPQ1RMX0dFTV9DTE9TRQogICAgLSBjbG9zZXMgcmVhbCBIVyBkcml2ZXIncyBoYW5kbGUgd2l0 aCBEUk1fSU9DVExfR0VNX0NMT1NFCiAgICAtIGNsb3NlcyBmaWxlIGRlc2NyaXB0b3Igb2YgdGhl IGltcG9ydGVkIGJ1ZmZlcgoKSW1wbGVtZW50IEdFTS9JT0NUTCBoYW5kbGluZyBkZXBlbmRpbmcg b24gZHJpdmVyIG1vZGUgb2Ygb3BlcmF0aW9uOgotIGlmIEdFTSBpcyBjcmVhdGVkIGZyb20gZ3Jh bnQgcmVmZXJlbmNlcywgdGhlbiBwcmVwYXJlIHRvIGNyZWF0ZQogIGEgZHVtYiBmcm9tIG1hcHBl ZCBwYWdlcwotIGlmIEdFTSBncmFudCByZWZlcmVuY2VzIGFyZSBhYm91dCB0byBiZSBwcm92aWRl ZCBmb3IgdGhlCiAgaW1wb3J0ZWQgUFJJTUUgYnVmZmVyLCB0aGVuIHByZXBhcmUgZm9yIGdyYW50 aW5nIHJlZmVyZW5jZXMKICBhbmQgcHJvdmlkaW5nIHRob3NlIHRvIHVzZXItc3BhY2UKCkltcGxl bWVudCBoYW5kbGluZyBvZiBkaXNwbGF5IGJ1ZmZlcnMgZnJvbSBiYWNrZW5kIHRvL2Zyb20gZnJv bnQKaW50ZXJhY3Rpb24gcG9pbnQgb3YgdmlldzoKLSB3aGVuIGltcG9ydGluZyBhIGJ1ZmZlciBm cm9tIHRoZSBmcm9udGVuZDoKICAtIGFsbG9jYXRlL2ZyZWUgeGVuIGJhbGxvb25lZCBwYWdlcyB2 aWEgWGVuIGJhbGxvb24gZHJpdmVyCiAgICBvciBieSBtYW51YWxseSBhbGxvY2F0aW5nIGEgRE1B IGJ1ZmZlcgogIC0gaWYgRE1BIGJ1ZmZlciBpcyB1c2VkLCB0aGVuIGluY3JlYXNlL2RlY3JlYXNl IGl0cyBwYWdlcwogICAgcmVzZXJ2YXRpb24gYWNjb3JkaW5nbHkKICAtIG1hcC91bm1hcCBmb3Jl aWduIHBhZ2VzIHRvIHRoZSBiYWxsb29uZWQgcGFnZXMKLSB3aGVuIGV4cG9ydGluZyBhIGJ1ZmZl ciB0byB0aGUgZnJvbnRlbmQ6CiAgLSBncmFudCByZWZlcmVuY2VzIGZvciB0aGUgcGFnZXMgb2Yg dGhlIGltcG9ydGVkIFBSSU1FIGJ1ZmZlcgogIC0gcGFzcyB0aGUgZ3JhbnRzIGJhY2sgdG8gdXNl ci1zcGFjZSwgc28gdGhvc2UgY2FuIGJlIHNoYXJlZAogICAgd2l0aCB0aGUgZnJvbnRlbmQKCkFk ZCBhbiBvcHRpb24gdG8gYWxsb2NhdGUgRE1BIGJ1ZmZlcnMgYXMgYmFja2luZyBzdG9yYWdlIHdo aWxlCmltcG9ydGluZyBhIGZyb250ZW5kJ3MgYnVmZmVyIGludG8gaG9zdCdzIG1lbW9yeToKZm9y IHRob3NlIHVzZS1jYXNlcyB3aGVuIGV4cG9ydGVkIFBSSU1FIGJ1ZmZlciB3aWxsIGJlIHVzZWQg YnkKYSBkZXZpY2UgZXhwZWN0aW5nIENNQSBidWZmZXJzIG9ubHksIGl0IGlzIHBvc3NpYmxlIHRv IG1hcApmcm9udGVuZCdzIHBhZ2VzIG9udG8gY29udGlndW91cyBidWZmZXIsIGUuZy4gYWxsb2Nh dGVkIHZpYQpETUEgQVBJLgoKSW1wbGVtZW50IHN5bmNocm9ub3VzIGJ1ZmZlciBkZWxldGlvbjog Zm9yIGJ1ZmZlcnMsIGNyZWF0ZWQgZnJvbSBmcm9udCdzCmdyYW50IHJlZmVyZW5jZXMsIHN5bmNo cm9uaXphdGlvbiBiZXR3ZWVuIGJhY2tlbmQgYW5kIGZyb250ZW5kIGlzIG5lZWRlZApvbiBidWZm ZXIgZGVsZXRpb24gYXMgZnJvbnQgZXhwZWN0cyB1cyB0byB1bm1hcCB0aGVzZSByZWZlcmVuY2Vz IGFmdGVyClhFTkRJU1BMX09QX0RCVUZfREVTVFJPWSByZXNwb25zZS4KRm9yIHRoYXQgcmVhc29u IGludHJvZHVjZSBEUk1fSU9DVExfWEVOX1pDT1BZX0RVTUJfV0FJVF9GUkVFIElPQ1RMOgp0aGlz IHdpbGwgYmxvY2sgdW50aWwgZHVtYiBidWZmZXIsIHdpdGggdGhlIHdhaXQgaGFuZGxlIHByb3Zp ZGVkLApiZSBmcmVlZC4KClRoZSByYXRpb25hbGUgYmVoaW5kIGltcGxlbWVudGluZyBvd24gd2Fp dCBoYW5kbGU6CiAgLSBkdW1iIGJ1ZmZlciBoYW5kbGUgY2Fubm90IGJlIHVzZWQgYXMgd2hlbiB0 aGUgUFJJTUUgYnVmZmVyCiAgICBnZXRzIGV4cG9ydGVkIHRoZXJlIGFyZSBhdCBsZWFzdCAyIGhh bmRsZXM6IG9uZSBpcyBmb3IgdGhlCiAgICBiYWNrZW5kIGFuZCBhbm90aGVyIG9uZSBmb3IgdGhl IGltcG9ydGluZyBhcHBsaWNhdGlvbiwKICAgIHNvIHdoZW4gYmFja2VuZCBjbG9zZXMgaXRzIGhh bmRsZSBhbmQgdGhlIG90aGVyIGFwcGxpY2F0aW9uIHN0aWxsCiAgICBob2xkcyB0aGUgYnVmZmVy IHRoZW4gdGhlcmUgaXMgbm8gd2F5IGZvciB0aGUgYmFja2VuZCB0byB0ZWxsCiAgICB3aGljaCBi dWZmZXIgd2Ugd2FudCB0byB3YWl0IGZvciB3aGlsZSBjYWxsaW5nIHhlbl9pb2N0bF93YWl0X2Zy ZWUKICAtIGZsaW5rIGNhbm5vdCBiZSB1c2VkIGFzIHdlbGwgYXMgaXQgaXMgZ29uZSB3aGVuIERS TSBjb3JlCiAgICBjYWxscyAuZ2VtX2ZyZWVfb2JqZWN0X3VubG9ja2VkCgpTaWduZWQtb2ZmLWJ5 OiBPbGVrc2FuZHIgQW5kcnVzaGNoZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBhbS5j b20+Ci0tLQogRG9jdW1lbnRhdGlvbi9ncHUvZHJpdmVycy5yc3QgICAgICAgICAgICAgICB8ICAg MSArCiBEb2N1bWVudGF0aW9uL2dwdS94ZW4temNvcHkucnN0ICAgICAgICAgICAgIHwgIDMyICsK IGRyaXZlcnMvZ3B1L2RybS94ZW4vS2NvbmZpZyAgICAgICAgICAgICAgICAgfCAgMjUgKwogZHJp dmVycy9ncHUvZHJtL3hlbi9NYWtlZmlsZSAgICAgICAgICAgICAgICB8ICAgNSArCiBkcml2ZXJz L2dwdS9kcm0veGVuL3hlbl9kcm1femNvcHkuYyAgICAgICAgIHwgODgwICsrKysrKysrKysrKysr KysrKysrKysrKysrKysKIGRyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV96Y29weV9iYWxsb29u LmMgfCAxNTQgKysrKysKIGRyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV96Y29weV9iYWxsb29u LmggfCAgMzggKysKIGluY2x1ZGUvdWFwaS9kcm0veGVuX3pjb3B5X2RybS5oICAgICAgICAgICAg fCAxMjkgKysrKwogOCBmaWxlcyBjaGFuZ2VkLCAxMjY0IGluc2VydGlvbnMoKykKIGNyZWF0ZSBt b2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL2dwdS94ZW4temNvcHkucnN0CiBjcmVhdGUgbW9kZSAx MDA2NDQgZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX3pjb3B5LmMKIGNyZWF0ZSBtb2RlIDEw MDY0NCBkcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1femNvcHlfYmFsbG9vbi5jCiBjcmVhdGUg bW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX3pjb3B5X2JhbGxvb24uaAog Y3JlYXRlIG1vZGUgMTAwNjQ0IGluY2x1ZGUvdWFwaS9kcm0veGVuX3pjb3B5X2RybS5oCgpkaWZm IC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi9ncHUvZHJpdmVycy5yc3QgYi9Eb2N1bWVudGF0aW9uL2dw dS9kcml2ZXJzLnJzdAppbmRleCBkM2FiNmFiYWU4MzguLjkwMGZmMWMzZDNmMSAxMDA2NDQKLS0t IGEvRG9jdW1lbnRhdGlvbi9ncHUvZHJpdmVycy5yc3QKKysrIGIvRG9jdW1lbnRhdGlvbi9ncHUv ZHJpdmVycy5yc3QKQEAgLTEzLDYgKzEzLDcgQEAgR1BVIERyaXZlciBEb2N1bWVudGF0aW9uCiAg ICB2YzQKICAgIGJyaWRnZS9kdy1oZG1pCiAgICB4ZW4tZnJvbnQKKyAgIHhlbi16Y29weQogCiAu LiBvbmx5OjogIHN1YnByb2plY3QgYW5kIGh0bWwKIApkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlv bi9ncHUveGVuLXpjb3B5LnJzdCBiL0RvY3VtZW50YXRpb24vZ3B1L3hlbi16Y29weS5yc3QKbmV3 IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4yOGQzOTQyYWYyYjgKLS0tIC9k ZXYvbnVsbAorKysgYi9Eb2N1bWVudGF0aW9uL2dwdS94ZW4temNvcHkucnN0CkBAIC0wLDAgKzEs MzIgQEAKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK1hlbiB6ZXJvLWNvcHkgaGVs cGVyIERSTSBkcml2ZXIKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworVGhpcyBo ZWxwZXIgZHJpdmVyIGFsbG93cyBpbXBsZW1lbnRpbmcgemVyby1jb3B5aW5nIHVzZS1jYXNlcwor d2hlbiB1c2luZyBYZW4gcGFyYS12aXJ0dWFsaXplZCBmcm9udGVuZCBkaXNwbGF5IGRyaXZlcjoK KworIC0gYSBkdW1iIGJ1ZmZlciBjcmVhdGVkIG9uIGJhY2tlbmQncyBzaWRlIGNhbiBiZSBzaGFy ZWQKKyAgIHdpdGggdGhlIFhlbiBQViBmcm9udGVuZCBkcml2ZXIsIHNvIGl0IGRpcmVjdGx5IHdy aXRlcworICAgaW50byBiYWNrZW5kJ3MgZG9tYWluIG1lbW9yeSAoaW50byB0aGUgYnVmZmVyIGV4 cG9ydGVkIGZyb20KKyAgIERSTS9LTVMgZHJpdmVyIG9mIGEgcGh5c2ljYWwgZGlzcGxheSBkZXZp Y2UpCisgLSBhIGR1bWIgYnVmZmVyIGFsbG9jYXRlZCBieSB0aGUgZnJvbnRlbmQgY2FuIGJlIGlt cG9ydGVkCisgICBpbnRvIHBoeXNpY2FsIGRldmljZSBEUk0vS01TIGRyaXZlciwgdGh1cyBhbGxv d2luZyB0bworICAgYWNoaWV2ZSBubyBjb3B5aW5nIGFzIHdlbGwKKworRFJNX1hFTl9aQ09QWV9E VU1CX0ZST01fUkVGUyBJT0NUTAorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQor CisuLiBrZXJuZWwtZG9jOjogaW5jbHVkZS91YXBpL2RybS94ZW5femNvcHlfZHJtLmgKKyAgIDpk b2M6IERSTV9YRU5fWkNPUFlfRFVNQl9GUk9NX1JFRlMKKworRFJNX1hFTl9aQ09QWV9EVU1CX1RP X1JFRlMgSU9DVEwKKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisKKy4uIGtlcm5l bC1kb2M6OiBpbmNsdWRlL3VhcGkvZHJtL3hlbl96Y29weV9kcm0uaAorICAgOmRvYzogRFJNX1hF Tl9aQ09QWV9EVU1CX1RPX1JFRlMKKworRFJNX1hFTl9aQ09QWV9EVU1CX1dBSVRfRlJFRSBJT0NU TAorPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQorCisuLiBrZXJuZWwtZG9jOjog aW5jbHVkZS91YXBpL2RybS94ZW5femNvcHlfZHJtLmgKKyAgIDpkb2M6IERSTV9YRU5fWkNPUFlf RFVNQl9XQUlUX0ZSRUUKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS94ZW4vS2NvbmZpZyBi L2RyaXZlcnMvZ3B1L2RybS94ZW4vS2NvbmZpZwppbmRleCA0ZjRhYmM5MWYzYjYuLjMxZWVkYjQx MDgyOSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3hlbi9LY29uZmlnCisrKyBiL2RyaXZl cnMvZ3B1L2RybS94ZW4vS2NvbmZpZwpAQCAtNSw2ICs1LDEwIEBAIGNvbmZpZyBEUk1fWEVOCiAJ ICBDaG9vc2UgdGhpcyBvcHRpb24gaWYgeW91IHdhbnQgdG8gZW5hYmxlIERSTSBzdXBwb3J0CiAJ ICBmb3IgWGVuLgogCitjaG9pY2UKKwlwcm9tcHQgIlhlbiBEUk0gZHJpdmVycyBzZWxlY3Rpb24i CisJZGVwZW5kcyBvbiBEUk1fWEVOCisKIGNvbmZpZyBEUk1fWEVOX0ZST05URU5ECiAJdHJpc3Rh dGUgIlBhcmEtdmlydHVhbGl6ZWQgZnJvbnRlbmQgZHJpdmVyIGZvciBYZW4gZ3Vlc3QgT1MiCiAJ ZGVwZW5kcyBvbiBEUk1fWEVOCkBAIC0yOCwzICszMiwyNCBAQCBjb25maWcgRFJNX1hFTl9GUk9O VEVORF9DTUEKIAkgIGNvbnRpZ3VvdXMgYnVmZmVycy4KIAkgIE5vdGU6IGluIHRoaXMgbW9kZSBk cml2ZXIgY2Fubm90IHVzZSBidWZmZXJzIGFsbG9jYXRlZAogCSAgYnkgdGhlIGJhY2tlbmQuCisK K2NvbmZpZyBEUk1fWEVOX1pDT1BZCisJdHJpc3RhdGUgIlplcm8gY29weSBoZWxwZXIgRFJNIGRy aXZlciBmb3IgWGVuIgorCWRlcGVuZHMgb24gRFJNX1hFTgorCWRlcGVuZHMgb24gRFJNCisJc2Vs ZWN0IERSTV9LTVNfSEVMUEVSCisJaGVscAorCSAgQ2hvb3NlIHRoaXMgb3B0aW9uIGlmIHlvdSB3 YW50IHRvIGVuYWJsZSBhIHplcm8gY29weQorCSAgaGVscGVyIERSTSBkcml2ZXIgZm9yIFhlbi4g VGhpcyBpcyBpbXBsZW1lbnRlZCB2aWEgbWFwcGluZworCSAgb2YgZm9yZWlnbiBkaXNwbGF5IGJ1 ZmZlciBwYWdlcyBpbnRvIGN1cnJlbnQgZG9tYWluIGFuZAorCSAgZXhwb3J0aW5nIGEgZHVtYiB2 aWEgUFJJTUUgaW50ZXJmYWNlLiBUaGlzIGFsbG93cworCSAgZHJpdmVyIGRvbWFpbnMgdG8gdXNl IGJ1ZmZlcnMgb2YgdW5wcml2ZWxlZGdlZCBndWVzdHMgd2l0aG91dAorCSAgYWRkaXRpb25hbCBt ZW1vcnkgY29weWluZy4KKworY29uZmlnIERSTV9YRU5fWkNPUFlfQ01BCisJYm9vbCAiVXNlIENN QSB0byBhbGxvY2F0ZSBidWZmZXJzIgorCWRlcGVuZHMgb24gRFJNX1hFTl9aQ09QWQorCWhlbHAK KwkgIFVzZSBDTUEgdG8gYWxsb2NhdGUgZGlzcGxheSBidWZmZXJzLgorCitlbmRjaG9pY2UKZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS94ZW4vTWFrZWZpbGUgYi9kcml2ZXJzL2dwdS9kcm0v eGVuL01ha2VmaWxlCmluZGV4IDM1MjczMGRjNmMxMy4uODMyZGFlYTc2MWE5IDEwMDY0NAotLS0g YS9kcml2ZXJzL2dwdS9kcm0veGVuL01ha2VmaWxlCisrKyBiL2RyaXZlcnMvZ3B1L2RybS94ZW4v TWFrZWZpbGUKQEAgLTE0LDMgKzE0LDggQEAgZWxzZQogZW5kaWYKIAogb2JqLSQoQ09ORklHX0RS TV9YRU5fRlJPTlRFTkQpICs9IGRybV94ZW5fZnJvbnQubworCitkcm1feGVuX3pjb3B5LW9ianMg Oj0geGVuX2RybV96Y29weS5vIFwKKwkJICAgICAgeGVuX2RybV96Y29weV9iYWxsb29uLm8KKwor b2JqLSQoQ09ORklHX0RSTV9YRU5fWkNPUFkpICs9IGRybV94ZW5femNvcHkubwpkaWZmIC0tZ2l0 IGEvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX3pjb3B5LmMgYi9kcml2ZXJzL2dwdS9kcm0v eGVuL3hlbl9kcm1femNvcHkuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAw MDAuLmMyZmE0ZmNmMWJmNgotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZ3B1L2RybS94ZW4v eGVuX2RybV96Y29weS5jCkBAIC0wLDAgKzEsODgwIEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRp ZmllcjogR1BMLTIuMCBPUiBNSVQKKworLyoKKyAqICBYZW4gemVyby1jb3B5IGhlbHBlciBEUk0g ZGV2aWNlCisgKgorICogQ29weXJpZ2h0IChDKSAyMDE2LTIwMTggRVBBTSBTeXN0ZW1zIEluYy4K KyAqCisgKiBBdXRob3I6IE9sZWtzYW5kciBBbmRydXNoY2hlbmtvIDxvbGVrc2FuZHJfYW5kcnVz aGNoZW5rb0BlcGFtLmNvbT4KKyAqLworCisjaW5jbHVkZSA8ZHJtL2RybVAuaD4KKyNpbmNsdWRl IDxkcm0vZHJtX2dlbS5oPgorCisjaW5jbHVkZSA8bGludXgvZG1hLWJ1Zi5oPgorI2luY2x1ZGUg PGxpbnV4L29mX2RldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgor CisjaW5jbHVkZSA8eGVuL2dyYW50X3RhYmxlLmg+CisjaW5jbHVkZSA8YXNtL3hlbi9wYWdlLmg+ CisKKyNpbmNsdWRlIDxkcm0veGVuX3pjb3B5X2RybS5oPgorCisjaW5jbHVkZSAieGVuX2RybV96 Y29weV9iYWxsb29uLmgiCisKK3N0cnVjdCB4ZW5fZ2VtX29iamVjdCB7CisJc3RydWN0IGRybV9n ZW1fb2JqZWN0IGJhc2U7CisJdWludDMyX3QgZHVtYl9oYW5kbGU7CisKKwlpbnQgb3RoZXJlbmRf aWQ7CisKKwl1aW50MzJfdCBudW1fcGFnZXM7CisJZ3JhbnRfcmVmX3QgKmdyZWZzOworCS8qIHRo ZXNlIGFyZSB0aGUgcGFnZXMgZnJvbSBYZW4gYmFsbG9vbiBmb3IgYWxsb2NhdGVkIFhlbiBHRU0g b2JqZWN0ICovCisJc3RydWN0IHBhZ2UgKipwYWdlczsKKworCXN0cnVjdCB4ZW5fZHJtX3pjb3B5 X2JhbGxvb24gYmFsbG9vbjsKKworCS8qIHRoaXMgd2lsbCBiZSBzZXQgaWYgd2UgaGF2ZSBpbXBv cnRlZCBhIFBSSU1FIGJ1ZmZlciAqLworCXN0cnVjdCBzZ190YWJsZSAqc2d0OworCS8qIG1hcCBn cmFudCBoYW5kbGVzICovCisJZ3JhbnRfaGFuZGxlX3QgKm1hcF9oYW5kbGVzOworCS8qCisJICog dGhlc2UgYXJlIHVzZWQgZm9yIHN5bmNocm9ub3VzIG9iamVjdCBkZWxldGlvbiwgZS5nLgorCSAq IHdoZW4gdXNlci1zcGFjZSB3YW50cyB0byBrbm93IHRoYXQgdGhlIGdyZWZzIGFyZSB1bm1hcHBl ZAorCSAqLworCXN0cnVjdCBrcmVmIHJlZmNvdW50OworCWludCB3YWl0X2hhbmRsZTsKK307CisK K3N0cnVjdCB4ZW5fd2FpdF9vYmogeworCXN0cnVjdCBsaXN0X2hlYWQgbGlzdDsKKwlzdHJ1Y3Qg eGVuX2dlbV9vYmplY3QgKnhlbl9vYmo7CisJc3RydWN0IGNvbXBsZXRpb24gY29tcGxldGlvbjsK K307CisKK3N0cnVjdCB4ZW5fZHJ2X2luZm8geworCXN0cnVjdCBkcm1fZGV2aWNlICpkcm1fZGV2 OworCisJLyoKKwkgKiBGb3IgYnVmZmVycywgY3JlYXRlZCBmcm9tIGZyb250J3MgZ3JhbnQgcmVm ZXJlbmNlcywgc3luY2hyb25pemF0aW9uCisJICogYmV0d2VlbiBiYWNrZW5kIGFuZCBmcm9udGVu ZCBpcyBuZWVkZWQgb24gYnVmZmVyIGRlbGV0aW9uIGFzIGZyb250CisJICogZXhwZWN0cyB1cyB0 byB1bm1hcCB0aGVzZSByZWZlcmVuY2VzIGFmdGVyIFhFTkRJU1BMX09QX0RCVUZfREVTVFJPWQor CSAqIHJlc3BvbnNlLiBUaGlzIG1lYW5zIHRoYXQgd2hlbiBjYWxsaW5nIERSTV9YRU5fWkNPUFlf RFVNQl9XQUlUX0ZSRUUKKwkgKiBpb2N0bCB1c2VyLXNwYWNlIGhhcyB0byBwcm92aWRlIHNvbWUg dW5pcXVlIGhhbmRsZSwgc28gd2UgY2FuIHRlbGwKKwkgKiB0aGUgYnVmZmVyLiBGb3IgdGhhdCBy ZWFzb24gd2UgdXNlIElEUiB0byBhbGxvY2F0ZSBhIHVuaXF1ZSB2YWx1ZS4KKwkgKiBUaGUgcmF0 aW9uYWxlIGJlaGluZCBpbXBsZW1lbnRpbmcgd2FpdCBoYW5kbGUgYXMgSURSOgorCSAqIC0gZHVt YiBidWZmZXIgaGFuZGxlIGNhbm5vdCBiZSB1c2VkIGFzIHdoZW4gdGhlIFBSSU1FIGJ1ZmZlcgor CSAqICAgZ2V0cyBleHBvcnRlZCB0aGVyZSBhcmUgYXQgbGVhc3QgMiBoYW5kbGVzOiBvbmUgaXMg Zm9yIHRoZQorCSAqICAgYmFja2VuZCBhbmQgYW5vdGhlciBvbmUgZm9yIHRoZSBpbXBvcnRpbmcg YXBwbGljYXRpb24sCisJICogICBzbyB3aGVuIGJhY2tlbmQgY2xvc2VzIGl0cyBoYW5kbGUgYW5k IHRoZSBvdGhlciBhcHBsaWNhdGlvbiBzdGlsbAorCSAqICAgaG9sZHMgdGhlIGJ1ZmZlciBhbmQg dGhlbiB0aGVyZSBpcyBubyB3YXkgZm9yIHRoZSBiYWNrZW5kIHRvIHRlbGwKKwkgKiAgIHdoaWNo IGJ1ZmZlciB3ZSB3YW50IHRvIHdhaXQgZm9yIHdoaWxlIGNhbGxpbmcgeGVuX2lvY3RsX3dhaXRf ZnJlZQorCSAqIC0gZmxpbmsgY2Fubm90IGJlIHVzZWQgYXMgd2VsbCBhcyBpdCBpcyBnb25lIHdo ZW4gRFJNIGNvcmUKKwkgKiAgIGNhbGxzIC5nZW1fZnJlZV9vYmplY3RfdW5sb2NrZWQKKwkgKiAt IHN5bmNfZmlsZSBjYW4gYmUgdXNlZCwgYnV0IGl0IHNlZW1zIHRvIGJlIGFuIG92ZXJoZWFkIHRv IHVzZSBpdAorCSAqICAgb25seSB0byBnZXQgYSB1bmlxdWUgImhhbmRsZSIKKwkgKi8KKwlzdHJ1 Y3QgbGlzdF9oZWFkIHdhaXRfb2JqX2xpc3Q7CisJc3RydWN0IGlkciBpZHI7CisJc3BpbmxvY2tf dCBpZHJfbG9jazsKKwlzcGlubG9ja190IHdhaXRfbGlzdF9sb2NrOworfTsKKworc3RhdGljIGlu bGluZSBzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnRvX3hlbl9nZW1fb2JqKAorCQlzdHJ1Y3QgZHJt X2dlbV9vYmplY3QgKmdlbV9vYmopCit7CisJcmV0dXJuIGNvbnRhaW5lcl9vZihnZW1fb2JqLCBz dHJ1Y3QgeGVuX2dlbV9vYmplY3QsIGJhc2UpOworfQorCitzdGF0aWMgc3RydWN0IHhlbl93YWl0 X29iaiAqd2FpdF9vYmpfbmV3KHN0cnVjdCB4ZW5fZHJ2X2luZm8gKmRydl9pbmZvLAorCQlzdHJ1 Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmopCit7CisJc3RydWN0IHhlbl93YWl0X29iaiAqd2Fp dF9vYmo7CisKKwl3YWl0X29iaiA9IGt6YWxsb2Moc2l6ZW9mKCp3YWl0X29iaiksIEdGUF9LRVJO RUwpOworCWlmICghd2FpdF9vYmopCisJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOworCisJaW5p dF9jb21wbGV0aW9uKCZ3YWl0X29iai0+Y29tcGxldGlvbik7CisJd2FpdF9vYmotPnhlbl9vYmog PSB4ZW5fb2JqOworCisJc3Bpbl9sb2NrKCZkcnZfaW5mby0+d2FpdF9saXN0X2xvY2spOworCWxp c3RfYWRkKCZ3YWl0X29iai0+bGlzdCwgJmRydl9pbmZvLT53YWl0X29ial9saXN0KTsKKwlzcGlu X3VubG9jaygmZHJ2X2luZm8tPndhaXRfbGlzdF9sb2NrKTsKKworCXJldHVybiB3YWl0X29iajsK K30KKworc3RhdGljIHZvaWQgd2FpdF9vYmpfZnJlZShzdHJ1Y3QgeGVuX2Rydl9pbmZvICpkcnZf aW5mbywKKwkJc3RydWN0IHhlbl93YWl0X29iaiAqd2FpdF9vYmopCit7CisJc3RydWN0IHhlbl93 YWl0X29iaiAqY3VyX3dhaXRfb2JqLCAqcTsKKworCXNwaW5fbG9jaygmZHJ2X2luZm8tPndhaXRf bGlzdF9sb2NrKTsKKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoY3VyX3dhaXRfb2JqLCBxLAor CQkJJmRydl9pbmZvLT53YWl0X29ial9saXN0LCBsaXN0KQorCQlpZiAoY3VyX3dhaXRfb2JqID09 IHdhaXRfb2JqKSB7CisJCQlsaXN0X2RlbCgmd2FpdF9vYmotPmxpc3QpOworCQkJa2ZyZWUod2Fp dF9vYmopOworCQkJYnJlYWs7CisJCX0KKwlzcGluX3VubG9jaygmZHJ2X2luZm8tPndhaXRfbGlz dF9sb2NrKTsKK30KKworc3RhdGljIHZvaWQgd2FpdF9vYmpfY2hlY2tfcGVuZGluZyhzdHJ1Y3Qg eGVuX2Rydl9pbmZvICpkcnZfaW5mbykKK3sKKwkvKgorCSAqIEl0IGlzIGludGVuZGVkIHRvIGJl IGNhbGxlZCBmcm9tIC5sYXN0X2Nsb3NlIHdoZW4KKwkgKiBubyBwZW5kaW5nIHdhaXQgb2JqZWN0 cyBzaG91bGQgYmUgb24gdGhlIGxpc3QuCisJICogbWFrZSBzdXJlIHdlIGRvbid0IG1pc3MgYSBi dWcgaWYgdGhpcyBpcyBub3QgdGhlIGNhc2UuCisJICovCisJV0FSTighbGlzdF9lbXB0eSgmZHJ2 X2luZm8tPndhaXRfb2JqX2xpc3QpLAorCQkJIlJlbW92aW5nIHdpdGggcGVuZGluZyB3YWl0IG9i amVjdHMhXG4iKTsKK30KKworc3RhdGljIGludCB3YWl0X29ial93YWl0KHN0cnVjdCB4ZW5fd2Fp dF9vYmogKndhaXRfb2JqLAorCQl1aW50MzJfdCB3YWl0X3RvX21zKQoreworCWlmICh3YWl0X2Zv cl9jb21wbGV0aW9uX3RpbWVvdXQoJndhaXRfb2JqLT5jb21wbGV0aW9uLAorCQkJbXNlY3NfdG9f amlmZmllcyh3YWl0X3RvX21zKSkgPD0gMCkKKwkJcmV0dXJuIC1FVElNRURPVVQ7CisKKwlyZXR1 cm4gMDsKK30KKworc3RhdGljIHZvaWQgd2FpdF9vYmpfc2lnbmFsKHN0cnVjdCB4ZW5fZHJ2X2lu Zm8gKmRydl9pbmZvLAorCQlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmopCit7CisJc3Ry dWN0IHhlbl93YWl0X29iaiAqd2FpdF9vYmosICpxOworCisJc3Bpbl9sb2NrKCZkcnZfaW5mby0+ d2FpdF9saXN0X2xvY2spOworCWxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZSh3YWl0X29iaiwgcSwg JmRydl9pbmZvLT53YWl0X29ial9saXN0LCBsaXN0KQorCQlpZiAod2FpdF9vYmotPnhlbl9vYmog PT0geGVuX29iaikgeworCQkJRFJNX0RFQlVHKCJGb3VuZCB4ZW5fb2JqIGluIHRoZSB3YWl0IGxp c3QsIHdha2VcbiIpOworCQkJY29tcGxldGVfYWxsKCZ3YWl0X29iai0+Y29tcGxldGlvbik7CisJ CX0KKwlzcGluX3VubG9jaygmZHJ2X2luZm8tPndhaXRfbGlzdF9sb2NrKTsKK30KKworc3RhdGlj IGludCB3YWl0X29ial9oYW5kbGVfbmV3KHN0cnVjdCB4ZW5fZHJ2X2luZm8gKmRydl9pbmZvLAor CQlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmopCit7CisJaW50IHJldDsKKworCWlkcl9w cmVsb2FkKEdGUF9LRVJORUwpOworCXNwaW5fbG9jaygmZHJ2X2luZm8tPmlkcl9sb2NrKTsKKwly ZXQgPSBpZHJfYWxsb2MoJmRydl9pbmZvLT5pZHIsIHhlbl9vYmosIDEsIDAsIEdGUF9OT1dBSVQp OworCXNwaW5fdW5sb2NrKCZkcnZfaW5mby0+aWRyX2xvY2spOworCWlkcl9wcmVsb2FkX2VuZCgp OworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyB2b2lkIHdhaXRfb2JqX2hhbmRsZV9mcmVlKHN0 cnVjdCB4ZW5fZHJ2X2luZm8gKmRydl9pbmZvLAorCQlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhl bl9vYmopCit7CisJc3Bpbl9sb2NrKCZkcnZfaW5mby0+aWRyX2xvY2spOworCWlkcl9yZW1vdmUo JmRydl9pbmZvLT5pZHIsIHhlbl9vYmotPndhaXRfaGFuZGxlKTsKKwlzcGluX3VubG9jaygmZHJ2 X2luZm8tPmlkcl9sb2NrKTsKK30KKworc3RhdGljIHN0cnVjdCB4ZW5fZ2VtX29iamVjdCAqZ2V0 X29ial9ieV93YWl0X2hhbmRsZSgKKwkJc3RydWN0IHhlbl9kcnZfaW5mbyAqZHJ2X2luZm8sIGlu dCB3YWl0X2hhbmRsZSkKK3sKKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmo7CisKKwlz cGluX2xvY2soJmRydl9pbmZvLT5pZHJfbG9jayk7CisJLyogY2hlY2sgaWYgeGVuX29iaiBzdGls bCBleGlzdHMgKi8KKwl4ZW5fb2JqID0gaWRyX2ZpbmQoJmRydl9pbmZvLT5pZHIsIHdhaXRfaGFu ZGxlKTsKKwlpZiAoeGVuX29iaikKKwkJa3JlZl9nZXQoJnhlbl9vYmotPnJlZmNvdW50KTsKKwlz cGluX3VubG9jaygmZHJ2X2luZm8tPmlkcl9sb2NrKTsKKwlyZXR1cm4geGVuX29iajsKK30KKwor I2RlZmluZSB4ZW5fcGFnZV90b192YWRkcihwYWdlKSBcCisJKChwaHlzX2FkZHJfdClwZm5fdG9f a2FkZHIocGFnZV90b194ZW5fcGZuKHBhZ2UpKSkKKworc3RhdGljIGludCBmcm9tX3JlZnNfdW5t YXAoc3RydWN0IGRldmljZSAqZGV2LAorCQlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmop Cit7CisJc3RydWN0IGdudHRhYl91bm1hcF9ncmFudF9yZWYgKnVubWFwX29wczsKKwlpbnQgaSwg cmV0OworCisJaWYgKCF4ZW5fb2JqLT5wYWdlcyB8fCAheGVuX29iai0+bWFwX2hhbmRsZXMpCisJ CXJldHVybiAwOworCisJdW5tYXBfb3BzID0ga2NhbGxvYyh4ZW5fb2JqLT5udW1fcGFnZXMsIHNp emVvZigqdW5tYXBfb3BzKSwgR0ZQX0tFUk5FTCk7CisJaWYgKCF1bm1hcF9vcHMpCisJCXJldHVy biAtRU5PTUVNOworCisJZm9yIChpID0gMDsgaSA8IHhlbl9vYmotPm51bV9wYWdlczsgaSsrKSB7 CisJCXBoeXNfYWRkcl90IGFkZHI7CisKKwkJLyoKKwkJICogV2hlbiB1bm1hcHBpbmcgdGhlIGdy YW50IGVudHJ5IGZvciBhY2Nlc3MgYnkgaG9zdCBDUFVzOgorCQkgKiBpZiA8aG9zdF9hZGRyPiBv ciA8ZGV2X2J1c19hZGRyPiBpcyB6ZXJvLCB0aGF0CisJCSAqIGZpZWxkIGlzIGlnbm9yZWQuIElm IG5vbi16ZXJvLCB0aGV5IG11c3QgcmVmZXIgdG8KKwkJICogYSBkZXZpY2UvaG9zdCBtYXBwaW5n IHRoYXQgaXMgdHJhY2tlZCBieSA8aGFuZGxlPgorCQkgKi8KKwkJYWRkciA9IHhlbl9wYWdlX3Rv X3ZhZGRyKHhlbl9vYmotPnBhZ2VzW2ldKTsKKwkJZ250dGFiX3NldF91bm1hcF9vcCgmdW5tYXBf b3BzW2ldLCBhZGRyLAorI2lmIGRlZmluZWQoQ09ORklHX1g4NikKKwkJCUdOVE1BUF9ob3N0X21h cCB8IEdOVE1BUF9kZXZpY2VfbWFwLAorI2Vsc2UKKwkJCUdOVE1BUF9ob3N0X21hcCwKKyNlbmRp ZgorCQkJeGVuX29iai0+bWFwX2hhbmRsZXNbaV0pOworCQl1bm1hcF9vcHNbaV0uZGV2X2J1c19h ZGRyID0gX19wZm5fdG9fcGh5cyhfX3Bmbl90b19tZm4oCisJCQkJcGFnZV90b19wZm4oeGVuX29i ai0+cGFnZXNbaV0pKSk7CisJfQorCisJcmV0ID0gZ250dGFiX3VubWFwX3JlZnModW5tYXBfb3Bz LCBOVUxMLCB4ZW5fb2JqLT5wYWdlcywKKwkJCXhlbl9vYmotPm51bV9wYWdlcyk7CisJLyoKKwkg KiBFdmVuIGlmIHdlIGRpZG4ndCB1bm1hcCBwcm9wZXJseSAtIGNvbnRpbnVlIHRvIHJlc2N1ZSB3 aGF0ZXZlcgorCSAqIHJlc291cmNlcyB3ZSBjYW4uCisJICovCisJaWYgKHJldCkKKwkJRFJNX0VS Uk9SKCJGYWlsZWQgdG8gdW5tYXAgZ3JhbnQgcmVmZXJlbmNlcywgcmV0ICVkIiwgcmV0KTsKKwor CWZvciAoaSA9IDA7IGkgPCB4ZW5fb2JqLT5udW1fcGFnZXM7IGkrKykgeworCQlpZiAodW5saWtl bHkodW5tYXBfb3BzW2ldLnN0YXR1cyAhPSBHTlRTVF9va2F5KSkKKwkJCURSTV9FUlJPUigiRmFp bGVkIHRvIHVubWFwIHBhZ2UgJWQgd2l0aCByZWYgJWQ6ICVkXG4iLAorCQkJCQlpLCB4ZW5fb2Jq LT5ncmVmc1tpXSwKKwkJCQkJdW5tYXBfb3BzW2ldLnN0YXR1cyk7CisJfQorCisJeGVuX2RybV96 Y29weV9iYWxsb29uZWRfcGFnZXNfZnJlZShkZXYsICZ4ZW5fb2JqLT5iYWxsb29uLAorCQkJeGVu X29iai0+bnVtX3BhZ2VzLCB4ZW5fb2JqLT5wYWdlcyk7CisKKwlrZnJlZSh4ZW5fb2JqLT5wYWdl cyk7CisJeGVuX29iai0+cGFnZXMgPSBOVUxMOworCWtmcmVlKHhlbl9vYmotPm1hcF9oYW5kbGVz KTsKKwl4ZW5fb2JqLT5tYXBfaGFuZGxlcyA9IE5VTEw7CisJa2ZyZWUodW5tYXBfb3BzKTsKKwlr ZnJlZSh4ZW5fb2JqLT5ncmVmcyk7CisJeGVuX29iai0+Z3JlZnMgPSBOVUxMOworCXJldHVybiBy ZXQ7Cit9CisKK3N0YXRpYyBpbnQgZnJvbV9yZWZzX21hcChzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0 cnVjdCB4ZW5fZ2VtX29iamVjdCAqeGVuX29iaikKK3sKKwlzdHJ1Y3QgZ250dGFiX21hcF9ncmFu dF9yZWYgKm1hcF9vcHMgPSBOVUxMOworCWludCByZXQsIGk7CisKKwlpZiAoeGVuX29iai0+cGFn ZXMpIHsKKwkJRFJNX0VSUk9SKCJNYXBwaW5nIGFscmVhZHkgbWFwcGVkIHBhZ2VzP1xuIik7CisJ CXJldHVybiAtRUlOVkFMOworCX0KKworCXhlbl9vYmotPnBhZ2VzID0ga2NhbGxvYyh4ZW5fb2Jq LT5udW1fcGFnZXMsIHNpemVvZigqeGVuX29iai0+cGFnZXMpLAorCQkJR0ZQX0tFUk5FTCk7CisJ aWYgKCF4ZW5fb2JqLT5wYWdlcykgeworCQlyZXQgPSAtRU5PTUVNOworCQlnb3RvIGZhaWw7CisJ fQorCisJeGVuX29iai0+bWFwX2hhbmRsZXMgPSBrY2FsbG9jKHhlbl9vYmotPm51bV9wYWdlcywK KwkJCXNpemVvZigqeGVuX29iai0+bWFwX2hhbmRsZXMpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXhl bl9vYmotPm1hcF9oYW5kbGVzKSB7CisJCXJldCA9IC1FTk9NRU07CisJCWdvdG8gZmFpbDsKKwl9 CisKKwltYXBfb3BzID0ga2NhbGxvYyh4ZW5fb2JqLT5udW1fcGFnZXMsIHNpemVvZigqbWFwX29w cyksIEdGUF9LRVJORUwpOworCWlmICghbWFwX29wcykgeworCQlyZXQgPSAtRU5PTUVNOworCQln b3RvIGZhaWw7CisJfQorCisJcmV0ID0geGVuX2RybV96Y29weV9iYWxsb29uZWRfcGFnZXNfYWxs b2MoZGV2LCAmeGVuX29iai0+YmFsbG9vbiwKKwkJCXhlbl9vYmotPm51bV9wYWdlcywgeGVuX29i ai0+cGFnZXMpOworCWlmIChyZXQgPCAwKSB7CisJCURSTV9FUlJPUigiQ2Fubm90IGFsbG9jYXRl ICVkIGJhbGxvb25lZCBwYWdlczogJWRcbiIsCisJCQkJeGVuX29iai0+bnVtX3BhZ2VzLCByZXQp OworCQlnb3RvIGZhaWw7CisJfQorCisJZm9yIChpID0gMDsgaSA8IHhlbl9vYmotPm51bV9wYWdl czsgaSsrKSB7CisJCXBoeXNfYWRkcl90IGFkZHI7CisKKwkJYWRkciA9IHhlbl9wYWdlX3RvX3Zh ZGRyKHhlbl9vYmotPnBhZ2VzW2ldKTsKKwkJZ250dGFiX3NldF9tYXBfb3AoJm1hcF9vcHNbaV0s IGFkZHIsCisjaWYgZGVmaW5lZChDT05GSUdfWDg2KQorCQkJR05UTUFQX2hvc3RfbWFwIHwgR05U TUFQX2RldmljZV9tYXAsCisjZWxzZQorCQkJR05UTUFQX2hvc3RfbWFwLAorI2VuZGlmCisJCQl4 ZW5fb2JqLT5ncmVmc1tpXSwgeGVuX29iai0+b3RoZXJlbmRfaWQpOworCX0KKwlyZXQgPSBnbnR0 YWJfbWFwX3JlZnMobWFwX29wcywgTlVMTCwgeGVuX29iai0+cGFnZXMsCisJCQl4ZW5fb2JqLT5u dW1fcGFnZXMpOworCisJLyogc2F2ZSBoYW5kbGVzIGV2ZW4gaWYgZXJyb3IsIHNvIHdlIGNhbiB1 bm1hcCAqLworCWZvciAoaSA9IDA7IGkgPCB4ZW5fb2JqLT5udW1fcGFnZXM7IGkrKykgeworCQl4 ZW5fb2JqLT5tYXBfaGFuZGxlc1tpXSA9IG1hcF9vcHNbaV0uaGFuZGxlOworCQlpZiAodW5saWtl bHkobWFwX29wc1tpXS5zdGF0dXMgIT0gR05UU1Rfb2theSkpCisJCQlEUk1fRVJST1IoIkZhaWxl ZCB0byBtYXAgcGFnZSAlZCB3aXRoIHJlZiAlZDogJWRcbiIsCisJCQkJaSwgeGVuX29iai0+Z3Jl ZnNbaV0sIG1hcF9vcHNbaV0uc3RhdHVzKTsKKwl9CisKKwlpZiAocmV0KSB7CisJCURSTV9FUlJP UigiRmFpbGVkIHRvIG1hcCBncmFudCByZWZlcmVuY2VzLCByZXQgJWQiLCByZXQpOworCQlmcm9t X3JlZnNfdW5tYXAoZGV2LCB4ZW5fb2JqKTsKKwkJZ290byBmYWlsOworCX0KKworCWtmcmVlKG1h cF9vcHMpOworCXJldHVybiAwOworCitmYWlsOgorCWtmcmVlKHhlbl9vYmotPnBhZ2VzKTsKKwl4 ZW5fb2JqLT5wYWdlcyA9IE5VTEw7CisJa2ZyZWUoeGVuX29iai0+bWFwX2hhbmRsZXMpOworCXhl bl9vYmotPm1hcF9oYW5kbGVzID0gTlVMTDsKKwlrZnJlZShtYXBfb3BzKTsKKwlyZXR1cm4gcmV0 OworCit9CisKK3N0YXRpYyB2b2lkIHRvX3JlZnNfZW5kX2ZvcmVpZ25fYWNjZXNzKHN0cnVjdCB4 ZW5fZ2VtX29iamVjdCAqeGVuX29iaikKK3sKKwlpbnQgaTsKKworCWlmICh4ZW5fb2JqLT5ncmVm cykKKwkJZm9yIChpID0gMDsgaSA8IHhlbl9vYmotPm51bV9wYWdlczsgaSsrKQorCQkJaWYgKHhl bl9vYmotPmdyZWZzW2ldICE9IEdSQU5UX0lOVkFMSURfUkVGKQorCQkJCWdudHRhYl9lbmRfZm9y ZWlnbl9hY2Nlc3MoeGVuX29iai0+Z3JlZnNbaV0sCisJCQkJCQkwLCAwVUwpOworCisJa2ZyZWUo eGVuX29iai0+Z3JlZnMpOworCXhlbl9vYmotPmdyZWZzID0gTlVMTDsKKwl4ZW5fb2JqLT5zZ3Qg PSBOVUxMOworfQorCitzdGF0aWMgaW50IHRvX3JlZnNfZ3JhbnRfZm9yZWlnbl9hY2Nlc3Moc3Ry dWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqKQoreworCWdyYW50X3JlZl90IHByaXZfZ3JlZl9o ZWFkOworCWludCByZXQsIGosIGN1cl9yZWYsIG51bV9wYWdlczsKKwlzdHJ1Y3Qgc2dfcGFnZV9p dGVyIHNnX2l0ZXI7CisKKwlyZXQgPSBnbnR0YWJfYWxsb2NfZ3JhbnRfcmVmZXJlbmNlcyh4ZW5f b2JqLT5udW1fcGFnZXMsCisJCQkmcHJpdl9ncmVmX2hlYWQpOworCWlmIChyZXQgPCAwKSB7CisJ CURSTV9FUlJPUigiQ2Fubm90IGFsbG9jYXRlIGdyYW50IHJlZmVyZW5jZXNcbiIpOworCQlyZXR1 cm4gcmV0OworCX0KKworCWogPSAwOworCW51bV9wYWdlcyA9IHhlbl9vYmotPm51bV9wYWdlczsK Kwlmb3JfZWFjaF9zZ19wYWdlKHhlbl9vYmotPnNndC0+c2dsLCAmc2dfaXRlciwgeGVuX29iai0+ c2d0LT5uZW50cywgMCkgeworCQlzdHJ1Y3QgcGFnZSAqcGFnZTsKKworCQlwYWdlID0gc2dfcGFn ZV9pdGVyX3BhZ2UoJnNnX2l0ZXIpOworCQljdXJfcmVmID0gZ250dGFiX2NsYWltX2dyYW50X3Jl ZmVyZW5jZSgmcHJpdl9ncmVmX2hlYWQpOworCQlpZiAoY3VyX3JlZiA8IDApCisJCQlyZXR1cm4g Y3VyX3JlZjsKKworCQlnbnR0YWJfZ3JhbnRfZm9yZWlnbl9hY2Nlc3NfcmVmKGN1cl9yZWYsCisJ CQkJeGVuX29iai0+b3RoZXJlbmRfaWQsIHhlbl9wYWdlX3RvX2dmbihwYWdlKSwgMCk7CisJCXhl bl9vYmotPmdyZWZzW2orK10gPSBjdXJfcmVmOworCQludW1fcGFnZXMtLTsKKwl9CisKKwlXQVJO X09OKG51bV9wYWdlcyAhPSAwKTsKKworCWdudHRhYl9mcmVlX2dyYW50X3JlZmVyZW5jZXMocHJp dl9ncmVmX2hlYWQpOworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGdlbV9jcmVhdGVfd2l0 aF9oYW5kbGUoc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqLAorCQlzdHJ1Y3QgZHJtX2Zp bGUgKmZpbHAsIHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIGludCBzaXplKQoreworCXN0cnVjdCBk cm1fZ2VtX29iamVjdCAqZ2VtX29iajsKKwlpbnQgcmV0OworCisJZHJtX2dlbV9wcml2YXRlX29i amVjdF9pbml0KGRldiwgJnhlbl9vYmotPmJhc2UsIHNpemUpOworCWdlbV9vYmogPSAmeGVuX29i ai0+YmFzZTsKKwlyZXQgPSBkcm1fZ2VtX2hhbmRsZV9jcmVhdGUoZmlscCwgZ2VtX29iaiwgJnhl bl9vYmotPmR1bWJfaGFuZGxlKTsKKwkvKiBkcm9wIHJlZmVyZW5jZSBmcm9tIGFsbG9jYXRlIC0g aGFuZGxlIGhvbGRzIGl0IG5vdy4gKi8KKwlkcm1fZ2VtX29iamVjdF9wdXRfdW5sb2NrZWQoZ2Vt X29iaik7CisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIGludCBnZW1fY3JlYXRlX29iaihzdHJ1 Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmosCisJCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYsIHN0 cnVjdCBkcm1fZmlsZSAqZmlscCwgaW50IHNpemUpCit7CisJc3RydWN0IGRybV9nZW1fb2JqZWN0 ICpnZW1fb2JqOworCWludCByZXQ7CisKKwlyZXQgPSBnZW1fY3JlYXRlX3dpdGhfaGFuZGxlKHhl bl9vYmosIGZpbHAsIGRldiwgc2l6ZSk7CisJaWYgKHJldCA8IDApCisJCWdvdG8gZmFpbDsKKwor CWdlbV9vYmogPSBkcm1fZ2VtX29iamVjdF9sb29rdXAoZmlscCwgeGVuX29iai0+ZHVtYl9oYW5k bGUpOworCWlmICghZ2VtX29iaikgeworCQlEUk1fRVJST1IoIkxvb2t1cCBmb3IgaGFuZGxlICVk IGZhaWxlZFxuIiwKKwkJCQl4ZW5fb2JqLT5kdW1iX2hhbmRsZSk7CisJCXJldCA9IC1FSU5WQUw7 CisJCWdvdG8gZmFpbF9kZXN0cm95OworCX0KKworCWRybV9nZW1fb2JqZWN0X3B1dF91bmxvY2tl ZChnZW1fb2JqKTsKKwlyZXR1cm4gMDsKKworZmFpbF9kZXN0cm95OgorCWRybV9nZW1fZHVtYl9k ZXN0cm95KGZpbHAsIGRldiwgeGVuX29iai0+ZHVtYl9oYW5kbGUpOworZmFpbDoKKwlEUk1fRVJS T1IoIkZhaWxlZCB0byBjcmVhdGUgZHVtYiBidWZmZXI6ICVkXG4iLCByZXQpOworCXhlbl9vYmot PmR1bWJfaGFuZGxlID0gMDsKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgaW50IGdlbV9pbml0 X29iaihzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmosCisJCXN0cnVjdCBkcm1fZGV2aWNl ICpkZXYsIGludCBzaXplKQoreworCXN0cnVjdCBkcm1fZ2VtX29iamVjdCAqZ2VtX29iaiA9ICZ4 ZW5fb2JqLT5iYXNlOworCWludCByZXQ7CisKKwlyZXQgPSBkcm1fZ2VtX29iamVjdF9pbml0KGRl diwgZ2VtX29iaiwgc2l6ZSk7CisJaWYgKHJldCA8IDApCisJCXJldHVybiByZXQ7CisKKwlyZXQg PSBkcm1fZ2VtX2NyZWF0ZV9tbWFwX29mZnNldChnZW1fb2JqKTsKKwlpZiAocmV0IDwgMCkgewor CQlkcm1fZ2VtX29iamVjdF9yZWxlYXNlKGdlbV9vYmopOworCQlyZXR1cm4gcmV0OworCX0KKwor CXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCBvYmpfcmVsZWFzZShzdHJ1Y3Qga3JlZiAqa3Jl ZikKK3sKKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmogPQorCQkJY29udGFpbmVyX29m KGtyZWYsIHN0cnVjdCB4ZW5fZ2VtX29iamVjdCwgcmVmY291bnQpOworCXN0cnVjdCB4ZW5fZHJ2 X2luZm8gKmRydl9pbmZvID0geGVuX29iai0+YmFzZS5kZXYtPmRldl9wcml2YXRlOworCisJd2Fp dF9vYmpfc2lnbmFsKGRydl9pbmZvLCB4ZW5fb2JqKTsKKwlrZnJlZSh4ZW5fb2JqKTsKK30KKwor c3RhdGljIHZvaWQgZ2VtX2ZyZWVfb2JqZWN0X3VubG9ja2VkKHN0cnVjdCBkcm1fZ2VtX29iamVj dCAqZ2VtX29iaikKK3sKKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmogPSB0b194ZW5f Z2VtX29iaihnZW1fb2JqKTsKKwlzdHJ1Y3QgeGVuX2Rydl9pbmZvICpkcnZfaW5mbyA9IGdlbV9v YmotPmRldi0+ZGV2X3ByaXZhdGU7CisKKwlEUk1fREVCVUcoIkZyZWVpbmcgZHVtYiB3aXRoIGhh bmRsZSAlZFxuIiwgeGVuX29iai0+ZHVtYl9oYW5kbGUpOworCWlmICh4ZW5fb2JqLT5ncmVmcykg eworCQlpZiAoeGVuX29iai0+c2d0KSB7CisJCQlkcm1fcHJpbWVfZ2VtX2Rlc3Ryb3koJnhlbl9v YmotPmJhc2UsIHhlbl9vYmotPnNndCk7CisJCQl0b19yZWZzX2VuZF9mb3JlaWduX2FjY2Vzcyh4 ZW5fb2JqKTsKKwkJfSBlbHNlCisJCQlmcm9tX3JlZnNfdW5tYXAoZ2VtX29iai0+ZGV2LT5kZXYs IHhlbl9vYmopOworCX0KKworCWRybV9nZW1fb2JqZWN0X3JlbGVhc2UoZ2VtX29iaik7CisKKwl3 YWl0X29ial9oYW5kbGVfZnJlZShkcnZfaW5mbywgeGVuX29iaik7CisJa3JlZl9wdXQoJnhlbl9v YmotPnJlZmNvdW50LCBvYmpfcmVsZWFzZSk7Cit9CisKK3N0YXRpYyBzdHJ1Y3Qgc2dfdGFibGUg KmdlbV9wcmltZV9nZXRfc2dfdGFibGUoCisJCXN0cnVjdCBkcm1fZ2VtX29iamVjdCAqZ2VtX29i aikKK3sKKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmogPSB0b194ZW5fZ2VtX29iaihn ZW1fb2JqKTsKKwlzdHJ1Y3Qgc2dfdGFibGUgKnNndCA9IE5VTEw7CisKKwlpZiAodW5saWtlbHko IXhlbl9vYmotPnBhZ2VzKSkKKwkJcmV0dXJuIE5VTEw7CisKKwlzZ3QgPSBkcm1fcHJpbWVfcGFn ZXNfdG9fc2coeGVuX29iai0+cGFnZXMsIHhlbl9vYmotPm51bV9wYWdlcyk7CisKKwlpZiAodW5s aWtlbHkoIXNndCkpCisJCURSTV9FUlJPUigiRmFpbGVkIHRvIGV4cG9ydCBzZ3RcbiIpOworCWVs c2UKKwkJRFJNX0RFQlVHKCJFeHBvcnRpbmcgJXNjb250aWd1b3VzIGJ1ZmZlciBuZW50cyAlZFxu IiwKKwkJCQlzZ3QtPm5lbnRzID09IDEgPyAiIiA6ICJub24tIiwgc2d0LT5uZW50cyk7CisJcmV0 dXJuIHNndDsKK30KKworc3RydWN0IGRybV9nZW1fb2JqZWN0ICpnZW1fcHJpbWVfaW1wb3J0X3Nn X3RhYmxlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCisJCXN0cnVjdCBkbWFfYnVmX2F0dGFjaG1l bnQgKmF0dGFjaCwgc3RydWN0IHNnX3RhYmxlICpzZ3QpCit7CisJc3RydWN0IHhlbl9nZW1fb2Jq ZWN0ICp4ZW5fb2JqOworCWludCByZXQ7CisKKwl4ZW5fb2JqID0ga3phbGxvYyhzaXplb2YoKnhl bl9vYmopLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXhlbl9vYmopCisJCXJldHVybiBFUlJfUFRSKC1F Tk9NRU0pOworCisJcmV0ID0gZ2VtX2luaXRfb2JqKHhlbl9vYmosIGRldiwgYXR0YWNoLT5kbWFi dWYtPnNpemUpOworCWlmIChyZXQgPCAwKQorCQlnb3RvIGZhaWw7CisKKwlrcmVmX2luaXQoJnhl bl9vYmotPnJlZmNvdW50KTsKKwl4ZW5fb2JqLT5zZ3QgPSBzZ3Q7CisJeGVuX29iai0+bnVtX3Bh Z2VzID0gRElWX1JPVU5EX1VQKGF0dGFjaC0+ZG1hYnVmLT5zaXplLCBQQUdFX1NJWkUpOworCisJ RFJNX0RFQlVHKCJJbXBvcnRlZCBidWZmZXIgb2Ygc2l6ZSAlenUgd2l0aCBuZW50cyAldVxuIiwK KwkJCWF0dGFjaC0+ZG1hYnVmLT5zaXplLCBzZ3QtPm5lbnRzKTsKKwlyZXR1cm4gJnhlbl9vYmot PmJhc2U7CisKK2ZhaWw6CisJa2ZyZWUoeGVuX29iaik7CisJcmV0dXJuIEVSUl9QVFIocmV0KTsK K30KKworc3RhdGljIGludCBkb19pb2N0bF9mcm9tX3JlZnMoc3RydWN0IGRybV9kZXZpY2UgKmRl diwKKwkJc3RydWN0IGRybV94ZW5femNvcHlfZHVtYl9mcm9tX3JlZnMgKnJlcSwKKwkJc3RydWN0 IGRybV9maWxlICpmaWxwKQoreworCXN0cnVjdCB4ZW5fZHJ2X2luZm8gKmRydl9pbmZvID0gZGV2 LT5kZXZfcHJpdmF0ZTsKKwlzdHJ1Y3QgeGVuX2dlbV9vYmplY3QgKnhlbl9vYmo7CisJaW50IHJl dDsKKworCXhlbl9vYmogPSBremFsbG9jKHNpemVvZigqeGVuX29iaiksIEdGUF9LRVJORUwpOwor CWlmICgheGVuX29iaikKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlrcmVmX2luaXQoJnhlbl9vYmot PnJlZmNvdW50KTsKKwl4ZW5fb2JqLT5udW1fcGFnZXMgPSByZXEtPm51bV9ncmVmczsKKwl4ZW5f b2JqLT5vdGhlcmVuZF9pZCA9IHJlcS0+b3RoZXJlbmRfaWQ7CisJeGVuX29iai0+Z3JlZnMgPSBr Y2FsbG9jKHhlbl9vYmotPm51bV9wYWdlcywKKwkJCXNpemVvZihncmFudF9yZWZfdCksIEdGUF9L RVJORUwpOworCWlmICgheGVuX29iai0+Z3JlZnMpIHsKKwkJcmV0ID0gLUVOT01FTTsKKwkJZ290 byBmYWlsOworCX0KKworCWlmIChjb3B5X2Zyb21fdXNlcih4ZW5fb2JqLT5ncmVmcywgcmVxLT5n cmVmcywKKwkJCXhlbl9vYmotPm51bV9wYWdlcyAqIHNpemVvZihncmFudF9yZWZfdCkpKSB7CisJ CXJldCA9IC1FSU5WQUw7CisJCWdvdG8gZmFpbDsKKwl9CisKKwlyZXQgPSBmcm9tX3JlZnNfbWFw KGRldi0+ZGV2LCB4ZW5fb2JqKTsKKwlpZiAocmV0IDwgMCkKKwkJZ290byBmYWlsOworCisJcmV0 ID0gZ2VtX2NyZWF0ZV9vYmooeGVuX29iaiwgZGV2LCBmaWxwLAorCQkJcm91bmRfdXAocmVxLT5k dW1iLnNpemUsIFBBR0VfU0laRSkpOworCWlmIChyZXQgPCAwKQorCQlnb3RvIGZhaWw7CisKKwly ZXEtPmR1bWIuaGFuZGxlID0geGVuX29iai0+ZHVtYl9oYW5kbGU7CisKKwkvKgorCSAqIEdldCB1 c2VyLXZpc2libGUgaGFuZGxlIGZvciB0aGlzIEdFTSBvYmplY3QuCisJICogdGhlIHdhaXQgb2Jq ZWN0IGlzIG5vdCBhbGxvY2F0ZWQgYXQgdGhlIG1vbWVudCwKKwkgKiBidXQgaWYgbmVlZCBiZSBp dCB3aWxsIGJlIGFsbG9jYXRlZCBhdCB0aGUgdGltZSBvZgorCSAqIERSTV9YRU5fWkNPUFlfRFVN Ql9XQUlUX0ZSRUUgSU9DVEwKKwkgKi8KKwlyZXQgPSB3YWl0X29ial9oYW5kbGVfbmV3KGRydl9p bmZvLCB4ZW5fb2JqKTsKKwlpZiAocmV0IDwgMCkKKwkJZ290byBmYWlsOworCisJcmVxLT53YWl0 X2hhbmRsZSA9IHJldDsKKwl4ZW5fb2JqLT53YWl0X2hhbmRsZSA9IHJldDsKKwlyZXR1cm4gMDsK KworZmFpbDoKKwlrZnJlZSh4ZW5fb2JqLT5ncmVmcyk7CisJeGVuX29iai0+Z3JlZnMgPSBOVUxM OworCWtmcmVlKHhlbl9vYmopOworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgaW9jdGxf ZnJvbV9yZWZzKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCisJCXZvaWQgKmRhdGEsIHN0cnVjdCBk cm1fZmlsZSAqZmlscCkKK3sKKwlzdHJ1Y3QgZHJtX3hlbl96Y29weV9kdW1iX2Zyb21fcmVmcyAq cmVxID0KKwkJCShzdHJ1Y3QgZHJtX3hlbl96Y29weV9kdW1iX2Zyb21fcmVmcyAqKWRhdGE7CisJ c3RydWN0IGRybV9tb2RlX2NyZWF0ZV9kdW1iICphcmdzID0gJnJlcS0+ZHVtYjsKKwl1aW50MzJf dCBjcHAsIHN0cmlkZSwgc2l6ZTsKKworCWlmICghcmVxLT5udW1fZ3JlZnMgfHwgIXJlcS0+Z3Jl ZnMpCisJCXJldHVybiAtRUlOVkFMOworCisJaWYgKCFhcmdzLT53aWR0aCB8fCAhYXJncy0+aGVp Z2h0IHx8ICFhcmdzLT5icHApCisJCXJldHVybiAtRUlOVkFMOworCisJY3BwID0gRElWX1JPVU5E X1VQKGFyZ3MtPmJwcCwgOCk7CisJaWYgKCFjcHAgfHwgY3BwID4gMHhmZmZmZmZmZlUgLyBhcmdz LT53aWR0aCkKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlzdHJpZGUgPSBjcHAgKiBhcmdzLT53aWR0 aDsKKwlpZiAoYXJncy0+aGVpZ2h0ID4gMHhmZmZmZmZmZlUgLyBzdHJpZGUpCisJCXJldHVybiAt RUlOVkFMOworCisJc2l6ZSA9IGFyZ3MtPmhlaWdodCAqIHN0cmlkZTsKKwlpZiAoUEFHRV9BTElH TihzaXplKSA9PSAwKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCWFyZ3MtPnBpdGNoID0gRElWX1JP VU5EX1VQKGFyZ3MtPndpZHRoICogYXJncy0+YnBwLCA4KTsKKwlhcmdzLT5zaXplID0gYXJncy0+ cGl0Y2ggKiBhcmdzLT5oZWlnaHQ7CisJYXJncy0+aGFuZGxlID0gMDsKKwlpZiAocmVxLT5udW1f Z3JlZnMgPCBESVZfUk9VTkRfVVAoYXJncy0+c2l6ZSwgUEFHRV9TSVpFKSkgeworCQlEUk1fRVJS T1IoIlByb3ZpZGVkICVkIHBhZ2VzLCBuZWVkICVkXG4iLCByZXEtPm51bV9ncmVmcywKKwkJCQko aW50KURJVl9ST1VORF9VUChhcmdzLT5zaXplLCBQQUdFX1NJWkUpKTsKKwkJcmV0dXJuIC1FSU5W QUw7CisJfQorCisJcmV0dXJuIGRvX2lvY3RsX2Zyb21fcmVmcyhkZXYsIHJlcSwgZmlscCk7Cit9 CisKK3N0YXRpYyBpbnQgaW9jdGxfdG9fcmVmcyhzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAorCQl2 b2lkICpkYXRhLCBzdHJ1Y3QgZHJtX2ZpbGUgKmZpbHApCit7CisJc3RydWN0IHhlbl9nZW1fb2Jq ZWN0ICp4ZW5fb2JqOworCXN0cnVjdCBkcm1fZ2VtX29iamVjdCAqZ2VtX29iajsKKwlzdHJ1Y3Qg ZHJtX3hlbl96Y29weV9kdW1iX3RvX3JlZnMgKnJlcSA9CisJCQkoc3RydWN0IGRybV94ZW5femNv cHlfZHVtYl90b19yZWZzICopZGF0YTsKKwlpbnQgcmV0OworCisJaWYgKCFyZXEtPm51bV9ncmVm cyB8fCAhcmVxLT5ncmVmcykKKwkJcmV0dXJuIC1FSU5WQUw7CisKKwlnZW1fb2JqID0gZHJtX2dl bV9vYmplY3RfbG9va3VwKGZpbHAsIHJlcS0+aGFuZGxlKTsKKwlpZiAoIWdlbV9vYmopIHsKKwkJ RFJNX0VSUk9SKCJMb29rdXAgZm9yIGhhbmRsZSAlZCBmYWlsZWRcbiIsIHJlcS0+aGFuZGxlKTsK KwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJZHJtX2dlbV9vYmplY3RfcHV0X3VubG9ja2VkKGdl bV9vYmopOworCXhlbl9vYmogPSB0b194ZW5fZ2VtX29iaihnZW1fb2JqKTsKKworCWlmICh4ZW5f b2JqLT5udW1fcGFnZXMgIT0gcmVxLT5udW1fZ3JlZnMpIHsKKwkJRFJNX0VSUk9SKCJQcm92aWRl ZCAlZCBwYWdlcywgbmVlZCAlZFxuIiwgcmVxLT5udW1fZ3JlZnMsCisJCQkJeGVuX29iai0+bnVt X3BhZ2VzKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJeGVuX29iai0+b3RoZXJlbmRfaWQg PSByZXEtPm90aGVyZW5kX2lkOworCXhlbl9vYmotPmdyZWZzID0ga2NhbGxvYyh4ZW5fb2JqLT5u dW1fcGFnZXMsCisJCQlzaXplb2YoZ3JhbnRfcmVmX3QpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXhl bl9vYmotPmdyZWZzKSB7CisJCXJldCA9IC1FTk9NRU07CisJCWdvdG8gZmFpbDsKKwl9CisKKwly ZXQgPSB0b19yZWZzX2dyYW50X2ZvcmVpZ25fYWNjZXNzKHhlbl9vYmopOworCWlmIChyZXQgPCAw KQorCQlnb3RvIGZhaWw7CisKKwlpZiAoY29weV90b191c2VyKHJlcS0+Z3JlZnMsIHhlbl9vYmot PmdyZWZzLAorCQkJeGVuX29iai0+bnVtX3BhZ2VzICogc2l6ZW9mKGdyYW50X3JlZl90KSkpIHsK KwkJcmV0ID0gLUVJTlZBTDsKKwkJZ290byBmYWlsOworCX0KKworCXJldHVybiAwOworCitmYWls OgorCXRvX3JlZnNfZW5kX2ZvcmVpZ25fYWNjZXNzKHhlbl9vYmopOworCXJldHVybiByZXQ7Cit9 CisKK3N0YXRpYyBpbnQgaW9jdGxfd2FpdF9mcmVlKHN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCisJ CXZvaWQgKmRhdGEsIHN0cnVjdCBkcm1fZmlsZSAqZmlsZV9wcml2KQoreworCXN0cnVjdCBkcm1f eGVuX3pjb3B5X2R1bWJfd2FpdF9mcmVlICpyZXEgPQorCQkJKHN0cnVjdCBkcm1feGVuX3pjb3B5 X2R1bWJfd2FpdF9mcmVlICopZGF0YTsKKwlzdHJ1Y3QgeGVuX2Rydl9pbmZvICpkcnZfaW5mbyA9 IGRldi0+ZGV2X3ByaXZhdGU7CisJc3RydWN0IHhlbl9nZW1fb2JqZWN0ICp4ZW5fb2JqOworCXN0 cnVjdCB4ZW5fd2FpdF9vYmogKndhaXRfb2JqOworCWludCB3YWl0X2hhbmRsZSwgcmV0OworCisJ d2FpdF9oYW5kbGUgPSByZXEtPndhaXRfaGFuZGxlOworCS8qCisJICogdHJ5IHRvIGZpbmQgdGhl IHdhaXQgaGFuZGxlOiBpZiBub3QgZm91bmQgbWVhbnMgdGhhdAorCSAqIGVpdGhlciB0aGUgaGFu ZGxlIGhhcyBhbHJlYWR5IGJlZW4gZnJlZWQgb3Igd3JvbmcKKwkgKi8KKwl4ZW5fb2JqID0gZ2V0 X29ial9ieV93YWl0X2hhbmRsZShkcnZfaW5mbywgd2FpdF9oYW5kbGUpOworCWlmICgheGVuX29i aikKKwkJcmV0dXJuIC1FTk9FTlQ7CisKKwkvKgorCSAqIHhlbl9vYmogc3RpbGwgZXhpc3RzIGFu ZCBpcyByZWZlcmVuY2UgY291bnQgbG9ja2VkIGJ5IHVzIG5vdywgc28KKwkgKiBwcmVwYXJlIHRv IHdhaXQ6IGFsbG9jYXRlIHdhaXQgb2JqZWN0IGFuZCBhZGQgaXQgdG8gdGhlIHdhaXQgbGlzdCwK KwkgKiBzbyB3ZSBjYW4gZmluZCBpdCBvbiByZWxlYXNlCisJICovCisJd2FpdF9vYmogPSB3YWl0 X29ial9uZXcoZHJ2X2luZm8sIHhlbl9vYmopOworCS8qIHB1dCBvdXIgcmVmZXJlbmNlIGFuZCB3 YWl0IGZvciB4ZW5fb2JqIHJlbGVhc2UgdG8gZmlyZSAqLworCWtyZWZfcHV0KCZ4ZW5fb2JqLT5y ZWZjb3VudCwgb2JqX3JlbGVhc2UpOworCXJldCA9IFBUUl9FUlJfT1JfWkVSTyh3YWl0X29iaik7 CisJaWYgKHJldCA8IDApIHsKKwkJRFJNX0VSUk9SKCJGYWlsZWQgdG8gc2V0dXAgd2FpdCBvYmpl Y3QsIHJldCAlZFxuIiwgcmV0KTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXQgPSB3YWl0X29i al93YWl0KHdhaXRfb2JqLCByZXEtPndhaXRfdG9fbXMpOworCXdhaXRfb2JqX2ZyZWUoZHJ2X2lu Zm8sIHdhaXRfb2JqKTsKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgdm9pZCBsYXN0Y2xvc2Uo c3RydWN0IGRybV9kZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgeGVuX2Rydl9pbmZvICpkcnZfaW5m byA9IGRldi0+ZGV2X3ByaXZhdGU7CisKKwl3YWl0X29ial9jaGVja19wZW5kaW5nKGRydl9pbmZv KTsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1faW9jdGxfZGVzYyB4ZW5fZHJtX2lvY3Rs c1tdID0geworCURSTV9JT0NUTF9ERUZfRFJWKFhFTl9aQ09QWV9EVU1CX0ZST01fUkVGUywKKwkJ aW9jdGxfZnJvbV9yZWZzLAorCQlEUk1fQVVUSCB8IERSTV9DT05UUk9MX0FMTE9XIHwgRFJNX1VO TE9DS0VEKSwKKwlEUk1fSU9DVExfREVGX0RSVihYRU5fWkNPUFlfRFVNQl9UT19SRUZTLAorCQlp b2N0bF90b19yZWZzLAorCQlEUk1fQVVUSCB8IERSTV9DT05UUk9MX0FMTE9XIHwgRFJNX1VOTE9D S0VEKSwKKwlEUk1fSU9DVExfREVGX0RSVihYRU5fWkNPUFlfRFVNQl9XQUlUX0ZSRUUsCisJCWlv Y3RsX3dhaXRfZnJlZSwKKwkJRFJNX0FVVEggfCBEUk1fQ09OVFJPTF9BTExPVyB8IERSTV9VTkxP Q0tFRCksCit9OworCitzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyB4ZW5fZHJt X2ZvcHMgPSB7CisJLm93bmVyICAgICAgICAgID0gVEhJU19NT0RVTEUsCisJLm9wZW4gICAgICAg ICAgID0gZHJtX29wZW4sCisJLnJlbGVhc2UgICAgICAgID0gZHJtX3JlbGVhc2UsCisJLnVubG9j a2VkX2lvY3RsID0gZHJtX2lvY3RsLAorfTsKKworc3RhdGljIHN0cnVjdCBkcm1fZHJpdmVyIHhl bl9kcm1fZHJpdmVyID0geworCS5kcml2ZXJfZmVhdHVyZXMgICAgICAgICAgID0gRFJJVkVSX0dF TSB8IERSSVZFUl9QUklNRSwKKwkubGFzdGNsb3NlICAgICAgICAgICAgICAgICA9IGxhc3RjbG9z ZSwKKwkucHJpbWVfaGFuZGxlX3RvX2ZkICAgICAgICA9IGRybV9nZW1fcHJpbWVfaGFuZGxlX3Rv X2ZkLAorCS5nZW1fcHJpbWVfZXhwb3J0ICAgICAgICAgID0gZHJtX2dlbV9wcmltZV9leHBvcnQs CisJLmdlbV9wcmltZV9nZXRfc2dfdGFibGUgICAgPSBnZW1fcHJpbWVfZ2V0X3NnX3RhYmxlLAor CS5wcmltZV9mZF90b19oYW5kbGUgICAgICAgID0gZHJtX2dlbV9wcmltZV9mZF90b19oYW5kbGUs CisJLmdlbV9wcmltZV9pbXBvcnQgICAgICAgICAgPSBkcm1fZ2VtX3ByaW1lX2ltcG9ydCwKKwku Z2VtX3ByaW1lX2ltcG9ydF9zZ190YWJsZSA9IGdlbV9wcmltZV9pbXBvcnRfc2dfdGFibGUsCisJ LmdlbV9mcmVlX29iamVjdF91bmxvY2tlZCAgPSBnZW1fZnJlZV9vYmplY3RfdW5sb2NrZWQsCisJ LmZvcHMgICAgICAgICAgICAgICAgICAgICAgPSAmeGVuX2RybV9mb3BzLAorCS5pb2N0bHMgICAg ICAgICAgICAgICAgICAgID0geGVuX2RybV9pb2N0bHMsCisJLm51bV9pb2N0bHMgICAgICAgICAg ICAgICAgPSBBUlJBWV9TSVpFKHhlbl9kcm1faW9jdGxzKSwKKwkubmFtZSAgICAgICAgICAgICAg ICAgICAgICA9IFhFTkRSTV9aQ09QWV9EUklWRVJfTkFNRSwKKwkuZGVzYyAgICAgICAgICAgICAg ICAgICAgICA9ICJYZW4gUFYgRFJNIHplcm8gY29weSIsCisJLmRhdGUgICAgICAgICAgICAgICAg ICAgICAgPSAiMjAxODAyMjEiLAorCS5tYWpvciAgICAgICAgICAgICAgICAgICAgID0gMSwKKwku bWlub3IgICAgICAgICAgICAgICAgICAgICA9IDAsCit9OworCitzdGF0aWMgaW50IHhlbl9kcm1f ZHJ2X3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQoreworCXN0cnVjdCB4ZW5f ZHJ2X2luZm8gKmRydl9pbmZvID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CisKKwlpZiAo ZHJ2X2luZm8gJiYgZHJ2X2luZm8tPmRybV9kZXYpIHsKKwkJZHJtX2Rldl91bnJlZ2lzdGVyKGRy dl9pbmZvLT5kcm1fZGV2KTsKKwkJZHJtX2Rldl91bnJlZihkcnZfaW5mby0+ZHJtX2Rldik7CisJ CWlkcl9kZXN0cm95KCZkcnZfaW5mby0+aWRyKTsKKwl9CisJcmV0dXJuIDA7Cit9CisKK3N0YXRp YyBpbnQgeGVuX2RybV9kcnZfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sK KwlzdHJ1Y3QgeGVuX2Rydl9pbmZvICpkcnZfaW5mbzsKKwlpbnQgcmV0OworCisJRFJNX0lORk8o IkNyZWF0aW5nICVzXG4iLCB4ZW5fZHJtX2RyaXZlci5kZXNjKTsKKwlkcnZfaW5mbyA9IGt6YWxs b2Moc2l6ZW9mKCpkcnZfaW5mbyksIEdGUF9LRVJORUwpOworCWlmICghZHJ2X2luZm8pCisJCXJl dHVybiAtRU5PTUVNOworCisJaWRyX2luaXQoJmRydl9pbmZvLT5pZHIpOworCXNwaW5fbG9ja19p bml0KCZkcnZfaW5mby0+aWRyX2xvY2spOworCXNwaW5fbG9ja19pbml0KCZkcnZfaW5mby0+d2Fp dF9saXN0X2xvY2spOworCUlOSVRfTElTVF9IRUFEKCZkcnZfaW5mby0+d2FpdF9vYmpfbGlzdCk7 CisKKwkvKgorCSAqIFRoZSBkZXZpY2UgaXMgbm90IHNwYXduIGZyb20gYSBkZXZpY2UgdHJlZSwg c28gYXJjaF9zZXR1cF9kbWFfb3BzCisJICogaXMgbm90IGNhbGxlZCwgdGh1cyBsZWF2aW5nIHRo ZSBkZXZpY2Ugd2l0aCBkdW1teSBETUEgb3BzLgorCSAqIFRoaXMgbWFrZXMgdGhlIGRldmljZSBy ZXR1cm4gZXJyb3Igb24gUFJJTUUgYnVmZmVyIGltcG9ydCwgd2hpY2gKKwkgKiBpcyBub3QgY29y cmVjdDogdG8gZml4IHRoaXMgY2FsbCBvZl9kbWFfY29uZmlndXJlKCkgd2l0aCBhIE5VTEwKKwkg KiBub2RlIHRvIHNldCBkZWZhdWx0IERNQSBvcHMuCisJICovCisJb2ZfZG1hX2NvbmZpZ3VyZSgm cGRldi0+ZGV2LCBOVUxMKTsKKworCWRydl9pbmZvLT5kcm1fZGV2ID0gZHJtX2Rldl9hbGxvYygm eGVuX2RybV9kcml2ZXIsICZwZGV2LT5kZXYpOworCWlmICghZHJ2X2luZm8tPmRybV9kZXYpCisJ CXJldHVybiAtRU5PTUVNOworCisJcmV0ID0gZHJtX2Rldl9yZWdpc3RlcihkcnZfaW5mby0+ZHJt X2RldiwgMCk7CisJaWYgKHJldCA8IDApCisJCWdvdG8gZmFpbDsKKworCWRydl9pbmZvLT5kcm1f ZGV2LT5kZXZfcHJpdmF0ZSA9IGRydl9pbmZvOworCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYs IGRydl9pbmZvKTsKKworCURSTV9JTkZPKCJJbml0aWFsaXplZCAlcyAlZC4lZC4lZCAlcyBvbiBt aW5vciAlZFxuIiwKKwkJCXhlbl9kcm1fZHJpdmVyLm5hbWUsIHhlbl9kcm1fZHJpdmVyLm1ham9y LAorCQkJeGVuX2RybV9kcml2ZXIubWlub3IsIHhlbl9kcm1fZHJpdmVyLnBhdGNobGV2ZWwsCisJ CQl4ZW5fZHJtX2RyaXZlci5kYXRlLCBkcnZfaW5mby0+ZHJtX2Rldi0+cHJpbWFyeS0+aW5kZXgp OworCXJldHVybiAwOworCitmYWlsOgorCWRybV9kZXZfdW5yZWYoZHJ2X2luZm8tPmRybV9kZXYp OworCWtmcmVlKGRydl9pbmZvKTsKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgc3RydWN0IHBs YXRmb3JtX2RyaXZlciB6Y29weV9wbGF0Zm9ybV9kcnZfaW5mbyA9IHsKKwkucHJvYmUJCT0geGVu X2RybV9kcnZfcHJvYmUsCisJLnJlbW92ZQkJPSB4ZW5fZHJtX2Rydl9yZW1vdmUsCisJLmRyaXZl cgkJPSB7CisJCS5uYW1lCT0gWEVORFJNX1pDT1BZX0RSSVZFUl9OQU1FLAorCX0sCit9OworCitz dHJ1Y3QgcGxhdGZvcm1fZGV2aWNlX2luZm8gemNvcHlfZGV2X2luZm8gPSB7CisJLm5hbWUgPSBY RU5EUk1fWkNPUFlfRFJJVkVSX05BTUUsCisJLmlkID0gMCwKKwkubnVtX3JlcyA9IDAsCisJLmRt YV9tYXNrID0gRE1BX0JJVF9NQVNLKDMyKSwKK307CisKK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1f ZGV2aWNlICp4ZW5fcGRldjsKKworc3RhdGljIGludCBfX2luaXQgeGVuX2Rydl9pbml0KHZvaWQp Cit7CisJaW50IHJldDsKKworCS8qIEF0IHRoZSBtb21lbnQgd2Ugb25seSBzdXBwb3J0IGNhc2Ug d2l0aCBYRU5fUEFHRV9TSVpFID09IFBBR0VfU0laRSAqLworCWlmIChYRU5fUEFHRV9TSVpFICE9 IFBBR0VfU0laRSkgeworCQlEUk1fRVJST1IoWEVORFJNX1pDT1BZX0RSSVZFUl9OQU1FICI6IGRp ZmZlcmVudCBrZXJuZWwgYW5kIFhlbiBwYWdlIHNpemVzIGFyZSBub3Qgc3VwcG9ydGVkOiBYRU5f UEFHRV9TSVpFICglbHUpICE9IFBBR0VfU0laRSAoJWx1KVxuIiwKKwkJCQlYRU5fUEFHRV9TSVpF LCBQQUdFX1NJWkUpOworCQlyZXR1cm4gLUVOT0RFVjsKKwl9CisKKwlpZiAoIXhlbl9kb21haW4o KSkKKwkJcmV0dXJuIC1FTk9ERVY7CisKKwl4ZW5fcGRldiA9IHBsYXRmb3JtX2RldmljZV9yZWdp c3Rlcl9mdWxsKCZ6Y29weV9kZXZfaW5mbyk7CisJaWYgKCF4ZW5fcGRldikgeworCQlEUk1fRVJS T1IoIkZhaWxlZCB0byByZWdpc3RlciAiIFhFTkRSTV9aQ09QWV9EUklWRVJfTkFNRSAiIGRldmlj ZVxuIik7CisJCXJldHVybiAtRU5PREVWOworCX0KKworCXJldCA9IHBsYXRmb3JtX2RyaXZlcl9y ZWdpc3RlcigmemNvcHlfcGxhdGZvcm1fZHJ2X2luZm8pOworCWlmIChyZXQgIT0gMCkgeworCQlE Uk1fRVJST1IoIkZhaWxlZCB0byByZWdpc3RlciAiIFhFTkRSTV9aQ09QWV9EUklWRVJfTkFNRSAi IGRyaXZlcjogJWRcbiIsIHJldCk7CisJCXBsYXRmb3JtX2RldmljZV91bnJlZ2lzdGVyKHhlbl9w ZGV2KTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQg X19leGl0IHhlbl9kcnZfZmluaSh2b2lkKQoreworCWlmICh4ZW5fcGRldikKKwkJcGxhdGZvcm1f ZGV2aWNlX3VucmVnaXN0ZXIoeGVuX3BkZXYpOworCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVy KCZ6Y29weV9wbGF0Zm9ybV9kcnZfaW5mbyk7Cit9CisKK21vZHVsZV9pbml0KHhlbl9kcnZfaW5p dCk7Cittb2R1bGVfZXhpdCh4ZW5fZHJ2X2ZpbmkpOworCitNT0RVTEVfREVTQ1JJUFRJT04oIlhl biB6ZXJvLWNvcHkgaGVscGVyIERSTSBkZXZpY2UiKTsKK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsK ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV96Y29weV9iYWxsb29uLmMg Yi9kcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1femNvcHlfYmFsbG9vbi5jCm5ldyBmaWxlIG1v ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uMjY3OTIzM2I5Zjg0Ci0tLSAvZGV2L251bGwK KysrIGIvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX3pjb3B5X2JhbGxvb24uYwpAQCAtMCww ICsxLDE1NCBAQAorLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAgT1IgTUlUCisK Ky8qCisgKiAgWGVuIHplcm8tY29weSBoZWxwZXIgRFJNIGRldmljZQorICoKKyAqIENvcHlyaWdo dCAoQykgMjAxNi0yMDE4IEVQQU0gU3lzdGVtcyBJbmMuCisgKgorICogQXV0aG9yOiBPbGVrc2Fu ZHIgQW5kcnVzaGNoZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBhbS5jb20+CisgKi8K KworI2luY2x1ZGUgPGRybS9kcm1QLmg+CisKKyNpZiBkZWZpbmVkKENPTkZJR19EUk1fWEVOX1pD T1BZX0NNQSkKKyNpbmNsdWRlIDxhc20veGVuL2h5cGVyY2FsbC5oPgorI2luY2x1ZGUgPHhlbi9p bnRlcmZhY2UvbWVtb3J5Lmg+CisjaW5jbHVkZSA8eGVuL3BhZ2UuaD4KKyNlbHNlCisjaW5jbHVk ZSA8eGVuL2JhbGxvb24uaD4KKyNlbmRpZgorCisjaW5jbHVkZSAieGVuX2RybV96Y29weV9iYWxs b29uLmgiCisKKyNpZiBkZWZpbmVkKENPTkZJR19EUk1fWEVOX1pDT1BZX0NNQSkKK2ludCB4ZW5f ZHJtX3pjb3B5X2JhbGxvb25lZF9wYWdlc19hbGxvYyhzdHJ1Y3QgZGV2aWNlICpkZXYsCisJCXN0 cnVjdCB4ZW5fZHJtX3pjb3B5X2JhbGxvb24gKm9iaiwgaW50IG51bV9wYWdlcywKKwkJc3RydWN0 IHBhZ2UgKipwYWdlcykKK3sKKwl4ZW5fcGZuX3QgKmZyYW1lX2xpc3Q7CisJc2l6ZV90IHNpemU7 CisJaW50IGksIHJldDsKKwlkbWFfYWRkcl90IGRldl9hZGRyLCBjcHVfYWRkcjsKKwl2b2lkICp2 YWRkciA9IE5VTEw7CisJc3RydWN0IHhlbl9tZW1vcnlfcmVzZXJ2YXRpb24gcmVzZXJ2YXRpb24g PSB7CisJCS5hZGRyZXNzX2JpdHMgPSAwLAorCQkuZXh0ZW50X29yZGVyID0gMCwKKwkJLmRvbWlk ICAgICAgICA9IERPTUlEX1NFTEYKKwl9OworCisJc2l6ZSA9IG51bV9wYWdlcyAqIFBBR0VfU0la RTsKKwlEUk1fREVCVUcoIkJhbGxvb25pbmcgb3V0ICVkIHBhZ2VzLCBzaXplICV6dVxuIiwgbnVt X3BhZ2VzLCBzaXplKTsKKwlmcmFtZV9saXN0ID0ga2NhbGxvYyhudW1fcGFnZXMsIHNpemVvZigq ZnJhbWVfbGlzdCksIEdGUF9LRVJORUwpOworCWlmICghZnJhbWVfbGlzdCkKKwkJcmV0dXJuIC1F Tk9NRU07CisKKwl2YWRkciA9IGRtYV9hbGxvY193YyhkZXYsIHNpemUsICZkZXZfYWRkciwgR0ZQ X0tFUk5FTCB8IF9fR0ZQX05PV0FSTik7CisJaWYgKCF2YWRkcikgeworCQlEUk1fRVJST1IoIkZh aWxlZCB0byBhbGxvY2F0ZSBETUEgYnVmZmVyIHdpdGggc2l6ZSAlenVcbiIsCisJCQkJc2l6ZSk7 CisJCXJldCA9IC1FTk9NRU07CisJCWdvdG8gZmFpbDsKKwl9CisKKwljcHVfYWRkciA9IGRldl9h ZGRyOworCWZvciAoaSA9IDA7IGkgPCBudW1fcGFnZXM7IGkrKykgeworCQlwYWdlc1tpXSA9IHBm bl90b19wYWdlKF9fcGh5c190b19wZm4oY3B1X2FkZHIpKTsKKwkJLyoKKwkJICogWEVOTUVNX3Bv cHVsYXRlX3BoeXNtYXAgcmVxdWlyZXMgYSBQRk4gYmFzZWQgb24gWGVuCisJCSAqIGdyYW51bGFy aXR5LgorCQkgKi8KKwkJZnJhbWVfbGlzdFtpXSA9IHBhZ2VfdG9feGVuX3BmbihwYWdlc1tpXSk7 CisJCWNwdV9hZGRyICs9IFBBR0VfU0laRTsKKwl9CisKKwlzZXRfeGVuX2d1ZXN0X2hhbmRsZShy ZXNlcnZhdGlvbi5leHRlbnRfc3RhcnQsIGZyYW1lX2xpc3QpOworCXJlc2VydmF0aW9uLm5yX2V4 dGVudHMgPSBudW1fcGFnZXM7CisJLyogcmMgd2lsbCBob2xkIG51bWJlciBvZiBwYWdlcyBwcm9j ZXNzZWQgKi8KKwlyZXQgPSBIWVBFUlZJU09SX21lbW9yeV9vcChYRU5NRU1fZGVjcmVhc2VfcmVz ZXJ2YXRpb24sICZyZXNlcnZhdGlvbik7CisJaWYgKHJldCA8PSAwKSB7CisJCURSTV9FUlJPUigi RmFpbGVkIHRvIGJhbGxvb24gb3V0ICVkIHBhZ2VzICglZCksIHJldHJ5aW5nXG4iLAorCQkJCW51 bV9wYWdlcywgcmV0KTsKKwkJV0FSTl9PTihyZXQgIT0gbnVtX3BhZ2VzKTsKKwkJcmV0ID0gLUVG QVVMVDsKKwkJZ290byBmYWlsOworCX0KKworCW9iai0+dmFkZHIgPSB2YWRkcjsKKwlvYmotPmRl dl9idXNfYWRkciA9IGRldl9hZGRyOworCWtmcmVlKGZyYW1lX2xpc3QpOworCXJldHVybiAwOwor CitmYWlsOgorCWlmICh2YWRkcikKKwkJZG1hX2ZyZWVfd2MoZGV2LCBzaXplLCB2YWRkciwgZGV2 X2FkZHIpOworCisJa2ZyZWUoZnJhbWVfbGlzdCk7CisJcmV0dXJuIHJldDsKK30KKwordm9pZCB4 ZW5fZHJtX3pjb3B5X2JhbGxvb25lZF9wYWdlc19mcmVlKHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJ c3RydWN0IHhlbl9kcm1femNvcHlfYmFsbG9vbiAqb2JqLCBpbnQgbnVtX3BhZ2VzLAorCQlzdHJ1 Y3QgcGFnZSAqKnBhZ2VzKQoreworCXhlbl9wZm5fdCAqZnJhbWVfbGlzdDsKKwlpbnQgaSwgcmV0 OworCXNpemVfdCBzaXplOworCXN0cnVjdCB4ZW5fbWVtb3J5X3Jlc2VydmF0aW9uIHJlc2VydmF0 aW9uID0geworCQkuYWRkcmVzc19iaXRzID0gMCwKKwkJLmV4dGVudF9vcmRlciA9IDAsCisJCS5k b21pZCAgICAgICAgPSBET01JRF9TRUxGCisJfTsKKworCWlmICghcGFnZXMpCisJCXJldHVybjsK KworCWlmICghb2JqLT52YWRkcikKKwkJcmV0dXJuOworCisJZnJhbWVfbGlzdCA9IGtjYWxsb2Mo bnVtX3BhZ2VzLCBzaXplb2YoKmZyYW1lX2xpc3QpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIWZyYW1l X2xpc3QpIHsKKwkJRFJNX0VSUk9SKCJGYWlsZWQgdG8gYmFsbG9vbiBpbiAlZCBwYWdlc1xuIiwg bnVtX3BhZ2VzKTsKKwkJcmV0dXJuOworCX0KKworCURSTV9ERUJVRygiQmFsbG9vbmluZyBpbiAl ZCBwYWdlc1xuIiwgbnVtX3BhZ2VzKTsKKwlzaXplID0gbnVtX3BhZ2VzICogUEFHRV9TSVpFOwor CWZvciAoaSA9IDA7IGkgPCBudW1fcGFnZXM7IGkrKykgeworCQkvKgorCQkgKiBYRU5NRU1fcG9w dWxhdGVfcGh5c21hcCByZXF1aXJlcyBhIFBGTiBiYXNlZCBvbiBYZW4KKwkJICogZ3JhbnVsYXJp dHkuCisJCSAqLworCQlmcmFtZV9saXN0W2ldID0gcGFnZV90b194ZW5fcGZuKHBhZ2VzW2ldKTsK Kwl9CisKKwlzZXRfeGVuX2d1ZXN0X2hhbmRsZShyZXNlcnZhdGlvbi5leHRlbnRfc3RhcnQsIGZy YW1lX2xpc3QpOworCXJlc2VydmF0aW9uLm5yX2V4dGVudHMgPSBudW1fcGFnZXM7CisJLyogcmMg d2lsbCBob2xkIG51bWJlciBvZiBwYWdlcyBwcm9jZXNzZWQgKi8KKwlyZXQgPSBIWVBFUlZJU09S X21lbW9yeV9vcChYRU5NRU1fcG9wdWxhdGVfcGh5c21hcCwgJnJlc2VydmF0aW9uKTsKKwlpZiAo cmV0IDw9IDApIHsKKwkJRFJNX0VSUk9SKCJGYWlsZWQgdG8gYmFsbG9vbiBpbiAlZCBwYWdlc1xu IiwgbnVtX3BhZ2VzKTsKKwkJV0FSTl9PTihyZXQgIT0gbnVtX3BhZ2VzKTsKKwl9CisKKwlpZiAo b2JqLT52YWRkcikKKwkJZG1hX2ZyZWVfd2MoZGV2LCBzaXplLCBvYmotPnZhZGRyLCBvYmotPmRl dl9idXNfYWRkcik7CisKKwlvYmotPnZhZGRyID0gTlVMTDsKKwlvYmotPmRldl9idXNfYWRkciA9 IDA7CisJa2ZyZWUoZnJhbWVfbGlzdCk7Cit9CisjZWxzZQoraW50IHhlbl9kcm1femNvcHlfYmFs bG9vbmVkX3BhZ2VzX2FsbG9jKHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJc3RydWN0IHhlbl9kcm1f emNvcHlfYmFsbG9vbiAqb2JqLCBpbnQgbnVtX3BhZ2VzLAorCQlzdHJ1Y3QgcGFnZSAqKnBhZ2Vz KQoreworCXJldHVybiBhbGxvY194ZW5iYWxsb29uZWRfcGFnZXMobnVtX3BhZ2VzLCBwYWdlcyk7 Cit9CisKK3ZvaWQgeGVuX2RybV96Y29weV9iYWxsb29uZWRfcGFnZXNfZnJlZShzdHJ1Y3QgZGV2 aWNlICpkZXYsCisJCXN0cnVjdCB4ZW5fZHJtX3pjb3B5X2JhbGxvb24gKm9iaiwgaW50IG51bV9w YWdlcywKKwkJc3RydWN0IHBhZ2UgKipwYWdlcykKK3sKKwlmcmVlX3hlbmJhbGxvb25lZF9wYWdl cyhudW1fcGFnZXMsIHBhZ2VzKTsKK30KKyNlbmRpZiAvKiBkZWZpbmVkKENPTkZJR19EUk1fWEVO X1pDT1BZX0NNQSkgKi8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS94ZW4veGVuX2RybV96 Y29weV9iYWxsb29uLmggYi9kcml2ZXJzL2dwdS9kcm0veGVuL3hlbl9kcm1femNvcHlfYmFsbG9v bi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uMTE1MWYxN2Y5MzM5 Ci0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9ncHUvZHJtL3hlbi94ZW5fZHJtX3pjb3B5X2Jh bGxvb24uaApAQCAtMCwwICsxLDM4IEBACisvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BM LTIuMCBPUiBNSVQgKi8KKworLyoKKyAqICBYZW4gemVyby1jb3B5IGhlbHBlciBEUk0gZGV2aWNl CisgKgorICogQ29weXJpZ2h0IChDKSAyMDE2LTIwMTggRVBBTSBTeXN0ZW1zIEluYy4KKyAqCisg KiBBdXRob3I6IE9sZWtzYW5kciBBbmRydXNoY2hlbmtvIDxvbGVrc2FuZHJfYW5kcnVzaGNoZW5r b0BlcGFtLmNvbT4KKyAqLworCisjaWZuZGVmIF9fWEVOX0RSTV9aQ09QWV9CQUxMT09OX0hfCisj ZGVmaW5lIF9fWEVOX0RSTV9aQ09QWV9CQUxMT09OX0hfCisKKyNpbmNsdWRlIDxsaW51eC90eXBl cy5oPgorCisjaWZuZGVmIEdSQU5UX0lOVkFMSURfUkVGCisvKgorICogTm90ZSBvbiB1c2FnZSBv ZiBncmFudCByZWZlcmVuY2UgMCBhcyBpbnZhbGlkIGdyYW50IHJlZmVyZW5jZToKKyAqIGdyYW50 IHJlZmVyZW5jZSAwIGlzIHZhbGlkLCBidXQgbmV2ZXIgZXhwb3NlZCB0byBhIFBWIGRyaXZlciwK KyAqIGJlY2F1c2Ugb2YgdGhlIGZhY3QgaXQgaXMgYWxyZWFkeSBpbiB1c2UvcmVzZXJ2ZWQgYnkg dGhlIFBWIGNvbnNvbGUuCisgKi8KKyNkZWZpbmUgR1JBTlRfSU5WQUxJRF9SRUYJMAorI2VuZGlm CisKK3N0cnVjdCB4ZW5fZHJtX3pjb3B5X2JhbGxvb24geworCXZvaWQgKnZhZGRyOworCWRtYV9h ZGRyX3QgZGV2X2J1c19hZGRyOworfTsKKworaW50IHhlbl9kcm1femNvcHlfYmFsbG9vbmVkX3Bh Z2VzX2FsbG9jKHN0cnVjdCBkZXZpY2UgKmRldiwKKwkJc3RydWN0IHhlbl9kcm1femNvcHlfYmFs bG9vbiAqb2JqLCBpbnQgbnVtX3BhZ2VzLAorCQlzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKKwordm9p ZCB4ZW5fZHJtX3pjb3B5X2JhbGxvb25lZF9wYWdlc19mcmVlKHN0cnVjdCBkZXZpY2UgKmRldiwK KwkJc3RydWN0IHhlbl9kcm1femNvcHlfYmFsbG9vbiAqb2JqLCBpbnQgbnVtX3BhZ2VzLAorCQlz dHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKKworI2VuZGlmIC8qIF9fWEVOX0RSTV9aQ09QWV9CQUxMT09O X0hfICovCmRpZmYgLS1naXQgYS9pbmNsdWRlL3VhcGkvZHJtL3hlbl96Y29weV9kcm0uaCBiL2lu Y2x1ZGUvdWFwaS9kcm0veGVuX3pjb3B5X2RybS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAwMDAwMC4uODc2N2NmYmYwMzUwCi0tLSAvZGV2L251bGwKKysrIGIvaW5jbHVkZS91 YXBpL2RybS94ZW5femNvcHlfZHJtLmgKQEAgLTAsMCArMSwxMjkgQEAKKy8qIFNQRFgtTGljZW5z ZS1JZGVudGlmaWVyOiBHUEwtMi4wIFdJVEggTGludXgtc3lzY2FsbC1ub3RlICovCisKKy8qCisg KiAgWGVuIHplcm8tY29weSBoZWxwZXIgRFJNIGRldmljZQorICoKKyAqIENvcHlyaWdodCAoQykg MjAxNi0yMDE4IEVQQU0gU3lzdGVtcyBJbmMuCisgKgorICogQXV0aG9yOiBPbGVrc2FuZHIgQW5k cnVzaGNoZW5rbyA8b2xla3NhbmRyX2FuZHJ1c2hjaGVua29AZXBhbS5jb20+CisgKi8KKyNpZm5k ZWYgX19YRU5fWkNPUFlfRFJNX0gKKyNkZWZpbmUgX19YRU5fWkNPUFlfRFJNX0gKKworI2luY2x1 ZGUgImRybS5oIgorCisjaWYgZGVmaW5lZChfX2NwbHVzcGx1cykKK2V4dGVybiAiQyIgeworI2Vu ZGlmCisKKyNkZWZpbmUgWEVORFJNX1pDT1BZX0RSSVZFUl9OQU1FCSJ4ZW5fZHJtX3pjb3B5Igor CisvKioKKyAqIERPQzogRFJNX1hFTl9aQ09QWV9EVU1CX0ZST01fUkVGUworICoKKyAqIFRoaXMg d2lsbCBjcmVhdGUgYSBEUk0gZHVtYiBidWZmZXIgZnJvbSBncmFudCByZWZlcmVuY2VzIHByb3Zp ZGVkCisgKiBieSB0aGUgZnJvbnRlbmQ6CisgKgorICogLSBGcm9udGVuZAorICoKKyAqICAtIGNy ZWF0ZXMgYSBkdW1iL2Rpc3BsYXkgYnVmZmVyIGFuZCBhbGxvY2F0ZXMgbWVtb3J5LgorICogIC0g Z3JhbnRzIGZvcmVpZ24gYWNjZXNzIHRvIHRoZSBidWZmZXIgcGFnZXMKKyAqICAtIHBhc3NlcyBn cmFudGVkIHJlZmVyZW5jZXMgdG8gdGhlIGJhY2tlbmQKKyAqCisgKiAtIEJhY2tlbmQKKyAqCisg KiAgLSBpc3N1ZXMgRFJNX1hFTl9aQ09QWV9EVU1CX0ZST01fUkVGUyBpb2N0bCB0byBtYXAKKyAq ICAgIGdyYW50ZWQgcmVmZXJlbmNlcyBhbmQgY3JlYXRlIGEgZHVtYiBidWZmZXIuCisgKiAgLSBy ZXF1ZXN0cyBoYW5kbGUgdG8gZmQgY29udmVyc2lvbiB2aWEgRFJNX0lPQ1RMX1BSSU1FX0hBTkRM RV9UT19GRAorICogIC0gcmVxdWVzdHMgcmVhbCBIVyBkcml2ZXIgdG8gaW1wb3J0IHRoZSBQUklN RSBidWZmZXIgd2l0aAorICogICAgRFJNX0lPQ1RMX1BSSU1FX0ZEX1RPX0hBTkRMRQorICogIC0g dXNlcyBoYW5kbGUgcmV0dXJuZWQgYnkgdGhlIHJlYWwgSFcgZHJpdmVyCisgKgorICogIEF0IHRo ZSBlbmQ6CisgKgorICogICAtIGNsb3NlcyByZWFsIEhXIGRyaXZlcidzIGhhbmRsZSB3aXRoIERS TV9JT0NUTF9HRU1fQ0xPU0UKKyAqICAgLSBjbG9zZXMgemVyby1jb3B5IGRyaXZlcidzIGhhbmRs ZSB3aXRoIERSTV9JT0NUTF9HRU1fQ0xPU0UKKyAqICAgLSBjbG9zZXMgZmlsZSBkZXNjcmlwdG9y IG9mIHRoZSBleHBvcnRlZCBidWZmZXIKKyAqICAgLSBtYXkgd2FpdCBmb3IgdGhlIG9iamVjdCB0 byBiZSBhY3R1YWxseSBmcmVlZCB2aWEgd2FpdF9oYW5kbGUKKyAqICAgICBhbmQgRFJNX1hFTl9a Q09QWV9EVU1CX1dBSVRfRlJFRQorICovCisjZGVmaW5lIERSTV9YRU5fWkNPUFlfRFVNQl9GUk9N X1JFRlMJMHgwMAorCitzdHJ1Y3QgZHJtX3hlbl96Y29weV9kdW1iX2Zyb21fcmVmcyB7CisJdWlu dDMyX3QgbnVtX2dyZWZzOworCS8qIHVzZXItc3BhY2UgdXNlcyB1aW50MzJfdCBpbnN0ZWFkIG9m IGdyYW50X3JlZl90IGZvciBtYXBwaW5nICovCisJdWludDMyX3QgKmdyZWZzOworCXVpbnQ2NF90 IG90aGVyZW5kX2lkOworCXN0cnVjdCBkcm1fbW9kZV9jcmVhdGVfZHVtYiBkdW1iOworCXVpbnQz Ml90IHdhaXRfaGFuZGxlOworfTsKKworLyoqCisgKiBET0M6IERSTV9YRU5fWkNPUFlfRFVNQl9U T19SRUZTCisgKgorICogVGhpcyB3aWxsIGdyYW50IHJlZmVyZW5jZXMgdG8gYSBkdW1iL2Rpc3Bs YXkgYnVmZmVyJ3MgbWVtb3J5IHByb3ZpZGVkIGJ5IHRoZQorICogYmFja2VuZDoKKyAqCisgKiAt IEZyb250ZW5kCisgKgorICogIC0gcmVxdWVzdHMgYmFja2VuZCB0byBhbGxvY2F0ZSBkdW1iL2Rp c3BsYXkgYnVmZmVyIGFuZCBncmFudCByZWZlcmVuY2VzCisgKiAgICB0byBpdHMgcGFnZXMKKyAq CisgKiAtIEJhY2tlbmQKKyAqCisgKiAgLSByZXF1ZXN0cyByZWFsIEhXIGRyaXZlciB0byBjcmVh dGUgYSBkdW1iIHdpdGggRFJNX0lPQ1RMX01PREVfQ1JFQVRFX0RVTUIKKyAqICAtIHJlcXVlc3Rz IGhhbmRsZSB0byBmZCBjb252ZXJzaW9uIHZpYSBEUk1fSU9DVExfUFJJTUVfSEFORExFX1RPX0ZE CisgKiAgLSByZXF1ZXN0cyB6ZXJvLWNvcHkgZHJpdmVyIHRvIGltcG9ydCB0aGUgUFJJTUUgYnVm ZmVyIHdpdGgKKyAqICAgIERSTV9JT0NUTF9QUklNRV9GRF9UT19IQU5ETEUKKyAqICAtIGlzc3Vl cyBEUk1fWEVOX1pDT1BZX0RVTUJfVE9fUkVGUyBpb2N0bCB0byBncmFudCByZWZlcmVuY2VzIHRv IHRoZQorICogICAgYnVmZmVyJ3MgbWVtb3J5LgorICogIC0gcGFzc2VzIGdyYW50IHJlZmVyZW5j ZXMgdG8gdGhlIGZyb250ZW5kCisgKgorICogIEF0IHRoZSBlbmQ6CisgKgorICogICAtIGNsb3Nl cyB6ZXJvLWNvcHkgZHJpdmVyJ3MgaGFuZGxlIHdpdGggRFJNX0lPQ1RMX0dFTV9DTE9TRQorICog ICAtIGNsb3NlcyByZWFsIEhXIGRyaXZlcidzIGhhbmRsZSB3aXRoIERSTV9JT0NUTF9HRU1fQ0xP U0UKKyAqICAgLSBjbG9zZXMgZmlsZSBkZXNjcmlwdG9yIG9mIHRoZSBpbXBvcnRlZCBidWZmZXIK KyAqLworI2RlZmluZSBEUk1fWEVOX1pDT1BZX0RVTUJfVE9fUkVGUwkweDAxCisKK3N0cnVjdCBk cm1feGVuX3pjb3B5X2R1bWJfdG9fcmVmcyB7CisJdWludDMyX3QgbnVtX2dyZWZzOworCS8qIHVz ZXItc3BhY2UgdXNlcyB1aW50MzJfdCBpbnN0ZWFkIG9mIGdyYW50X3JlZl90IGZvciBtYXBwaW5n ICovCisJdWludDMyX3QgKmdyZWZzOworCXVpbnQ2NF90IG90aGVyZW5kX2lkOworCXVpbnQzMl90 IGhhbmRsZTsKK307CisKKy8qKgorICogRE9DOiBEUk1fWEVOX1pDT1BZX0RVTUJfV0FJVF9GUkVF CisgKgorICogVGhpcyB3aWxsIGJsb2NrIHVudGlsIHRoZSBkdW1iIGJ1ZmZlciB3aXRoIHRoZSB3 YWl0IGhhbmRsZSBwcm92aWRlZCBiZSBmcmVlZDoKKyAqIHRoaXMgaXMgbmVlZGVkIGZvciBzeW5j aHJvbml6YXRpb24gYmV0d2VlbiBmcm9udGVuZCBhbmQgYmFja2VuZCBpbiBjYXNlCisgKiBmcm9u dGVuZCBwcm92aWRlcyBncmFudCByZWZlcmVuY2VzIG9mIHRoZSBidWZmZXIgdmlhCisgKiBEUk1f WEVOX1pDT1BZX0RVTUJfRlJPTV9SRUZTIElPQ1RMIGFuZCB3aGljaCBtdXN0IGJlIHJlbGVhc2Vk IGJlZm9yZQorICogYmFja2VuZCByZXBsaWVzIHdpdGggWEVORElTUExfT1BfREJVRl9ERVNUUk9Z IHJlc3BvbnNlLgorICogd2FpdF9oYW5kbGUgbXVzdCBiZSB0aGUgc2FtZSB2YWx1ZSByZXR1cm5l ZCB3aGlsZSBjYWxsaW5nCisgKiBEUk1fWEVOX1pDT1BZX0RVTUJfRlJPTV9SRUZTIElPQ1RMLgor ICovCisjZGVmaW5lIERSTV9YRU5fWkNPUFlfRFVNQl9XQUlUX0ZSRUUJMHgwMgorCitzdHJ1Y3Qg ZHJtX3hlbl96Y29weV9kdW1iX3dhaXRfZnJlZSB7CisJdWludDMyX3Qgd2FpdF9oYW5kbGU7CisJ dWludDMyX3Qgd2FpdF90b19tczsKK307CisKKyNkZWZpbmUgRFJNX0lPQ1RMX1hFTl9aQ09QWV9E VU1CX0ZST01fUkVGUyBEUk1fSU9XUihEUk1fQ09NTUFORF9CQVNFICsgXAorCURSTV9YRU5fWkNP UFlfRFVNQl9GUk9NX1JFRlMsIHN0cnVjdCBkcm1feGVuX3pjb3B5X2R1bWJfZnJvbV9yZWZzKQor CisjZGVmaW5lIERSTV9JT0NUTF9YRU5fWkNPUFlfRFVNQl9UT19SRUZTIERSTV9JT1dSKERSTV9D T01NQU5EX0JBU0UgKyBcCisJRFJNX1hFTl9aQ09QWV9EVU1CX1RPX1JFRlMsIHN0cnVjdCBkcm1f eGVuX3pjb3B5X2R1bWJfdG9fcmVmcykKKworI2RlZmluZSBEUk1fSU9DVExfWEVOX1pDT1BZX0RV TUJfV0FJVF9GUkVFIERSTV9JT1dSKERSTV9DT01NQU5EX0JBU0UgKyBcCisJRFJNX1hFTl9aQ09Q WV9EVU1CX1dBSVRfRlJFRSwgc3RydWN0IGRybV94ZW5femNvcHlfZHVtYl93YWl0X2ZyZWUpCisK KyNpZiBkZWZpbmVkKF9fY3BsdXNwbHVzKQorfQorI2VuZGlmCisKKyNlbmRpZiAvKiBfX1hFTl9a Q09QWV9EUk1fSCovCi0tIAoyLjE2LjIKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZy ZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3Rp bmZvL2RyaS1kZXZlbAo=