From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2307EC49EA4 for ; Tue, 22 Jun 2021 07:22:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F420D60FD8 for ; Tue, 22 Jun 2021 07:22:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230057AbhFVHYj (ORCPT ); Tue, 22 Jun 2021 03:24:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229628AbhFVHYg (ORCPT ); Tue, 22 Jun 2021 03:24:36 -0400 Received: from mail-ej1-x634.google.com (mail-ej1-x634.google.com [IPv6:2a00:1450:4864:20::634]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7DD83C06175F for ; Tue, 22 Jun 2021 00:22:19 -0700 (PDT) Received: by mail-ej1-x634.google.com with SMTP id nd37so32950455ejc.3 for ; Tue, 22 Jun 2021 00:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=gLom4lP2hibA/zirOs75HpOQiLkyphvf9WwSZgUj8y4=; b=rZBYgIQ6eaQoJrR7/aULlx9tHfvP2U7yxchPCrKLCrDU8W2OjwYDQc4dlaDK7rwmEh t/MSfYdryYIRV6GqOkE5Pl+AlwNSIbD534x8uD5inNtL3X0rcDaJskmnwtJ0NM4rfQ/g kEeKUtbSW8CPlC37Wuu1JSc4VcQH3EUhO85OSN7cUEv8GpGpxC82WDFPRp01f9B0DgIJ m3Q621+iidL8cgVBnEkFMWzlSgoT36riwgEyhGZiuyTs+T9rJC3En+Pd1Y8P0IjeObhd M5AeHhKOnPBvgRKWfVMQuiY+90lsjrjyE0fRsZQNapLK/40+W8G/hsPzLaiP42OM41m3 D2aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=gLom4lP2hibA/zirOs75HpOQiLkyphvf9WwSZgUj8y4=; b=So55OQPKC77yAaOXRlMXBG3x5BQkt6oc2JmAq2CGxhCwcumEtUgOPelm6Ks1yZSF0q kMlytIWawp28IK97YbzitCaHyqEe3dGQO9mTtl2aq+xj3uS7DHNeMj5hzF3ExCNjIHAk ud287crHZe0NoQFWSs5n5tWKFNCaT8+1pxLbm4HbWRFv1t/8fFyfzUnmsy6OI5sbYqPr Fa48c0cFP//CmED3ZxbNr+qMG3AFD3bw2i9aaVGhDB0uEapr1wIyUSUoEsriYbl4ddJC 6e6xObOcTYQLG5j9LxNZXZ1WbWru32QIxy8YL+hD+uGMJB95Pv1sMgPBnq795EGyghMk K8CQ== X-Gm-Message-State: AOAM530XMmUI6zdEkFeiMDrLBkwb9GPnL1csN/6hJSIm1VaeH/lsYwF1 5nhJbiBWLGOMQcdj4uwD9NtoLzG6GeTNZbgRP8N3 X-Google-Smtp-Source: ABdhPJxChMepMHmwcjDcpaa0xcreEesoNRhNDDJguXaRU2cc/7WY7PBM6Sc1eEidlncBPzdp7VKgwyXRxV1Wwk4Tym4= X-Received: by 2002:a17:906:3c4a:: with SMTP id i10mr2432624ejg.372.1624346537905; Tue, 22 Jun 2021 00:22:17 -0700 (PDT) MIME-Version: 1.0 References: <20210615141331.407-1-xieyongji@bytedance.com> <20210615141331.407-10-xieyongji@bytedance.com> <1bba439f-ffc8-c20e-e8a4-ac73e890c592@redhat.com> In-Reply-To: <1bba439f-ffc8-c20e-e8a4-ac73e890c592@redhat.com> From: Yongji Xie Date: Tue, 22 Jun 2021 15:22:06 +0800 Message-ID: Subject: Re: Re: [PATCH v8 09/10] vduse: Introduce VDUSE - vDPA Device in Userspace To: Jason Wang Cc: "Michael S. Tsirkin" , Stefan Hajnoczi , Stefano Garzarella , Parav Pandit , Christoph Hellwig , Christian Brauner , Randy Dunlap , Matthew Wilcox , Al Viro , Jens Axboe , bcrl@kvack.org, Jonathan Corbet , =?UTF-8?Q?Mika_Penttil=C3=A4?= , Dan Carpenter , joro@8bytes.org, Greg KH , songmuchun@bytedance.com, virtualization , netdev@vger.kernel.org, kvm , linux-fsdevel@vger.kernel.org, iommu@lists.linux-foundation.org, linux-kernel Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org .On Tue, Jun 22, 2021 at 1:07 PM Jason Wang wrote: > > > =E5=9C=A8 2021/6/21 =E4=B8=8B=E5=8D=886:41, Yongji Xie =E5=86=99=E9=81=93= : > > On Mon, Jun 21, 2021 at 5:14 PM Jason Wang wrote: > >> > >> =E5=9C=A8 2021/6/15 =E4=B8=8B=E5=8D=8810:13, Xie Yongji =E5=86=99=E9= =81=93: > >>> This VDUSE driver enables implementing vDPA devices in userspace. > >>> The vDPA device's control path is handled in kernel and the data > >>> path is handled in userspace. > >>> > >>> A message mechnism is used by VDUSE driver to forward some control > >>> messages such as starting/stopping datapath to userspace. Userspace > >>> can use read()/write() to receive/reply those control messages. > >>> > >>> And some ioctls are introduced to help userspace to implement the > >>> data path. VDUSE_IOTLB_GET_FD ioctl can be used to get the file > >>> descriptors referring to vDPA device's iova regions. Then userspace > >>> can use mmap() to access those iova regions. VDUSE_DEV_GET_FEATURES > >>> and VDUSE_VQ_GET_INFO ioctls are used to get the negotiated features > >>> and metadata of virtqueues. VDUSE_INJECT_VQ_IRQ and VDUSE_VQ_SETUP_KI= CKFD > >>> ioctls can be used to inject interrupt and setup the kickfd for > >>> virtqueues. VDUSE_DEV_UPDATE_CONFIG ioctl is used to update the > >>> configuration space and inject a config interrupt. > >>> > >>> Signed-off-by: Xie Yongji > >>> --- > >>> Documentation/userspace-api/ioctl/ioctl-number.rst | 1 + > >>> drivers/vdpa/Kconfig | 10 + > >>> drivers/vdpa/Makefile | 1 + > >>> drivers/vdpa/vdpa_user/Makefile | 5 + > >>> drivers/vdpa/vdpa_user/vduse_dev.c | 1453 ++++++++= ++++++++++++ > >>> include/uapi/linux/vduse.h | 143 ++ > >>> 6 files changed, 1613 insertions(+) > >>> create mode 100644 drivers/vdpa/vdpa_user/Makefile > >>> create mode 100644 drivers/vdpa/vdpa_user/vduse_dev.c > >>> create mode 100644 include/uapi/linux/vduse.h > >>> > >>> diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Doc= umentation/userspace-api/ioctl/ioctl-number.rst > >>> index 9bfc2b510c64..acd95e9dcfe7 100644 > >>> --- a/Documentation/userspace-api/ioctl/ioctl-number.rst > >>> +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst > >>> @@ -300,6 +300,7 @@ Code Seq# Include File = Comments > >>> 'z' 10-4F drivers/s390/crypto/zcrypt_api.h = conflict! > >>> '|' 00-7F linux/media.h > >>> 0x80 00-1F linux/fb.h > >>> +0x81 00-1F linux/vduse.h > >>> 0x89 00-06 arch/x86/include/asm/sockios.h > >>> 0x89 0B-DF linux/sockios.h > >>> 0x89 E0-EF linux/sockios.h = SIOCPROTOPRIVATE range > >>> diff --git a/drivers/vdpa/Kconfig b/drivers/vdpa/Kconfig > >>> index a503c1b2bfd9..6e23bce6433a 100644 > >>> --- a/drivers/vdpa/Kconfig > >>> +++ b/drivers/vdpa/Kconfig > >>> @@ -33,6 +33,16 @@ config VDPA_SIM_BLOCK > >>> vDPA block device simulator which terminates IO request in a > >>> memory buffer. > >>> > >>> +config VDPA_USER > >>> + tristate "VDUSE (vDPA Device in Userspace) support" > >>> + depends on EVENTFD && MMU && HAS_DMA > >>> + select DMA_OPS > >>> + select VHOST_IOTLB > >>> + select IOMMU_IOVA > >>> + help > >>> + With VDUSE it is possible to emulate a vDPA Device > >>> + in a userspace program. > >>> + > >>> config IFCVF > >>> tristate "Intel IFC VF vDPA driver" > >>> depends on PCI_MSI > >>> diff --git a/drivers/vdpa/Makefile b/drivers/vdpa/Makefile > >>> index 67fe7f3d6943..f02ebed33f19 100644 > >>> --- a/drivers/vdpa/Makefile > >>> +++ b/drivers/vdpa/Makefile > >>> @@ -1,6 +1,7 @@ > >>> # SPDX-License-Identifier: GPL-2.0 > >>> obj-$(CONFIG_VDPA) +=3D vdpa.o > >>> obj-$(CONFIG_VDPA_SIM) +=3D vdpa_sim/ > >>> +obj-$(CONFIG_VDPA_USER) +=3D vdpa_user/ > >>> obj-$(CONFIG_IFCVF) +=3D ifcvf/ > >>> obj-$(CONFIG_MLX5_VDPA) +=3D mlx5/ > >>> obj-$(CONFIG_VP_VDPA) +=3D virtio_pci/ > >>> diff --git a/drivers/vdpa/vdpa_user/Makefile b/drivers/vdpa/vdpa_user= /Makefile > >>> new file mode 100644 > >>> index 000000000000..260e0b26af99 > >>> --- /dev/null > >>> +++ b/drivers/vdpa/vdpa_user/Makefile > >>> @@ -0,0 +1,5 @@ > >>> +# SPDX-License-Identifier: GPL-2.0 > >>> + > >>> +vduse-y :=3D vduse_dev.o iova_domain.o > >>> + > >>> +obj-$(CONFIG_VDPA_USER) +=3D vduse.o > >>> diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_u= ser/vduse_dev.c > >>> new file mode 100644 > >>> index 000000000000..5271cbd15e28 > >>> --- /dev/null > >>> +++ b/drivers/vdpa/vdpa_user/vduse_dev.c > >>> @@ -0,0 +1,1453 @@ > >>> +// SPDX-License-Identifier: GPL-2.0-only > >>> +/* > >>> + * VDUSE: vDPA Device in Userspace > >>> + * > >>> + * Copyright (C) 2020-2021 Bytedance Inc. and/or its affiliates. All= rights reserved. > >>> + * > >>> + * Author: Xie Yongji > >>> + * > >>> + */ > >>> + > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> +#include > >>> + > >>> +#include "iova_domain.h" > >>> + > >>> +#define DRV_AUTHOR "Yongji Xie " > >>> +#define DRV_DESC "vDPA Device in Userspace" > >>> +#define DRV_LICENSE "GPL v2" > >>> + > >>> +#define VDUSE_DEV_MAX (1U << MINORBITS) > >>> +#define VDUSE_MAX_BOUNCE_SIZE (64 * 1024 * 1024) > >>> +#define VDUSE_IOVA_SIZE (128 * 1024 * 1024) > >>> +#define VDUSE_REQUEST_TIMEOUT 30 > >>> + > >>> +struct vduse_virtqueue { > >>> + u16 index; > >>> + u32 num; > >>> + u32 avail_idx; > >>> + u64 desc_addr; > >>> + u64 driver_addr; > >>> + u64 device_addr; > >>> + bool ready; > >>> + bool kicked; > >>> + spinlock_t kick_lock; > >>> + spinlock_t irq_lock; > >>> + struct eventfd_ctx *kickfd; > >>> + struct vdpa_callback cb; > >>> + struct work_struct inject; > >>> +}; > >>> + > >>> +struct vduse_dev; > >>> + > >>> +struct vduse_vdpa { > >>> + struct vdpa_device vdpa; > >>> + struct vduse_dev *dev; > >>> +}; > >>> + > >>> +struct vduse_dev { > >>> + struct vduse_vdpa *vdev; > >>> + struct device *dev; > >>> + struct vduse_virtqueue *vqs; > >>> + struct vduse_iova_domain *domain; > >>> + char *name; > >>> + struct mutex lock; > >>> + spinlock_t msg_lock; > >>> + u64 msg_unique; > >>> + wait_queue_head_t waitq; > >>> + struct list_head send_list; > >>> + struct list_head recv_list; > >>> + struct vdpa_callback config_cb; > >>> + struct work_struct inject; > >>> + spinlock_t irq_lock; > >>> + int minor; > >>> + bool connected; > >>> + bool started; > >>> + u64 api_version; > >>> + u64 user_features; > >> > >> Let's use device_features. > >> > > OK. > > > >>> + u64 features; > >> > >> And driver features. > >> > > OK. > > > >>> + u32 device_id; > >>> + u32 vendor_id; > >>> + u32 generation; > >>> + u32 config_size; > >>> + void *config; > >>> + u8 status; > >>> + u16 vq_size_max; > >>> + u32 vq_num; > >>> + u32 vq_align; > >>> +}; > >>> + > >>> +struct vduse_dev_msg { > >>> + struct vduse_dev_request req; > >>> + struct vduse_dev_response resp; > >>> + struct list_head list; > >>> + wait_queue_head_t waitq; > >>> + bool completed; > >>> +}; > >>> + > >>> +struct vduse_control { > >>> + u64 api_version; > >>> +}; > >>> + > >>> +static DEFINE_MUTEX(vduse_lock); > >>> +static DEFINE_IDR(vduse_idr); > >>> + > >>> +static dev_t vduse_major; > >>> +static struct class *vduse_class; > >>> +static struct cdev vduse_ctrl_cdev; > >>> +static struct cdev vduse_cdev; > >>> +static struct workqueue_struct *vduse_irq_wq; > >>> + > >>> +static u32 allowed_device_id[] =3D { > >>> + VIRTIO_ID_BLOCK, > >>> +}; > >>> + > >>> +static inline struct vduse_dev *vdpa_to_vduse(struct vdpa_device *vd= pa) > >>> +{ > >>> + struct vduse_vdpa *vdev =3D container_of(vdpa, struct vduse_vdp= a, vdpa); > >>> + > >>> + return vdev->dev; > >>> +} > >>> + > >>> +static inline struct vduse_dev *dev_to_vduse(struct device *dev) > >>> +{ > >>> + struct vdpa_device *vdpa =3D dev_to_vdpa(dev); > >>> + > >>> + return vdpa_to_vduse(vdpa); > >>> +} > >>> + > >>> +static struct vduse_dev_msg *vduse_find_msg(struct list_head *head, > >>> + uint32_t request_id) > >>> +{ > >>> + struct vduse_dev_msg *msg; > >>> + > >>> + list_for_each_entry(msg, head, list) { > >>> + if (msg->req.request_id =3D=3D request_id) { > >>> + list_del(&msg->list); > >>> + return msg; > >>> + } > >>> + } > >>> + > >>> + return NULL; > >>> +} > >>> + > >>> +static struct vduse_dev_msg *vduse_dequeue_msg(struct list_head *hea= d) > >>> +{ > >>> + struct vduse_dev_msg *msg =3D NULL; > >>> + > >>> + if (!list_empty(head)) { > >>> + msg =3D list_first_entry(head, struct vduse_dev_msg, li= st); > >>> + list_del(&msg->list); > >>> + } > >>> + > >>> + return msg; > >>> +} > >>> + > >>> +static void vduse_enqueue_msg(struct list_head *head, > >>> + struct vduse_dev_msg *msg) > >>> +{ > >>> + list_add_tail(&msg->list, head); > >>> +} > >>> + > >>> +static int vduse_dev_msg_send(struct vduse_dev *dev, > >>> + struct vduse_dev_msg *msg, bool no_reply) > >>> +{ > >> > >> It looks to me the only user for no_reply=3Dtrue is the dataplane star= t. I > >> wonder no_reply is really needed consider we have switched to use > >> wait_event_killable_timeout(). > >> > > Do we need to handle the error in this case if we remove the no_reply > > flag. Print a warning message? > > > See below. > > > > > >> In another way, no_reply is false for vq state synchronization and IOT= LB > >> updating. I wonder if we can simply use no_reply =3D true for them. > >> > > Looks like we can't, e.g. we need to get a reply from userspace for vq = state. > > > Right. > > > > > >>> + init_waitqueue_head(&msg->waitq); > >>> + spin_lock(&dev->msg_lock); > >>> + msg->req.request_id =3D dev->msg_unique++; > >>> + vduse_enqueue_msg(&dev->send_list, msg); > >>> + wake_up(&dev->waitq); > >>> + spin_unlock(&dev->msg_lock); > >>> + if (no_reply) > >>> + return 0; > >>> + > >>> + wait_event_killable_timeout(msg->waitq, msg->completed, > >>> + VDUSE_REQUEST_TIMEOUT * HZ); > >>> + spin_lock(&dev->msg_lock); > >>> + if (!msg->completed) { > >>> + list_del(&msg->list); > >>> + msg->resp.result =3D VDUSE_REQ_RESULT_FAILED; > >>> + } > >>> + spin_unlock(&dev->msg_lock); > >>> + > >>> + return (msg->resp.result =3D=3D VDUSE_REQ_RESULT_OK) ? 0 : -EIO= ; > >> > >> Do we need to serialize the check by protecting it with the spinlock a= bove? > >> > > Good point. > > > >>> +} > >>> + > >>> +static void vduse_dev_msg_cleanup(struct vduse_dev *dev) > >>> +{ > >>> + struct vduse_dev_msg *msg; > >>> + > >>> + spin_lock(&dev->msg_lock); > >>> + while ((msg =3D vduse_dequeue_msg(&dev->send_list))) { > >>> + if (msg->req.flags & VDUSE_REQ_FLAGS_NO_REPLY) > >>> + kfree(msg); > >>> + else > >>> + vduse_enqueue_msg(&dev->recv_list, msg); > >>> + } > >>> + while ((msg =3D vduse_dequeue_msg(&dev->recv_list))) { > >>> + msg->resp.result =3D VDUSE_REQ_RESULT_FAILED; > >>> + msg->completed =3D 1; > >>> + wake_up(&msg->waitq); > >>> + } > >>> + spin_unlock(&dev->msg_lock); > >>> +} > >>> + > >>> +static void vduse_dev_start_dataplane(struct vduse_dev *dev) > >>> +{ > >>> + struct vduse_dev_msg *msg =3D kzalloc(sizeof(*msg), > >>> + GFP_KERNEL | __GFP_NOFAIL); > >>> + > >>> + msg->req.type =3D VDUSE_START_DATAPLANE; > >>> + msg->req.flags |=3D VDUSE_REQ_FLAGS_NO_REPLY; > >>> + vduse_dev_msg_send(dev, msg, true); > >>> +} > >>> + > >>> +static void vduse_dev_stop_dataplane(struct vduse_dev *dev) > >>> +{ > >>> + struct vduse_dev_msg *msg =3D kzalloc(sizeof(*msg), > >>> + GFP_KERNEL | __GFP_NOFAIL); > >>> + > >>> + msg->req.type =3D VDUSE_STOP_DATAPLANE; > >>> + msg->req.flags |=3D VDUSE_REQ_FLAGS_NO_REPLY; > >> > >> Can we simply use this flag instead of introducing a new parameter > >> (no_reply) in vduse_dev_msg_send()? > >> > > Looks good to me. > > > >>> + vduse_dev_msg_send(dev, msg, true); > >>> +} > >>> + > >>> +static int vduse_dev_get_vq_state(struct vduse_dev *dev, > >>> + struct vduse_virtqueue *vq, > >>> + struct vdpa_vq_state *state) > >>> +{ > >>> + struct vduse_dev_msg msg =3D { 0 }; > >>> + int ret; > >> > >> Note that I post a series that implement the packed virtqueue support: > >> > >> https://lists.linuxfoundation.org/pipermail/virtualization/2021-June/0= 54501.html > >> > >> So this patch needs to be updated as well. > >> > > Will do it. > > > >>> + > >>> + msg.req.type =3D VDUSE_GET_VQ_STATE; > >>> + msg.req.vq_state.index =3D vq->index; > >>> + > >>> + ret =3D vduse_dev_msg_send(dev, &msg, false); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + state->avail_index =3D msg.resp.vq_state.avail_idx; > >>> + return 0; > >>> +} > >>> + > >>> +static int vduse_dev_update_iotlb(struct vduse_dev *dev, > >>> + u64 start, u64 last) > >>> +{ > >>> + struct vduse_dev_msg msg =3D { 0 }; > >>> + > >>> + if (last < start) > >>> + return -EINVAL; > >>> + > >>> + msg.req.type =3D VDUSE_UPDATE_IOTLB; > >>> + msg.req.iova.start =3D start; > >>> + msg.req.iova.last =3D last; > >>> + > >>> + return vduse_dev_msg_send(dev, &msg, false); > >>> +} > >>> + > >>> +static ssize_t vduse_dev_read_iter(struct kiocb *iocb, struct iov_it= er *to) > >>> +{ > >>> + struct file *file =3D iocb->ki_filp; > >>> + struct vduse_dev *dev =3D file->private_data; > >>> + struct vduse_dev_msg *msg; > >>> + int size =3D sizeof(struct vduse_dev_request); > >>> + ssize_t ret; > >>> + > >>> + if (iov_iter_count(to) < size) > >>> + return -EINVAL; > >>> + > >>> + spin_lock(&dev->msg_lock); > >>> + while (1) { > >>> + msg =3D vduse_dequeue_msg(&dev->send_list); > >>> + if (msg) > >>> + break; > >>> + > >>> + ret =3D -EAGAIN; > >>> + if (file->f_flags & O_NONBLOCK) > >>> + goto unlock; > >>> + > >>> + spin_unlock(&dev->msg_lock); > >>> + ret =3D wait_event_interruptible_exclusive(dev->waitq, > >>> + !list_empty(&dev->send_list)); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + spin_lock(&dev->msg_lock); > >>> + } > >>> + spin_unlock(&dev->msg_lock); > >>> + ret =3D copy_to_iter(&msg->req, size, to); > >>> + spin_lock(&dev->msg_lock); > >>> + if (ret !=3D size) { > >>> + ret =3D -EFAULT; > >>> + vduse_enqueue_msg(&dev->send_list, msg); > >>> + goto unlock; > >>> + } > >>> + if (msg->req.flags & VDUSE_REQ_FLAGS_NO_REPLY) > >>> + kfree(msg); > >>> + else > >>> + vduse_enqueue_msg(&dev->recv_list, msg); > >>> +unlock: > >>> + spin_unlock(&dev->msg_lock); > >>> + > >>> + return ret; > >>> +} > >>> + > >>> +static ssize_t vduse_dev_write_iter(struct kiocb *iocb, struct iov_i= ter *from) > >>> +{ > >>> + struct file *file =3D iocb->ki_filp; > >>> + struct vduse_dev *dev =3D file->private_data; > >>> + struct vduse_dev_response resp; > >>> + struct vduse_dev_msg *msg; > >>> + size_t ret; > >>> + > >>> + ret =3D copy_from_iter(&resp, sizeof(resp), from); > >>> + if (ret !=3D sizeof(resp)) > >>> + return -EINVAL; > >>> + > >>> + spin_lock(&dev->msg_lock); > >>> + msg =3D vduse_find_msg(&dev->recv_list, resp.request_id); > >>> + if (!msg) { > >>> + ret =3D -ENOENT; > >>> + goto unlock; > >>> + } > >>> + > >>> + memcpy(&msg->resp, &resp, sizeof(resp)); > >>> + msg->completed =3D 1; > >>> + wake_up(&msg->waitq); > >>> +unlock: > >>> + spin_unlock(&dev->msg_lock); > >>> + > >>> + return ret; > >>> +} > >>> + > >>> +static __poll_t vduse_dev_poll(struct file *file, poll_table *wait) > >>> +{ > >>> + struct vduse_dev *dev =3D file->private_data; > >>> + __poll_t mask =3D 0; > >>> + > >>> + poll_wait(file, &dev->waitq, wait); > >>> + > >>> + if (!list_empty(&dev->send_list)) > >>> + mask |=3D EPOLLIN | EPOLLRDNORM; > >>> + if (!list_empty(&dev->recv_list)) > >>> + mask |=3D EPOLLOUT | EPOLLWRNORM; > >>> + > >>> + return mask; > >>> +} > >>> + > >>> +static void vduse_dev_reset(struct vduse_dev *dev) > >>> +{ > >>> + int i; > >>> + struct vduse_iova_domain *domain =3D dev->domain; > >>> + > >>> + /* The coherent mappings are handled in vduse_dev_free_coherent= () */ > >>> + if (domain->bounce_map) > >>> + vduse_domain_reset_bounce_map(domain); > >>> + > >>> + dev->features =3D 0; > >>> + dev->generation++; > >>> + spin_lock(&dev->irq_lock); > >>> + dev->config_cb.callback =3D NULL; > >>> + dev->config_cb.private =3D NULL; > >>> + spin_unlock(&dev->irq_lock); > >>> + > >>> + for (i =3D 0; i < dev->vq_num; i++) { > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[i]; > >>> + > >>> + vq->ready =3D false; > >>> + vq->desc_addr =3D 0; > >>> + vq->driver_addr =3D 0; > >>> + vq->device_addr =3D 0; > >>> + vq->avail_idx =3D 0; > >>> + vq->num =3D 0; > >>> + > >>> + spin_lock(&vq->kick_lock); > >>> + vq->kicked =3D false; > >>> + if (vq->kickfd) > >>> + eventfd_ctx_put(vq->kickfd); > >>> + vq->kickfd =3D NULL; > >>> + spin_unlock(&vq->kick_lock); > >>> + > >>> + spin_lock(&vq->irq_lock); > >>> + vq->cb.callback =3D NULL; > >>> + vq->cb.private =3D NULL; > >>> + spin_unlock(&vq->irq_lock); > >>> + } > >>> +} > >>> + > >>> +static int vduse_vdpa_set_vq_address(struct vdpa_device *vdpa, u16 i= dx, > >>> + u64 desc_area, u64 driver_area, > >>> + u64 device_area) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + vq->desc_addr =3D desc_area; > >>> + vq->driver_addr =3D driver_area; > >>> + vq->device_addr =3D device_area; > >>> + > >>> + return 0; > >>> +} > >>> + > >>> +static void vduse_vdpa_kick_vq(struct vdpa_device *vdpa, u16 idx) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + spin_lock(&vq->kick_lock); > >>> + if (!vq->ready) > >>> + goto unlock; > >>> + > >>> + if (vq->kickfd) > >>> + eventfd_signal(vq->kickfd, 1); > >>> + else > >>> + vq->kicked =3D true; > >>> +unlock: > >>> + spin_unlock(&vq->kick_lock); > >>> +} > >>> + > >>> +static void vduse_vdpa_set_vq_cb(struct vdpa_device *vdpa, u16 idx, > >>> + struct vdpa_callback *cb) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + spin_lock(&vq->irq_lock); > >>> + vq->cb.callback =3D cb->callback; > >>> + vq->cb.private =3D cb->private; > >>> + spin_unlock(&vq->irq_lock); > >>> +} > >>> + > >>> +static void vduse_vdpa_set_vq_num(struct vdpa_device *vdpa, u16 idx,= u32 num) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + vq->num =3D num; > >>> +} > >>> + > >>> +static void vduse_vdpa_set_vq_ready(struct vdpa_device *vdpa, > >>> + u16 idx, bool ready) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + vq->ready =3D ready; > >>> +} > >>> + > >>> +static bool vduse_vdpa_get_vq_ready(struct vdpa_device *vdpa, u16 id= x) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + return vq->ready; > >>> +} > >>> + > >>> +static int vduse_vdpa_set_vq_state(struct vdpa_device *vdpa, u16 idx= , > >>> + const struct vdpa_vq_state *state) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + vq->avail_idx =3D state->avail_index; > >>> + return 0; > >>> +} > >>> + > >>> +static int vduse_vdpa_get_vq_state(struct vdpa_device *vdpa, u16 idx= , > >>> + struct vdpa_vq_state *state) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + struct vduse_virtqueue *vq =3D &dev->vqs[idx]; > >>> + > >>> + return vduse_dev_get_vq_state(dev, vq, state); > >>> +} > >>> + > >>> +static u32 vduse_vdpa_get_vq_align(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->vq_align; > >>> +} > >>> + > >>> +static u64 vduse_vdpa_get_features(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->user_features; > >>> +} > >>> + > >>> +static int vduse_vdpa_set_features(struct vdpa_device *vdpa, u64 fea= tures) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + dev->features =3D features; > >>> + return 0; > >>> +} > >>> + > >>> +static void vduse_vdpa_set_config_cb(struct vdpa_device *vdpa, > >>> + struct vdpa_callback *cb) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + spin_lock(&dev->irq_lock); > >>> + dev->config_cb.callback =3D cb->callback; > >>> + dev->config_cb.private =3D cb->private; > >>> + spin_unlock(&dev->irq_lock); > >>> +} > >>> + > >>> +static u16 vduse_vdpa_get_vq_num_max(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->vq_size_max; > >>> +} > >>> + > >>> +static u32 vduse_vdpa_get_device_id(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->device_id; > >>> +} > >>> + > >>> +static u32 vduse_vdpa_get_vendor_id(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->vendor_id; > >>> +} > >>> + > >>> +static u8 vduse_vdpa_get_status(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->status; > >>> +} > >>> + > >>> +static void vduse_vdpa_set_status(struct vdpa_device *vdpa, u8 statu= s) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + bool started =3D !!(status & VIRTIO_CONFIG_S_DRIVER_OK); > >>> + > >>> + dev->status =3D status; > >>> + > >>> + if (dev->started =3D=3D started) > >>> + return; > >> > >> If we check dev->status =3D=3D status, (or only check the DRIVER_OK bi= t) > >> then there's no need to introduce an extra dev->started. > >> > > Will do it. > > > >>> + > >>> + dev->started =3D started; > >>> + if (dev->started) { > >>> + vduse_dev_start_dataplane(dev); > >>> + } else { > >>> + vduse_dev_reset(dev); > >>> + vduse_dev_stop_dataplane(dev); > >> > >> I wonder if no_reply work for the case of vhost-vdpa. For virtio-vDPA, > >> we have bouncing buffers so it's harmless if usersapce dataplane keeps > >> performing read/write. For vhost-vDPA we don't have such stuffs. > >> > > OK. So it still needs to be synchronized here. If so, how to handle > > the error? Looks like printing a warning message should be enough. > > > We need fix a way to propagate the error to the userspace. > > E.g if we want to stop the deivce, we will delay the status reset until > we get respose from the userspace? > I didn't get how to delay the status reset. And should it be a DoS that we want to fix if the userspace doesn't give a response forever? > > > > >>> + } > >>> +} > >>> + > >>> +static size_t vduse_vdpa_get_config_size(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->config_size; > >>> +} > >>> + > >>> +static void vduse_vdpa_get_config(struct vdpa_device *vdpa, unsigned= int offset, > >>> + void *buf, unsigned int len) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + memcpy(buf, dev->config + offset, len); > >>> +} > >>> + > >>> +static void vduse_vdpa_set_config(struct vdpa_device *vdpa, unsigned= int offset, > >>> + const void *buf, unsigned int len) > >>> +{ > >>> + /* Now we only support read-only configuration space */ > >>> +} > >>> + > >>> +static u32 vduse_vdpa_get_generation(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + return dev->generation; > >>> +} > >>> + > >>> +static int vduse_vdpa_set_map(struct vdpa_device *vdpa, > >>> + struct vhost_iotlb *iotlb) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + int ret; > >>> + > >>> + ret =3D vduse_domain_set_map(dev->domain, iotlb); > >>> + if (ret) > >>> + return ret; > >>> + > >>> + ret =3D vduse_dev_update_iotlb(dev, 0ULL, ULLONG_MAX); > >>> + if (ret) { > >>> + vduse_domain_clear_map(dev->domain, iotlb); > >>> + return ret; > >>> + } > >>> + > >>> + return 0; > >>> +} > >>> + > >>> +static void vduse_vdpa_free(struct vdpa_device *vdpa) > >>> +{ > >>> + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > >>> + > >>> + dev->vdev =3D NULL; > >>> +} > >>> + > >>> +static const struct vdpa_config_ops vduse_vdpa_config_ops =3D { > >>> + .set_vq_address =3D vduse_vdpa_set_vq_address, > >>> + .kick_vq =3D vduse_vdpa_kick_vq, > >>> + .set_vq_cb =3D vduse_vdpa_set_vq_cb, > >>> + .set_vq_num =3D vduse_vdpa_set_vq_num, > >>> + .set_vq_ready =3D vduse_vdpa_set_vq_ready, > >>> + .get_vq_ready =3D vduse_vdpa_get_vq_ready, > >>> + .set_vq_state =3D vduse_vdpa_set_vq_state, > >>> + .get_vq_state =3D vduse_vdpa_get_vq_state, > >>> + .get_vq_align =3D vduse_vdpa_get_vq_align, > >>> + .get_features =3D vduse_vdpa_get_features, > >>> + .set_features =3D vduse_vdpa_set_features, > >>> + .set_config_cb =3D vduse_vdpa_set_config_cb, > >>> + .get_vq_num_max =3D vduse_vdpa_get_vq_num_max, > >>> + .get_device_id =3D vduse_vdpa_get_device_id, > >>> + .get_vendor_id =3D vduse_vdpa_get_vendor_id, > >>> + .get_status =3D vduse_vdpa_get_status, > >>> + .set_status =3D vduse_vdpa_set_status, > >>> + .get_config_size =3D vduse_vdpa_get_config_size, > >>> + .get_config =3D vduse_vdpa_get_config, > >>> + .set_config =3D vduse_vdpa_set_config, > >>> + .get_generation =3D vduse_vdpa_get_generation, > >>> + .set_map =3D vduse_vdpa_set_map, > >>> + .free =3D vduse_vdpa_free, > >>> +}; > >>> + > >>> +static dma_addr_t vduse_dev_map_page(struct device *dev, struct page= *page, > >>> + unsigned long offset, size_t size, > >>> + enum dma_data_direction dir, > >>> + unsigned long attrs) > >>> +{ > >>> + struct vduse_dev *vdev =3D dev_to_vduse(dev); > >>> + struct vduse_iova_domain *domain =3D vdev->domain; > >>> + > >>> + return vduse_domain_map_page(domain, page, offset, size, dir, a= ttrs); > >>> +} > >>> + > >>> +static void vduse_dev_unmap_page(struct device *dev, dma_addr_t dma_= addr, > >>> + size_t size, enum dma_data_direction di= r, > >>> + unsigned long attrs) > >>> +{ > >>> + struct vduse_dev *vdev =3D dev_to_vduse(dev); > >>> + struct vduse_iova_domain *domain =3D vdev->domain; > >>> + > >>> + return vduse_domain_unmap_page(domain, dma_addr, size, dir, att= rs); > >>> +} > >>> + > >>> +static void *vduse_dev_alloc_coherent(struct device *dev, size_t siz= e, > >>> + dma_addr_t *dma_addr, gfp_t fla= g, > >>> + unsigned long attrs) > >>> +{ > >>> + struct vduse_dev *vdev =3D dev_to_vduse(dev); > >>> + struct vduse_iova_domain *domain =3D vdev->domain; > >>> + unsigned long iova; > >>> + void *addr; > >>> + > >>> + *dma_addr =3D DMA_MAPPING_ERROR; > >>> + addr =3D vduse_domain_alloc_coherent(domain, size, > >>> + (dma_addr_t *)&iova, flag, attrs); > >>> + if (!addr) > >>> + return NULL; > >>> + > >>> + *dma_addr =3D (dma_addr_t)iova; > >>> + > >>> + return addr; > >>> +} > >>> + > >>> +static void vduse_dev_free_coherent(struct device *dev, size_t size, > >>> + void *vaddr, dma_addr_t dma_add= r, > >>> + unsigned long attrs) > >>> +{ > >>> + struct vduse_dev *vdev =3D dev_to_vduse(dev); > >>> + struct vduse_iova_domain *domain =3D vdev->domain; > >>> + > >>> + vduse_domain_free_coherent(domain, size, vaddr, dma_addr, attrs= ); > >>> +} > >>> + > >>> +static size_t vduse_dev_max_mapping_size(struct device *dev) > >>> +{ > >>> + struct vduse_dev *vdev =3D dev_to_vduse(dev); > >>> + struct vduse_iova_domain *domain =3D vdev->domain; > >>> + > >>> + return domain->bounce_size; > >>> +} > >>> + > >>> +static const struct dma_map_ops vduse_dev_dma_ops =3D { > >>> + .map_page =3D vduse_dev_map_page, > >>> + .unmap_page =3D vduse_dev_unmap_page, > >>> + .alloc =3D vduse_dev_alloc_coherent, > >>> + .free =3D vduse_dev_free_coherent, > >>> + .max_mapping_size =3D vduse_dev_max_mapping_size, > >>> +}; > >>> + > >>> +static unsigned int perm_to_file_flags(u8 perm) > >>> +{ > >>> + unsigned int flags =3D 0; > >>> + > >>> + switch (perm) { > >>> + case VDUSE_ACCESS_WO: > >>> + flags |=3D O_WRONLY; > >>> + break; > >>> + case VDUSE_ACCESS_RO: > >>> + flags |=3D O_RDONLY; > >>> + break; > >>> + case VDUSE_ACCESS_RW: > >>> + flags |=3D O_RDWR; > >>> + break; > >>> + default: > >>> + WARN(1, "invalidate vhost IOTLB permission\n"); > >>> + break; > >>> + } > >>> + > >>> + return flags; > >>> +} > >>> + > >>> +static int vduse_kickfd_setup(struct vduse_dev *dev, > >>> + struct vduse_vq_eventfd *eventfd) > >>> +{ > >>> + struct eventfd_ctx *ctx =3D NULL; > >>> + struct vduse_virtqueue *vq; > >>> + u32 index; > >>> + > >>> + if (eventfd->index >=3D dev->vq_num) > >>> + return -EINVAL; > >>> + > >>> + index =3D array_index_nospec(eventfd->index, dev->vq_num); > >>> + vq =3D &dev->vqs[index]; > >>> + if (eventfd->fd >=3D 0) { > >>> + ctx =3D eventfd_ctx_fdget(eventfd->fd); > >>> + if (IS_ERR(ctx)) > >>> + return PTR_ERR(ctx); > >>> + } else if (eventfd->fd !=3D VDUSE_EVENTFD_DEASSIGN) > >>> + return 0; > >>> + > >>> + spin_lock(&vq->kick_lock); > >>> + if (vq->kickfd) > >>> + eventfd_ctx_put(vq->kickfd); > >>> + vq->kickfd =3D ctx; > >>> + if (vq->ready && vq->kicked && vq->kickfd) { > >>> + eventfd_signal(vq->kickfd, 1); > >>> + vq->kicked =3D false; > >>> + } > >>> + spin_unlock(&vq->kick_lock); > >>> + > >>> + return 0; > >>> +} > >>> + > >>> +static void vduse_dev_irq_inject(struct work_struct *work) > >>> +{ > >>> + struct vduse_dev *dev =3D container_of(work, struct vduse_dev, = inject); > >>> + > >>> + spin_lock_irq(&dev->irq_lock); > >>> + if (dev->config_cb.callback) > >>> + dev->config_cb.callback(dev->config_cb.private); > >>> + spin_unlock_irq(&dev->irq_lock); > >>> +} > >>> + > >>> +static void vduse_vq_irq_inject(struct work_struct *work) > >>> +{ > >>> + struct vduse_virtqueue *vq =3D container_of(work, > >>> + struct vduse_virtqueue, inject)= ; > >>> + > >>> + spin_lock_irq(&vq->irq_lock); > >>> + if (vq->ready && vq->cb.callback) > >>> + vq->cb.callback(vq->cb.private); > >>> + spin_unlock_irq(&vq->irq_lock); > >>> +} > >>> + > >>> +static long vduse_dev_ioctl(struct file *file, unsigned int cmd, > >>> + unsigned long arg) > >>> +{ > >>> + struct vduse_dev *dev =3D file->private_data; > >>> + void __user *argp =3D (void __user *)arg; > >>> + int ret; > >>> + > >>> + switch (cmd) { > >>> + case VDUSE_IOTLB_GET_FD: { > >>> + struct vduse_iotlb_entry entry; > >>> + struct vhost_iotlb_map *map; > >>> + struct vdpa_map_file *map_file; > >>> + struct vduse_iova_domain *domain =3D dev->domain; > >>> + struct file *f =3D NULL; > >>> + > >>> + ret =3D -EFAULT; > >>> + if (copy_from_user(&entry, argp, sizeof(entry))) > >>> + break; > >>> + > >>> + ret =3D -EINVAL; > >>> + if (entry.start > entry.last) > >>> + break; > >>> + > >>> + spin_lock(&domain->iotlb_lock); > >>> + map =3D vhost_iotlb_itree_first(domain->iotlb, > >>> + entry.start, entry.last); > >>> + if (map) { > >>> + map_file =3D (struct vdpa_map_file *)map->opaqu= e; > >>> + f =3D get_file(map_file->file); > >>> + entry.offset =3D map_file->offset; > >>> + entry.start =3D map->start; > >>> + entry.last =3D map->last; > >>> + entry.perm =3D map->perm; > >>> + } > >>> + spin_unlock(&domain->iotlb_lock); > >>> + ret =3D -EINVAL; > >>> + if (!f) > >>> + break; > >>> + > >>> + ret =3D -EFAULT; > >>> + if (copy_to_user(argp, &entry, sizeof(entry))) { > >>> + fput(f); > >>> + break; > >>> + } > >>> + ret =3D receive_fd(f, perm_to_file_flags(entry.perm)); > >>> + fput(f); > >>> + break; > >>> + } > >>> + case VDUSE_DEV_GET_FEATURES: > >>> + ret =3D put_user(dev->features, (u64 __user *)argp); > >>> + break; > >>> + case VDUSE_DEV_UPDATE_CONFIG: { > >>> + struct vduse_config_update config; > >>> + unsigned long size =3D offsetof(struct vduse_config_upd= ate, > >>> + buffer); > >>> + > >>> + ret =3D -EFAULT; > >>> + if (copy_from_user(&config, argp, size)) > >>> + break; > >>> + > >>> + ret =3D -EINVAL; > >>> + if (config.length =3D=3D 0 || > >>> + config.length > dev->config_size - config.offset) > >>> + break; > >>> + > >>> + ret =3D -EFAULT; > >>> + if (copy_from_user(dev->config + config.offset, argp + = size, > >>> + config.length)) > >>> + break; > >>> + > >>> + ret =3D 0; > >>> + queue_work(vduse_irq_wq, &dev->inject); > >> > >> I wonder if it's better to separate config interrupt out of config > >> update or we need document this. > >> > > I have documented it in the docs. Looks like a config update should be > > always followed by a config interrupt. I didn't find a case that uses > > them separately. > > > The uAPI doesn't prevent us from the following scenario: > > update_config(mac[0], ..); > update_config(max[1], ..); > > So it looks to me it's better to separate the config interrupt from the > config updating. > Fine. > > > > >>> + break; > >>> + } > >>> + case VDUSE_VQ_GET_INFO: { > >> > >> Do we need to limit this only when DRIVER_OK is set? > >> > > Any reason to add this limitation? > > > Otherwise the vq is not fully initialized, e.g the desc_addr might not > be correct. > The vq_info->ready can be used to tell userspace whether the vq is initialized or not. Thanks, Yongji From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC0DEC48BDF for ; Tue, 22 Jun 2021 07:22:28 +0000 (UTC) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7394C6112D for ; Tue, 22 Jun 2021 07:22:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7394C6112D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=bytedance.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=iommu-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 3CF734029A; Tue, 22 Jun 2021 07:22:28 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id IVqVIBG2sG1V; Tue, 22 Jun 2021 07:22:26 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 1ED6B4015B; Tue, 22 Jun 2021 07:22:26 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id E9830C001A; Tue, 22 Jun 2021 07:22:25 +0000 (UTC) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6A258C000E for ; Tue, 22 Jun 2021 07:22:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 4123C4047B for ; Tue, 22 Jun 2021 07:22:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp4.osuosl.org (amavisd-new); dkim=pass (2048-bit key) header.d=bytedance-com.20150623.gappssmtp.com Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id L0kLeaRApiBS for ; Tue, 22 Jun 2021 07:22:20 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by smtp4.osuosl.org (Postfix) with ESMTPS id 40C1140456 for ; Tue, 22 Jun 2021 07:22:19 +0000 (UTC) Received: by mail-ej1-x62e.google.com with SMTP id nb6so32789593ejc.10 for ; Tue, 22 Jun 2021 00:22:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=gLom4lP2hibA/zirOs75HpOQiLkyphvf9WwSZgUj8y4=; b=rZBYgIQ6eaQoJrR7/aULlx9tHfvP2U7yxchPCrKLCrDU8W2OjwYDQc4dlaDK7rwmEh t/MSfYdryYIRV6GqOkE5Pl+AlwNSIbD534x8uD5inNtL3X0rcDaJskmnwtJ0NM4rfQ/g kEeKUtbSW8CPlC37Wuu1JSc4VcQH3EUhO85OSN7cUEv8GpGpxC82WDFPRp01f9B0DgIJ m3Q621+iidL8cgVBnEkFMWzlSgoT36riwgEyhGZiuyTs+T9rJC3En+Pd1Y8P0IjeObhd M5AeHhKOnPBvgRKWfVMQuiY+90lsjrjyE0fRsZQNapLK/40+W8G/hsPzLaiP42OM41m3 D2aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=gLom4lP2hibA/zirOs75HpOQiLkyphvf9WwSZgUj8y4=; b=VYZ2fOzm7FdMJLcaUnMUFrdNDgGcEEJyfdpJ5tEx59DsefQWbm5kgSM8H9kW8Ot4Ku 4A5+c5V6/HgkWfCGNb6paOx60TxLlHBn+GkLHIwKQ16FFEiTr178xKpPZuI/2XRS8TOq xl9OXiLKCPWea1O7RVbJfL+7HvGRiyP/IMeBu955U4DfQfxjvSn986yYBdNU3I7J0xcZ HgCDXjOVBvOKoo/riYFjqChme2xia7LU3S0LBeKUg8Puj7c4Zk4xxKJJx7T1C3uXaNRh yuJqt7xAoffrvW7Zhbee9sHJj0SpoN6Ku+Om2BI3iwUUIU1FvJLSwGwJVyRp0GHOjw5A Xutg== X-Gm-Message-State: AOAM533JO0q31bg6bWBuMjkdKgYAnsEkwTzm9NlhyNpBXDUsJeKdvEvD pF9amJ7spxPzcSJaf9eWtZP0B2au6miRjLGwGzs4 X-Google-Smtp-Source: ABdhPJxChMepMHmwcjDcpaa0xcreEesoNRhNDDJguXaRU2cc/7WY7PBM6Sc1eEidlncBPzdp7VKgwyXRxV1Wwk4Tym4= X-Received: by 2002:a17:906:3c4a:: with SMTP id i10mr2432624ejg.372.1624346537905; Tue, 22 Jun 2021 00:22:17 -0700 (PDT) MIME-Version: 1.0 References: <20210615141331.407-1-xieyongji@bytedance.com> <20210615141331.407-10-xieyongji@bytedance.com> <1bba439f-ffc8-c20e-e8a4-ac73e890c592@redhat.com> In-Reply-To: <1bba439f-ffc8-c20e-e8a4-ac73e890c592@redhat.com> From: Yongji Xie Date: Tue, 22 Jun 2021 15:22:06 +0800 Message-ID: Subject: Re: Re: [PATCH v8 09/10] vduse: Introduce VDUSE - vDPA Device in Userspace To: Jason Wang Cc: kvm , "Michael S. Tsirkin" , virtualization , Christian Brauner , Jonathan Corbet , Matthew Wilcox , Christoph Hellwig , Dan Carpenter , Stefano Garzarella , Al Viro , Stefan Hajnoczi , songmuchun@bytedance.com, Jens Axboe , Greg KH , Randy Dunlap , linux-kernel , iommu@lists.linux-foundation.org, bcrl@kvack.org, netdev@vger.kernel.org, linux-fsdevel@vger.kernel.org, =?UTF-8?Q?Mika_Penttil=C3=A4?= X-BeenThere: iommu@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Development issues for Linux IOMMU support List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: iommu-bounces@lists.linux-foundation.org Sender: "iommu" Lk9uIFR1ZSwgSnVuIDIyLCAyMDIxIGF0IDE6MDcgUE0gSmFzb24gV2FuZyA8amFzb3dhbmdAcmVk aGF0LmNvbT4gd3JvdGU6Cj4KPgo+IOWcqCAyMDIxLzYvMjEg5LiL5Y2INjo0MSwgWW9uZ2ppIFhp ZSDlhpnpgZM6Cj4gPiBPbiBNb24sIEp1biAyMSwgMjAyMSBhdCA1OjE0IFBNIEphc29uIFdhbmcg PGphc293YW5nQHJlZGhhdC5jb20+IHdyb3RlOgo+ID4+Cj4gPj4g5ZyoIDIwMjEvNi8xNSDkuIvl jYgxMDoxMywgWGllIFlvbmdqaSDlhpnpgZM6Cj4gPj4+IFRoaXMgVkRVU0UgZHJpdmVyIGVuYWJs ZXMgaW1wbGVtZW50aW5nIHZEUEEgZGV2aWNlcyBpbiB1c2Vyc3BhY2UuCj4gPj4+IFRoZSB2RFBB IGRldmljZSdzIGNvbnRyb2wgcGF0aCBpcyBoYW5kbGVkIGluIGtlcm5lbCBhbmQgdGhlIGRhdGEK PiA+Pj4gcGF0aCBpcyBoYW5kbGVkIGluIHVzZXJzcGFjZS4KPiA+Pj4KPiA+Pj4gQSBtZXNzYWdl IG1lY2huaXNtIGlzIHVzZWQgYnkgVkRVU0UgZHJpdmVyIHRvIGZvcndhcmQgc29tZSBjb250cm9s Cj4gPj4+IG1lc3NhZ2VzIHN1Y2ggYXMgc3RhcnRpbmcvc3RvcHBpbmcgZGF0YXBhdGggdG8gdXNl cnNwYWNlLiBVc2Vyc3BhY2UKPiA+Pj4gY2FuIHVzZSByZWFkKCkvd3JpdGUoKSB0byByZWNlaXZl L3JlcGx5IHRob3NlIGNvbnRyb2wgbWVzc2FnZXMuCj4gPj4+Cj4gPj4+IEFuZCBzb21lIGlvY3Rs cyBhcmUgaW50cm9kdWNlZCB0byBoZWxwIHVzZXJzcGFjZSB0byBpbXBsZW1lbnQgdGhlCj4gPj4+ IGRhdGEgcGF0aC4gVkRVU0VfSU9UTEJfR0VUX0ZEIGlvY3RsIGNhbiBiZSB1c2VkIHRvIGdldCB0 aGUgZmlsZQo+ID4+PiBkZXNjcmlwdG9ycyByZWZlcnJpbmcgdG8gdkRQQSBkZXZpY2UncyBpb3Zh IHJlZ2lvbnMuIFRoZW4gdXNlcnNwYWNlCj4gPj4+IGNhbiB1c2UgbW1hcCgpIHRvIGFjY2VzcyB0 aG9zZSBpb3ZhIHJlZ2lvbnMuIFZEVVNFX0RFVl9HRVRfRkVBVFVSRVMKPiA+Pj4gYW5kIFZEVVNF X1ZRX0dFVF9JTkZPIGlvY3RscyBhcmUgdXNlZCB0byBnZXQgdGhlIG5lZ290aWF0ZWQgZmVhdHVy ZXMKPiA+Pj4gYW5kIG1ldGFkYXRhIG9mIHZpcnRxdWV1ZXMuIFZEVVNFX0lOSkVDVF9WUV9JUlEg YW5kIFZEVVNFX1ZRX1NFVFVQX0tJQ0tGRAo+ID4+PiBpb2N0bHMgY2FuIGJlIHVzZWQgdG8gaW5q ZWN0IGludGVycnVwdCBhbmQgc2V0dXAgdGhlIGtpY2tmZCBmb3IKPiA+Pj4gdmlydHF1ZXVlcy4g VkRVU0VfREVWX1VQREFURV9DT05GSUcgaW9jdGwgaXMgdXNlZCB0byB1cGRhdGUgdGhlCj4gPj4+ IGNvbmZpZ3VyYXRpb24gc3BhY2UgYW5kIGluamVjdCBhIGNvbmZpZyBpbnRlcnJ1cHQuCj4gPj4+ Cj4gPj4+IFNpZ25lZC1vZmYtYnk6IFhpZSBZb25namkgPHhpZXlvbmdqaUBieXRlZGFuY2UuY29t Pgo+ID4+PiAtLS0KPiA+Pj4gICAgRG9jdW1lbnRhdGlvbi91c2Vyc3BhY2UtYXBpL2lvY3RsL2lv Y3RsLW51bWJlci5yc3QgfCAgICAxICsKPiA+Pj4gICAgZHJpdmVycy92ZHBhL0tjb25maWcgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDEwICsKPiA+Pj4gICAgZHJpdmVycy92ZHBh L01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAxICsKPiA+Pj4gICAg ZHJpdmVycy92ZHBhL3ZkcGFfdXNlci9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAgfCAgICA1 ICsKPiA+Pj4gICAgZHJpdmVycy92ZHBhL3ZkcGFfdXNlci92ZHVzZV9kZXYuYyAgICAgICAgICAg ICAgICAgfCAxNDUzICsrKysrKysrKysrKysrKysrKysrCj4gPj4+ICAgIGluY2x1ZGUvdWFwaS9s aW51eC92ZHVzZS5oICAgICAgICAgICAgICAgICAgICAgICAgIHwgIDE0MyArKwo+ID4+PiAgICA2 IGZpbGVzIGNoYW5nZWQsIDE2MTMgaW5zZXJ0aW9ucygrKQo+ID4+PiAgICBjcmVhdGUgbW9kZSAx MDA2NDQgZHJpdmVycy92ZHBhL3ZkcGFfdXNlci9NYWtlZmlsZQo+ID4+PiAgICBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy92ZHBhL3ZkcGFfdXNlci92ZHVzZV9kZXYuYwo+ID4+PiAgICBjcmVh dGUgbW9kZSAxMDA2NDQgaW5jbHVkZS91YXBpL2xpbnV4L3ZkdXNlLmgKPiA+Pj4KPiA+Pj4gZGlm ZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vdXNlcnNwYWNlLWFwaS9pb2N0bC9pb2N0bC1udW1iZXIu cnN0IGIvRG9jdW1lbnRhdGlvbi91c2Vyc3BhY2UtYXBpL2lvY3RsL2lvY3RsLW51bWJlci5yc3QK PiA+Pj4gaW5kZXggOWJmYzJiNTEwYzY0Li5hY2Q5NWU5ZGNmZTcgMTAwNjQ0Cj4gPj4+IC0tLSBh L0RvY3VtZW50YXRpb24vdXNlcnNwYWNlLWFwaS9pb2N0bC9pb2N0bC1udW1iZXIucnN0Cj4gPj4+ ICsrKyBiL0RvY3VtZW50YXRpb24vdXNlcnNwYWNlLWFwaS9pb2N0bC9pb2N0bC1udW1iZXIucnN0 Cj4gPj4+IEBAIC0zMDAsNiArMzAwLDcgQEAgQ29kZSAgU2VxIyAgICBJbmNsdWRlIEZpbGUgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29tbWVudHMKPiA+Pj4gICAg J3onICAgMTAtNEYgIGRyaXZlcnMvczM5MC9jcnlwdG8vemNyeXB0X2FwaS5oICAgICAgICAgICAg ICAgICAgICAgICAgY29uZmxpY3QhCj4gPj4+ICAgICd8JyAgIDAwLTdGICBsaW51eC9tZWRpYS5o Cj4gPj4+ICAgIDB4ODAgIDAwLTFGICBsaW51eC9mYi5oCj4gPj4+ICsweDgxICAwMC0xRiAgbGlu dXgvdmR1c2UuaAo+ID4+PiAgICAweDg5ICAwMC0wNiAgYXJjaC94ODYvaW5jbHVkZS9hc20vc29j a2lvcy5oCj4gPj4+ICAgIDB4ODkgIDBCLURGICBsaW51eC9zb2NraW9zLmgKPiA+Pj4gICAgMHg4 OSAgRTAtRUYgIGxpbnV4L3NvY2tpb3MuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgU0lPQ1BST1RPUFJJVkFURSByYW5nZQo+ID4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVy cy92ZHBhL0tjb25maWcgYi9kcml2ZXJzL3ZkcGEvS2NvbmZpZwo+ID4+PiBpbmRleCBhNTAzYzFi MmJmZDkuLjZlMjNiY2U2NDMzYSAxMDA2NDQKPiA+Pj4gLS0tIGEvZHJpdmVycy92ZHBhL0tjb25m aWcKPiA+Pj4gKysrIGIvZHJpdmVycy92ZHBhL0tjb25maWcKPiA+Pj4gQEAgLTMzLDYgKzMzLDE2 IEBAIGNvbmZpZyBWRFBBX1NJTV9CTE9DSwo+ID4+PiAgICAgICAgICB2RFBBIGJsb2NrIGRldmlj ZSBzaW11bGF0b3Igd2hpY2ggdGVybWluYXRlcyBJTyByZXF1ZXN0IGluIGEKPiA+Pj4gICAgICAg ICAgbWVtb3J5IGJ1ZmZlci4KPiA+Pj4KPiA+Pj4gK2NvbmZpZyBWRFBBX1VTRVIKPiA+Pj4gKyAg ICAgdHJpc3RhdGUgIlZEVVNFICh2RFBBIERldmljZSBpbiBVc2Vyc3BhY2UpIHN1cHBvcnQiCj4g Pj4+ICsgICAgIGRlcGVuZHMgb24gRVZFTlRGRCAmJiBNTVUgJiYgSEFTX0RNQQo+ID4+PiArICAg ICBzZWxlY3QgRE1BX09QUwo+ID4+PiArICAgICBzZWxlY3QgVkhPU1RfSU9UTEIKPiA+Pj4gKyAg ICAgc2VsZWN0IElPTU1VX0lPVkEKPiA+Pj4gKyAgICAgaGVscAo+ID4+PiArICAgICAgIFdpdGgg VkRVU0UgaXQgaXMgcG9zc2libGUgdG8gZW11bGF0ZSBhIHZEUEEgRGV2aWNlCj4gPj4+ICsgICAg ICAgaW4gYSB1c2Vyc3BhY2UgcHJvZ3JhbS4KPiA+Pj4gKwo+ID4+PiAgICBjb25maWcgSUZDVkYK PiA+Pj4gICAgICAgIHRyaXN0YXRlICJJbnRlbCBJRkMgVkYgdkRQQSBkcml2ZXIiCj4gPj4+ICAg ICAgICBkZXBlbmRzIG9uIFBDSV9NU0kKPiA+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdmRwYS9N YWtlZmlsZSBiL2RyaXZlcnMvdmRwYS9NYWtlZmlsZQo+ID4+PiBpbmRleCA2N2ZlN2YzZDY5NDMu LmYwMmViZWQzM2YxOSAxMDA2NDQKPiA+Pj4gLS0tIGEvZHJpdmVycy92ZHBhL01ha2VmaWxlCj4g Pj4+ICsrKyBiL2RyaXZlcnMvdmRwYS9NYWtlZmlsZQo+ID4+PiBAQCAtMSw2ICsxLDcgQEAKPiA+ Pj4gICAgIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ID4+PiAgICBvYmotJChD T05GSUdfVkRQQSkgKz0gdmRwYS5vCj4gPj4+ICAgIG9iai0kKENPTkZJR19WRFBBX1NJTSkgKz0g dmRwYV9zaW0vCj4gPj4+ICtvYmotJChDT05GSUdfVkRQQV9VU0VSKSArPSB2ZHBhX3VzZXIvCj4g Pj4+ICAgIG9iai0kKENPTkZJR19JRkNWRikgICAgKz0gaWZjdmYvCj4gPj4+ICAgIG9iai0kKENP TkZJR19NTFg1X1ZEUEEpICs9IG1seDUvCj4gPj4+ICAgIG9iai0kKENPTkZJR19WUF9WRFBBKSAg ICArPSB2aXJ0aW9fcGNpLwo+ID4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy92ZHBhL3ZkcGFfdXNl ci9NYWtlZmlsZSBiL2RyaXZlcnMvdmRwYS92ZHBhX3VzZXIvTWFrZWZpbGUKPiA+Pj4gbmV3IGZp bGUgbW9kZSAxMDA2NDQKPiA+Pj4gaW5kZXggMDAwMDAwMDAwMDAwLi4yNjBlMGIyNmFmOTkKPiA+ Pj4gLS0tIC9kZXYvbnVsbAo+ID4+PiArKysgYi9kcml2ZXJzL3ZkcGEvdmRwYV91c2VyL01ha2Vm aWxlCj4gPj4+IEBAIC0wLDAgKzEsNSBAQAo+ID4+PiArIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmll cjogR1BMLTIuMAo+ID4+PiArCj4gPj4+ICt2ZHVzZS15IDo9IHZkdXNlX2Rldi5vIGlvdmFfZG9t YWluLm8KPiA+Pj4gKwo+ID4+PiArb2JqLSQoQ09ORklHX1ZEUEFfVVNFUikgKz0gdmR1c2Uubwo+ ID4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy92ZHBhL3ZkcGFfdXNlci92ZHVzZV9kZXYuYyBiL2Ry aXZlcnMvdmRwYS92ZHBhX3VzZXIvdmR1c2VfZGV2LmMKPiA+Pj4gbmV3IGZpbGUgbW9kZSAxMDA2 NDQKPiA+Pj4gaW5kZXggMDAwMDAwMDAwMDAwLi41MjcxY2JkMTVlMjgKPiA+Pj4gLS0tIC9kZXYv bnVsbAo+ID4+PiArKysgYi9kcml2ZXJzL3ZkcGEvdmRwYV91c2VyL3ZkdXNlX2Rldi5jCj4gPj4+ IEBAIC0wLDAgKzEsMTQ1MyBAQAo+ID4+PiArLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQ TC0yLjAtb25seQo+ID4+PiArLyoKPiA+Pj4gKyAqIFZEVVNFOiB2RFBBIERldmljZSBpbiBVc2Vy c3BhY2UKPiA+Pj4gKyAqCj4gPj4+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyMSBCeXRlZGFu Y2UgSW5jLiBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCj4gPj4+ ICsgKgo+ID4+PiArICogQXV0aG9yOiBYaWUgWW9uZ2ppIDx4aWV5b25namlAYnl0ZWRhbmNlLmNv bT4KPiA+Pj4gKyAqCj4gPj4+ICsgKi8KPiA+Pj4gKwo+ID4+PiArI2luY2x1ZGUgPGxpbnV4L2lu aXQuaD4KPiA+Pj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiA+Pj4gKyNpbmNsdWRlIDxs aW51eC9jZGV2Lmg+Cj4gPj4+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+Cj4gPj4+ICsjaW5j bHVkZSA8bGludXgvZXZlbnRmZC5oPgo+ID4+PiArI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPiA+ Pj4gKyNpbmNsdWRlIDxsaW51eC93YWl0Lmg+Cj4gPj4+ICsjaW5jbHVkZSA8bGludXgvZG1hLW1h cC1vcHMuaD4KPiA+Pj4gKyNpbmNsdWRlIDxsaW51eC9wb2xsLmg+Cj4gPj4+ICsjaW5jbHVkZSA8 bGludXgvZmlsZS5oPgo+ID4+PiArI2luY2x1ZGUgPGxpbnV4L3Vpby5oPgo+ID4+PiArI2luY2x1 ZGUgPGxpbnV4L3ZkcGEuaD4KPiA+Pj4gKyNpbmNsdWRlIDxsaW51eC9ub3NwZWMuaD4KPiA+Pj4g KyNpbmNsdWRlIDx1YXBpL2xpbnV4L3ZkdXNlLmg+Cj4gPj4+ICsjaW5jbHVkZSA8dWFwaS9saW51 eC92ZHBhLmg+Cj4gPj4+ICsjaW5jbHVkZSA8dWFwaS9saW51eC92aXJ0aW9fY29uZmlnLmg+Cj4g Pj4+ICsjaW5jbHVkZSA8dWFwaS9saW51eC92aXJ0aW9faWRzLmg+Cj4gPj4+ICsjaW5jbHVkZSA8 dWFwaS9saW51eC92aXJ0aW9fYmxrLmg+Cj4gPj4+ICsjaW5jbHVkZSA8bGludXgvbW9kX2Rldmlj ZXRhYmxlLmg+Cj4gPj4+ICsKPiA+Pj4gKyNpbmNsdWRlICJpb3ZhX2RvbWFpbi5oIgo+ID4+PiAr Cj4gPj4+ICsjZGVmaW5lIERSVl9BVVRIT1IgICAiWW9uZ2ppIFhpZSA8eGlleW9uZ2ppQGJ5dGVk YW5jZS5jb20+Igo+ID4+PiArI2RlZmluZSBEUlZfREVTQyAgICAgInZEUEEgRGV2aWNlIGluIFVz ZXJzcGFjZSIKPiA+Pj4gKyNkZWZpbmUgRFJWX0xJQ0VOU0UgICJHUEwgdjIiCj4gPj4+ICsKPiA+ Pj4gKyNkZWZpbmUgVkRVU0VfREVWX01BWCAoMVUgPDwgTUlOT1JCSVRTKQo+ID4+PiArI2RlZmlu ZSBWRFVTRV9NQVhfQk9VTkNFX1NJWkUgKDY0ICogMTAyNCAqIDEwMjQpCj4gPj4+ICsjZGVmaW5l IFZEVVNFX0lPVkFfU0laRSAoMTI4ICogMTAyNCAqIDEwMjQpCj4gPj4+ICsjZGVmaW5lIFZEVVNF X1JFUVVFU1RfVElNRU9VVCAzMAo+ID4+PiArCj4gPj4+ICtzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVl IHsKPiA+Pj4gKyAgICAgdTE2IGluZGV4Owo+ID4+PiArICAgICB1MzIgbnVtOwo+ID4+PiArICAg ICB1MzIgYXZhaWxfaWR4Owo+ID4+PiArICAgICB1NjQgZGVzY19hZGRyOwo+ID4+PiArICAgICB1 NjQgZHJpdmVyX2FkZHI7Cj4gPj4+ICsgICAgIHU2NCBkZXZpY2VfYWRkcjsKPiA+Pj4gKyAgICAg Ym9vbCByZWFkeTsKPiA+Pj4gKyAgICAgYm9vbCBraWNrZWQ7Cj4gPj4+ICsgICAgIHNwaW5sb2Nr X3Qga2lja19sb2NrOwo+ID4+PiArICAgICBzcGlubG9ja190IGlycV9sb2NrOwo+ID4+PiArICAg ICBzdHJ1Y3QgZXZlbnRmZF9jdHggKmtpY2tmZDsKPiA+Pj4gKyAgICAgc3RydWN0IHZkcGFfY2Fs bGJhY2sgY2I7Cj4gPj4+ICsgICAgIHN0cnVjdCB3b3JrX3N0cnVjdCBpbmplY3Q7Cj4gPj4+ICt9 Owo+ID4+PiArCj4gPj4+ICtzdHJ1Y3QgdmR1c2VfZGV2Owo+ID4+PiArCj4gPj4+ICtzdHJ1Y3Qg dmR1c2VfdmRwYSB7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHBhX2RldmljZSB2ZHBhOwo+ID4+PiAr ICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXY7Cj4gPj4+ICt9Owo+ID4+PiArCj4gPj4+ICtzdHJ1 Y3QgdmR1c2VfZGV2IHsKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX3ZkcGEgKnZkZXY7Cj4gPj4+ ICsgICAgIHN0cnVjdCBkZXZpY2UgKmRldjsKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX3ZpcnRx dWV1ZSAqdnFzOwo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbjsK PiA+Pj4gKyAgICAgY2hhciAqbmFtZTsKPiA+Pj4gKyAgICAgc3RydWN0IG11dGV4IGxvY2s7Cj4g Pj4+ICsgICAgIHNwaW5sb2NrX3QgbXNnX2xvY2s7Cj4gPj4+ICsgICAgIHU2NCBtc2dfdW5pcXVl Owo+ID4+PiArICAgICB3YWl0X3F1ZXVlX2hlYWRfdCB3YWl0cTsKPiA+Pj4gKyAgICAgc3RydWN0 IGxpc3RfaGVhZCBzZW5kX2xpc3Q7Cj4gPj4+ICsgICAgIHN0cnVjdCBsaXN0X2hlYWQgcmVjdl9s aXN0Owo+ID4+PiArICAgICBzdHJ1Y3QgdmRwYV9jYWxsYmFjayBjb25maWdfY2I7Cj4gPj4+ICsg ICAgIHN0cnVjdCB3b3JrX3N0cnVjdCBpbmplY3Q7Cj4gPj4+ICsgICAgIHNwaW5sb2NrX3QgaXJx X2xvY2s7Cj4gPj4+ICsgICAgIGludCBtaW5vcjsKPiA+Pj4gKyAgICAgYm9vbCBjb25uZWN0ZWQ7 Cj4gPj4+ICsgICAgIGJvb2wgc3RhcnRlZDsKPiA+Pj4gKyAgICAgdTY0IGFwaV92ZXJzaW9uOwo+ ID4+PiArICAgICB1NjQgdXNlcl9mZWF0dXJlczsKPiA+Pgo+ID4+IExldCdzIHVzZSBkZXZpY2Vf ZmVhdHVyZXMuCj4gPj4KPiA+IE9LLgo+ID4KPiA+Pj4gKyAgICAgdTY0IGZlYXR1cmVzOwo+ID4+ Cj4gPj4gQW5kIGRyaXZlciBmZWF0dXJlcy4KPiA+Pgo+ID4gT0suCj4gPgo+ID4+PiArICAgICB1 MzIgZGV2aWNlX2lkOwo+ID4+PiArICAgICB1MzIgdmVuZG9yX2lkOwo+ID4+PiArICAgICB1MzIg Z2VuZXJhdGlvbjsKPiA+Pj4gKyAgICAgdTMyIGNvbmZpZ19zaXplOwo+ID4+PiArICAgICB2b2lk ICpjb25maWc7Cj4gPj4+ICsgICAgIHU4IHN0YXR1czsKPiA+Pj4gKyAgICAgdTE2IHZxX3NpemVf bWF4Owo+ID4+PiArICAgICB1MzIgdnFfbnVtOwo+ID4+PiArICAgICB1MzIgdnFfYWxpZ247Cj4g Pj4+ICt9Owo+ID4+PiArCj4gPj4+ICtzdHJ1Y3QgdmR1c2VfZGV2X21zZyB7Cj4gPj4+ICsgICAg IHN0cnVjdCB2ZHVzZV9kZXZfcmVxdWVzdCByZXE7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9k ZXZfcmVzcG9uc2UgcmVzcDsKPiA+Pj4gKyAgICAgc3RydWN0IGxpc3RfaGVhZCBsaXN0Owo+ID4+ PiArICAgICB3YWl0X3F1ZXVlX2hlYWRfdCB3YWl0cTsKPiA+Pj4gKyAgICAgYm9vbCBjb21wbGV0 ZWQ7Cj4gPj4+ICt9Owo+ID4+PiArCj4gPj4+ICtzdHJ1Y3QgdmR1c2VfY29udHJvbCB7Cj4gPj4+ ICsgICAgIHU2NCBhcGlfdmVyc2lvbjsKPiA+Pj4gK307Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBE RUZJTkVfTVVURVgodmR1c2VfbG9jayk7Cj4gPj4+ICtzdGF0aWMgREVGSU5FX0lEUih2ZHVzZV9p ZHIpOwo+ID4+PiArCj4gPj4+ICtzdGF0aWMgZGV2X3QgdmR1c2VfbWFqb3I7Cj4gPj4+ICtzdGF0 aWMgc3RydWN0IGNsYXNzICp2ZHVzZV9jbGFzczsKPiA+Pj4gK3N0YXRpYyBzdHJ1Y3QgY2RldiB2 ZHVzZV9jdHJsX2NkZXY7Cj4gPj4+ICtzdGF0aWMgc3RydWN0IGNkZXYgdmR1c2VfY2RldjsKPiA+ Pj4gK3N0YXRpYyBzdHJ1Y3Qgd29ya3F1ZXVlX3N0cnVjdCAqdmR1c2VfaXJxX3dxOwo+ID4+PiAr Cj4gPj4+ICtzdGF0aWMgdTMyIGFsbG93ZWRfZGV2aWNlX2lkW10gPSB7Cj4gPj4+ICsgICAgIFZJ UlRJT19JRF9CTE9DSywKPiA+Pj4gK307Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBpbmxpbmUgc3Ry dWN0IHZkdXNlX2RldiAqdmRwYV90b192ZHVzZShzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEpCj4g Pj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV92ZHBhICp2ZGV2ID0gY29udGFpbmVyX29m KHZkcGEsIHN0cnVjdCB2ZHVzZV92ZHBhLCB2ZHBhKTsKPiA+Pj4gKwo+ID4+PiArICAgICByZXR1 cm4gdmRldi0+ZGV2Owo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgaW5saW5lIHN0cnVj dCB2ZHVzZV9kZXYgKmRldl90b192ZHVzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gPj4+ICt7Cj4g Pj4+ICsgICAgIHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSA9IGRldl90b192ZHBhKGRldik7Cj4g Pj4+ICsKPiA+Pj4gKyAgICAgcmV0dXJuIHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ICt9Cj4g Pj4+ICsKPiA+Pj4gK3N0YXRpYyBzdHJ1Y3QgdmR1c2VfZGV2X21zZyAqdmR1c2VfZmluZF9tc2co c3RydWN0IGxpc3RfaGVhZCAqaGVhZCwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgdWludDMyX3QgcmVxdWVzdF9pZCkKPiA+Pj4gK3sKPiA+Pj4gKyAgICAg c3RydWN0IHZkdXNlX2Rldl9tc2cgKm1zZzsKPiA+Pj4gKwo+ID4+PiArICAgICBsaXN0X2Zvcl9l YWNoX2VudHJ5KG1zZywgaGVhZCwgbGlzdCkgewo+ID4+PiArICAgICAgICAgICAgIGlmIChtc2ct PnJlcS5yZXF1ZXN0X2lkID09IHJlcXVlc3RfaWQpIHsKPiA+Pj4gKyAgICAgICAgICAgICAgICAg ICAgIGxpc3RfZGVsKCZtc2ctPmxpc3QpOwo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgcmV0 dXJuIG1zZzsKPiA+Pj4gKyAgICAgICAgICAgICB9Cj4gPj4+ICsgICAgIH0KPiA+Pj4gKwo+ID4+ PiArICAgICByZXR1cm4gTlVMTDsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHN0cnVj dCB2ZHVzZV9kZXZfbXNnICp2ZHVzZV9kZXF1ZXVlX21zZyhzdHJ1Y3QgbGlzdF9oZWFkICpoZWFk KQo+ID4+PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2X21zZyAqbXNnID0gTlVMTDsK PiA+Pj4gKwo+ID4+PiArICAgICBpZiAoIWxpc3RfZW1wdHkoaGVhZCkpIHsKPiA+Pj4gKyAgICAg ICAgICAgICBtc2cgPSBsaXN0X2ZpcnN0X2VudHJ5KGhlYWQsIHN0cnVjdCB2ZHVzZV9kZXZfbXNn LCBsaXN0KTsKPiA+Pj4gKyAgICAgICAgICAgICBsaXN0X2RlbCgmbXNnLT5saXN0KTsKPiA+Pj4g KyAgICAgfQo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiBtc2c7Cj4gPj4+ICt9Cj4gPj4+ICsK PiA+Pj4gK3N0YXRpYyB2b2lkIHZkdXNlX2VucXVldWVfbXNnKHN0cnVjdCBsaXN0X2hlYWQgKmhl YWQsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2VfZGV2X21z ZyAqbXNnKQo+ID4+PiArewo+ID4+PiArICAgICBsaXN0X2FkZF90YWlsKCZtc2ctPmxpc3QsIGhl YWQpOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgaW50IHZkdXNlX2Rldl9tc2dfc2Vu ZChzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICBzdHJ1Y3QgdmR1c2VfZGV2X21zZyAqbXNnLCBib29sIG5vX3JlcGx5KQo+ID4+PiArewo+ID4+ Cj4gPj4gSXQgbG9va3MgdG8gbWUgdGhlIG9ubHkgdXNlciBmb3Igbm9fcmVwbHk9dHJ1ZSBpcyB0 aGUgZGF0YXBsYW5lIHN0YXJ0LiBJCj4gPj4gd29uZGVyIG5vX3JlcGx5IGlzIHJlYWxseSBuZWVk ZWQgY29uc2lkZXIgd2UgaGF2ZSBzd2l0Y2hlZCB0byB1c2UKPiA+PiB3YWl0X2V2ZW50X2tpbGxh YmxlX3RpbWVvdXQoKS4KPiA+Pgo+ID4gRG8gd2UgbmVlZCB0byBoYW5kbGUgdGhlIGVycm9yIGlu IHRoaXMgY2FzZSBpZiB3ZSByZW1vdmUgdGhlIG5vX3JlcGx5Cj4gPiBmbGFnLiBQcmludCBhIHdh cm5pbmcgbWVzc2FnZT8KPgo+Cj4gU2VlIGJlbG93Lgo+Cj4KPiA+Cj4gPj4gSW4gYW5vdGhlciB3 YXksIG5vX3JlcGx5IGlzIGZhbHNlIGZvciB2cSBzdGF0ZSBzeW5jaHJvbml6YXRpb24gYW5kIElP VExCCj4gPj4gdXBkYXRpbmcuIEkgd29uZGVyIGlmIHdlIGNhbiBzaW1wbHkgdXNlIG5vX3JlcGx5 ID0gdHJ1ZSBmb3IgdGhlbS4KPiA+Pgo+ID4gTG9va3MgbGlrZSB3ZSBjYW4ndCwgZS5nLiB3ZSBu ZWVkIHRvIGdldCBhIHJlcGx5IGZyb20gdXNlcnNwYWNlIGZvciB2cSBzdGF0ZS4KPgo+Cj4gUmln aHQuCj4KPgo+ID4KPiA+Pj4gKyAgICAgaW5pdF93YWl0cXVldWVfaGVhZCgmbXNnLT53YWl0cSk7 Cj4gPj4+ICsgICAgIHNwaW5fbG9jaygmZGV2LT5tc2dfbG9jayk7Cj4gPj4+ICsgICAgIG1zZy0+ cmVxLnJlcXVlc3RfaWQgPSBkZXYtPm1zZ191bmlxdWUrKzsKPiA+Pj4gKyAgICAgdmR1c2VfZW5x dWV1ZV9tc2coJmRldi0+c2VuZF9saXN0LCBtc2cpOwo+ID4+PiArICAgICB3YWtlX3VwKCZkZXYt PndhaXRxKTsKPiA+Pj4gKyAgICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ID4+PiAr ICAgICBpZiAobm9fcmVwbHkpCj4gPj4+ICsgICAgICAgICAgICAgcmV0dXJuIDA7Cj4gPj4+ICsK PiA+Pj4gKyAgICAgd2FpdF9ldmVudF9raWxsYWJsZV90aW1lb3V0KG1zZy0+d2FpdHEsIG1zZy0+ Y29tcGxldGVkLAo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkRVU0Vf UkVRVUVTVF9USU1FT1VUICogSFopOwo+ID4+PiArICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xv Y2spOwo+ID4+PiArICAgICBpZiAoIW1zZy0+Y29tcGxldGVkKSB7Cj4gPj4+ICsgICAgICAgICAg ICAgbGlzdF9kZWwoJm1zZy0+bGlzdCk7Cj4gPj4+ICsgICAgICAgICAgICAgbXNnLT5yZXNwLnJl c3VsdCA9IFZEVVNFX1JFUV9SRVNVTFRfRkFJTEVEOwo+ID4+PiArICAgICB9Cj4gPj4+ICsgICAg IHNwaW5fdW5sb2NrKCZkZXYtPm1zZ19sb2NrKTsKPiA+Pj4gKwo+ID4+PiArICAgICByZXR1cm4g KG1zZy0+cmVzcC5yZXN1bHQgPT0gVkRVU0VfUkVRX1JFU1VMVF9PSykgPyAwIDogLUVJTzsKPiA+ Pgo+ID4+IERvIHdlIG5lZWQgdG8gc2VyaWFsaXplIHRoZSBjaGVjayBieSBwcm90ZWN0aW5nIGl0 IHdpdGggdGhlIHNwaW5sb2NrIGFib3ZlPwo+ID4+Cj4gPiBHb29kIHBvaW50Lgo+ID4KPiA+Pj4g K30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHZvaWQgdmR1c2VfZGV2X21zZ19jbGVhbnVwKHN0cnVj dCB2ZHVzZV9kZXYgKmRldikKPiA+Pj4gK3sKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2Rldl9t c2cgKm1zZzsKPiA+Pj4gKwo+ID4+PiArICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xvY2spOwo+ ID4+PiArICAgICB3aGlsZSAoKG1zZyA9IHZkdXNlX2RlcXVldWVfbXNnKCZkZXYtPnNlbmRfbGlz dCkpKSB7Cj4gPj4+ICsgICAgICAgICAgICAgaWYgKG1zZy0+cmVxLmZsYWdzICYgVkRVU0VfUkVR X0ZMQUdTX05PX1JFUExZKQo+ID4+PiArICAgICAgICAgICAgICAgICAgICAga2ZyZWUobXNnKTsK PiA+Pj4gKyAgICAgICAgICAgICBlbHNlCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICB2ZHVz ZV9lbnF1ZXVlX21zZygmZGV2LT5yZWN2X2xpc3QsIG1zZyk7Cj4gPj4+ICsgICAgIH0KPiA+Pj4g KyAgICAgd2hpbGUgKChtc2cgPSB2ZHVzZV9kZXF1ZXVlX21zZygmZGV2LT5yZWN2X2xpc3QpKSkg ewo+ID4+PiArICAgICAgICAgICAgIG1zZy0+cmVzcC5yZXN1bHQgPSBWRFVTRV9SRVFfUkVTVUxU X0ZBSUxFRDsKPiA+Pj4gKyAgICAgICAgICAgICBtc2ctPmNvbXBsZXRlZCA9IDE7Cj4gPj4+ICsg ICAgICAgICAgICAgd2FrZV91cCgmbXNnLT53YWl0cSk7Cj4gPj4+ICsgICAgIH0KPiA+Pj4gKyAg ICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtz dGF0aWMgdm9pZCB2ZHVzZV9kZXZfc3RhcnRfZGF0YXBsYW5lKHN0cnVjdCB2ZHVzZV9kZXYgKmRl dikKPiA+Pj4gK3sKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2Rldl9tc2cgKm1zZyA9IGt6YWxs b2Moc2l6ZW9mKCptc2cpLAo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBHRlBfS0VSTkVMIHwgX19HRlBfTk9GQUlMKTsKPiA+Pj4gKwo+ID4+PiArICAgICBt c2ctPnJlcS50eXBlID0gVkRVU0VfU1RBUlRfREFUQVBMQU5FOwo+ID4+PiArICAgICBtc2ctPnJl cS5mbGFncyB8PSBWRFVTRV9SRVFfRkxBR1NfTk9fUkVQTFk7Cj4gPj4+ICsgICAgIHZkdXNlX2Rl dl9tc2dfc2VuZChkZXYsIG1zZywgdHJ1ZSk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRp YyB2b2lkIHZkdXNlX2Rldl9zdG9wX2RhdGFwbGFuZShzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYpCj4g Pj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXZfbXNnICptc2cgPSBremFsbG9jKHNp emVvZigqbXNnKSwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgR0ZQX0tFUk5FTCB8IF9fR0ZQX05PRkFJTCk7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgbXNnLT5y ZXEudHlwZSA9IFZEVVNFX1NUT1BfREFUQVBMQU5FOwo+ID4+PiArICAgICBtc2ctPnJlcS5mbGFn cyB8PSBWRFVTRV9SRVFfRkxBR1NfTk9fUkVQTFk7Cj4gPj4KPiA+PiBDYW4gd2Ugc2ltcGx5IHVz ZSB0aGlzIGZsYWcgaW5zdGVhZCBvZiBpbnRyb2R1Y2luZyBhIG5ldyBwYXJhbWV0ZXIKPiA+PiAo bm9fcmVwbHkpIGluIHZkdXNlX2Rldl9tc2dfc2VuZCgpPwo+ID4+Cj4gPiBMb29rcyBnb29kIHRv IG1lLgo+ID4KPiA+Pj4gKyAgICAgdmR1c2VfZGV2X21zZ19zZW5kKGRldiwgbXNnLCB0cnVlKTsK PiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIGludCB2ZHVzZV9kZXZfZ2V0X3ZxX3N0YXRl KHN0cnVjdCB2ZHVzZV9kZXYgKmRldiwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSwKPiA+Pj4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBzdHJ1Y3QgdmRwYV92cV9zdGF0ZSAqc3RhdGUpCj4gPj4+ICt7Cj4gPj4+ ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXZfbXNnIG1zZyA9IHsgMCB9Owo+ID4+PiArICAgICBpbnQg cmV0Owo+ID4+Cj4gPj4gTm90ZSB0aGF0IEkgcG9zdCBhIHNlcmllcyB0aGF0IGltcGxlbWVudCB0 aGUgcGFja2VkIHZpcnRxdWV1ZSBzdXBwb3J0Ogo+ID4+Cj4gPj4gaHR0cHM6Ly9saXN0cy5saW51 eGZvdW5kYXRpb24ub3JnL3BpcGVybWFpbC92aXJ0dWFsaXphdGlvbi8yMDIxLUp1bmUvMDU0NTAx Lmh0bWwKPiA+Pgo+ID4+IFNvIHRoaXMgcGF0Y2ggbmVlZHMgdG8gYmUgdXBkYXRlZCBhcyB3ZWxs Lgo+ID4+Cj4gPiBXaWxsIGRvIGl0Lgo+ID4KPiA+Pj4gKwo+ID4+PiArICAgICBtc2cucmVxLnR5 cGUgPSBWRFVTRV9HRVRfVlFfU1RBVEU7Cj4gPj4+ICsgICAgIG1zZy5yZXEudnFfc3RhdGUuaW5k ZXggPSB2cS0+aW5kZXg7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgcmV0ID0gdmR1c2VfZGV2X21zZ19z ZW5kKGRldiwgJm1zZywgZmFsc2UpOwo+ID4+PiArICAgICBpZiAocmV0KQo+ID4+PiArICAgICAg ICAgICAgIHJldHVybiByZXQ7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgc3RhdGUtPmF2YWlsX2luZGV4 ID0gbXNnLnJlc3AudnFfc3RhdGUuYXZhaWxfaWR4Owo+ID4+PiArICAgICByZXR1cm4gMDsKPiA+ Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIGludCB2ZHVzZV9kZXZfdXBkYXRlX2lvdGxiKHN0 cnVjdCB2ZHVzZV9kZXYgKmRldiwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg dTY0IHN0YXJ0LCB1NjQgbGFzdCkKPiA+Pj4gK3sKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2Rl dl9tc2cgbXNnID0geyAwIH07Cj4gPj4+ICsKPiA+Pj4gKyAgICAgaWYgKGxhc3QgPCBzdGFydCkK PiA+Pj4gKyAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiA+Pj4gKwo+ID4+PiArICAgICBt c2cucmVxLnR5cGUgPSBWRFVTRV9VUERBVEVfSU9UTEI7Cj4gPj4+ICsgICAgIG1zZy5yZXEuaW92 YS5zdGFydCA9IHN0YXJ0Owo+ID4+PiArICAgICBtc2cucmVxLmlvdmEubGFzdCA9IGxhc3Q7Cj4g Pj4+ICsKPiA+Pj4gKyAgICAgcmV0dXJuIHZkdXNlX2Rldl9tc2dfc2VuZChkZXYsICZtc2csIGZh bHNlKTsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHNzaXplX3QgdmR1c2VfZGV2X3Jl YWRfaXRlcihzdHJ1Y3Qga2lvY2IgKmlvY2IsIHN0cnVjdCBpb3ZfaXRlciAqdG8pCj4gPj4+ICt7 Cj4gPj4+ICsgICAgIHN0cnVjdCBmaWxlICpmaWxlID0gaW9jYi0+a2lfZmlscDsKPiA+Pj4gKyAg ICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ID4+PiArICAg ICBzdHJ1Y3QgdmR1c2VfZGV2X21zZyAqbXNnOwo+ID4+PiArICAgICBpbnQgc2l6ZSA9IHNpemVv ZihzdHJ1Y3QgdmR1c2VfZGV2X3JlcXVlc3QpOwo+ID4+PiArICAgICBzc2l6ZV90IHJldDsKPiA+ Pj4gKwo+ID4+PiArICAgICBpZiAoaW92X2l0ZXJfY291bnQodG8pIDwgc2l6ZSkKPiA+Pj4gKyAg ICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiA+Pj4gKwo+ID4+PiArICAgICBzcGluX2xvY2so JmRldi0+bXNnX2xvY2spOwo+ID4+PiArICAgICB3aGlsZSAoMSkgewo+ID4+PiArICAgICAgICAg ICAgIG1zZyA9IHZkdXNlX2RlcXVldWVfbXNnKCZkZXYtPnNlbmRfbGlzdCk7Cj4gPj4+ICsgICAg ICAgICAgICAgaWYgKG1zZykKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4+ PiArCj4gPj4+ICsgICAgICAgICAgICAgcmV0ID0gLUVBR0FJTjsKPiA+Pj4gKyAgICAgICAgICAg ICBpZiAoZmlsZS0+Zl9mbGFncyAmIE9fTk9OQkxPQ0spCj4gPj4+ICsgICAgICAgICAgICAgICAg ICAgICBnb3RvIHVubG9jazsKPiA+Pj4gKwo+ID4+PiArICAgICAgICAgICAgIHNwaW5fdW5sb2Nr KCZkZXYtPm1zZ19sb2NrKTsKPiA+Pj4gKyAgICAgICAgICAgICByZXQgPSB3YWl0X2V2ZW50X2lu dGVycnVwdGlibGVfZXhjbHVzaXZlKGRldi0+d2FpdHEsCj4gPj4+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIWxpc3RfZW1wdHkoJmRldi0+c2VuZF9saXN0KSk7Cj4gPj4+ ICsgICAgICAgICAgICAgaWYgKHJldCkKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgIHJldHVy biByZXQ7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgICAgICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xv Y2spOwo+ID4+PiArICAgICB9Cj4gPj4+ICsgICAgIHNwaW5fdW5sb2NrKCZkZXYtPm1zZ19sb2Nr KTsKPiA+Pj4gKyAgICAgcmV0ID0gY29weV90b19pdGVyKCZtc2ctPnJlcSwgc2l6ZSwgdG8pOwo+ ID4+PiArICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xvY2spOwo+ID4+PiArICAgICBpZiAocmV0 ICE9IHNpemUpIHsKPiA+Pj4gKyAgICAgICAgICAgICByZXQgPSAtRUZBVUxUOwo+ID4+PiArICAg ICAgICAgICAgIHZkdXNlX2VucXVldWVfbXNnKCZkZXYtPnNlbmRfbGlzdCwgbXNnKTsKPiA+Pj4g KyAgICAgICAgICAgICBnb3RvIHVubG9jazsKPiA+Pj4gKyAgICAgfQo+ID4+PiArICAgICBpZiAo bXNnLT5yZXEuZmxhZ3MgJiBWRFVTRV9SRVFfRkxBR1NfTk9fUkVQTFkpCj4gPj4+ICsgICAgICAg ICAgICAga2ZyZWUobXNnKTsKPiA+Pj4gKyAgICAgZWxzZQo+ID4+PiArICAgICAgICAgICAgIHZk dXNlX2VucXVldWVfbXNnKCZkZXYtPnJlY3ZfbGlzdCwgbXNnKTsKPiA+Pj4gK3VubG9jazoKPiA+ Pj4gKyAgICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ID4+PiArCj4gPj4+ICsgICAg IHJldHVybiByZXQ7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBzc2l6ZV90IHZkdXNl X2Rldl93cml0ZV9pdGVyKHN0cnVjdCBraW9jYiAqaW9jYiwgc3RydWN0IGlvdl9pdGVyICpmcm9t KQo+ID4+PiArewo+ID4+PiArICAgICBzdHJ1Y3QgZmlsZSAqZmlsZSA9IGlvY2ItPmtpX2ZpbHA7 Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IGZpbGUtPnByaXZhdGVfZGF0YTsK PiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2Rldl9yZXNwb25zZSByZXNwOwo+ID4+PiArICAgICBz dHJ1Y3QgdmR1c2VfZGV2X21zZyAqbXNnOwo+ID4+PiArICAgICBzaXplX3QgcmV0Owo+ID4+PiAr Cj4gPj4+ICsgICAgIHJldCA9IGNvcHlfZnJvbV9pdGVyKCZyZXNwLCBzaXplb2YocmVzcCksIGZy b20pOwo+ID4+PiArICAgICBpZiAocmV0ICE9IHNpemVvZihyZXNwKSkKPiA+Pj4gKyAgICAgICAg ICAgICByZXR1cm4gLUVJTlZBTDsKPiA+Pj4gKwo+ID4+PiArICAgICBzcGluX2xvY2soJmRldi0+ bXNnX2xvY2spOwo+ID4+PiArICAgICBtc2cgPSB2ZHVzZV9maW5kX21zZygmZGV2LT5yZWN2X2xp c3QsIHJlc3AucmVxdWVzdF9pZCk7Cj4gPj4+ICsgICAgIGlmICghbXNnKSB7Cj4gPj4+ICsgICAg ICAgICAgICAgcmV0ID0gLUVOT0VOVDsKPiA+Pj4gKyAgICAgICAgICAgICBnb3RvIHVubG9jazsK PiA+Pj4gKyAgICAgfQo+ID4+PiArCj4gPj4+ICsgICAgIG1lbWNweSgmbXNnLT5yZXNwLCAmcmVz cCwgc2l6ZW9mKHJlc3ApKTsKPiA+Pj4gKyAgICAgbXNnLT5jb21wbGV0ZWQgPSAxOwo+ID4+PiAr ICAgICB3YWtlX3VwKCZtc2ctPndhaXRxKTsKPiA+Pj4gK3VubG9jazoKPiA+Pj4gKyAgICAgc3Bp bl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiByZXQ7 Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBfX3BvbGxfdCB2ZHVzZV9kZXZfcG9sbChz dHJ1Y3QgZmlsZSAqZmlsZSwgcG9sbF90YWJsZSAqd2FpdCkKPiA+Pj4gK3sKPiA+Pj4gKyAgICAg c3RydWN0IHZkdXNlX2RldiAqZGV2ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ID4+PiArICAgICBf X3BvbGxfdCBtYXNrID0gMDsKPiA+Pj4gKwo+ID4+PiArICAgICBwb2xsX3dhaXQoZmlsZSwgJmRl di0+d2FpdHEsIHdhaXQpOwo+ID4+PiArCj4gPj4+ICsgICAgIGlmICghbGlzdF9lbXB0eSgmZGV2 LT5zZW5kX2xpc3QpKQo+ID4+PiArICAgICAgICAgICAgIG1hc2sgfD0gRVBPTExJTiB8IEVQT0xM UkROT1JNOwo+ID4+PiArICAgICBpZiAoIWxpc3RfZW1wdHkoJmRldi0+cmVjdl9saXN0KSkKPiA+ Pj4gKyAgICAgICAgICAgICBtYXNrIHw9IEVQT0xMT1VUIHwgRVBPTExXUk5PUk07Cj4gPj4+ICsK PiA+Pj4gKyAgICAgcmV0dXJuIG1hc2s7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyB2 b2lkIHZkdXNlX2Rldl9yZXNldChzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYpCj4gPj4+ICt7Cj4gPj4+ ICsgICAgIGludCBpOwo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFp biA9IGRldi0+ZG9tYWluOwo+ID4+PiArCj4gPj4+ICsgICAgIC8qIFRoZSBjb2hlcmVudCBtYXBw aW5ncyBhcmUgaGFuZGxlZCBpbiB2ZHVzZV9kZXZfZnJlZV9jb2hlcmVudCgpICovCj4gPj4+ICsg ICAgIGlmIChkb21haW4tPmJvdW5jZV9tYXApCj4gPj4+ICsgICAgICAgICAgICAgdmR1c2VfZG9t YWluX3Jlc2V0X2JvdW5jZV9tYXAoZG9tYWluKTsKPiA+Pj4gKwo+ID4+PiArICAgICBkZXYtPmZl YXR1cmVzID0gMDsKPiA+Pj4gKyAgICAgZGV2LT5nZW5lcmF0aW9uKys7Cj4gPj4+ICsgICAgIHNw aW5fbG9jaygmZGV2LT5pcnFfbG9jayk7Cj4gPj4+ICsgICAgIGRldi0+Y29uZmlnX2NiLmNhbGxi YWNrID0gTlVMTDsKPiA+Pj4gKyAgICAgZGV2LT5jb25maWdfY2IucHJpdmF0ZSA9IE5VTEw7Cj4g Pj4+ICsgICAgIHNwaW5fdW5sb2NrKCZkZXYtPmlycV9sb2NrKTsKPiA+Pj4gKwo+ID4+PiArICAg ICBmb3IgKGkgPSAwOyBpIDwgZGV2LT52cV9udW07IGkrKykgewo+ID4+PiArICAgICAgICAgICAg IHN0cnVjdCB2ZHVzZV92aXJ0cXVldWUgKnZxID0gJmRldi0+dnFzW2ldOwo+ID4+PiArCj4gPj4+ ICsgICAgICAgICAgICAgdnEtPnJlYWR5ID0gZmFsc2U7Cj4gPj4+ICsgICAgICAgICAgICAgdnEt PmRlc2NfYWRkciA9IDA7Cj4gPj4+ICsgICAgICAgICAgICAgdnEtPmRyaXZlcl9hZGRyID0gMDsK PiA+Pj4gKyAgICAgICAgICAgICB2cS0+ZGV2aWNlX2FkZHIgPSAwOwo+ID4+PiArICAgICAgICAg ICAgIHZxLT5hdmFpbF9pZHggPSAwOwo+ID4+PiArICAgICAgICAgICAgIHZxLT5udW0gPSAwOwo+ ID4+PiArCj4gPj4+ICsgICAgICAgICAgICAgc3Bpbl9sb2NrKCZ2cS0+a2lja19sb2NrKTsKPiA+ Pj4gKyAgICAgICAgICAgICB2cS0+a2lja2VkID0gZmFsc2U7Cj4gPj4+ICsgICAgICAgICAgICAg aWYgKHZxLT5raWNrZmQpCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICBldmVudGZkX2N0eF9w dXQodnEtPmtpY2tmZCk7Cj4gPj4+ICsgICAgICAgICAgICAgdnEtPmtpY2tmZCA9IE5VTEw7Cj4g Pj4+ICsgICAgICAgICAgICAgc3Bpbl91bmxvY2soJnZxLT5raWNrX2xvY2spOwo+ID4+PiArCj4g Pj4+ICsgICAgICAgICAgICAgc3Bpbl9sb2NrKCZ2cS0+aXJxX2xvY2spOwo+ID4+PiArICAgICAg ICAgICAgIHZxLT5jYi5jYWxsYmFjayA9IE5VTEw7Cj4gPj4+ICsgICAgICAgICAgICAgdnEtPmNi LnByaXZhdGUgPSBOVUxMOwo+ID4+PiArICAgICAgICAgICAgIHNwaW5fdW5sb2NrKCZ2cS0+aXJx X2xvY2spOwo+ID4+PiArICAgICB9Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBpbnQg dmR1c2VfdmRwYV9zZXRfdnFfYWRkcmVzcyhzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEsIHUxNiBp ZHgsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHU2NCBkZXNjX2FyZWEsIHU2 NCBkcml2ZXJfYXJlYSwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTY0IGRl dmljZV9hcmVhKQo+ID4+PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2 ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2 cSA9ICZkZXYtPnZxc1tpZHhdOwo+ID4+PiArCj4gPj4+ICsgICAgIHZxLT5kZXNjX2FkZHIgPSBk ZXNjX2FyZWE7Cj4gPj4+ICsgICAgIHZxLT5kcml2ZXJfYWRkciA9IGRyaXZlcl9hcmVhOwo+ID4+ PiArICAgICB2cS0+ZGV2aWNlX2FkZHIgPSBkZXZpY2VfYXJlYTsKPiA+Pj4gKwo+ID4+PiArICAg ICByZXR1cm4gMDsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHZvaWQgdmR1c2VfdmRw YV9raWNrX3ZxKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwgdTE2IGlkeCkKPiA+Pj4gK3sKPiA+ Pj4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ Pj4gKyAgICAgc3RydWN0IHZkdXNlX3ZpcnRxdWV1ZSAqdnEgPSAmZGV2LT52cXNbaWR4XTsKPiA+ Pj4gKwo+ID4+PiArICAgICBzcGluX2xvY2soJnZxLT5raWNrX2xvY2spOwo+ID4+PiArICAgICBp ZiAoIXZxLT5yZWFkeSkKPiA+Pj4gKyAgICAgICAgICAgICBnb3RvIHVubG9jazsKPiA+Pj4gKwo+ ID4+PiArICAgICBpZiAodnEtPmtpY2tmZCkKPiA+Pj4gKyAgICAgICAgICAgICBldmVudGZkX3Np Z25hbCh2cS0+a2lja2ZkLCAxKTsKPiA+Pj4gKyAgICAgZWxzZQo+ID4+PiArICAgICAgICAgICAg IHZxLT5raWNrZWQgPSB0cnVlOwo+ID4+PiArdW5sb2NrOgo+ID4+PiArICAgICBzcGluX3VubG9j aygmdnEtPmtpY2tfbG9jayk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyB2b2lkIHZk dXNlX3ZkcGFfc2V0X3ZxX2NiKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwgdTE2IGlkeCwKPiA+ Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2ZHBhX2NhbGxiYWNrICpjYikK PiA+Pj4gK3sKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVz ZSh2ZHBhKTsKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX3ZpcnRxdWV1ZSAqdnEgPSAmZGV2LT52 cXNbaWR4XTsKPiA+Pj4gKwo+ID4+PiArICAgICBzcGluX2xvY2soJnZxLT5pcnFfbG9jayk7Cj4g Pj4+ICsgICAgIHZxLT5jYi5jYWxsYmFjayA9IGNiLT5jYWxsYmFjazsKPiA+Pj4gKyAgICAgdnEt PmNiLnByaXZhdGUgPSBjYi0+cHJpdmF0ZTsKPiA+Pj4gKyAgICAgc3Bpbl91bmxvY2soJnZxLT5p cnFfbG9jayk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyB2b2lkIHZkdXNlX3ZkcGFf c2V0X3ZxX251bShzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEsIHUxNiBpZHgsIHUzMiBudW0pCj4g Pj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2Uo dmRwYSk7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV92aXJ0cXVldWUgKnZxID0gJmRldi0+dnFz W2lkeF07Cj4gPj4+ICsKPiA+Pj4gKyAgICAgdnEtPm51bSA9IG51bTsKPiA+Pj4gK30KPiA+Pj4g Kwo+ID4+PiArc3RhdGljIHZvaWQgdmR1c2VfdmRwYV9zZXRfdnFfcmVhZHkoc3RydWN0IHZkcGFf ZGV2aWNlICp2ZHBhLAo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHUxNiBpZHgsIGJvb2wgcmVhZHkpCj4gPj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9k ZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV92 aXJ0cXVldWUgKnZxID0gJmRldi0+dnFzW2lkeF07Cj4gPj4+ICsKPiA+Pj4gKyAgICAgdnEtPnJl YWR5ID0gcmVhZHk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBib29sIHZkdXNlX3Zk cGFfZ2V0X3ZxX3JlYWR5KHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwgdTE2IGlkeCkKPiA+Pj4g K3sKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBh KTsKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX3ZpcnRxdWV1ZSAqdnEgPSAmZGV2LT52cXNbaWR4 XTsKPiA+Pj4gKwo+ID4+PiArICAgICByZXR1cm4gdnEtPnJlYWR5Owo+ID4+PiArfQo+ID4+PiAr Cj4gPj4+ICtzdGF0aWMgaW50IHZkdXNlX3ZkcGFfc2V0X3ZxX3N0YXRlKHN0cnVjdCB2ZHBhX2Rl dmljZSAqdmRwYSwgdTE2IGlkeCwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg Y29uc3Qgc3RydWN0IHZkcGFfdnFfc3RhdGUgKnN0YXRlKQo+ID4+PiArewo+ID4+PiArICAgICBz dHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ID4+PiArICAgICBz dHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSA9ICZkZXYtPnZxc1tpZHhdOwo+ID4+PiArCj4gPj4+ ICsgICAgIHZxLT5hdmFpbF9pZHggPSBzdGF0ZS0+YXZhaWxfaW5kZXg7Cj4gPj4+ICsgICAgIHJl dHVybiAwOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgaW50IHZkdXNlX3ZkcGFfZ2V0 X3ZxX3N0YXRlKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwgdTE2IGlkeCwKPiA+Pj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHZkcGFfdnFfc3RhdGUgKnN0YXRlKQo+ID4+ PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZk cGEpOwo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSA9ICZkZXYtPnZxc1tp ZHhdOwo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiB2ZHVzZV9kZXZfZ2V0X3ZxX3N0YXRlKGRl diwgdnEsIHN0YXRlKTsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHUzMiB2ZHVzZV92 ZHBhX2dldF92cV9hbGlnbihzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEpCj4gPj4+ICt7Cj4gPj4+ ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ ICsKPiA+Pj4gKyAgICAgcmV0dXJuIGRldi0+dnFfYWxpZ247Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+ Pj4gK3N0YXRpYyB1NjQgdmR1c2VfdmRwYV9nZXRfZmVhdHVyZXMoc3RydWN0IHZkcGFfZGV2aWNl ICp2ZHBhKQo+ID4+PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBh X3RvX3ZkdXNlKHZkcGEpOwo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiBkZXYtPnVzZXJfZmVh dHVyZXM7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBpbnQgdmR1c2VfdmRwYV9zZXRf ZmVhdHVyZXMoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhLCB1NjQgZmVhdHVyZXMpCj4gPj4+ICt7 Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7 Cj4gPj4+ICsKPiA+Pj4gKyAgICAgZGV2LT5mZWF0dXJlcyA9IGZlYXR1cmVzOwo+ID4+PiArICAg ICByZXR1cm4gMDsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHZvaWQgdmR1c2VfdmRw YV9zZXRfY29uZmlnX2NiKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwKPiA+Pj4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdmRwYV9jYWxsYmFjayAqY2IpCj4gPj4+ICt7 Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7 Cj4gPj4+ICsKPiA+Pj4gKyAgICAgc3Bpbl9sb2NrKCZkZXYtPmlycV9sb2NrKTsKPiA+Pj4gKyAg ICAgZGV2LT5jb25maWdfY2IuY2FsbGJhY2sgPSBjYi0+Y2FsbGJhY2s7Cj4gPj4+ICsgICAgIGRl di0+Y29uZmlnX2NiLnByaXZhdGUgPSBjYi0+cHJpdmF0ZTsKPiA+Pj4gKyAgICAgc3Bpbl91bmxv Y2soJmRldi0+aXJxX2xvY2spOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgdTE2IHZk dXNlX3ZkcGFfZ2V0X3ZxX251bV9tYXgoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhKQo+ID4+PiAr ewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEp Owo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiBkZXYtPnZxX3NpemVfbWF4Owo+ID4+PiArfQo+ ID4+PiArCj4gPj4+ICtzdGF0aWMgdTMyIHZkdXNlX3ZkcGFfZ2V0X2RldmljZV9pZChzdHJ1Y3Qg dmRwYV9kZXZpY2UgKnZkcGEpCj4gPj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYg KmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgcmV0dXJuIGRl di0+ZGV2aWNlX2lkOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgdTMyIHZkdXNlX3Zk cGFfZ2V0X3ZlbmRvcl9pZChzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEpCj4gPj4+ICt7Cj4gPj4+ ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ ICsKPiA+Pj4gKyAgICAgcmV0dXJuIGRldi0+dmVuZG9yX2lkOwo+ID4+PiArfQo+ID4+PiArCj4g Pj4+ICtzdGF0aWMgdTggdmR1c2VfdmRwYV9nZXRfc3RhdHVzKHN0cnVjdCB2ZHBhX2RldmljZSAq dmRwYSkKPiA+Pj4gK3sKPiA+Pj4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90 b192ZHVzZSh2ZHBhKTsKPiA+Pj4gKwo+ID4+PiArICAgICByZXR1cm4gZGV2LT5zdGF0dXM7Cj4g Pj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyB2b2lkIHZkdXNlX3ZkcGFfc2V0X3N0YXR1cyhz dHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEsIHU4IHN0YXR1cykKPiA+Pj4gK3sKPiA+Pj4gKyAgICAg c3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+Pj4gKyAgICAg Ym9vbCBzdGFydGVkID0gISEoc3RhdHVzICYgVklSVElPX0NPTkZJR19TX0RSSVZFUl9PSyk7Cj4g Pj4+ICsKPiA+Pj4gKyAgICAgZGV2LT5zdGF0dXMgPSBzdGF0dXM7Cj4gPj4+ICsKPiA+Pj4gKyAg ICAgaWYgKGRldi0+c3RhcnRlZCA9PSBzdGFydGVkKQo+ID4+PiArICAgICAgICAgICAgIHJldHVy bjsKPiA+Pgo+ID4+IElmIHdlIGNoZWNrIGRldi0+c3RhdHVzID09IHN0YXR1cywgKG9yIG9ubHkg Y2hlY2sgdGhlIERSSVZFUl9PSyBiaXQpCj4gPj4gdGhlbiB0aGVyZSdzIG5vIG5lZWQgdG8gaW50 cm9kdWNlIGFuIGV4dHJhIGRldi0+c3RhcnRlZC4KPiA+Pgo+ID4gV2lsbCBkbyBpdC4KPiA+Cj4g Pj4+ICsKPiA+Pj4gKyAgICAgZGV2LT5zdGFydGVkID0gc3RhcnRlZDsKPiA+Pj4gKyAgICAgaWYg KGRldi0+c3RhcnRlZCkgewo+ID4+PiArICAgICAgICAgICAgIHZkdXNlX2Rldl9zdGFydF9kYXRh cGxhbmUoZGV2KTsKPiA+Pj4gKyAgICAgfSBlbHNlIHsKPiA+Pj4gKyAgICAgICAgICAgICB2ZHVz ZV9kZXZfcmVzZXQoZGV2KTsKPiA+Pj4gKyAgICAgICAgICAgICB2ZHVzZV9kZXZfc3RvcF9kYXRh cGxhbmUoZGV2KTsKPiA+Pgo+ID4+IEkgd29uZGVyIGlmIG5vX3JlcGx5IHdvcmsgZm9yIHRoZSBj YXNlIG9mIHZob3N0LXZkcGEuIEZvciB2aXJ0aW8tdkRQQSwKPiA+PiB3ZSBoYXZlIGJvdW5jaW5n IGJ1ZmZlcnMgc28gaXQncyBoYXJtbGVzcyBpZiB1c2Vyc2FwY2UgZGF0YXBsYW5lIGtlZXBzCj4g Pj4gcGVyZm9ybWluZyByZWFkL3dyaXRlLiBGb3Igdmhvc3QtdkRQQSB3ZSBkb24ndCBoYXZlIHN1 Y2ggc3R1ZmZzLgo+ID4+Cj4gPiBPSy4gU28gaXQgc3RpbGwgbmVlZHMgdG8gYmUgc3luY2hyb25p emVkIGhlcmUuIElmIHNvLCBob3cgdG8gaGFuZGxlCj4gPiB0aGUgZXJyb3I/IExvb2tzIGxpa2Ug cHJpbnRpbmcgYSB3YXJuaW5nIG1lc3NhZ2Ugc2hvdWxkIGJlIGVub3VnaC4KPgo+Cj4gV2UgbmVl ZCBmaXggYSB3YXkgdG8gcHJvcGFnYXRlIHRoZSBlcnJvciB0byB0aGUgdXNlcnNwYWNlLgo+Cj4g RS5nIGlmIHdlIHdhbnQgdG8gc3RvcCB0aGUgZGVpdmNlLCB3ZSB3aWxsIGRlbGF5IHRoZSBzdGF0 dXMgcmVzZXQgdW50aWwKPiB3ZSBnZXQgcmVzcG9zZSBmcm9tIHRoZSB1c2Vyc3BhY2U/Cj4KCkkg ZGlkbid0IGdldCBob3cgdG8gZGVsYXkgdGhlIHN0YXR1cyByZXNldC4gQW5kIHNob3VsZCBpdCBi ZSBhIERvUwp0aGF0IHdlIHdhbnQgdG8gZml4IGlmIHRoZSB1c2Vyc3BhY2UgZG9lc24ndCBnaXZl IGEgcmVzcG9uc2UgZm9yZXZlcj8KCj4KPiA+Cj4gPj4+ICsgICAgIH0KPiA+Pj4gK30KPiA+Pj4g Kwo+ID4+PiArc3RhdGljIHNpemVfdCB2ZHVzZV92ZHBhX2dldF9jb25maWdfc2l6ZShzdHJ1Y3Qg dmRwYV9kZXZpY2UgKnZkcGEpCj4gPj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYg KmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgcmV0dXJuIGRl di0+Y29uZmlnX3NpemU7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyB2b2lkIHZkdXNl X3ZkcGFfZ2V0X2NvbmZpZyhzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEsIHVuc2lnbmVkIGludCBv ZmZzZXQsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYnVmLCB1 bnNpZ25lZCBpbnQgbGVuKQo+ID4+PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpk ZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ID4+PiArCj4gPj4+ICsgICAgIG1lbWNweShidWYs IGRldi0+Y29uZmlnICsgb2Zmc2V0LCBsZW4pOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0 aWMgdm9pZCB2ZHVzZV92ZHBhX3NldF9jb25maWcoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhLCB1 bnNpZ25lZCBpbnQgb2Zmc2V0LAo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9p ZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQo+ID4+PiArewo+ID4+PiArICAgICAvKiBOb3cgd2Ug b25seSBzdXBwb3J0IHJlYWQtb25seSBjb25maWd1cmF0aW9uIHNwYWNlICovCj4gPj4+ICt9Cj4g Pj4+ICsKPiA+Pj4gK3N0YXRpYyB1MzIgdmR1c2VfdmRwYV9nZXRfZ2VuZXJhdGlvbihzdHJ1Y3Qg dmRwYV9kZXZpY2UgKnZkcGEpCj4gPj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYg KmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgcmV0dXJuIGRl di0+Z2VuZXJhdGlvbjsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIGludCB2ZHVzZV92 ZHBhX3NldF9tYXAoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhLAo+ID4+PiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBzdHJ1Y3Qgdmhvc3RfaW90bGIgKmlvdGxiKQo+ID4+PiArewo+ID4+ PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ID4+ PiArICAgICBpbnQgcmV0Owo+ID4+PiArCj4gPj4+ICsgICAgIHJldCA9IHZkdXNlX2RvbWFpbl9z ZXRfbWFwKGRldi0+ZG9tYWluLCBpb3RsYik7Cj4gPj4+ICsgICAgIGlmIChyZXQpCj4gPj4+ICsg ICAgICAgICAgICAgcmV0dXJuIHJldDsKPiA+Pj4gKwo+ID4+PiArICAgICByZXQgPSB2ZHVzZV9k ZXZfdXBkYXRlX2lvdGxiKGRldiwgMFVMTCwgVUxMT05HX01BWCk7Cj4gPj4+ICsgICAgIGlmIChy ZXQpIHsKPiA+Pj4gKyAgICAgICAgICAgICB2ZHVzZV9kb21haW5fY2xlYXJfbWFwKGRldi0+ZG9t YWluLCBpb3RsYik7Cj4gPj4+ICsgICAgICAgICAgICAgcmV0dXJuIHJldDsKPiA+Pj4gKyAgICAg fQo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiAwOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtz dGF0aWMgdm9pZCB2ZHVzZV92ZHBhX2ZyZWUoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhKQo+ID4+ PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZk cGEpOwo+ID4+PiArCj4gPj4+ICsgICAgIGRldi0+dmRldiA9IE5VTEw7Cj4gPj4+ICt9Cj4gPj4+ ICsKPiA+Pj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdmRwYV9jb25maWdfb3BzIHZkdXNlX3ZkcGFf Y29uZmlnX29wcyA9IHsKPiA+Pj4gKyAgICAgLnNldF92cV9hZGRyZXNzICAgICAgICAgPSB2ZHVz ZV92ZHBhX3NldF92cV9hZGRyZXNzLAo+ID4+PiArICAgICAua2lja192cSAgICAgICAgICAgICAg ICA9IHZkdXNlX3ZkcGFfa2lja192cSwKPiA+Pj4gKyAgICAgLnNldF92cV9jYiAgICAgICAgICAg ICAgPSB2ZHVzZV92ZHBhX3NldF92cV9jYiwKPiA+Pj4gKyAgICAgLnNldF92cV9udW0gICAgICAg ICAgICAgPSB2ZHVzZV92ZHBhX3NldF92cV9udW0sCj4gPj4+ICsgICAgIC5zZXRfdnFfcmVhZHkg ICAgICAgICAgID0gdmR1c2VfdmRwYV9zZXRfdnFfcmVhZHksCj4gPj4+ICsgICAgIC5nZXRfdnFf cmVhZHkgICAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRfdnFfcmVhZHksCj4gPj4+ICsgICAgIC5z ZXRfdnFfc3RhdGUgICAgICAgICAgID0gdmR1c2VfdmRwYV9zZXRfdnFfc3RhdGUsCj4gPj4+ICsg ICAgIC5nZXRfdnFfc3RhdGUgICAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRfdnFfc3RhdGUsCj4g Pj4+ICsgICAgIC5nZXRfdnFfYWxpZ24gICAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRfdnFfYWxp Z24sCj4gPj4+ICsgICAgIC5nZXRfZmVhdHVyZXMgICAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRf ZmVhdHVyZXMsCj4gPj4+ICsgICAgIC5zZXRfZmVhdHVyZXMgICAgICAgICAgID0gdmR1c2VfdmRw YV9zZXRfZmVhdHVyZXMsCj4gPj4+ICsgICAgIC5zZXRfY29uZmlnX2NiICAgICAgICAgID0gdmR1 c2VfdmRwYV9zZXRfY29uZmlnX2NiLAo+ID4+PiArICAgICAuZ2V0X3ZxX251bV9tYXggICAgICAg ICA9IHZkdXNlX3ZkcGFfZ2V0X3ZxX251bV9tYXgsCj4gPj4+ICsgICAgIC5nZXRfZGV2aWNlX2lk ICAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRfZGV2aWNlX2lkLAo+ID4+PiArICAgICAuZ2V0X3Zl bmRvcl9pZCAgICAgICAgICA9IHZkdXNlX3ZkcGFfZ2V0X3ZlbmRvcl9pZCwKPiA+Pj4gKyAgICAg LmdldF9zdGF0dXMgICAgICAgICAgICAgPSB2ZHVzZV92ZHBhX2dldF9zdGF0dXMsCj4gPj4+ICsg ICAgIC5zZXRfc3RhdHVzICAgICAgICAgICAgID0gdmR1c2VfdmRwYV9zZXRfc3RhdHVzLAo+ID4+ PiArICAgICAuZ2V0X2NvbmZpZ19zaXplICAgICAgICA9IHZkdXNlX3ZkcGFfZ2V0X2NvbmZpZ19z aXplLAo+ID4+PiArICAgICAuZ2V0X2NvbmZpZyAgICAgICAgICAgICA9IHZkdXNlX3ZkcGFfZ2V0 X2NvbmZpZywKPiA+Pj4gKyAgICAgLnNldF9jb25maWcgICAgICAgICAgICAgPSB2ZHVzZV92ZHBh X3NldF9jb25maWcsCj4gPj4+ICsgICAgIC5nZXRfZ2VuZXJhdGlvbiAgICAgICAgID0gdmR1c2Vf dmRwYV9nZXRfZ2VuZXJhdGlvbiwKPiA+Pj4gKyAgICAgLnNldF9tYXAgICAgICAgICAgICAgICAg PSB2ZHVzZV92ZHBhX3NldF9tYXAsCj4gPj4+ICsgICAgIC5mcmVlICAgICAgICAgICAgICAgICAg ID0gdmR1c2VfdmRwYV9mcmVlLAo+ID4+PiArfTsKPiA+Pj4gKwo+ID4+PiArc3RhdGljIGRtYV9h ZGRyX3QgdmR1c2VfZGV2X21hcF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHBhZ2Ug KnBhZ2UsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQg bG9uZyBvZmZzZXQsIHNpemVfdCBzaXplLAo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpciwKPiA+Pj4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGF0dHJzKQo+ID4+PiArewo+ID4+ PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICp2ZGV2ID0gZGV2X3RvX3ZkdXNlKGRldik7Cj4gPj4+ ICsgICAgIHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRldi0+ZG9tYWluOwo+ ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiB2ZHVzZV9kb21haW5fbWFwX3BhZ2UoZG9tYWluLCBw YWdlLCBvZmZzZXQsIHNpemUsIGRpciwgYXR0cnMpOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtz dGF0aWMgdm9pZCB2ZHVzZV9kZXZfdW5tYXBfcGFnZShzdHJ1Y3QgZGV2aWNlICpkZXYsIGRtYV9h ZGRyX3QgZG1hX2FkZHIsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVf dCBzaXplLCBlbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIsCj4gPj4+ICsgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgYXR0cnMpCj4gPj4+ICt7Cj4gPj4+ICsgICAg IHN0cnVjdCB2ZHVzZV9kZXYgKnZkZXYgPSBkZXZfdG9fdmR1c2UoZGV2KTsKPiA+Pj4gKyAgICAg c3RydWN0IHZkdXNlX2lvdmFfZG9tYWluICpkb21haW4gPSB2ZGV2LT5kb21haW47Cj4gPj4+ICsK PiA+Pj4gKyAgICAgcmV0dXJuIHZkdXNlX2RvbWFpbl91bm1hcF9wYWdlKGRvbWFpbiwgZG1hX2Fk ZHIsIHNpemUsIGRpciwgYXR0cnMpOwo+ID4+PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgdm9p ZCAqdmR1c2VfZGV2X2FsbG9jX2NvaGVyZW50KHN0cnVjdCBkZXZpY2UgKmRldiwgc2l6ZV90IHNp emUsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG1hX2FkZHJf dCAqZG1hX2FkZHIsIGdmcF90IGZsYWcsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBhdHRycykKPiA+Pj4gK3sKPiA+Pj4gKyAgICAgc3Ry dWN0IHZkdXNlX2RldiAqdmRldiA9IGRldl90b192ZHVzZShkZXYpOwo+ID4+PiArICAgICBzdHJ1 Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbiA9IHZkZXYtPmRvbWFpbjsKPiA+Pj4gKyAgICAg dW5zaWduZWQgbG9uZyBpb3ZhOwo+ID4+PiArICAgICB2b2lkICphZGRyOwo+ID4+PiArCj4gPj4+ ICsgICAgICpkbWFfYWRkciA9IERNQV9NQVBQSU5HX0VSUk9SOwo+ID4+PiArICAgICBhZGRyID0g dmR1c2VfZG9tYWluX2FsbG9jX2NvaGVyZW50KGRvbWFpbiwgc2l6ZSwKPiA+Pj4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgKGRtYV9hZGRyX3QgKikmaW92YSwgZmxhZywgYXR0cnMpOwo+ ID4+PiArICAgICBpZiAoIWFkZHIpCj4gPj4+ICsgICAgICAgICAgICAgcmV0dXJuIE5VTEw7Cj4g Pj4+ICsKPiA+Pj4gKyAgICAgKmRtYV9hZGRyID0gKGRtYV9hZGRyX3QpaW92YTsKPiA+Pj4gKwo+ ID4+PiArICAgICByZXR1cm4gYWRkcjsKPiA+Pj4gK30KPiA+Pj4gKwo+ID4+PiArc3RhdGljIHZv aWQgdmR1c2VfZGV2X2ZyZWVfY29oZXJlbnQoc3RydWN0IGRldmljZSAqZGV2LCBzaXplX3Qgc2l6 ZSwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICp2YWRk ciwgZG1hX2FkZHJfdCBkbWFfYWRkciwKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB1bnNpZ25lZCBsb25nIGF0dHJzKQo+ID4+PiArewo+ID4+PiArICAgICBzdHJ1 Y3QgdmR1c2VfZGV2ICp2ZGV2ID0gZGV2X3RvX3ZkdXNlKGRldik7Cj4gPj4+ICsgICAgIHN0cnVj dCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRldi0+ZG9tYWluOwo+ID4+PiArCj4gPj4+ ICsgICAgIHZkdXNlX2RvbWFpbl9mcmVlX2NvaGVyZW50KGRvbWFpbiwgc2l6ZSwgdmFkZHIsIGRt YV9hZGRyLCBhdHRycyk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBzaXplX3QgdmR1 c2VfZGV2X21heF9tYXBwaW5nX3NpemUoc3RydWN0IGRldmljZSAqZGV2KQo+ID4+PiArewo+ID4+ PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICp2ZGV2ID0gZGV2X3RvX3ZkdXNlKGRldik7Cj4gPj4+ ICsgICAgIHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRldi0+ZG9tYWluOwo+ ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiBkb21haW4tPmJvdW5jZV9zaXplOwo+ID4+PiArfQo+ ID4+PiArCj4gPj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRtYV9tYXBfb3BzIHZkdXNlX2Rldl9k bWFfb3BzID0gewo+ID4+PiArICAgICAubWFwX3BhZ2UgPSB2ZHVzZV9kZXZfbWFwX3BhZ2UsCj4g Pj4+ICsgICAgIC51bm1hcF9wYWdlID0gdmR1c2VfZGV2X3VubWFwX3BhZ2UsCj4gPj4+ICsgICAg IC5hbGxvYyA9IHZkdXNlX2Rldl9hbGxvY19jb2hlcmVudCwKPiA+Pj4gKyAgICAgLmZyZWUgPSB2 ZHVzZV9kZXZfZnJlZV9jb2hlcmVudCwKPiA+Pj4gKyAgICAgLm1heF9tYXBwaW5nX3NpemUgPSB2 ZHVzZV9kZXZfbWF4X21hcHBpbmdfc2l6ZSwKPiA+Pj4gK307Cj4gPj4+ICsKPiA+Pj4gK3N0YXRp YyB1bnNpZ25lZCBpbnQgcGVybV90b19maWxlX2ZsYWdzKHU4IHBlcm0pCj4gPj4+ICt7Cj4gPj4+ ICsgICAgIHVuc2lnbmVkIGludCBmbGFncyA9IDA7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgc3dpdGNo IChwZXJtKSB7Cj4gPj4+ICsgICAgIGNhc2UgVkRVU0VfQUNDRVNTX1dPOgo+ID4+PiArICAgICAg ICAgICAgIGZsYWdzIHw9IE9fV1JPTkxZOwo+ID4+PiArICAgICAgICAgICAgIGJyZWFrOwo+ID4+ PiArICAgICBjYXNlIFZEVVNFX0FDQ0VTU19STzoKPiA+Pj4gKyAgICAgICAgICAgICBmbGFncyB8 PSBPX1JET05MWTsKPiA+Pj4gKyAgICAgICAgICAgICBicmVhazsKPiA+Pj4gKyAgICAgY2FzZSBW RFVTRV9BQ0NFU1NfUlc6Cj4gPj4+ICsgICAgICAgICAgICAgZmxhZ3MgfD0gT19SRFdSOwo+ID4+ PiArICAgICAgICAgICAgIGJyZWFrOwo+ID4+PiArICAgICBkZWZhdWx0Ogo+ID4+PiArICAgICAg ICAgICAgIFdBUk4oMSwgImludmFsaWRhdGUgdmhvc3QgSU9UTEIgcGVybWlzc2lvblxuIik7Cj4g Pj4+ICsgICAgICAgICAgICAgYnJlYWs7Cj4gPj4+ICsgICAgIH0KPiA+Pj4gKwo+ID4+PiArICAg ICByZXR1cm4gZmxhZ3M7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0YXRpYyBpbnQgdmR1c2Vf a2lja2ZkX3NldHVwKHN0cnVjdCB2ZHVzZV9kZXYgKmRldiwKPiA+Pj4gKyAgICAgICAgICAgICAg ICAgICAgIHN0cnVjdCB2ZHVzZV92cV9ldmVudGZkICpldmVudGZkKQo+ID4+PiArewo+ID4+PiAr ICAgICBzdHJ1Y3QgZXZlbnRmZF9jdHggKmN0eCA9IE5VTEw7Cj4gPj4+ICsgICAgIHN0cnVjdCB2 ZHVzZV92aXJ0cXVldWUgKnZxOwo+ID4+PiArICAgICB1MzIgaW5kZXg7Cj4gPj4+ICsKPiA+Pj4g KyAgICAgaWYgKGV2ZW50ZmQtPmluZGV4ID49IGRldi0+dnFfbnVtKQo+ID4+PiArICAgICAgICAg ICAgIHJldHVybiAtRUlOVkFMOwo+ID4+PiArCj4gPj4+ICsgICAgIGluZGV4ID0gYXJyYXlfaW5k ZXhfbm9zcGVjKGV2ZW50ZmQtPmluZGV4LCBkZXYtPnZxX251bSk7Cj4gPj4+ICsgICAgIHZxID0g JmRldi0+dnFzW2luZGV4XTsKPiA+Pj4gKyAgICAgaWYgKGV2ZW50ZmQtPmZkID49IDApIHsKPiA+ Pj4gKyAgICAgICAgICAgICBjdHggPSBldmVudGZkX2N0eF9mZGdldChldmVudGZkLT5mZCk7Cj4g Pj4+ICsgICAgICAgICAgICAgaWYgKElTX0VSUihjdHgpKQo+ID4+PiArICAgICAgICAgICAgICAg ICAgICAgcmV0dXJuIFBUUl9FUlIoY3R4KTsKPiA+Pj4gKyAgICAgfSBlbHNlIGlmIChldmVudGZk LT5mZCAhPSBWRFVTRV9FVkVOVEZEX0RFQVNTSUdOKQo+ID4+PiArICAgICAgICAgICAgIHJldHVy biAwOwo+ID4+PiArCj4gPj4+ICsgICAgIHNwaW5fbG9jaygmdnEtPmtpY2tfbG9jayk7Cj4gPj4+ ICsgICAgIGlmICh2cS0+a2lja2ZkKQo+ID4+PiArICAgICAgICAgICAgIGV2ZW50ZmRfY3R4X3B1 dCh2cS0+a2lja2ZkKTsKPiA+Pj4gKyAgICAgdnEtPmtpY2tmZCA9IGN0eDsKPiA+Pj4gKyAgICAg aWYgKHZxLT5yZWFkeSAmJiB2cS0+a2lja2VkICYmIHZxLT5raWNrZmQpIHsKPiA+Pj4gKyAgICAg ICAgICAgICBldmVudGZkX3NpZ25hbCh2cS0+a2lja2ZkLCAxKTsKPiA+Pj4gKyAgICAgICAgICAg ICB2cS0+a2lja2VkID0gZmFsc2U7Cj4gPj4+ICsgICAgIH0KPiA+Pj4gKyAgICAgc3Bpbl91bmxv Y2soJnZxLT5raWNrX2xvY2spOwo+ID4+PiArCj4gPj4+ICsgICAgIHJldHVybiAwOwo+ID4+PiAr fQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgdm9pZCB2ZHVzZV9kZXZfaXJxX2luamVjdChzdHJ1Y3Qg d29ya19zdHJ1Y3QgKndvcmspCj4gPj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYg KmRldiA9IGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QgdmR1c2VfZGV2LCBpbmplY3QpOwo+ID4+ PiArCj4gPj4+ICsgICAgIHNwaW5fbG9ja19pcnEoJmRldi0+aXJxX2xvY2spOwo+ID4+PiArICAg ICBpZiAoZGV2LT5jb25maWdfY2IuY2FsbGJhY2spCj4gPj4+ICsgICAgICAgICAgICAgZGV2LT5j b25maWdfY2IuY2FsbGJhY2soZGV2LT5jb25maWdfY2IucHJpdmF0ZSk7Cj4gPj4+ICsgICAgIHNw aW5fdW5sb2NrX2lycSgmZGV2LT5pcnFfbG9jayk7Cj4gPj4+ICt9Cj4gPj4+ICsKPiA+Pj4gK3N0 YXRpYyB2b2lkIHZkdXNlX3ZxX2lycV9pbmplY3Qoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+ ID4+PiArewo+ID4+PiArICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSA9IGNvbnRhaW5l cl9vZih3b3JrLAo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0 cnVjdCB2ZHVzZV92aXJ0cXVldWUsIGluamVjdCk7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgc3Bpbl9s b2NrX2lycSgmdnEtPmlycV9sb2NrKTsKPiA+Pj4gKyAgICAgaWYgKHZxLT5yZWFkeSAmJiB2cS0+ Y2IuY2FsbGJhY2spCj4gPj4+ICsgICAgICAgICAgICAgdnEtPmNiLmNhbGxiYWNrKHZxLT5jYi5w cml2YXRlKTsKPiA+Pj4gKyAgICAgc3Bpbl91bmxvY2tfaXJxKCZ2cS0+aXJxX2xvY2spOwo+ID4+ PiArfQo+ID4+PiArCj4gPj4+ICtzdGF0aWMgbG9uZyB2ZHVzZV9kZXZfaW9jdGwoc3RydWN0IGZp bGUgKmZpbGUsIHVuc2lnbmVkIGludCBjbWQsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgdW5zaWduZWQgbG9uZyBhcmcpCj4gPj4+ICt7Cj4gPj4+ICsgICAgIHN0cnVjdCB2ZHVzZV9k ZXYgKmRldiA9IGZpbGUtPnByaXZhdGVfZGF0YTsKPiA+Pj4gKyAgICAgdm9pZCBfX3VzZXIgKmFy Z3AgPSAodm9pZCBfX3VzZXIgKilhcmc7Cj4gPj4+ICsgICAgIGludCByZXQ7Cj4gPj4+ICsKPiA+ Pj4gKyAgICAgc3dpdGNoIChjbWQpIHsKPiA+Pj4gKyAgICAgY2FzZSBWRFVTRV9JT1RMQl9HRVRf RkQ6IHsKPiA+Pj4gKyAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2VfaW90bGJfZW50cnkgZW50cnk7 Cj4gPj4+ICsgICAgICAgICAgICAgc3RydWN0IHZob3N0X2lvdGxiX21hcCAqbWFwOwo+ID4+PiAr ICAgICAgICAgICAgIHN0cnVjdCB2ZHBhX21hcF9maWxlICptYXBfZmlsZTsKPiA+Pj4gKyAgICAg ICAgICAgICBzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbiA9IGRldi0+ZG9tYWluOwo+ ID4+PiArICAgICAgICAgICAgIHN0cnVjdCBmaWxlICpmID0gTlVMTDsKPiA+Pj4gKwo+ID4+PiAr ICAgICAgICAgICAgIHJldCA9IC1FRkFVTFQ7Cj4gPj4+ICsgICAgICAgICAgICAgaWYgKGNvcHlf ZnJvbV91c2VyKCZlbnRyeSwgYXJncCwgc2l6ZW9mKGVudHJ5KSkpCj4gPj4+ICsgICAgICAgICAg ICAgICAgICAgICBicmVhazsKPiA+Pj4gKwo+ID4+PiArICAgICAgICAgICAgIHJldCA9IC1FSU5W QUw7Cj4gPj4+ICsgICAgICAgICAgICAgaWYgKGVudHJ5LnN0YXJ0ID4gZW50cnkubGFzdCkKPiA+ Pj4gKyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4+PiArCj4gPj4+ICsgICAgICAgICAg ICAgc3Bpbl9sb2NrKCZkb21haW4tPmlvdGxiX2xvY2spOwo+ID4+PiArICAgICAgICAgICAgIG1h cCA9IHZob3N0X2lvdGxiX2l0cmVlX2ZpcnN0KGRvbWFpbi0+aW90bGIsCj4gPj4+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnkuc3RhcnQsIGVudHJ5Lmxh c3QpOwo+ID4+PiArICAgICAgICAgICAgIGlmIChtYXApIHsKPiA+Pj4gKyAgICAgICAgICAgICAg ICAgICAgIG1hcF9maWxlID0gKHN0cnVjdCB2ZHBhX21hcF9maWxlICopbWFwLT5vcGFxdWU7Cj4g Pj4+ICsgICAgICAgICAgICAgICAgICAgICBmID0gZ2V0X2ZpbGUobWFwX2ZpbGUtPmZpbGUpOwo+ ID4+PiArICAgICAgICAgICAgICAgICAgICAgZW50cnkub2Zmc2V0ID0gbWFwX2ZpbGUtPm9mZnNl dDsKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgIGVudHJ5LnN0YXJ0ID0gbWFwLT5zdGFydDsK PiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgIGVudHJ5Lmxhc3QgPSBtYXAtPmxhc3Q7Cj4gPj4+ ICsgICAgICAgICAgICAgICAgICAgICBlbnRyeS5wZXJtID0gbWFwLT5wZXJtOwo+ID4+PiArICAg ICAgICAgICAgIH0KPiA+Pj4gKyAgICAgICAgICAgICBzcGluX3VubG9jaygmZG9tYWluLT5pb3Rs Yl9sb2NrKTsKPiA+Pj4gKyAgICAgICAgICAgICByZXQgPSAtRUlOVkFMOwo+ID4+PiArICAgICAg ICAgICAgIGlmICghZikKPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4+PiAr Cj4gPj4+ICsgICAgICAgICAgICAgcmV0ID0gLUVGQVVMVDsKPiA+Pj4gKyAgICAgICAgICAgICBp ZiAoY29weV90b191c2VyKGFyZ3AsICZlbnRyeSwgc2l6ZW9mKGVudHJ5KSkpIHsKPiA+Pj4gKyAg ICAgICAgICAgICAgICAgICAgIGZwdXQoZik7Cj4gPj4+ICsgICAgICAgICAgICAgICAgICAgICBi cmVhazsKPiA+Pj4gKyAgICAgICAgICAgICB9Cj4gPj4+ICsgICAgICAgICAgICAgcmV0ID0gcmVj ZWl2ZV9mZChmLCBwZXJtX3RvX2ZpbGVfZmxhZ3MoZW50cnkucGVybSkpOwo+ID4+PiArICAgICAg ICAgICAgIGZwdXQoZik7Cj4gPj4+ICsgICAgICAgICAgICAgYnJlYWs7Cj4gPj4+ICsgICAgIH0K PiA+Pj4gKyAgICAgY2FzZSBWRFVTRV9ERVZfR0VUX0ZFQVRVUkVTOgo+ID4+PiArICAgICAgICAg ICAgIHJldCA9IHB1dF91c2VyKGRldi0+ZmVhdHVyZXMsICh1NjQgX191c2VyICopYXJncCk7Cj4g Pj4+ICsgICAgICAgICAgICAgYnJlYWs7Cj4gPj4+ICsgICAgIGNhc2UgVkRVU0VfREVWX1VQREFU RV9DT05GSUc6IHsKPiA+Pj4gKyAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2VfY29uZmlnX3VwZGF0 ZSBjb25maWc7Cj4gPj4+ICsgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBzaXplID0gb2Zmc2V0 b2Yoc3RydWN0IHZkdXNlX2NvbmZpZ191cGRhdGUsCj4gPj4+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyKTsKPiA+Pj4gKwo+ID4+PiArICAgICAgICAg ICAgIHJldCA9IC1FRkFVTFQ7Cj4gPj4+ICsgICAgICAgICAgICAgaWYgKGNvcHlfZnJvbV91c2Vy KCZjb25maWcsIGFyZ3AsIHNpemUpKQo+ID4+PiArICAgICAgICAgICAgICAgICAgICAgYnJlYWs7 Cj4gPj4+ICsKPiA+Pj4gKyAgICAgICAgICAgICByZXQgPSAtRUlOVkFMOwo+ID4+PiArICAgICAg ICAgICAgIGlmIChjb25maWcubGVuZ3RoID09IDAgfHwKPiA+Pj4gKyAgICAgICAgICAgICAgICAg Y29uZmlnLmxlbmd0aCA+IGRldi0+Y29uZmlnX3NpemUgLSBjb25maWcub2Zmc2V0KQo+ID4+PiAr ICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4gPj4+ICsKPiA+Pj4gKyAgICAgICAgICAgICBy ZXQgPSAtRUZBVUxUOwo+ID4+PiArICAgICAgICAgICAgIGlmIChjb3B5X2Zyb21fdXNlcihkZXYt PmNvbmZpZyArIGNvbmZpZy5vZmZzZXQsIGFyZ3AgKyBzaXplLAo+ID4+PiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBjb25maWcubGVuZ3RoKSkKPiA+Pj4gKyAgICAgICAgICAgICAg ICAgICAgIGJyZWFrOwo+ID4+PiArCj4gPj4+ICsgICAgICAgICAgICAgcmV0ID0gMDsKPiA+Pj4g KyAgICAgICAgICAgICBxdWV1ZV93b3JrKHZkdXNlX2lycV93cSwgJmRldi0+aW5qZWN0KTsKPiA+ Pgo+ID4+IEkgd29uZGVyIGlmIGl0J3MgYmV0dGVyIHRvIHNlcGFyYXRlIGNvbmZpZyBpbnRlcnJ1 cHQgb3V0IG9mIGNvbmZpZwo+ID4+IHVwZGF0ZSBvciB3ZSBuZWVkIGRvY3VtZW50IHRoaXMuCj4g Pj4KPiA+IEkgaGF2ZSBkb2N1bWVudGVkIGl0IGluIHRoZSBkb2NzLiBMb29rcyBsaWtlIGEgY29u ZmlnIHVwZGF0ZSBzaG91bGQgYmUKPiA+IGFsd2F5cyBmb2xsb3dlZCBieSBhIGNvbmZpZyBpbnRl cnJ1cHQuIEkgZGlkbid0IGZpbmQgYSBjYXNlIHRoYXQgdXNlcwo+ID4gdGhlbSBzZXBhcmF0ZWx5 Lgo+Cj4KPiBUaGUgdUFQSSBkb2Vzbid0IHByZXZlbnQgdXMgZnJvbSB0aGUgZm9sbG93aW5nIHNj ZW5hcmlvOgo+Cj4gdXBkYXRlX2NvbmZpZyhtYWNbMF0sIC4uKTsKPiB1cGRhdGVfY29uZmlnKG1h eFsxXSwgLi4pOwo+Cj4gU28gaXQgbG9va3MgdG8gbWUgaXQncyBiZXR0ZXIgdG8gc2VwYXJhdGUg dGhlIGNvbmZpZyBpbnRlcnJ1cHQgZnJvbSB0aGUKPiBjb25maWcgdXBkYXRpbmcuCj4KCkZpbmUu Cgo+Cj4gPgo+ID4+PiArICAgICAgICAgICAgIGJyZWFrOwo+ID4+PiArICAgICB9Cj4gPj4+ICsg ICAgIGNhc2UgVkRVU0VfVlFfR0VUX0lORk86IHsKPiA+Pgo+ID4+IERvIHdlIG5lZWQgdG8gbGlt aXQgdGhpcyBvbmx5IHdoZW4gRFJJVkVSX09LIGlzIHNldD8KPiA+Pgo+ID4gQW55IHJlYXNvbiB0 byBhZGQgdGhpcyBsaW1pdGF0aW9uPwo+Cj4KPiBPdGhlcndpc2UgdGhlIHZxIGlzIG5vdCBmdWxs eSBpbml0aWFsaXplZCwgZS5nIHRoZSBkZXNjX2FkZHIgbWlnaHQgbm90Cj4gYmUgY29ycmVjdC4K PgoKVGhlIHZxX2luZm8tPnJlYWR5IGNhbiBiZSB1c2VkIHRvIHRlbGwgdXNlcnNwYWNlIHdoZXRo ZXIgdGhlIHZxIGlzCmluaXRpYWxpemVkIG9yIG5vdC4KClRoYW5rcywKWW9uZ2ppCgpfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwppb21tdSBtYWlsaW5nIGxp c3QKaW9tbXVAbGlzdHMubGludXgtZm91bmRhdGlvbi5vcmcKaHR0cHM6Ly9saXN0cy5saW51eGZv dW5kYXRpb24ub3JnL21haWxtYW4vbGlzdGluZm8vaW9tbXU=