From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1764677AbdEWT0N (ORCPT ); Tue, 23 May 2017 15:26:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47264 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1764623AbdEWTZz (ORCPT ); Tue, 23 May 2017 15:25:55 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A5EDB80F9F Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=alex.williamson@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A5EDB80F9F Date: Tue, 23 May 2017 13:25:44 -0600 From: Alex Williamson To: Xiaoguang Chen Cc: kraxel@redhat.com, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, zhenyuw@linux.intel.com, zhiyuan.lv@intel.com, intel-gvt-dev@lists.freedesktop.org, zhi.a.wang@intel.com, kevin.tian@intel.com Subject: Re: [PATCH v5 4/5] drm/i915/gvt: Dmabuf support for GVT-g Message-ID: <20170523132544.361611a6@w520.home> In-Reply-To: <1495535521-2120-5-git-send-email-xiaoguang.chen@intel.com> References: <1495535521-2120-1-git-send-email-xiaoguang.chen@intel.com> <1495535521-2120-5-git-send-email-xiaoguang.chen@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 23 May 2017 19:25:54 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 23 May 2017 18:32:00 +0800 Xiaoguang Chen wrote: > dmabuf for GVT-g can be exported to users who can use the dmabuf to show > the desktop of vm which use intel vgpu. > > Currently we provide query and create new dmabuf operations. > > Users of dmabuf can cache some created dmabufs and related information > such as the framebuffer's address, size, tiling mode, width, height etc. > When refresh the screen first query the currnet vgpu's frambuffer and > compare with the cached ones(address, size, tiling, width, height etc) > if found one then reuse the found dmabuf to gain performance improvment. > > If there is no dmabuf created yet or not found in the cached dmabufs then > need to create a new dmabuf. To create a dmabuf first a gem object will > be created and the backing storage of this gem object is the vgpu's > framebuffer(primary/cursor). > Set caching mode, change tiling mode and set domains of this gem object > is not supported. > Then associate this gem object to a dmabuf and export this dmabuf. > A file descriptor will be generated for this dmabuf and this file > descriptor can be sent to user space to do display. > > Signed-off-by: Xiaoguang Chen > --- > drivers/gpu/drm/i915/gvt/Makefile | 2 +- > drivers/gpu/drm/i915/gvt/dmabuf.c | 276 +++++++++++++++++++++++++++++++++ > drivers/gpu/drm/i915/gvt/dmabuf.h | 53 +++++++ > drivers/gpu/drm/i915/gvt/gvt.h | 1 + > drivers/gpu/drm/i915/i915_gem.c | 8 + > drivers/gpu/drm/i915/i915_gem_object.h | 9 ++ > 6 files changed, 348 insertions(+), 1 deletion(-) > create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.c > create mode 100644 drivers/gpu/drm/i915/gvt/dmabuf.h > > diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile > index 192ca26..e480f7d 100644 > --- a/drivers/gpu/drm/i915/gvt/Makefile > +++ b/drivers/gpu/drm/i915/gvt/Makefile > @@ -2,7 +2,7 @@ GVT_DIR := gvt > GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \ > interrupt.o gtt.o cfg_space.o opregion.o mmio.o display.o edid.o \ > execlist.o scheduler.o sched_policy.o render.o cmd_parser.o \ > - fb_decoder.o > + fb_decoder.o dmabuf.o > > ccflags-y += -I$(src) -I$(src)/$(GVT_DIR) -Wall > i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE)) > diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c > new file mode 100644 > index 0000000..415453b > --- /dev/null > +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c > @@ -0,0 +1,276 @@ > +/* > + * Copyright 2017 Intel Corporation. All rights reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * > + * Authors: > + * Zhiyuan Lv > + * > + * Contributors: > + * Xiaoguang Chen > + */ > + > +#include > +#include > + > +#include "i915_drv.h" > +#include "gvt.h" > + > +#define GEN8_DECODE_PTE(pte) \ > + ((dma_addr_t)(((((u64)pte) >> 12) & 0x7ffffffULL) << 12)) > + > +static struct sg_table *intel_vgpu_gem_get_pages( > + struct drm_i915_gem_object *obj) > +{ > + struct drm_i915_private *dev_priv = to_i915(obj->base.dev); > + struct sg_table *st; > + struct scatterlist *sg; > + int i, ret; > + gen8_pte_t __iomem *gtt_entries; > + unsigned int fb_gma = 0, fb_size = 0; > + struct intel_vgpu_plane_info *plane_info; > + > + plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info; I can't find where gvt_plane_info is defined, but it's curious why it's not already this type. > + if (WARN_ON(!plane_info)) > + return ERR_PTR(-EINVAL); > + > + fb_gma = plane_info->start; > + fb_size = plane_info->size; > + > + st = kmalloc(sizeof(*st), GFP_KERNEL); > + if (!st) { > + ret = -ENOMEM; > + return ERR_PTR(ret); > + } > + > + ret = sg_alloc_table(st, fb_size, GFP_KERNEL); > + if (ret) { > + kfree(st); > + return ERR_PTR(ret); > + } > + gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + > + (fb_gma >> PAGE_SHIFT); > + for_each_sg(st->sgl, sg, fb_size, i) { > + sg->offset = 0; > + sg->length = PAGE_SIZE; > + sg_dma_address(sg) = > + GEN8_DECODE_PTE(readq(>t_entries[i])); > + sg_dma_len(sg) = PAGE_SIZE; > + } > + > + return st; > +} > + > +static void intel_vgpu_gem_put_pages(struct drm_i915_gem_object *obj, > + struct sg_table *pages) > +{ > + struct intel_vgpu_plane_info *plane_info; > + > + plane_info = (struct intel_vgpu_plane_info *)obj->gvt_plane_info; > + if (WARN_ON(!plane_info)) > + return; > + > + sg_free_table(pages); > + kfree(pages); > +} > + > +static const struct drm_i915_gem_object_ops intel_vgpu_gem_ops = { > + .flags = I915_GEM_OBJECT_IS_GVT_DMABUF, > + .get_pages = intel_vgpu_gem_get_pages, > + .put_pages = intel_vgpu_gem_put_pages, > +}; > + > +static struct drm_i915_gem_object *intel_vgpu_create_gem(struct drm_device *dev, > + struct intel_vgpu_plane_info *info) > +{ > + struct drm_i915_private *pri = dev->dev_private; > + struct drm_i915_gem_object *obj; > + > + obj = i915_gem_object_alloc(pri); > + if (obj == NULL) > + return NULL; > + > + drm_gem_private_object_init(dev, &obj->base, > + info->size << PAGE_SHIFT); > + i915_gem_object_init(obj, &intel_vgpu_gem_ops); > + > + obj->base.read_domains = I915_GEM_DOMAIN_GTT; > + obj->base.write_domain = 0; > + obj->framebuffer_references++; > + obj->gvt_plane_info = info; > + > + if (IS_SKYLAKE(pri)) { > + unsigned int tiling_mode = 0; > + > + switch (info->drm_format_mod << 10) { > + case PLANE_CTL_TILED_LINEAR: > + tiling_mode = I915_TILING_NONE; > + break; > + case PLANE_CTL_TILED_X: > + tiling_mode = I915_TILING_X; > + break; > + case PLANE_CTL_TILED_Y: > + tiling_mode = I915_TILING_Y; > + break; > + default: > + gvt_dbg_core("not supported tiling mode\n"); > + } > + obj->tiling_and_stride = tiling_mode | info->stride; > + } else { > + obj->tiling_and_stride = info->drm_format_mod ? > + I915_TILING_X : 0; > + } > + > + return obj; > +} > + > +static struct intel_vgpu_plane_info *intel_vgpu_get_plane_info( > + struct drm_device *dev, > + struct intel_vgpu *vgpu, uint32_t plane_id) > +{ > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_vgpu_primary_plane_format *p; > + struct intel_vgpu_cursor_plane_format *c; > + struct intel_vgpu_plane_info *info; > + struct intel_vgpu_pipe_format *pipe; > + > + info = kmalloc(sizeof(*info), GFP_KERNEL); > + if (!info) > + return NULL; > + > + pipe = intel_vgpu_decode_plane(dev, vgpu); > + if (pipe == NULL) > + return NULL; Leaks info, reverse order? > + > + if (plane_id == INTEL_GVT_PLANE_PRIMARY) { > + p = &pipe->primary; > + if (p != NULL) { > + info->start = p->base; > + info->width = p->width; > + info->height = p->height; > + info->stride = p->stride; > + info->drm_format = p->drm_format; > + info->drm_format_mod = p->tiled; > + info->size = (((p->stride * p->height * p->bpp) / 8) + > + (PAGE_SIZE - 1)) >> PAGE_SHIFT; > + } else { > + kfree(info); > + gvt_vgpu_err("invalid primary plane\n"); > + return NULL; > + } > + } else if (plane_id == INTEL_GVT_PLANE_CURSOR) { > + c = &pipe->cursor; > + if (c != NULL) { > + info->start = c->base; > + info->width = c->width; > + info->height = c->height; > + info->stride = c->width * (c->bpp / 8); > + info->drm_format_mod = 0; > + info->x_pos = c->x_pos; > + info->y_pos = c->y_pos; > + info->size = (((info->stride * c->height * c->bpp) / 8) > + + (PAGE_SIZE - 1)) >> PAGE_SHIFT; > + } else { > + kfree(info); > + gvt_vgpu_err("invalid cursor plane\n"); > + return NULL; > + } > + } else { > + kfree(info); > + gvt_vgpu_err("invalid plane id:%d\n", plane_id); > + return NULL; > + } > + > + if (info->size == 0) { > + kfree(info); > + gvt_vgpu_err("fb size is zero\n"); > + return NULL; > + } > + > + if (info->start & (PAGE_SIZE - 1)) { > + kfree(info); > + gvt_vgpu_err("Not aligned fb address:0x%x\n", info->start); > + return NULL; > + } > + if (((info->start >> PAGE_SHIFT) + info->size) > > + ggtt_total_entries(&dev_priv->ggtt)) { > + kfree(info); > + gvt_vgpu_err("Invalid GTT offset or size\n"); > + return NULL; > + } > + > + if (!intel_gvt_ggtt_validate_range(vgpu, info->start, info->size)) { > + kfree(info); > + gvt_vgpu_err("invalid gma addr\n"); > + return NULL; > + } Would it be useful to use ERR_PTR() so we could pass a relevant errno back up the stack to the user? > + > + return info; > +} > + > +int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args) > +{ > + struct drm_device *dev = &vgpu->gvt->dev_priv->drm; > + struct intel_vgpu_plane_info *info = args; > + > + info = intel_vgpu_get_plane_info(dev, vgpu, info->plane_id); > + if (info == NULL) > + return -EINVAL; Rather than this? > + > + return 0; > +} > + > +int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void *args) > +{ > + struct dma_buf *dmabuf; > + struct drm_i915_gem_object *obj; > + struct drm_device *dev = &vgpu->gvt->dev_priv->drm; > + struct intel_vgpu_dmabuf *gvt_dmabuf = args; > + struct intel_vgpu_plane_info *info; > + int ret; > + > + info = intel_vgpu_get_plane_info(dev, vgpu, > + gvt_dmabuf->plane_info.plane_id); > + if (info == NULL) > + return -EINVAL; > + > + obj = intel_vgpu_create_gem(dev, info); > + if (obj == NULL) { > + gvt_vgpu_err("create gvt gem obj failed:%d\n", vgpu->id); > + return -EINVAL; @info is leaked? > + } > + > + dmabuf = i915_gem_prime_export(dev, &obj->base, DRM_CLOEXEC | DRM_RDWR); > + > + if (IS_ERR(dmabuf)) { > + gvt_vgpu_err("export dma-buf failed\n"); > + return -EINVAL; @info & @obj leaked? > + } > + > + ret = dma_buf_fd(dmabuf, DRM_CLOEXEC | DRM_RDWR); > + if (ret < 0) { > + gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret); > + return -EINVAL; same Also, the fd is provided to the user and is a reference to the device, we need to increment the vfio_device reference and decrement on release. > + } > + gvt_dmabuf->fd = ret; > + gvt_dmabuf->plane_info = *info; > + > + return 0; same > +} > diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.h b/drivers/gpu/drm/i915/gvt/dmabuf.h > new file mode 100644 > index 0000000..43562af > --- /dev/null > +++ b/drivers/gpu/drm/i915/gvt/dmabuf.h > @@ -0,0 +1,53 @@ > + > +/* > + * Copyright(c) 2017 Intel Corporation. All rights reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE > + * SOFTWARE. > + * > + */ > + > +#ifndef _GVT_DMABUF_H_ > +#define _GVT_DMABUF_H_ > + > +struct intel_vgpu_plane_info { > + uint32_t plane_id; > + uint32_t drm_format; > + uint32_t width; > + uint32_t height; > + uint32_t stride; > + uint32_t start; > + uint32_t x_pos; > + uint32_t y_pos; > + uint32_t size; > + uint64_t drm_format_mod; > +}; Alignment issue as Gerd mentions. > + > +#define INTEL_VGPU_QUERY_PLANE 0 > +#define INTEL_VGPU_GENERATE_DMABUF 1 > + > +struct intel_vgpu_dmabuf { > + uint32_t fd; > + struct intel_vgpu_plane_info plane_info; > +}; And here, also as Gerd mentions. > + > +int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args); > +int intel_vgpu_create_dmabuf(struct intel_vgpu *vgpu, void *args); > + > +#endif > diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h > index c42266c..763a8c5 100644 > --- a/drivers/gpu/drm/i915/gvt/gvt.h > +++ b/drivers/gpu/drm/i915/gvt/gvt.h > @@ -47,6 +47,7 @@ > #include "render.h" > #include "cmd_parser.h" > #include "fb_decoder.h" > +#include "dmabuf.h" > > #define GVT_MAX_VGPU 8 > > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index 0c1cbe9..54f7a0f 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -1609,6 +1609,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, > if (!obj) > return -ENOENT; > > + /* The obj is a gvt dma-buf object and set domain is not supported */ > + if (i915_gem_object_is_gvt_dmabuf(obj)) > + return -EPERM; > + > /* Try to flush the object off the GPU without holding the lock. > * We will repeat the flush holding the lock in the normal manner > * to catch cases where we are gazumped. > @@ -3717,6 +3721,10 @@ int i915_gem_set_caching_ioctl(struct drm_device *dev, void *data, > if (!obj) > return -ENOENT; > > + /* the obj is a gvt dma-buf and set caching mode is not supported */ > + if (i915_gem_object_is_gvt_dmabuf(obj)) > + return -EPERM; > + > if (obj->cache_level == level) > goto out; > > diff --git a/drivers/gpu/drm/i915/i915_gem_object.h b/drivers/gpu/drm/i915/i915_gem_object.h > index 174cf92..986af43 100644 > --- a/drivers/gpu/drm/i915/i915_gem_object.h > +++ b/drivers/gpu/drm/i915/i915_gem_object.h > @@ -39,6 +39,7 @@ struct drm_i915_gem_object_ops { > unsigned int flags; > #define I915_GEM_OBJECT_HAS_STRUCT_PAGE 0x1 > #define I915_GEM_OBJECT_IS_SHRINKABLE 0x2 > +#define I915_GEM_OBJECT_IS_GVT_DMABUF 0x4 > > /* Interface between the GEM object and its backing storage. > * get_pages() is called once prior to the use of the associated set > @@ -184,6 +185,8 @@ struct drm_i915_gem_object { > } userptr; > > unsigned long scratch; > + > + void *gvt_plane_info; > }; > > /** for phys allocated objects */ > @@ -286,6 +289,12 @@ i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj) > } > > static inline bool > +i915_gem_object_is_gvt_dmabuf(const struct drm_i915_gem_object *obj) > +{ > + return obj->ops->flags & I915_GEM_OBJECT_IS_GVT_DMABUF; > +} > + > +static inline bool > i915_gem_object_is_active(const struct drm_i915_gem_object *obj) > { > return obj->active_count; From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Williamson Subject: Re: [PATCH v5 4/5] drm/i915/gvt: Dmabuf support for GVT-g Date: Tue, 23 May 2017 13:25:44 -0600 Message-ID: <20170523132544.361611a6@w520.home> References: <1495535521-2120-1-git-send-email-xiaoguang.chen@intel.com> <1495535521-2120-5-git-send-email-xiaoguang.chen@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1495535521-2120-5-git-send-email-xiaoguang.chen@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Xiaoguang Chen Cc: intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, zhiyuan.lv@intel.com, intel-gvt-dev@lists.freedesktop.org, kraxel@redhat.com List-Id: intel-gfx@lists.freedesktop.org T24gVHVlLCAyMyBNYXkgMjAxNyAxODozMjowMCArMDgwMApYaWFvZ3VhbmcgQ2hlbiA8eGlhb2d1 YW5nLmNoZW5AaW50ZWwuY29tPiB3cm90ZToKCj4gZG1hYnVmIGZvciBHVlQtZyBjYW4gYmUgZXhw b3J0ZWQgdG8gdXNlcnMgd2hvIGNhbiB1c2UgdGhlIGRtYWJ1ZiB0byBzaG93Cj4gdGhlIGRlc2t0 b3Agb2Ygdm0gd2hpY2ggdXNlIGludGVsIHZncHUuCj4gCj4gQ3VycmVudGx5IHdlIHByb3ZpZGUg cXVlcnkgYW5kIGNyZWF0ZSBuZXcgZG1hYnVmIG9wZXJhdGlvbnMuCj4gCj4gVXNlcnMgb2YgZG1h YnVmIGNhbiBjYWNoZSBzb21lIGNyZWF0ZWQgZG1hYnVmcyBhbmQgcmVsYXRlZCBpbmZvcm1hdGlv bgo+IHN1Y2ggYXMgdGhlIGZyYW1lYnVmZmVyJ3MgYWRkcmVzcywgc2l6ZSwgdGlsaW5nIG1vZGUs IHdpZHRoLCBoZWlnaHQgZXRjLgo+IFdoZW4gcmVmcmVzaCB0aGUgc2NyZWVuIGZpcnN0IHF1ZXJ5 IHRoZSBjdXJybmV0IHZncHUncyBmcmFtYnVmZmVyIGFuZAo+IGNvbXBhcmUgd2l0aCB0aGUgY2Fj aGVkIG9uZXMoYWRkcmVzcywgc2l6ZSwgdGlsaW5nLCB3aWR0aCwgaGVpZ2h0IGV0YykKPiBpZiBm b3VuZCBvbmUgdGhlbiByZXVzZSB0aGUgZm91bmQgZG1hYnVmIHRvIGdhaW4gcGVyZm9ybWFuY2Ug aW1wcm92bWVudC4KPiAKPiBJZiB0aGVyZSBpcyBubyBkbWFidWYgY3JlYXRlZCB5ZXQgb3Igbm90 IGZvdW5kIGluIHRoZSBjYWNoZWQgZG1hYnVmcyB0aGVuCj4gbmVlZCB0byBjcmVhdGUgYSBuZXcg ZG1hYnVmLiBUbyBjcmVhdGUgYSBkbWFidWYgZmlyc3QgYSBnZW0gb2JqZWN0IHdpbGwKPiBiZSBj cmVhdGVkIGFuZCB0aGUgYmFja2luZyBzdG9yYWdlIG9mIHRoaXMgZ2VtIG9iamVjdCBpcyB0aGUg dmdwdSdzCj4gZnJhbWVidWZmZXIocHJpbWFyeS9jdXJzb3IpLgo+IFNldCBjYWNoaW5nIG1vZGUs IGNoYW5nZSB0aWxpbmcgbW9kZSBhbmQgc2V0IGRvbWFpbnMgb2YgdGhpcyBnZW0gb2JqZWN0Cj4g aXMgbm90IHN1cHBvcnRlZC4KPiBUaGVuIGFzc29jaWF0ZSB0aGlzIGdlbSBvYmplY3QgdG8gYSBk bWFidWYgYW5kIGV4cG9ydCB0aGlzIGRtYWJ1Zi4KPiBBIGZpbGUgZGVzY3JpcHRvciB3aWxsIGJl IGdlbmVyYXRlZCBmb3IgdGhpcyBkbWFidWYgYW5kIHRoaXMgZmlsZQo+IGRlc2NyaXB0b3IgY2Fu IGJlIHNlbnQgdG8gdXNlciBzcGFjZSB0byBkbyBkaXNwbGF5Lgo+IAo+IFNpZ25lZC1vZmYtYnk6 IFhpYW9ndWFuZyBDaGVuIDx4aWFvZ3VhbmcuY2hlbkBpbnRlbC5jb20+Cj4gLS0tCj4gIGRyaXZl cnMvZ3B1L2RybS9pOTE1L2d2dC9NYWtlZmlsZSAgICAgIHwgICAyICstCj4gIGRyaXZlcnMvZ3B1 L2RybS9pOTE1L2d2dC9kbWFidWYuYyAgICAgIHwgMjc2ICsrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKwo+ICBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndnQvZG1hYnVmLmggICAgICB8ICA1 MyArKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d2dC9ndnQuaCAgICAgICAgIHwgICAx ICsKPiAgZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9nZW0uYyAgICAgICAgfCAgIDggKwo+ICBk cml2ZXJzL2dwdS9kcm0vaTkxNS9pOTE1X2dlbV9vYmplY3QuaCB8ICAgOSArKwo+ICA2IGZpbGVz IGNoYW5nZWQsIDM0OCBpbnNlcnRpb25zKCspLCAxIGRlbGV0aW9uKC0pCj4gIGNyZWF0ZSBtb2Rl IDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vaTkxNS9ndnQvZG1hYnVmLmMKPiAgY3JlYXRlIG1vZGUg MTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9pOTE1L2d2dC9kbWFidWYuaAo+IAo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndnQvTWFrZWZpbGUgYi9kcml2ZXJzL2dwdS9kcm0vaTkx NS9ndnQvTWFrZWZpbGUKPiBpbmRleCAxOTJjYTI2Li5lNDgwZjdkIDEwMDY0NAo+IC0tLSBhL2Ry aXZlcnMvZ3B1L2RybS9pOTE1L2d2dC9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9p OTE1L2d2dC9NYWtlZmlsZQo+IEBAIC0yLDcgKzIsNyBAQCBHVlRfRElSIDo9IGd2dAo+ICBHVlRf U09VUkNFIDo9IGd2dC5vIGFwZXJ0dXJlX2dtLm8gaGFuZGxlcnMubyB2Z3B1Lm8gdHJhY2VfcG9p bnRzLm8gZmlybXdhcmUubyBcCj4gIAlpbnRlcnJ1cHQubyBndHQubyBjZmdfc3BhY2UubyBvcHJl Z2lvbi5vIG1taW8ubyBkaXNwbGF5Lm8gZWRpZC5vIFwKPiAgCWV4ZWNsaXN0Lm8gc2NoZWR1bGVy Lm8gc2NoZWRfcG9saWN5Lm8gcmVuZGVyLm8gY21kX3BhcnNlci5vIFwKPiAtCWZiX2RlY29kZXIu bwo+ICsJZmJfZGVjb2Rlci5vIGRtYWJ1Zi5vCj4gIAo+ICBjY2ZsYWdzLXkJCQkJKz0gLUkkKHNy YykgLUkkKHNyYykvJChHVlRfRElSKSAtV2FsbAo+ICBpOTE1LXkJCQkJCSs9ICQoYWRkcHJlZml4 ICQoR1ZUX0RJUikvLCAkKEdWVF9TT1VSQ0UpKQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9k cm0vaTkxNS9ndnQvZG1hYnVmLmMgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndnQvZG1hYnVmLmMK PiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAuLjQxNTQ1M2IKPiAtLS0gL2Rl di9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Z0L2RtYWJ1Zi5jCj4gQEAgLTAs MCArMSwyNzYgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IDIwMTcgSW50ZWwgQ29ycG9yYXRpb24u IEFsbCByaWdodHMgcmVzZXJ2ZWQuCj4gKyAqCj4gKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdy YW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCj4gKyAqIGNv cHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0 aGUgIlNvZnR3YXJlIiksCj4gKyAqIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVz dHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KPiArICogdGhlIHJpZ2h0cyB0 byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vu c2UsCj4gKyAqIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJt aXQgcGVyc29ucyB0byB3aG9tIHRoZQo+ICsgKiBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8g c28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgo+ICsgKgo+ICsgKiBUaGUg YWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVk aW5nIHRoZSBuZXh0Cj4gKyAqIHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNv cGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUKPiArICogU29mdHdhcmUuCj4gKyAq Cj4gKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZ IE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCj4gKyAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9U IExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAo+ICsgKiBGSVRO RVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8g RVZFTlQgU0hBTEwKPiArICogVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElB QkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKPiArICogTElBQklMSVRZLCBXSEVU SEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcK PiArICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1Ig VEhFIFVTRSBPUiBPVEhFUgo+ICsgKiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCj4gKyAqCj4g KyAqIEF1dGhvcnM6Cj4gKyAqICAgIFpoaXl1YW4gTHYgPHpoaXl1YW4ubHZAaW50ZWwuY29tPgo+ ICsgKgo+ICsgKiBDb250cmlidXRvcnM6Cj4gKyAqICAgIFhpYW9ndWFuZyBDaGVuIDx4aWFvZ3Vh bmcuY2hlbkBpbnRlbC5jb20+Cj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2RtYS1idWYu aD4KPiArI2luY2x1ZGUgPGRybS9kcm1QLmg+Cj4gKwo+ICsjaW5jbHVkZSAiaTkxNV9kcnYuaCIK PiArI2luY2x1ZGUgImd2dC5oIgo+ICsKPiArI2RlZmluZSBHRU44X0RFQ09ERV9QVEUocHRlKSBc Cj4gKwkoKGRtYV9hZGRyX3QpKCgoKCh1NjQpcHRlKSA+PiAxMikgJiAweDdmZmZmZmZVTEwpIDw8 IDEyKSkKPiArCj4gK3N0YXRpYyBzdHJ1Y3Qgc2dfdGFibGUgKmludGVsX3ZncHVfZ2VtX2dldF9w YWdlcygKPiArCQlzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCAqb2JqKQo+ICt7Cj4gKwlzdHJ1 Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYgPSB0b19pOTE1KG9iai0+YmFzZS5kZXYpOwo+ ICsJc3RydWN0IHNnX3RhYmxlICpzdDsKPiArCXN0cnVjdCBzY2F0dGVybGlzdCAqc2c7Cj4gKwlp bnQgaSwgcmV0Owo+ICsJZ2VuOF9wdGVfdCBfX2lvbWVtICpndHRfZW50cmllczsKPiArCXVuc2ln bmVkIGludCBmYl9nbWEgPSAwLCBmYl9zaXplID0gMDsKPiArCXN0cnVjdCBpbnRlbF92Z3B1X3Bs YW5lX2luZm8gKnBsYW5lX2luZm87Cj4gKwo+ICsJcGxhbmVfaW5mbyA9IChzdHJ1Y3QgaW50ZWxf dmdwdV9wbGFuZV9pbmZvICopb2JqLT5ndnRfcGxhbmVfaW5mbzsKCkkgY2FuJ3QgZmluZCB3aGVy ZSBndnRfcGxhbmVfaW5mbyBpcyBkZWZpbmVkLCBidXQgaXQncyBjdXJpb3VzIHdoeSBpdCdzCm5v dCBhbHJlYWR5IHRoaXMgdHlwZS4KCj4gKwlpZiAoV0FSTl9PTighcGxhbmVfaW5mbykpCj4gKwkJ cmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gKwo+ICsJZmJfZ21hID0gcGxhbmVfaW5mby0+c3Rh cnQ7Cj4gKwlmYl9zaXplID0gcGxhbmVfaW5mby0+c2l6ZTsKPiArCj4gKwlzdCA9IGttYWxsb2Mo c2l6ZW9mKCpzdCksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFzdCkgewo+ICsJCXJldCA9IC1FTk9N RU07Cj4gKwkJcmV0dXJuIEVSUl9QVFIocmV0KTsKPiArCX0KPiArCj4gKwlyZXQgPSBzZ19hbGxv Y190YWJsZShzdCwgZmJfc2l6ZSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJa2Zy ZWUoc3QpOwo+ICsJCXJldHVybiBFUlJfUFRSKHJldCk7Cj4gKwl9Cj4gKwlndHRfZW50cmllcyA9 IChnZW44X3B0ZV90IF9faW9tZW0gKilkZXZfcHJpdi0+Z2d0dC5nc20gKwo+ICsJCShmYl9nbWEg Pj4gUEFHRV9TSElGVCk7Cj4gKwlmb3JfZWFjaF9zZyhzdC0+c2dsLCBzZywgZmJfc2l6ZSwgaSkg ewo+ICsJCXNnLT5vZmZzZXQgPSAwOwo+ICsJCXNnLT5sZW5ndGggPSBQQUdFX1NJWkU7Cj4gKwkJ c2dfZG1hX2FkZHJlc3Moc2cpID0KPiArCQkJR0VOOF9ERUNPREVfUFRFKHJlYWRxKCZndHRfZW50 cmllc1tpXSkpOwo+ICsJCXNnX2RtYV9sZW4oc2cpID0gUEFHRV9TSVpFOwo+ICsJfQo+ICsKPiAr CXJldHVybiBzdDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgaW50ZWxfdmdwdV9nZW1fcHV0X3Bh Z2VzKHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmosCj4gKwkJc3RydWN0IHNnX3RhYmxl ICpwYWdlcykKPiArewo+ICsJc3RydWN0IGludGVsX3ZncHVfcGxhbmVfaW5mbyAqcGxhbmVfaW5m bzsKPiArCj4gKwlwbGFuZV9pbmZvID0gKHN0cnVjdCBpbnRlbF92Z3B1X3BsYW5lX2luZm8gKilv YmotPmd2dF9wbGFuZV9pbmZvOwo+ICsJaWYgKFdBUk5fT04oIXBsYW5lX2luZm8pKQo+ICsJCXJl dHVybjsKPiArCj4gKwlzZ19mcmVlX3RhYmxlKHBhZ2VzKTsKPiArCWtmcmVlKHBhZ2VzKTsKPiAr fQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0X29wcyBpbnRl bF92Z3B1X2dlbV9vcHMgPSB7Cj4gKwkuZmxhZ3MgPSBJOTE1X0dFTV9PQkpFQ1RfSVNfR1ZUX0RN QUJVRiwKPiArCS5nZXRfcGFnZXMgPSBpbnRlbF92Z3B1X2dlbV9nZXRfcGFnZXMsCj4gKwkucHV0 X3BhZ2VzID0gaW50ZWxfdmdwdV9nZW1fcHV0X3BhZ2VzLAo+ICt9Owo+ICsKPiArc3RhdGljIHN0 cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICppbnRlbF92Z3B1X2NyZWF0ZV9nZW0oc3RydWN0IGRy bV9kZXZpY2UgKmRldiwKPiArCQlzdHJ1Y3QgaW50ZWxfdmdwdV9wbGFuZV9pbmZvICppbmZvKQo+ ICt7Cj4gKwlzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqcHJpID0gZGV2LT5kZXZfcHJpdmF0ZTsK PiArCXN0cnVjdCBkcm1faTkxNV9nZW1fb2JqZWN0ICpvYmo7Cj4gKwo+ICsJb2JqID0gaTkxNV9n ZW1fb2JqZWN0X2FsbG9jKHByaSk7Cj4gKwlpZiAob2JqID09IE5VTEwpCj4gKwkJcmV0dXJuIE5V TEw7Cj4gKwo+ICsJZHJtX2dlbV9wcml2YXRlX29iamVjdF9pbml0KGRldiwgJm9iai0+YmFzZSwK PiArCQlpbmZvLT5zaXplIDw8IFBBR0VfU0hJRlQpOwo+ICsJaTkxNV9nZW1fb2JqZWN0X2luaXQo b2JqLCAmaW50ZWxfdmdwdV9nZW1fb3BzKTsKPiArCj4gKwlvYmotPmJhc2UucmVhZF9kb21haW5z ID0gSTkxNV9HRU1fRE9NQUlOX0dUVDsKPiArCW9iai0+YmFzZS53cml0ZV9kb21haW4gPSAwOwo+ ICsJb2JqLT5mcmFtZWJ1ZmZlcl9yZWZlcmVuY2VzKys7Cj4gKwlvYmotPmd2dF9wbGFuZV9pbmZv ID0gaW5mbzsKPiArCj4gKwlpZiAoSVNfU0tZTEFLRShwcmkpKSB7Cj4gKwkJdW5zaWduZWQgaW50 IHRpbGluZ19tb2RlID0gMDsKPiArCj4gKwkJc3dpdGNoIChpbmZvLT5kcm1fZm9ybWF0X21vZCA8 PCAxMCkgewo+ICsJCWNhc2UgUExBTkVfQ1RMX1RJTEVEX0xJTkVBUjoKPiArCQkJdGlsaW5nX21v ZGUgPSBJOTE1X1RJTElOR19OT05FOwo+ICsJCQlicmVhazsKPiArCQljYXNlIFBMQU5FX0NUTF9U SUxFRF9YOgo+ICsJCQl0aWxpbmdfbW9kZSA9IEk5MTVfVElMSU5HX1g7Cj4gKwkJCWJyZWFrOwo+ ICsJCWNhc2UgUExBTkVfQ1RMX1RJTEVEX1k6Cj4gKwkJCXRpbGluZ19tb2RlID0gSTkxNV9USUxJ TkdfWTsKPiArCQkJYnJlYWs7Cj4gKwkJZGVmYXVsdDoKPiArCQkJZ3Z0X2RiZ19jb3JlKCJub3Qg c3VwcG9ydGVkIHRpbGluZyBtb2RlXG4iKTsKPiArCQl9Cj4gKwkJb2JqLT50aWxpbmdfYW5kX3N0 cmlkZSA9IHRpbGluZ19tb2RlIHwgaW5mby0+c3RyaWRlOwo+ICsJfSBlbHNlIHsKPiArCQlvYmot PnRpbGluZ19hbmRfc3RyaWRlID0gaW5mby0+ZHJtX2Zvcm1hdF9tb2QgPwo+ICsJCQkJCUk5MTVf VElMSU5HX1ggOiAwOwo+ICsJfQo+ICsKPiArCXJldHVybiBvYmo7Cj4gK30KPiArCj4gK3N0YXRp YyBzdHJ1Y3QgaW50ZWxfdmdwdV9wbGFuZV9pbmZvICppbnRlbF92Z3B1X2dldF9wbGFuZV9pbmZv KAo+ICsJCXN0cnVjdCBkcm1fZGV2aWNlICpkZXYsCj4gKwkJc3RydWN0IGludGVsX3ZncHUgKnZn cHUsIHVpbnQzMl90IHBsYW5lX2lkKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAq ZGV2X3ByaXYgPSBkZXYtPmRldl9wcml2YXRlOwo+ICsJc3RydWN0IGludGVsX3ZncHVfcHJpbWFy eV9wbGFuZV9mb3JtYXQgKnA7Cj4gKwlzdHJ1Y3QgaW50ZWxfdmdwdV9jdXJzb3JfcGxhbmVfZm9y bWF0ICpjOwo+ICsJc3RydWN0IGludGVsX3ZncHVfcGxhbmVfaW5mbyAqaW5mbzsKPiArCXN0cnVj dCBpbnRlbF92Z3B1X3BpcGVfZm9ybWF0ICpwaXBlOwo+ICsKPiArCWluZm8gPSBrbWFsbG9jKHNp emVvZigqaW5mbyksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFpbmZvKQo+ICsJCXJldHVybiBOVUxM Owo+ICsKPiArCXBpcGUgPSBpbnRlbF92Z3B1X2RlY29kZV9wbGFuZShkZXYsIHZncHUpOwo+ICsJ aWYgKHBpcGUgPT0gTlVMTCkKPiArCQlyZXR1cm4gTlVMTDsKCkxlYWtzIGluZm8sIHJldmVyc2Ug b3JkZXI/Cgo+ICsKPiArCWlmIChwbGFuZV9pZCA9PSBJTlRFTF9HVlRfUExBTkVfUFJJTUFSWSkg ewo+ICsJCXAgPSAmcGlwZS0+cHJpbWFyeTsKPiArCQlpZiAocCAhPSBOVUxMKSB7Cj4gKwkJCWlu Zm8tPnN0YXJ0ID0gcC0+YmFzZTsKPiArCQkJaW5mby0+d2lkdGggPSBwLT53aWR0aDsKPiArCQkJ aW5mby0+aGVpZ2h0ID0gcC0+aGVpZ2h0Owo+ICsJCQlpbmZvLT5zdHJpZGUgPSBwLT5zdHJpZGU7 Cj4gKwkJCWluZm8tPmRybV9mb3JtYXQgPSBwLT5kcm1fZm9ybWF0Owo+ICsJCQlpbmZvLT5kcm1f Zm9ybWF0X21vZCA9IHAtPnRpbGVkOwo+ICsJCQlpbmZvLT5zaXplID0gKCgocC0+c3RyaWRlICog cC0+aGVpZ2h0ICogcC0+YnBwKSAvIDgpICsKPiArCQkJCQkoUEFHRV9TSVpFIC0gMSkpID4+IFBB R0VfU0hJRlQ7Cj4gKwkJfSBlbHNlIHsKPiArCQkJa2ZyZWUoaW5mbyk7Cj4gKwkJCWd2dF92Z3B1 X2VycigiaW52YWxpZCBwcmltYXJ5IHBsYW5lXG4iKTsKPiArCQkJcmV0dXJuIE5VTEw7Cj4gKwkJ fQo+ICsJfSBlbHNlIGlmIChwbGFuZV9pZCA9PSBJTlRFTF9HVlRfUExBTkVfQ1VSU09SKSB7Cj4g KwkJYyA9ICZwaXBlLT5jdXJzb3I7Cj4gKwkJaWYgKGMgIT0gTlVMTCkgewo+ICsJCQlpbmZvLT5z dGFydCA9IGMtPmJhc2U7Cj4gKwkJCWluZm8tPndpZHRoID0gYy0+d2lkdGg7Cj4gKwkJCWluZm8t PmhlaWdodCA9IGMtPmhlaWdodDsKPiArCQkJaW5mby0+c3RyaWRlID0gYy0+d2lkdGggKiAoYy0+ YnBwIC8gOCk7Cj4gKwkJCWluZm8tPmRybV9mb3JtYXRfbW9kID0gMDsKPiArCQkJaW5mby0+eF9w b3MgPSBjLT54X3BvczsKPiArCQkJaW5mby0+eV9wb3MgPSBjLT55X3BvczsKPiArCQkJaW5mby0+ c2l6ZSA9ICgoKGluZm8tPnN0cmlkZSAqIGMtPmhlaWdodCAqIGMtPmJwcCkgLyA4KQo+ICsJCQkJ CSsgKFBBR0VfU0laRSAtIDEpKSA+PiBQQUdFX1NISUZUOwo+ICsJCX0gZWxzZSB7Cj4gKwkJCWtm cmVlKGluZm8pOwo+ICsJCQlndnRfdmdwdV9lcnIoImludmFsaWQgY3Vyc29yIHBsYW5lXG4iKTsK PiArCQkJcmV0dXJuIE5VTEw7Cj4gKwkJfQo+ICsJfSBlbHNlIHsKPiArCQlrZnJlZShpbmZvKTsK PiArCQlndnRfdmdwdV9lcnIoImludmFsaWQgcGxhbmUgaWQ6JWRcbiIsIHBsYW5lX2lkKTsKPiAr CQlyZXR1cm4gTlVMTDsKPiArCX0KPiArCj4gKwlpZiAoaW5mby0+c2l6ZSA9PSAwKSB7Cj4gKwkJ a2ZyZWUoaW5mbyk7Cj4gKwkJZ3Z0X3ZncHVfZXJyKCJmYiBzaXplIGlzIHplcm9cbiIpOwo+ICsJ CXJldHVybiBOVUxMOwo+ICsJfQo+ICsKPiArCWlmIChpbmZvLT5zdGFydCAmIChQQUdFX1NJWkUg LSAxKSkgewo+ICsJCWtmcmVlKGluZm8pOwo+ICsJCWd2dF92Z3B1X2VycigiTm90IGFsaWduZWQg ZmIgYWRkcmVzczoweCV4XG4iLCBpbmZvLT5zdGFydCk7Cj4gKwkJcmV0dXJuIE5VTEw7Cj4gKwl9 Cj4gKwlpZiAoKChpbmZvLT5zdGFydCA+PiBQQUdFX1NISUZUKSArIGluZm8tPnNpemUpID4KPiAr CQlnZ3R0X3RvdGFsX2VudHJpZXMoJmRldl9wcml2LT5nZ3R0KSkgewo+ICsJCWtmcmVlKGluZm8p Owo+ICsJCWd2dF92Z3B1X2VycigiSW52YWxpZCBHVFQgb2Zmc2V0IG9yIHNpemVcbiIpOwo+ICsJ CXJldHVybiBOVUxMOwo+ICsJfQo+ICsKPiArCWlmICghaW50ZWxfZ3Z0X2dndHRfdmFsaWRhdGVf cmFuZ2UodmdwdSwgaW5mby0+c3RhcnQsIGluZm8tPnNpemUpKSB7Cj4gKwkJa2ZyZWUoaW5mbyk7 Cj4gKwkJZ3Z0X3ZncHVfZXJyKCJpbnZhbGlkIGdtYSBhZGRyXG4iKTsKPiArCQlyZXR1cm4gTlVM TDsKPiArCX0KCldvdWxkIGl0IGJlIHVzZWZ1bCB0byB1c2UgRVJSX1BUUigpIHNvIHdlIGNvdWxk IHBhc3MgYSByZWxldmFudCBlcnJubwpiYWNrIHVwIHRoZSBzdGFjayB0byB0aGUgdXNlcj8KCj4g Kwo+ICsJcmV0dXJuIGluZm87Cj4gK30KPiArCj4gK2ludCBpbnRlbF92Z3B1X3F1ZXJ5X3BsYW5l KHN0cnVjdCBpbnRlbF92Z3B1ICp2Z3B1LCB2b2lkICphcmdzKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJt X2RldmljZSAqZGV2ID0gJnZncHUtPmd2dC0+ZGV2X3ByaXYtPmRybTsKPiArCXN0cnVjdCBpbnRl bF92Z3B1X3BsYW5lX2luZm8gKmluZm8gPSBhcmdzOwo+ICsKPiArCWluZm8gPSBpbnRlbF92Z3B1 X2dldF9wbGFuZV9pbmZvKGRldiwgdmdwdSwgaW5mby0+cGxhbmVfaWQpOwo+ICsJaWYgKGluZm8g PT0gTlVMTCkKPiArCQlyZXR1cm4gLUVJTlZBTDsKClJhdGhlciB0aGFuIHRoaXM/Cgo+ICsKPiAr CXJldHVybiAwOwo+ICt9Cj4gKwo+ICtpbnQgaW50ZWxfdmdwdV9jcmVhdGVfZG1hYnVmKHN0cnVj dCBpbnRlbF92Z3B1ICp2Z3B1LCB2b2lkICphcmdzKQo+ICt7Cj4gKwlzdHJ1Y3QgZG1hX2J1ZiAq ZG1hYnVmOwo+ICsJc3RydWN0IGRybV9pOTE1X2dlbV9vYmplY3QgKm9iajsKPiArCXN0cnVjdCBk cm1fZGV2aWNlICpkZXYgPSAmdmdwdS0+Z3Z0LT5kZXZfcHJpdi0+ZHJtOwo+ICsJc3RydWN0IGlu dGVsX3ZncHVfZG1hYnVmICpndnRfZG1hYnVmID0gYXJnczsKPiArCXN0cnVjdCBpbnRlbF92Z3B1 X3BsYW5lX2luZm8gKmluZm87Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWluZm8gPSBpbnRlbF92Z3B1 X2dldF9wbGFuZV9pbmZvKGRldiwgdmdwdSwKPiArCQkJCQlndnRfZG1hYnVmLT5wbGFuZV9pbmZv LnBsYW5lX2lkKTsKPiArCWlmIChpbmZvID09IE5VTEwpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4g Kwo+ICsJb2JqID0gaW50ZWxfdmdwdV9jcmVhdGVfZ2VtKGRldiwgaW5mbyk7Cj4gKwlpZiAob2Jq ID09IE5VTEwpIHsKPiArCQlndnRfdmdwdV9lcnIoImNyZWF0ZSBndnQgZ2VtIG9iaiBmYWlsZWQ6 JWRcbiIsIHZncHUtPmlkKTsKPiArCQlyZXR1cm4gLUVJTlZBTDsKCkBpbmZvIGlzIGxlYWtlZD8K Cj4gKwl9Cj4gKwo+ICsJZG1hYnVmID0gaTkxNV9nZW1fcHJpbWVfZXhwb3J0KGRldiwgJm9iai0+ YmFzZSwgRFJNX0NMT0VYRUMgfCBEUk1fUkRXUik7Cj4gKwo+ICsJaWYgKElTX0VSUihkbWFidWYp KSB7Cj4gKwkJZ3Z0X3ZncHVfZXJyKCJleHBvcnQgZG1hLWJ1ZiBmYWlsZWRcbiIpOwo+ICsJCXJl dHVybiAtRUlOVkFMOwoKQGluZm8gJiBAb2JqIGxlYWtlZD8KCj4gKwl9Cj4gKwo+ICsJcmV0ID0g ZG1hX2J1Zl9mZChkbWFidWYsIERSTV9DTE9FWEVDIHwgRFJNX1JEV1IpOwo+ICsJaWYgKHJldCA8 IDApIHsKPiArCQlndnRfdmdwdV9lcnIoImNyZWF0ZSBkbWEtYnVmIGZkIGZhaWxlZCByZXQ6JWRc biIsIHJldCk7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7CgpzYW1lCgpBbHNvLCB0aGUgZmQgaXMgcHJv dmlkZWQgdG8gdGhlIHVzZXIgYW5kIGlzIGEgcmVmZXJlbmNlIHRvIHRoZSBkZXZpY2UsCndlIG5l ZWQgdG8gaW5jcmVtZW50IHRoZSB2ZmlvX2RldmljZSByZWZlcmVuY2UgYW5kIGRlY3JlbWVudCBv biByZWxlYXNlLgoKPiArCX0KPiArCWd2dF9kbWFidWYtPmZkID0gcmV0Owo+ICsJZ3Z0X2RtYWJ1 Zi0+cGxhbmVfaW5mbyA9ICppbmZvOwo+ICsKPiArCXJldHVybiAwOwoKc2FtZQoKPiArfQo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9ndnQvZG1hYnVmLmggYi9kcml2ZXJzL2dw dS9kcm0vaTkxNS9ndnQvZG1hYnVmLmgKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAw MDAwMDAuLjQzNTYyYWYKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5 MTUvZ3Z0L2RtYWJ1Zi5oCj4gQEAgLTAsMCArMSw1MyBAQAo+ICsKPiArLyoKPiArICogQ29weXJp Z2h0KGMpIDIwMTcgSW50ZWwgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCj4gKyAq Cj4gKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBh bnkgcGVyc29uIG9idGFpbmluZyBhCj4gKyAqIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNz b2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksCj4gKyAqIHRvIGRl YWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0 IGxpbWl0YXRpb24KPiArICogdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2Us IHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCj4gKyAqIGFuZC9vciBzZWxsIGNvcGll cyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQo+ICsg KiBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2lu ZyBjb25kaXRpb25zOgo+ICsgKgo+ICsgKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQg dGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZSBuZXh0Cj4gKyAqIHBhcmFncmFw aCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9u cyBvZiB0aGUKPiArICogU29mdHdhcmUuCj4gKyAqCj4gKyAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9W SURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCj4g KyAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMg T0YgTUVSQ0hBTlRBQklMSVRZLAo+ICsgKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9T RSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQgU0hBTEwKPiArICogVEhFIEFVVEhP UlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMg T1IgT1RIRVIKPiArICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFD VCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKPiArICogT1VUIE9GIE9SIElOIENP Tk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJ TiBUSEUKPiArICogU09GVFdBUkUuCj4gKyAqCj4gKyAqLwo+ICsKPiArI2lmbmRlZiBfR1ZUX0RN QUJVRl9IXwo+ICsjZGVmaW5lIF9HVlRfRE1BQlVGX0hfCj4gKwo+ICtzdHJ1Y3QgaW50ZWxfdmdw dV9wbGFuZV9pbmZvIHsKPiArCXVpbnQzMl90IHBsYW5lX2lkOwo+ICsJdWludDMyX3QgZHJtX2Zv cm1hdDsKPiArCXVpbnQzMl90IHdpZHRoOwo+ICsJdWludDMyX3QgaGVpZ2h0Owo+ICsJdWludDMy X3Qgc3RyaWRlOwo+ICsJdWludDMyX3Qgc3RhcnQ7Cj4gKwl1aW50MzJfdCB4X3BvczsKPiArCXVp bnQzMl90IHlfcG9zOwo+ICsJdWludDMyX3Qgc2l6ZTsKPiArCXVpbnQ2NF90IGRybV9mb3JtYXRf bW9kOwo+ICt9OwoKQWxpZ25tZW50IGlzc3VlIGFzIEdlcmQgbWVudGlvbnMuCgo+ICsKPiArI2Rl ZmluZSBJTlRFTF9WR1BVX1FVRVJZX1BMQU5FCQkwCj4gKyNkZWZpbmUgSU5URUxfVkdQVV9HRU5F UkFURV9ETUFCVUYJMQo+ICsKPiArc3RydWN0IGludGVsX3ZncHVfZG1hYnVmIHsKPiArCXVpbnQz Ml90IGZkOwo+ICsJc3RydWN0IGludGVsX3ZncHVfcGxhbmVfaW5mbyBwbGFuZV9pbmZvOwo+ICt9 OwoKQW5kIGhlcmUsIGFsc28gYXMgR2VyZCBtZW50aW9ucy4KCj4gKwo+ICtpbnQgaW50ZWxfdmdw dV9xdWVyeV9wbGFuZShzdHJ1Y3QgaW50ZWxfdmdwdSAqdmdwdSwgdm9pZCAqYXJncyk7Cj4gK2lu dCBpbnRlbF92Z3B1X2NyZWF0ZV9kbWFidWYoc3RydWN0IGludGVsX3ZncHUgKnZncHUsIHZvaWQg KmFyZ3MpOwo+ICsKPiArI2VuZGlmCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1 L2d2dC9ndnQuaCBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2d2dC9ndnQuaAo+IGluZGV4IGM0MjI2 NmMuLjc2M2E4YzUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Z0L2d2dC5o Cj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvZ3Z0L2d2dC5oCj4gQEAgLTQ3LDYgKzQ3LDcg QEAKPiAgI2luY2x1ZGUgInJlbmRlci5oIgo+ICAjaW5jbHVkZSAiY21kX3BhcnNlci5oIgo+ICAj aW5jbHVkZSAiZmJfZGVjb2Rlci5oIgo+ICsjaW5jbHVkZSAiZG1hYnVmLmgiCj4gIAo+ICAjZGVm aW5lIEdWVF9NQVhfVkdQVSA4Cj4gIAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkx NS9pOTE1X2dlbS5jIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9nZW0uYwo+IGluZGV4IDBj MWNiZTkuLjU0ZjdhMGYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9n ZW0uYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfZ2VtLmMKPiBAQCAtMTYwOSw2 ICsxNjA5LDEwIEBAIGk5MTVfZ2VtX3NldF9kb21haW5faW9jdGwoc3RydWN0IGRybV9kZXZpY2Ug KmRldiwgdm9pZCAqZGF0YSwKPiAgCWlmICghb2JqKQo+ICAJCXJldHVybiAtRU5PRU5UOwo+ICAK PiArCS8qIFRoZSBvYmogaXMgYSBndnQgZG1hLWJ1ZiBvYmplY3QgYW5kIHNldCBkb21haW4gaXMg bm90IHN1cHBvcnRlZCAqLwo+ICsJaWYgKGk5MTVfZ2VtX29iamVjdF9pc19ndnRfZG1hYnVmKG9i aikpCj4gKwkJcmV0dXJuIC1FUEVSTTsKPiArCj4gIAkvKiBUcnkgdG8gZmx1c2ggdGhlIG9iamVj dCBvZmYgdGhlIEdQVSB3aXRob3V0IGhvbGRpbmcgdGhlIGxvY2suCj4gIAkgKiBXZSB3aWxsIHJl cGVhdCB0aGUgZmx1c2ggaG9sZGluZyB0aGUgbG9jayBpbiB0aGUgbm9ybWFsIG1hbm5lcgo+ICAJ ICogdG8gY2F0Y2ggY2FzZXMgd2hlcmUgd2UgYXJlIGdhenVtcGVkLgo+IEBAIC0zNzE3LDYgKzM3 MjEsMTAgQEAgaW50IGk5MTVfZ2VtX3NldF9jYWNoaW5nX2lvY3RsKHN0cnVjdCBkcm1fZGV2aWNl ICpkZXYsIHZvaWQgKmRhdGEsCj4gIAlpZiAoIW9iaikKPiAgCQlyZXR1cm4gLUVOT0VOVDsKPiAg Cj4gKwkvKiB0aGUgb2JqIGlzIGEgZ3Z0IGRtYS1idWYgYW5kIHNldCBjYWNoaW5nIG1vZGUgaXMg bm90IHN1cHBvcnRlZCAqLwo+ICsJaWYgKGk5MTVfZ2VtX29iamVjdF9pc19ndnRfZG1hYnVmKG9i aikpCj4gKwkJcmV0dXJuIC1FUEVSTTsKPiArCj4gIAlpZiAob2JqLT5jYWNoZV9sZXZlbCA9PSBs ZXZlbCkKPiAgCQlnb3RvIG91dDsKPiAgCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9p OTE1L2k5MTVfZ2VtX29iamVjdC5oIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9nZW1fb2Jq ZWN0LmgKPiBpbmRleCAxNzRjZjkyLi45ODZhZjQzIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1 L2RybS9pOTE1L2k5MTVfZ2VtX29iamVjdC5oCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUv aTkxNV9nZW1fb2JqZWN0LmgKPiBAQCAtMzksNiArMzksNyBAQCBzdHJ1Y3QgZHJtX2k5MTVfZ2Vt X29iamVjdF9vcHMgewo+ICAJdW5zaWduZWQgaW50IGZsYWdzOwo+ICAjZGVmaW5lIEk5MTVfR0VN X09CSkVDVF9IQVNfU1RSVUNUX1BBR0UgMHgxCj4gICNkZWZpbmUgSTkxNV9HRU1fT0JKRUNUX0lT X1NIUklOS0FCTEUgICAweDIKPiArI2RlZmluZSBJOTE1X0dFTV9PQkpFQ1RfSVNfR1ZUX0RNQUJV RgkweDQKPiAgCj4gIAkvKiBJbnRlcmZhY2UgYmV0d2VlbiB0aGUgR0VNIG9iamVjdCBhbmQgaXRz IGJhY2tpbmcgc3RvcmFnZS4KPiAgCSAqIGdldF9wYWdlcygpIGlzIGNhbGxlZCBvbmNlIHByaW9y IHRvIHRoZSB1c2Ugb2YgdGhlIGFzc29jaWF0ZWQgc2V0Cj4gQEAgLTE4NCw2ICsxODUsOCBAQCBz dHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCB7Cj4gIAkJfSB1c2VycHRyOwo+ICAKPiAgCQl1bnNp Z25lZCBsb25nIHNjcmF0Y2g7Cj4gKwo+ICsJCXZvaWQgKmd2dF9wbGFuZV9pbmZvOwo+ICAJfTsK PiAgCj4gIAkvKiogZm9yIHBoeXMgYWxsb2NhdGVkIG9iamVjdHMgKi8KPiBAQCAtMjg2LDYgKzI4 OSwxMiBAQCBpOTE1X2dlbV9vYmplY3RfaXNfc2hyaW5rYWJsZShjb25zdCBzdHJ1Y3QgZHJtX2k5 MTVfZ2VtX29iamVjdCAqb2JqKQo+ICB9Cj4gIAo+ICBzdGF0aWMgaW5saW5lIGJvb2wKPiAraTkx NV9nZW1fb2JqZWN0X2lzX2d2dF9kbWFidWYoY29uc3Qgc3RydWN0IGRybV9pOTE1X2dlbV9vYmpl Y3QgKm9iaikKPiArewo+ICsJcmV0dXJuIG9iai0+b3BzLT5mbGFncyAmIEk5MTVfR0VNX09CSkVD VF9JU19HVlRfRE1BQlVGOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW5saW5lIGJvb2wKPiAgaTkxNV9n ZW1fb2JqZWN0X2lzX2FjdGl2ZShjb25zdCBzdHJ1Y3QgZHJtX2k5MTVfZ2VtX29iamVjdCAqb2Jq KQo+ICB7Cj4gIAlyZXR1cm4gb2JqLT5hY3RpdmVfY291bnQ7CgpfX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXwpJbnRlbC1nZnggbWFpbGluZyBsaXN0CkludGVs LWdmeEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcv bWFpbG1hbi9saXN0aW5mby9pbnRlbC1nZngK