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.8 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=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 09937C07E9A for ; Wed, 14 Jul 2021 06:49:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D659C613AF for ; Wed, 14 Jul 2021 06:49:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238172AbhGNGw1 (ORCPT ); Wed, 14 Jul 2021 02:52:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40108 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237948AbhGNGw1 (ORCPT ); Wed, 14 Jul 2021 02:52:27 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B95EC06175F for ; Tue, 13 Jul 2021 23:49:34 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id x17so1626467edd.12 for ; Tue, 13 Jul 2021 23:49:34 -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=/y1qjoZoHTwNonJ1lKQNeeY7dEhw6LB/91MF2j/IZHg=; b=wUzbktiNUytMD/S6WOP0BwIPrB37QNP/1vdDGm9FQxIzrTXAQs52TUSIledRBCBqIL LNMBQgHC0PAPRgaxB2YafVdfiKGxQu7IC1kwgS3sC9asX7IPjruJcAMJVWNm2tUK7tye v0/sb6W1xnScelyei6KZZ46tj3L4RwuFXDbonO97qMwTQQo+bnQUQuiZfNAiZTlDUy04 yLmLbV7d47RE6DbWDT/Qc1IWQ1z40+BvikIr3g+dme62IPQNKEpFE+OtOlmYx0jguCDH iFj5GHwqw1gxTT3G8Y+iPn+4oKZWpwPsqUpIPY+884Z0auAhImnIq4S3VFjQmEGCMD8l tutg== 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=/y1qjoZoHTwNonJ1lKQNeeY7dEhw6LB/91MF2j/IZHg=; b=cyKy10L5qWjuTM7PJuJDzKCUjNuxxVo+jv2R+QAOgw+cpcL3tyRW3Monl1MCHpXW1H sBaJuA5LbPxAxTYxWOxb5VzQvW1DzgxGDq5qPNYQHyPjsFNqrJLF1i8HzHijotsi7Ces Mv4mP5kCk/kVP7NzaGPW6HdwyYGW/xiM1kF2wT2NZK2jxGQVDeJOoMQwrl54Asr8gUyn RGhHMWmhHrmugK/WO0oy0DHU0KfzpTt3sDH0wr/+bktt3oXBpZMWofypMvvz/KiXuV7j JnDfWBlf4Lxip/s2HV5vc4qStC0yeWDHnIY9zQE2F6x3VECWpDY3LdSlMNTLW8cA704j qB/Q== X-Gm-Message-State: AOAM532a+sMif/nr4tpcFm+MMy/D4vwRCDUvRKplV9PbVFrY4Ki6c6al K0oxIpDUVgcGBccc1+iG4L5m+TKg3P6lUvPKKTPZ X-Google-Smtp-Source: ABdhPJyKd50YAda/QQS+upa5EyNhb1tiftJb3o7UzgBQeYVOgTniYP5qXdl2X1swzDB43WBpsEyXgoMUEHuhqNc5Kx4= X-Received: by 2002:aa7:dcd2:: with SMTP id w18mr11516012edu.145.1626245372864; Tue, 13 Jul 2021 23:49:32 -0700 (PDT) MIME-Version: 1.0 References: <20210713084656.232-1-xieyongji@bytedance.com> <20210713084656.232-17-xieyongji@bytedance.com> <26116714-f485-eeab-4939-71c4c10c30de@redhat.com> In-Reply-To: <26116714-f485-eeab-4939-71c4c10c30de@redhat.com> From: Yongji Xie Date: Wed, 14 Jul 2021 14:49:21 +0800 Message-ID: Subject: Re: [PATCH v9 16/17] 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 , He Zhe , Liu Xiaodong , 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 Wed, Jul 14, 2021 at 1:45 PM Jason Wang wrote: > > > =E5=9C=A8 2021/7/13 =E4=B8=8B=E5=8D=884:46, Xie Yongji =E5=86=99=E9=81=93= : > > This VDUSE driver enables implementing software-emulated vDPA > > devices in userspace. The vDPA device is created by > > ioctl(VDUSE_CREATE_DEV) on /dev/vduse/control. Then a char device > > interface (/dev/vduse/$NAME) is exported to userspace for device > > emulation. > > > > In order to make the device emulation more secure, the device's > > control path is handled in kernel. A message mechnism is introduced > > to forward some dataplane related control messages to userspace. > > > > And in the data path, the DMA buffer will be mapped into userspace > > address space through different ways depending on the vDPA bus to > > which the vDPA device is attached. In virtio-vdpa case, the MMU-based > > IOMMU driver is used to achieve that. And in vhost-vdpa case, the > > DMA buffer is reside in a userspace memory region which can be shared > > to the VDUSE userspace processs via transferring the shmfd. > > > > For more details on VDUSE design and usage, please see the follow-on > > Documentation commit. > > > > 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 | 1502 +++++++++++= +++++++++ > > include/uapi/linux/vduse.h | 221 +++ > > 6 files changed, 1740 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/Docum= entation/userspace-api/ioctl/ioctl-number.rst > > index 1409e40e6345..293ca3aef358 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/M= akefile > > 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_use= r/vduse_dev.c > > new file mode 100644 > > index 000000000000..c994a4a4660c > > --- /dev/null > > +++ b/drivers/vdpa/vdpa_user/vduse_dev.c > > @@ -0,0 +1,1502 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * VDUSE: vDPA Device in Userspace > > + * > > + * Copyright (C) 2020-2021 Bytedance Inc. and/or its affiliates. All r= ights 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; > > + u16 num_max; > > + u32 num; > > + u64 desc_addr; > > + u64 driver_addr; > > + u64 device_addr; > > + struct vdpa_vq_state state; > > + 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; > > + u64 api_version; > > + u64 device_features; > > + u64 driver_features; > > + u32 device_id; > > + u32 vendor_id; > > + u32 generation; > > + u32 config_size; > > + void *config; > > + u8 status; > > + 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 *vdpa= ) > > +{ > > + struct vduse_vdpa *vdev =3D container_of(vdpa, struct vduse_vdpa,= 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 *head) > > +{ > > + struct vduse_dev_msg *msg =3D NULL; > > + > > + if (!list_empty(head)) { > > + msg =3D list_first_entry(head, struct vduse_dev_msg, list= ); > > + 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_sync(struct vduse_dev *dev, > > + struct vduse_dev_msg *msg) > > +{ > > + int ret; > > + > > + 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); > > + > > + 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; > > + } > > + ret =3D (msg->resp.result =3D=3D VDUSE_REQ_RESULT_OK) ? 0 : -EIO; > > > I think we should mark the device as malfunction when there is a timeout > and forbid any userspace operations except for the destroy aftwards for > safety. > Is it necessary? Actually we can't stop the dataplane processing in userspace. It doesn=E2=80=99t seem to help much if we only forbid ioctl and read/write. And there might be some messages that can tolerate failure. Even userspace can do something like NEEDS_RESET to do recovery. > > > + spin_unlock(&dev->msg_lock); > > + > > + return ret; > > +} > > + > > +static int vduse_dev_get_vq_state_packed(struct vduse_dev *dev, > > + struct vduse_virtqueue *vq, > > + struct vdpa_vq_state_packed *pac= ked) > > +{ > > + struct vduse_dev_msg msg =3D { 0 }; > > + int ret; > > + > > + msg.req.type =3D VDUSE_GET_VQ_STATE; > > + msg.req.vq_state.index =3D vq->index; > > + > > + ret =3D vduse_dev_msg_sync(dev, &msg); > > + if (ret) > > + return ret; > > + > > + packed->last_avail_counter =3D > > + msg.resp.vq_state.packed.last_avail_counter; > > + packed->last_avail_idx =3D msg.resp.vq_state.packed.last_avail_id= x; > > + packed->last_used_counter =3D msg.resp.vq_state.packed.last_used_= counter; > > + packed->last_used_idx =3D msg.resp.vq_state.packed.last_used_idx; > > + > > + return 0; > > +} > > + > > +static int vduse_dev_get_vq_state_split(struct vduse_dev *dev, > > + struct vduse_virtqueue *vq, > > + struct vdpa_vq_state_split *split= ) > > +{ > > + struct vduse_dev_msg msg =3D { 0 }; > > + int ret; > > + > > + msg.req.type =3D VDUSE_GET_VQ_STATE; > > + msg.req.vq_state.index =3D vq->index; > > + > > + ret =3D vduse_dev_msg_sync(dev, &msg); > > + if (ret) > > + return ret; > > + > > + split->avail_index =3D msg.resp.vq_state.split.avail_index; > > + > > + return 0; > > +} > > + > > +static int vduse_dev_set_status(struct vduse_dev *dev, u8 status) > > +{ > > + struct vduse_dev_msg msg =3D { 0 }; > > + > > + msg.req.type =3D VDUSE_SET_STATUS; > > + msg.req.s.status =3D status; > > + > > + return vduse_dev_msg_sync(dev, &msg); > > +} > > + > > +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_sync(dev, &msg); > > +} > > + > > +static ssize_t vduse_dev_read_iter(struct kiocb *iocb, struct iov_iter= *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; > > + } > > + 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_ite= r *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->driver_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); > > + flush_work(&dev->inject); > > + > > + 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->num =3D 0; > > + memset(&vq->state, 0, sizeof(vq->state)); > > + > > + 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); > > + flush_work(&vq->inject); > > + } > > +} > > + > > +static int vduse_vdpa_set_vq_address(struct vdpa_device *vdpa, u16 idx= , > > + 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, u= 32 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 idx) > > +{ > > + 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]; > > + > > + if (dev->driver_features & BIT_ULL(VIRTIO_F_RING_PACKED)) { > > + vq->state.packed.last_avail_counter =3D > > + state->packed.last_avail_counter; > > + vq->state.packed.last_avail_idx =3D state->packed.last_av= ail_idx; > > + vq->state.packed.last_used_counter =3D > > + state->packed.last_used_counter; > > + vq->state.packed.last_used_idx =3D state->packed.last_use= d_idx; > > + } else > > + vq->state.split.avail_index =3D state->split.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]; > > + > > + if (dev->driver_features & BIT_ULL(VIRTIO_F_RING_PACKED)) > > + return vduse_dev_get_vq_state_packed(dev, vq, &state->pac= ked); > > + > > + return vduse_dev_get_vq_state_split(dev, vq, &state->split); > > +} > > + > > +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->device_features; > > +} > > + > > +static int vduse_vdpa_set_features(struct vdpa_device *vdpa, u64 featu= res) > > +{ > > + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > > + > > + dev->driver_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, u16 idx= ) > > +{ > > + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > > + > > + return dev->vqs[idx].num_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 status) > > +{ > > + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > > + > > + if (vduse_dev_set_status(dev, status)) > > + return; > > + > > + dev->status =3D status; > > > It looks to me such design exclude the possibility of letting userspace > device to set bit like (NEEDS_RESET) in the future. > Looks like we can achieve that via the ioctl. > I wonder if it's better to do something similar to ccw: > > 1) requires the userspace to update the status bit in the response > 2) update the dev->status to the status in the response if no timeout > > Then userspace could then set NEEDS_RESET if necessary. > But NEEDS_RESET does not only happen in this case. > > > + if (status =3D=3D 0) > > + vduse_dev_reset(dev); > > +} > > + > > +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 i= nt offset, > > + void *buf, unsigned int len) > > +{ > > + struct vduse_dev *dev =3D vdpa_to_vduse(vdpa); > > + > > + if (len > dev->config_size - offset) > > + return; > > + > > + memcpy(buf, dev->config + offset, len); > > +} > > + > > +static void vduse_vdpa_set_config(struct vdpa_device *vdpa, unsigned i= nt 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, att= rs); > > +} > > + > > +static void vduse_dev_unmap_page(struct device *dev, dma_addr_t dma_ad= dr, > > + 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_unmap_page(domain, dma_addr, size, dir, attrs= ); > > +} > > + > > +static void *vduse_dev_alloc_coherent(struct device *dev, size_t size, > > + dma_addr_t *dma_addr, gfp_t flag, > > + 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_addr, > > + 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 bool vduse_dev_is_ready(struct vduse_dev *dev) > > +{ > > + int i; > > + > > + for (i =3D 0; i < dev->vq_num; i++) > > + if (!dev->vqs[i].num_max) > > + return false; > > + > > + return true; > > +} > > + > > +static void vduse_dev_irq_inject(struct work_struct *work) > > +{ > > + struct vduse_dev *dev =3D container_of(work, struct vduse_dev, in= ject); > > + > > + 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->opaque; > > + 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: > > > Let's add a comment to explain here. E.g we just mirror what driver > wrote and the drier is expected to check FEATURE_OK. > I already document some details in include/uapi/linux/vduse.h and Documentation/userspace-api/vduse.rst > > > + ret =3D put_user(dev->driver_features, (u64 __user *)argp= ); > > + break; > > + case VDUSE_DEV_SET_CONFIG: { > > + struct vduse_config_data config; > > + unsigned long size =3D offsetof(struct vduse_config_data, > > + 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 + si= ze, > > + config.length)) > > + break; > > + > > + ret =3D 0; > > + break; > > + } > > + case VDUSE_DEV_INJECT_IRQ: > > > It's better to have "config" in the name. > OK. > > > + ret =3D 0; > > + queue_work(vduse_irq_wq, &dev->inject); > > + break; > > + case VDUSE_VQ_SETUP: { > > + struct vduse_vq_config config; > > + u32 index; > > + > > + ret =3D -EFAULT; > > + if (copy_from_user(&config, argp, sizeof(config))) > > + break; > > + > > + ret =3D -EINVAL; > > + if (config.index >=3D dev->vq_num) > > + break; > > + > > + index =3D array_index_nospec(config.index, dev->vq_num); > > + dev->vqs[index].num_max =3D config.max_size; > > + ret =3D 0; > > + break; > > + } > > + case VDUSE_VQ_GET_INFO: { > > + struct vduse_vq_info vq_info; > > + struct vduse_virtqueue *vq; > > + u32 index; > > + > > + ret =3D -EFAULT; > > + if (copy_from_user(&vq_info, argp, sizeof(vq_info))) > > + break; > > + > > + ret =3D -EINVAL; > > + if (vq_info.index >=3D dev->vq_num) > > + break; > > + > > + index =3D array_index_nospec(vq_info.index, dev->vq_num); > > + vq =3D &dev->vqs[index]; > > + vq_info.desc_addr =3D vq->desc_addr; > > + vq_info.driver_addr =3D vq->driver_addr; > > + vq_info.device_addr =3D vq->device_addr; > > + vq_info.num =3D vq->num; > > + > > + if (dev->driver_features & BIT_ULL(VIRTIO_F_RING_PACKED))= { > > + vq_info.packed.last_avail_counter =3D > > + vq->state.packed.last_avail_counter; > > + vq_info.packed.last_avail_idx =3D > > + vq->state.packed.last_avail_idx; > > + vq_info.packed.last_used_counter =3D > > + vq->state.packed.last_used_counter; > > + vq_info.packed.last_used_idx =3D > > + vq->state.packed.last_used_idx; > > + } else > > + vq_info.split.avail_index =3D > > + vq->state.split.avail_index; > > + > > + vq_info.ready =3D vq->ready; > > + > > + ret =3D -EFAULT; > > + if (copy_to_user(argp, &vq_info, sizeof(vq_info))) > > + break; > > + > > + ret =3D 0; > > + break; > > + } > > + case VDUSE_VQ_SETUP_KICKFD: { > > + struct vduse_vq_eventfd eventfd; > > + > > + ret =3D -EFAULT; > > + if (copy_from_user(&eventfd, argp, sizeof(eventfd))) > > + break; > > + > > + ret =3D vduse_kickfd_setup(dev, &eventfd); > > + break; > > + } > > + case VDUSE_VQ_INJECT_IRQ: { > > + u32 index; > > + > > + ret =3D -EFAULT; > > + if (get_user(index, (u32 __user *)argp)) > > + break; > > + > > + ret =3D -EINVAL; > > + if (index >=3D dev->vq_num) > > + break; > > + > > + ret =3D 0; > > + index =3D array_index_nospec(index, dev->vq_num); > > + queue_work(vduse_irq_wq, &dev->vqs[index].inject); > > + break; > > + } > > + default: > > + ret =3D -ENOIOCTLCMD; > > + break; > > + } > > + > > + return ret; > > +} > > + > > +static int vduse_dev_release(struct inode *inode, struct file *file) > > +{ > > + struct vduse_dev *dev =3D file->private_data; > > + > > + spin_lock(&dev->msg_lock); > > + /* Make sure the inflight messages can processed after reconncect= ion */ > > + list_splice_init(&dev->recv_list, &dev->send_list); > > + spin_unlock(&dev->msg_lock); > > + dev->connected =3D false; > > + > > + return 0; > > +} > > + > > +static struct vduse_dev *vduse_dev_get_from_minor(int minor) > > +{ > > + struct vduse_dev *dev; > > + > > + mutex_lock(&vduse_lock); > > + dev =3D idr_find(&vduse_idr, minor); > > + mutex_unlock(&vduse_lock); > > + > > + return dev; > > +} > > + > > +static int vduse_dev_open(struct inode *inode, struct file *file) > > +{ > > + int ret; > > + struct vduse_dev *dev =3D vduse_dev_get_from_minor(iminor(inode))= ; > > + > > + if (!dev) > > + return -ENODEV; > > + > > + ret =3D -EBUSY; > > + mutex_lock(&dev->lock); > > + if (dev->connected) > > + goto unlock; > > + > > + ret =3D 0; > > + dev->connected =3D true; > > + file->private_data =3D dev; > > +unlock: > > + mutex_unlock(&dev->lock); > > + > > + return ret; > > +} > > + > > +static const struct file_operations vduse_dev_fops =3D { > > + .owner =3D THIS_MODULE, > > + .open =3D vduse_dev_open, > > + .release =3D vduse_dev_release, > > + .read_iter =3D vduse_dev_read_iter, > > + .write_iter =3D vduse_dev_write_iter, > > + .poll =3D vduse_dev_poll, > > + .unlocked_ioctl =3D vduse_dev_ioctl, > > + .compat_ioctl =3D compat_ptr_ioctl, > > + .llseek =3D noop_llseek, > > +}; > > + > > +static struct vduse_dev *vduse_dev_create(void) > > +{ > > + struct vduse_dev *dev =3D kzalloc(sizeof(*dev), GFP_KERNEL); > > + > > + if (!dev) > > + return NULL; > > + > > + mutex_init(&dev->lock); > > + spin_lock_init(&dev->msg_lock); > > + INIT_LIST_HEAD(&dev->send_list); > > + INIT_LIST_HEAD(&dev->recv_list); > > + spin_lock_init(&dev->irq_lock); > > + > > + INIT_WORK(&dev->inject, vduse_dev_irq_inject); > > + init_waitqueue_head(&dev->waitq); > > + > > + return dev; > > +} > > + > > +static void vduse_dev_destroy(struct vduse_dev *dev) > > +{ > > + kfree(dev); > > +} > > + > > +static struct vduse_dev *vduse_find_dev(const char *name) > > +{ > > + struct vduse_dev *dev; > > + int id; > > + > > + idr_for_each_entry(&vduse_idr, dev, id) > > + if (!strcmp(dev->name, name)) > > + return dev; > > + > > + return NULL; > > +} > > + > > +static int vduse_destroy_dev(char *name) > > +{ > > + struct vduse_dev *dev =3D vduse_find_dev(name); > > + > > + if (!dev) > > + return -EINVAL; > > + > > + mutex_lock(&dev->lock); > > + if (dev->vdev || dev->connected) { > > + mutex_unlock(&dev->lock); > > + return -EBUSY; > > + } > > + dev->connected =3D true; > > + mutex_unlock(&dev->lock); > > + > > + vduse_dev_reset(dev); > > + device_destroy(vduse_class, MKDEV(MAJOR(vduse_major), dev->minor)= ); > > + idr_remove(&vduse_idr, dev->minor); > > + kvfree(dev->config); > > + kfree(dev->vqs); > > + vduse_domain_destroy(dev->domain); > > + kfree(dev->name); > > + vduse_dev_destroy(dev); > > + module_put(THIS_MODULE); > > + > > + return 0; > > +} > > + > > +static bool device_is_allowed(u32 device_id) > > +{ > > + int i; > > + > > + for (i =3D 0; i < ARRAY_SIZE(allowed_device_id); i++) > > + if (allowed_device_id[i] =3D=3D device_id) > > + return true; > > + > > + return false; > > +} > > + > > +static bool features_is_valid(u64 features) > > +{ > > + if (!(features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) > > + return false; > > + > > + /* Now we only support read-only configuration space */ > > + if (features & (1ULL << VIRTIO_BLK_F_CONFIG_WCE)) > > + return false; > > + > > + return true; > > +} > > + > > +static bool vduse_validate_config(struct vduse_dev_config *config) > > +{ > > + if (config->bounce_size > VDUSE_MAX_BOUNCE_SIZE) > > + return false; > > + > > + if (config->vq_align > PAGE_SIZE) > > + return false; > > + > > + if (config->config_size > PAGE_SIZE) > > + return false; > > > Any reason for this check? > To limit the kernel buffer size for configuration space. Is the PAGE_SIZE enough? 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.6 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 2403AC11F67 for ; Wed, 14 Jul 2021 06:49:43 +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 B00B3613B5 for ; Wed, 14 Jul 2021 06:49:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B00B3613B5 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 7BA88400F2; Wed, 14 Jul 2021 06:49:42 +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 vGp9XJCylir4; Wed, 14 Jul 2021 06:49:40 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 5DF8F40193; Wed, 14 Jul 2021 06:49:40 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2E7E9C001C; Wed, 14 Jul 2021 06:49:40 +0000 (UTC) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 01A10C000E for ; Wed, 14 Jul 2021 06:49:39 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id CDA6C40193 for ; Wed, 14 Jul 2021 06:49:38 +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 6edEAdyAvtJW for ; Wed, 14 Jul 2021 06:49:35 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by smtp2.osuosl.org (Postfix) with ESMTPS id 65646400F2 for ; Wed, 14 Jul 2021 06:49:34 +0000 (UTC) Received: by mail-ed1-x52a.google.com with SMTP id w14so1655246edc.8 for ; Tue, 13 Jul 2021 23:49:34 -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=/y1qjoZoHTwNonJ1lKQNeeY7dEhw6LB/91MF2j/IZHg=; b=wUzbktiNUytMD/S6WOP0BwIPrB37QNP/1vdDGm9FQxIzrTXAQs52TUSIledRBCBqIL LNMBQgHC0PAPRgaxB2YafVdfiKGxQu7IC1kwgS3sC9asX7IPjruJcAMJVWNm2tUK7tye v0/sb6W1xnScelyei6KZZ46tj3L4RwuFXDbonO97qMwTQQo+bnQUQuiZfNAiZTlDUy04 yLmLbV7d47RE6DbWDT/Qc1IWQ1z40+BvikIr3g+dme62IPQNKEpFE+OtOlmYx0jguCDH iFj5GHwqw1gxTT3G8Y+iPn+4oKZWpwPsqUpIPY+884Z0auAhImnIq4S3VFjQmEGCMD8l tutg== 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=/y1qjoZoHTwNonJ1lKQNeeY7dEhw6LB/91MF2j/IZHg=; b=RX1+C1RN77SRUtIRVv9MaogLgtT5C8Z9DkyBRwE/xoTa75Q5TRNDFlxqij6KUhp9Xi B21iKy3dW0FDak4V1p2wF4RaSXPgv+7nxnmQeNalbmGk4oHm2Tr9rlrlNHOAVzXJl7Hp ZPoItA/Il+BBeJO1r1/B5Du80hPB9+zKwxbEzcO3ztU45Ri88WETfXj3GdU7Nzd9PsAm yYDUWFF57yCi7x+Y2+P8Tvpg+gg2jm10HY1RQvPV9DL5pLYCQ9GwPhpSGq5zYDd71ot9 kh15KY0V5IbQ8IfLBhr7ImhpFjEHoxhiveDW/wfBpyxzYCWzAGiy7Pq7ZEx1987VEr4c jOng== X-Gm-Message-State: AOAM531V04MwgUN8y5Ey5tYaX7wSUhI/v83grDVJnY8YXThStnJYnQUx pnzFsx5iSagU2dRzLwONd0wH/VXYxcXJqGPTuieU X-Google-Smtp-Source: ABdhPJyKd50YAda/QQS+upa5EyNhb1tiftJb3o7UzgBQeYVOgTniYP5qXdl2X1swzDB43WBpsEyXgoMUEHuhqNc5Kx4= X-Received: by 2002:aa7:dcd2:: with SMTP id w18mr11516012edu.145.1626245372864; Tue, 13 Jul 2021 23:49:32 -0700 (PDT) MIME-Version: 1.0 References: <20210713084656.232-1-xieyongji@bytedance.com> <20210713084656.232-17-xieyongji@bytedance.com> <26116714-f485-eeab-4939-71c4c10c30de@redhat.com> In-Reply-To: <26116714-f485-eeab-4939-71c4c10c30de@redhat.com> From: Yongji Xie Date: Wed, 14 Jul 2021 14:49:21 +0800 Message-ID: Subject: Re: [PATCH v9 16/17] 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 , Liu Xiaodong , Al Viro , Stefan Hajnoczi , songmuchun@bytedance.com, Jens Axboe , He Zhe , 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" T24gV2VkLCBKdWwgMTQsIDIwMjEgYXQgMTo0NSBQTSBKYXNvbiBXYW5nIDxqYXNvd2FuZ0ByZWRo YXQuY29tPiB3cm90ZToKPgo+Cj4g5ZyoIDIwMjEvNy8xMyDkuIvljYg0OjQ2LCBYaWUgWW9uZ2pp IOWGmemBkzoKPiA+IFRoaXMgVkRVU0UgZHJpdmVyIGVuYWJsZXMgaW1wbGVtZW50aW5nIHNvZnR3 YXJlLWVtdWxhdGVkIHZEUEEKPiA+IGRldmljZXMgaW4gdXNlcnNwYWNlLiBUaGUgdkRQQSBkZXZp Y2UgaXMgY3JlYXRlZCBieQo+ID4gaW9jdGwoVkRVU0VfQ1JFQVRFX0RFVikgb24gL2Rldi92ZHVz ZS9jb250cm9sLiBUaGVuIGEgY2hhciBkZXZpY2UKPiA+IGludGVyZmFjZSAoL2Rldi92ZHVzZS8k TkFNRSkgaXMgZXhwb3J0ZWQgdG8gdXNlcnNwYWNlIGZvciBkZXZpY2UKPiA+IGVtdWxhdGlvbi4K PiA+Cj4gPiBJbiBvcmRlciB0byBtYWtlIHRoZSBkZXZpY2UgZW11bGF0aW9uIG1vcmUgc2VjdXJl LCB0aGUgZGV2aWNlJ3MKPiA+IGNvbnRyb2wgcGF0aCBpcyBoYW5kbGVkIGluIGtlcm5lbC4gQSBt ZXNzYWdlIG1lY2huaXNtIGlzIGludHJvZHVjZWQKPiA+IHRvIGZvcndhcmQgc29tZSBkYXRhcGxh bmUgcmVsYXRlZCBjb250cm9sIG1lc3NhZ2VzIHRvIHVzZXJzcGFjZS4KPiA+Cj4gPiBBbmQgaW4g dGhlIGRhdGEgcGF0aCwgdGhlIERNQSBidWZmZXIgd2lsbCBiZSBtYXBwZWQgaW50byB1c2Vyc3Bh Y2UKPiA+IGFkZHJlc3Mgc3BhY2UgdGhyb3VnaCBkaWZmZXJlbnQgd2F5cyBkZXBlbmRpbmcgb24g dGhlIHZEUEEgYnVzIHRvCj4gPiB3aGljaCB0aGUgdkRQQSBkZXZpY2UgaXMgYXR0YWNoZWQuIElu IHZpcnRpby12ZHBhIGNhc2UsIHRoZSBNTVUtYmFzZWQKPiA+IElPTU1VIGRyaXZlciBpcyB1c2Vk IHRvIGFjaGlldmUgdGhhdC4gQW5kIGluIHZob3N0LXZkcGEgY2FzZSwgdGhlCj4gPiBETUEgYnVm ZmVyIGlzIHJlc2lkZSBpbiBhIHVzZXJzcGFjZSBtZW1vcnkgcmVnaW9uIHdoaWNoIGNhbiBiZSBz aGFyZWQKPiA+IHRvIHRoZSBWRFVTRSB1c2Vyc3BhY2UgcHJvY2Vzc3MgdmlhIHRyYW5zZmVycmlu ZyB0aGUgc2htZmQuCj4gPgo+ID4gRm9yIG1vcmUgZGV0YWlscyBvbiBWRFVTRSBkZXNpZ24gYW5k IHVzYWdlLCBwbGVhc2Ugc2VlIHRoZSBmb2xsb3ctb24KPiA+IERvY3VtZW50YXRpb24gY29tbWl0 Lgo+ID4KPiA+IFNpZ25lZC1vZmYtYnk6IFhpZSBZb25namkgPHhpZXlvbmdqaUBieXRlZGFuY2Uu Y29tPgo+ID4gLS0tCj4gPiAgIERvY3VtZW50YXRpb24vdXNlcnNwYWNlLWFwaS9pb2N0bC9pb2N0 bC1udW1iZXIucnN0IHwgICAgMSArCj4gPiAgIGRyaXZlcnMvdmRwYS9LY29uZmlnICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAxMCArCj4gPiAgIGRyaXZlcnMvdmRwYS9NYWtlZmls ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgMSArCj4gPiAgIGRyaXZlcnMvdmRw YS92ZHBhX3VzZXIvTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgIHwgICAgNSArCj4gPiAgIGRy aXZlcnMvdmRwYS92ZHBhX3VzZXIvdmR1c2VfZGV2LmMgICAgICAgICAgICAgICAgIHwgMTUwMiAr KysrKysrKysrKysrKysrKysrKwo+ID4gICBpbmNsdWRlL3VhcGkvbGludXgvdmR1c2UuaCAgICAg ICAgICAgICAgICAgICAgICAgICB8ICAyMjEgKysrCj4gPiAgIDYgZmlsZXMgY2hhbmdlZCwgMTc0 MCBpbnNlcnRpb25zKCspCj4gPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3ZkcGEvdmRw YV91c2VyL01ha2VmaWxlCj4gPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3ZkcGEvdmRw YV91c2VyL3ZkdXNlX2Rldi5jCj4gPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBpbmNsdWRlL3VhcGkv bGludXgvdmR1c2UuaAo+ID4KPiA+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL3VzZXJzcGFj ZS1hcGkvaW9jdGwvaW9jdGwtbnVtYmVyLnJzdCBiL0RvY3VtZW50YXRpb24vdXNlcnNwYWNlLWFw aS9pb2N0bC9pb2N0bC1udW1iZXIucnN0Cj4gPiBpbmRleCAxNDA5ZTQwZTYzNDUuLjI5M2NhM2Fl ZjM1OCAxMDA2NDQKPiA+IC0tLSBhL0RvY3VtZW50YXRpb24vdXNlcnNwYWNlLWFwaS9pb2N0bC9p b2N0bC1udW1iZXIucnN0Cj4gPiArKysgYi9Eb2N1bWVudGF0aW9uL3VzZXJzcGFjZS1hcGkvaW9j dGwvaW9jdGwtbnVtYmVyLnJzdAo+ID4gQEAgLTMwMCw2ICszMDAsNyBAQCBDb2RlICBTZXEjICAg IEluY2x1ZGUgRmlsZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBD b21tZW50cwo+ID4gICAneicgICAxMC00RiAgZHJpdmVycy9zMzkwL2NyeXB0by96Y3J5cHRfYXBp LmggICAgICAgICAgICAgICAgICAgICAgICBjb25mbGljdCEKPiA+ICAgJ3wnICAgMDAtN0YgIGxp bnV4L21lZGlhLmgKPiA+ICAgMHg4MCAgMDAtMUYgIGxpbnV4L2ZiLmgKPiA+ICsweDgxICAwMC0x RiAgbGludXgvdmR1c2UuaAo+ID4gICAweDg5ICAwMC0wNiAgYXJjaC94ODYvaW5jbHVkZS9hc20v c29ja2lvcy5oCj4gPiAgIDB4ODkgIDBCLURGICBsaW51eC9zb2NraW9zLmgKPiA+ICAgMHg4OSAg RTAtRUYgIGxpbnV4L3NvY2tpb3MuaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgU0lPQ1BST1RPUFJJVkFURSByYW5nZQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdmRw YS9LY29uZmlnIGIvZHJpdmVycy92ZHBhL0tjb25maWcKPiA+IGluZGV4IGE1MDNjMWIyYmZkOS4u NmUyM2JjZTY0MzNhIDEwMDY0NAo+ID4gLS0tIGEvZHJpdmVycy92ZHBhL0tjb25maWcKPiA+ICsr KyBiL2RyaXZlcnMvdmRwYS9LY29uZmlnCj4gPiBAQCAtMzMsNiArMzMsMTYgQEAgY29uZmlnIFZE UEFfU0lNX0JMT0NLCj4gPiAgICAgICAgIHZEUEEgYmxvY2sgZGV2aWNlIHNpbXVsYXRvciB3aGlj aCB0ZXJtaW5hdGVzIElPIHJlcXVlc3QgaW4gYQo+ID4gICAgICAgICBtZW1vcnkgYnVmZmVyLgo+ ID4KPiA+ICtjb25maWcgVkRQQV9VU0VSCj4gPiArICAgICB0cmlzdGF0ZSAiVkRVU0UgKHZEUEEg RGV2aWNlIGluIFVzZXJzcGFjZSkgc3VwcG9ydCIKPiA+ICsgICAgIGRlcGVuZHMgb24gRVZFTlRG RCAmJiBNTVUgJiYgSEFTX0RNQQo+ID4gKyAgICAgc2VsZWN0IERNQV9PUFMKPiA+ICsgICAgIHNl bGVjdCBWSE9TVF9JT1RMQgo+ID4gKyAgICAgc2VsZWN0IElPTU1VX0lPVkEKPiA+ICsgICAgIGhl bHAKPiA+ICsgICAgICAgV2l0aCBWRFVTRSBpdCBpcyBwb3NzaWJsZSB0byBlbXVsYXRlIGEgdkRQ QSBEZXZpY2UKPiA+ICsgICAgICAgaW4gYSB1c2Vyc3BhY2UgcHJvZ3JhbS4KPiA+ICsKPiA+ICAg Y29uZmlnIElGQ1ZGCj4gPiAgICAgICB0cmlzdGF0ZSAiSW50ZWwgSUZDIFZGIHZEUEEgZHJpdmVy Igo+ID4gICAgICAgZGVwZW5kcyBvbiBQQ0lfTVNJCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy92 ZHBhL01ha2VmaWxlIGIvZHJpdmVycy92ZHBhL01ha2VmaWxlCj4gPiBpbmRleCA2N2ZlN2YzZDY5 NDMuLmYwMmViZWQzM2YxOSAxMDA2NDQKPiA+IC0tLSBhL2RyaXZlcnMvdmRwYS9NYWtlZmlsZQo+ ID4gKysrIGIvZHJpdmVycy92ZHBhL01ha2VmaWxlCj4gPiBAQCAtMSw2ICsxLDcgQEAKPiA+ICAg IyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ID4gICBvYmotJChDT05GSUdfVkRQ QSkgKz0gdmRwYS5vCj4gPiAgIG9iai0kKENPTkZJR19WRFBBX1NJTSkgKz0gdmRwYV9zaW0vCj4g PiArb2JqLSQoQ09ORklHX1ZEUEFfVVNFUikgKz0gdmRwYV91c2VyLwo+ID4gICBvYmotJChDT05G SUdfSUZDVkYpICAgICs9IGlmY3ZmLwo+ID4gICBvYmotJChDT05GSUdfTUxYNV9WRFBBKSArPSBt bHg1Lwo+ID4gICBvYmotJChDT05GSUdfVlBfVkRQQSkgICAgKz0gdmlydGlvX3BjaS8KPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3ZkcGEvdmRwYV91c2VyL01ha2VmaWxlIGIvZHJpdmVycy92ZHBh L3ZkcGFfdXNlci9NYWtlZmlsZQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiA+IGluZGV4IDAw MDAwMDAwMDAwMC4uMjYwZTBiMjZhZjk5Cj4gPiAtLS0gL2Rldi9udWxsCj4gPiArKysgYi9kcml2 ZXJzL3ZkcGEvdmRwYV91c2VyL01ha2VmaWxlCj4gPiBAQCAtMCwwICsxLDUgQEAKPiA+ICsjIFNQ RFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wCj4gPiArCj4gPiArdmR1c2UteSA6PSB2ZHVz ZV9kZXYubyBpb3ZhX2RvbWFpbi5vCj4gPiArCj4gPiArb2JqLSQoQ09ORklHX1ZEUEFfVVNFUikg Kz0gdmR1c2Uubwo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdmRwYS92ZHBhX3VzZXIvdmR1c2Vf ZGV2LmMgYi9kcml2ZXJzL3ZkcGEvdmRwYV91c2VyL3ZkdXNlX2Rldi5jCj4gPiBuZXcgZmlsZSBt b2RlIDEwMDY0NAo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi5jOTk0YTRhNDY2MGMKPiA+IC0tLSAv ZGV2L251bGwKPiA+ICsrKyBiL2RyaXZlcnMvdmRwYS92ZHBhX3VzZXIvdmR1c2VfZGV2LmMKPiA+ IEBAIC0wLDAgKzEsMTUwMiBAQAo+ID4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwt Mi4wLW9ubHkKPiA+ICsvKgo+ID4gKyAqIFZEVVNFOiB2RFBBIERldmljZSBpbiBVc2Vyc3BhY2UK PiA+ICsgKgo+ID4gKyAqIENvcHlyaWdodCAoQykgMjAyMC0yMDIxIEJ5dGVkYW5jZSBJbmMuIGFu ZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KPiA+ICsgKgo+ID4gKyAq IEF1dGhvcjogWGllIFlvbmdqaSA8eGlleW9uZ2ppQGJ5dGVkYW5jZS5jb20+Cj4gPiArICoKPiA+ ICsgKi8KPiA+ICsKPiA+ICsjaW5jbHVkZSA8bGludXgvaW5pdC5oPgo+ID4gKyNpbmNsdWRlIDxs aW51eC9tb2R1bGUuaD4KPiA+ICsjaW5jbHVkZSA8bGludXgvY2Rldi5oPgo+ID4gKyNpbmNsdWRl IDxsaW51eC9kZXZpY2UuaD4KPiA+ICsjaW5jbHVkZSA8bGludXgvZXZlbnRmZC5oPgo+ID4gKyNp bmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3dhaXQuaD4KPiA+ICsj aW5jbHVkZSA8bGludXgvZG1hLW1hcC1vcHMuaD4KPiA+ICsjaW5jbHVkZSA8bGludXgvcG9sbC5o Pgo+ID4gKyNpbmNsdWRlIDxsaW51eC9maWxlLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L3Vpby5o Pgo+ID4gKyNpbmNsdWRlIDxsaW51eC92ZHBhLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4L25vc3Bl Yy5oPgo+ID4gKyNpbmNsdWRlIDx1YXBpL2xpbnV4L3ZkdXNlLmg+Cj4gPiArI2luY2x1ZGUgPHVh cGkvbGludXgvdmRwYS5oPgo+ID4gKyNpbmNsdWRlIDx1YXBpL2xpbnV4L3ZpcnRpb19jb25maWcu aD4KPiA+ICsjaW5jbHVkZSA8dWFwaS9saW51eC92aXJ0aW9faWRzLmg+Cj4gPiArI2luY2x1ZGUg PHVhcGkvbGludXgvdmlydGlvX2Jsay5oPgo+ID4gKyNpbmNsdWRlIDxsaW51eC9tb2RfZGV2aWNl dGFibGUuaD4KPiA+ICsKPiA+ICsjaW5jbHVkZSAiaW92YV9kb21haW4uaCIKPiA+ICsKPiA+ICsj ZGVmaW5lIERSVl9BVVRIT1IgICAiWW9uZ2ppIFhpZSA8eGlleW9uZ2ppQGJ5dGVkYW5jZS5jb20+ Igo+ID4gKyNkZWZpbmUgRFJWX0RFU0MgICAgICJ2RFBBIERldmljZSBpbiBVc2Vyc3BhY2UiCj4g PiArI2RlZmluZSBEUlZfTElDRU5TRSAgIkdQTCB2MiIKPiA+ICsKPiA+ICsjZGVmaW5lIFZEVVNF X0RFVl9NQVggKDFVIDw8IE1JTk9SQklUUykKPiA+ICsjZGVmaW5lIFZEVVNFX01BWF9CT1VOQ0Vf U0laRSAoNjQgKiAxMDI0ICogMTAyNCkKPiA+ICsjZGVmaW5lIFZEVVNFX0lPVkFfU0laRSAoMTI4 ICogMTAyNCAqIDEwMjQpCj4gPiArI2RlZmluZSBWRFVTRV9SRVFVRVNUX1RJTUVPVVQgMzAKPiA+ ICsKPiA+ICtzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlIHsKPiA+ICsgICAgIHUxNiBpbmRleDsKPiA+ ICsgICAgIHUxNiBudW1fbWF4Owo+ID4gKyAgICAgdTMyIG51bTsKPiA+ICsgICAgIHU2NCBkZXNj X2FkZHI7Cj4gPiArICAgICB1NjQgZHJpdmVyX2FkZHI7Cj4gPiArICAgICB1NjQgZGV2aWNlX2Fk ZHI7Cj4gPiArICAgICBzdHJ1Y3QgdmRwYV92cV9zdGF0ZSBzdGF0ZTsKPiA+ICsgICAgIGJvb2wg cmVhZHk7Cj4gPiArICAgICBib29sIGtpY2tlZDsKPiA+ICsgICAgIHNwaW5sb2NrX3Qga2lja19s b2NrOwo+ID4gKyAgICAgc3BpbmxvY2tfdCBpcnFfbG9jazsKPiA+ICsgICAgIHN0cnVjdCBldmVu dGZkX2N0eCAqa2lja2ZkOwo+ID4gKyAgICAgc3RydWN0IHZkcGFfY2FsbGJhY2sgY2I7Cj4gPiAr ICAgICBzdHJ1Y3Qgd29ya19zdHJ1Y3QgaW5qZWN0Owo+ID4gK307Cj4gPiArCj4gPiArc3RydWN0 IHZkdXNlX2RldjsKPiA+ICsKPiA+ICtzdHJ1Y3QgdmR1c2VfdmRwYSB7Cj4gPiArICAgICBzdHJ1 Y3QgdmRwYV9kZXZpY2UgdmRwYTsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldjsKPiA+ ICt9Owo+ID4gKwo+ID4gK3N0cnVjdCB2ZHVzZV9kZXYgewo+ID4gKyAgICAgc3RydWN0IHZkdXNl X3ZkcGEgKnZkZXY7Cj4gPiArICAgICBzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4gPiArICAgICBzdHJ1 Y3QgdmR1c2VfdmlydHF1ZXVlICp2cXM7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfaW92YV9kb21h aW4gKmRvbWFpbjsKPiA+ICsgICAgIGNoYXIgKm5hbWU7Cj4gPiArICAgICBzdHJ1Y3QgbXV0ZXgg bG9jazsKPiA+ICsgICAgIHNwaW5sb2NrX3QgbXNnX2xvY2s7Cj4gPiArICAgICB1NjQgbXNnX3Vu aXF1ZTsKPiA+ICsgICAgIHdhaXRfcXVldWVfaGVhZF90IHdhaXRxOwo+ID4gKyAgICAgc3RydWN0 IGxpc3RfaGVhZCBzZW5kX2xpc3Q7Cj4gPiArICAgICBzdHJ1Y3QgbGlzdF9oZWFkIHJlY3ZfbGlz dDsKPiA+ICsgICAgIHN0cnVjdCB2ZHBhX2NhbGxiYWNrIGNvbmZpZ19jYjsKPiA+ICsgICAgIHN0 cnVjdCB3b3JrX3N0cnVjdCBpbmplY3Q7Cj4gPiArICAgICBzcGlubG9ja190IGlycV9sb2NrOwo+ ID4gKyAgICAgaW50IG1pbm9yOwo+ID4gKyAgICAgYm9vbCBjb25uZWN0ZWQ7Cj4gPiArICAgICB1 NjQgYXBpX3ZlcnNpb247Cj4gPiArICAgICB1NjQgZGV2aWNlX2ZlYXR1cmVzOwo+ID4gKyAgICAg dTY0IGRyaXZlcl9mZWF0dXJlczsKPiA+ICsgICAgIHUzMiBkZXZpY2VfaWQ7Cj4gPiArICAgICB1 MzIgdmVuZG9yX2lkOwo+ID4gKyAgICAgdTMyIGdlbmVyYXRpb247Cj4gPiArICAgICB1MzIgY29u ZmlnX3NpemU7Cj4gPiArICAgICB2b2lkICpjb25maWc7Cj4gPiArICAgICB1OCBzdGF0dXM7Cj4g PiArICAgICB1MzIgdnFfbnVtOwo+ID4gKyAgICAgdTMyIHZxX2FsaWduOwo+ID4gK307Cj4gPiAr Cj4gPiArc3RydWN0IHZkdXNlX2Rldl9tc2cgewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2Rldl9y ZXF1ZXN0IHJlcTsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXZfcmVzcG9uc2UgcmVzcDsKPiA+ ICsgICAgIHN0cnVjdCBsaXN0X2hlYWQgbGlzdDsKPiA+ICsgICAgIHdhaXRfcXVldWVfaGVhZF90 IHdhaXRxOwo+ID4gKyAgICAgYm9vbCBjb21wbGV0ZWQ7Cj4gPiArfTsKPiA+ICsKPiA+ICtzdHJ1 Y3QgdmR1c2VfY29udHJvbCB7Cj4gPiArICAgICB1NjQgYXBpX3ZlcnNpb247Cj4gPiArfTsKPiA+ ICsKPiA+ICtzdGF0aWMgREVGSU5FX01VVEVYKHZkdXNlX2xvY2spOwo+ID4gK3N0YXRpYyBERUZJ TkVfSURSKHZkdXNlX2lkcik7Cj4gPiArCj4gPiArc3RhdGljIGRldl90IHZkdXNlX21ham9yOwo+ ID4gK3N0YXRpYyBzdHJ1Y3QgY2xhc3MgKnZkdXNlX2NsYXNzOwo+ID4gK3N0YXRpYyBzdHJ1Y3Qg Y2RldiB2ZHVzZV9jdHJsX2NkZXY7Cj4gPiArc3RhdGljIHN0cnVjdCBjZGV2IHZkdXNlX2NkZXY7 Cj4gPiArc3RhdGljIHN0cnVjdCB3b3JrcXVldWVfc3RydWN0ICp2ZHVzZV9pcnFfd3E7Cj4gPiAr Cj4gPiArc3RhdGljIHUzMiBhbGxvd2VkX2RldmljZV9pZFtdID0gewo+ID4gKyAgICAgVklSVElP X0lEX0JMT0NLLAo+ID4gK307Cj4gPiArCj4gPiArc3RhdGljIGlubGluZSBzdHJ1Y3QgdmR1c2Vf ZGV2ICp2ZHBhX3RvX3ZkdXNlKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSkKPiA+ICt7Cj4gPiAr ICAgICBzdHJ1Y3QgdmR1c2VfdmRwYSAqdmRldiA9IGNvbnRhaW5lcl9vZih2ZHBhLCBzdHJ1Y3Qg dmR1c2VfdmRwYSwgdmRwYSk7Cj4gPiArCj4gPiArICAgICByZXR1cm4gdmRldi0+ZGV2Owo+ID4g K30KPiA+ICsKPiA+ICtzdGF0aWMgaW5saW5lIHN0cnVjdCB2ZHVzZV9kZXYgKmRldl90b192ZHVz ZShzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkcGFfZGV2aWNl ICp2ZHBhID0gZGV2X3RvX3ZkcGEoZGV2KTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiB2ZHBhX3Rv X3ZkdXNlKHZkcGEpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgc3RydWN0IHZkdXNlX2Rldl9t c2cgKnZkdXNlX2ZpbmRfbXNnKHN0cnVjdCBsaXN0X2hlYWQgKmhlYWQsCj4gPiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCByZXF1ZXN0X2lkKQo+ID4g K3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXZfbXNnICptc2c7Cj4gPiArCj4gPiArICAgICBs aXN0X2Zvcl9lYWNoX2VudHJ5KG1zZywgaGVhZCwgbGlzdCkgewo+ID4gKyAgICAgICAgICAgICBp ZiAobXNnLT5yZXEucmVxdWVzdF9pZCA9PSByZXF1ZXN0X2lkKSB7Cj4gPiArICAgICAgICAgICAg ICAgICAgICAgbGlzdF9kZWwoJm1zZy0+bGlzdCk7Cj4gPiArICAgICAgICAgICAgICAgICAgICAg cmV0dXJuIG1zZzsKPiA+ICsgICAgICAgICAgICAgfQo+ID4gKyAgICAgfQo+ID4gKwo+ID4gKyAg ICAgcmV0dXJuIE5VTEw7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBzdHJ1Y3QgdmR1c2VfZGV2 X21zZyAqdmR1c2VfZGVxdWV1ZV9tc2coc3RydWN0IGxpc3RfaGVhZCAqaGVhZCkKPiA+ICt7Cj4g PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2X21zZyAqbXNnID0gTlVMTDsKPiA+ICsKPiA+ICsgICAg IGlmICghbGlzdF9lbXB0eShoZWFkKSkgewo+ID4gKyAgICAgICAgICAgICBtc2cgPSBsaXN0X2Zp cnN0X2VudHJ5KGhlYWQsIHN0cnVjdCB2ZHVzZV9kZXZfbXNnLCBsaXN0KTsKPiA+ICsgICAgICAg ICAgICAgbGlzdF9kZWwoJm1zZy0+bGlzdCk7Cj4gPiArICAgICB9Cj4gPiArCj4gPiArICAgICBy ZXR1cm4gbXNnOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2ZHVzZV9lbnF1ZXVlX21z ZyhzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkLAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg IHN0cnVjdCB2ZHVzZV9kZXZfbXNnICptc2cpCj4gPiArewo+ID4gKyAgICAgbGlzdF9hZGRfdGFp bCgmbXNnLT5saXN0LCBoZWFkKTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGludCB2ZHVzZV9k ZXZfbXNnX3N5bmMoc3RydWN0IHZkdXNlX2RldiAqZGV2LAo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgIHN0cnVjdCB2ZHVzZV9kZXZfbXNnICptc2cpCj4gPiArewo+ID4gKyAgICAgaW50 IHJldDsKPiA+ICsKPiA+ICsgICAgIGluaXRfd2FpdHF1ZXVlX2hlYWQoJm1zZy0+d2FpdHEpOwo+ ID4gKyAgICAgc3Bpbl9sb2NrKCZkZXYtPm1zZ19sb2NrKTsKPiA+ICsgICAgIG1zZy0+cmVxLnJl cXVlc3RfaWQgPSBkZXYtPm1zZ191bmlxdWUrKzsKPiA+ICsgICAgIHZkdXNlX2VucXVldWVfbXNn KCZkZXYtPnNlbmRfbGlzdCwgbXNnKTsKPiA+ICsgICAgIHdha2VfdXAoJmRldi0+d2FpdHEpOwo+ ID4gKyAgICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ID4gKwo+ID4gKyAgICAgd2Fp dF9ldmVudF9raWxsYWJsZV90aW1lb3V0KG1zZy0+d2FpdHEsIG1zZy0+Y29tcGxldGVkLAo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZEVVNFX1JFUVVFU1RfVElNRU9VVCAq IEhaKTsKPiA+ICsgICAgIHNwaW5fbG9jaygmZGV2LT5tc2dfbG9jayk7Cj4gPiArICAgICBpZiAo IW1zZy0+Y29tcGxldGVkKSB7Cj4gPiArICAgICAgICAgICAgIGxpc3RfZGVsKCZtc2ctPmxpc3Qp Owo+ID4gKyAgICAgICAgICAgICBtc2ctPnJlc3AucmVzdWx0ID0gVkRVU0VfUkVRX1JFU1VMVF9G QUlMRUQ7Cj4gPiArICAgICB9Cj4gPiArICAgICByZXQgPSAobXNnLT5yZXNwLnJlc3VsdCA9PSBW RFVTRV9SRVFfUkVTVUxUX09LKSA/IDAgOiAtRUlPOwo+Cj4KPiBJIHRoaW5rIHdlIHNob3VsZCBt YXJrIHRoZSBkZXZpY2UgYXMgbWFsZnVuY3Rpb24gd2hlbiB0aGVyZSBpcyBhIHRpbWVvdXQKPiBh bmQgZm9yYmlkIGFueSB1c2Vyc3BhY2Ugb3BlcmF0aW9ucyBleGNlcHQgZm9yIHRoZSBkZXN0cm95 IGFmdHdhcmRzIGZvcgo+IHNhZmV0eS4KPgoKSXMgaXQgbmVjZXNzYXJ5PyBBY3R1YWxseSB3ZSBj YW4ndCBzdG9wIHRoZSBkYXRhcGxhbmUgcHJvY2Vzc2luZyBpbgp1c2Vyc3BhY2UuIEl0IGRvZXNu 4oCZdCBzZWVtIHRvIGhlbHAgbXVjaCBpZiB3ZSBvbmx5IGZvcmJpZCBpb2N0bCBhbmQKcmVhZC93 cml0ZS4gQW5kIHRoZXJlIG1pZ2h0IGJlIHNvbWUgbWVzc2FnZXMgdGhhdCBjYW4gdG9sZXJhdGUK ZmFpbHVyZS4gRXZlbiB1c2Vyc3BhY2UgY2FuIGRvIHNvbWV0aGluZyBsaWtlIE5FRURTX1JFU0VU IHRvIGRvCnJlY292ZXJ5LgoKPgo+ID4gKyAgICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2sp Owo+ID4gKwo+ID4gKyAgICAgcmV0dXJuIHJldDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGlu dCB2ZHVzZV9kZXZfZ2V0X3ZxX3N0YXRlX3BhY2tlZChzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYsCj4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2Vfdmly dHF1ZXVlICp2cSwKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0 cnVjdCB2ZHBhX3ZxX3N0YXRlX3BhY2tlZCAqcGFja2VkKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVj dCB2ZHVzZV9kZXZfbXNnIG1zZyA9IHsgMCB9Owo+ID4gKyAgICAgaW50IHJldDsKPiA+ICsKPiA+ ICsgICAgIG1zZy5yZXEudHlwZSA9IFZEVVNFX0dFVF9WUV9TVEFURTsKPiA+ICsgICAgIG1zZy5y ZXEudnFfc3RhdGUuaW5kZXggPSB2cS0+aW5kZXg7Cj4gPiArCj4gPiArICAgICByZXQgPSB2ZHVz ZV9kZXZfbXNnX3N5bmMoZGV2LCAmbXNnKTsKPiA+ICsgICAgIGlmIChyZXQpCj4gPiArICAgICAg ICAgICAgIHJldHVybiByZXQ7Cj4gPiArCj4gPiArICAgICBwYWNrZWQtPmxhc3RfYXZhaWxfY291 bnRlciA9Cj4gPiArICAgICAgICAgICAgICAgICAgICAgbXNnLnJlc3AudnFfc3RhdGUucGFja2Vk Lmxhc3RfYXZhaWxfY291bnRlcjsKPiA+ICsgICAgIHBhY2tlZC0+bGFzdF9hdmFpbF9pZHggPSBt c2cucmVzcC52cV9zdGF0ZS5wYWNrZWQubGFzdF9hdmFpbF9pZHg7Cj4gPiArICAgICBwYWNrZWQt Pmxhc3RfdXNlZF9jb3VudGVyID0gbXNnLnJlc3AudnFfc3RhdGUucGFja2VkLmxhc3RfdXNlZF9j b3VudGVyOwo+ID4gKyAgICAgcGFja2VkLT5sYXN0X3VzZWRfaWR4ID0gbXNnLnJlc3AudnFfc3Rh dGUucGFja2VkLmxhc3RfdXNlZF9pZHg7Cj4gPiArCj4gPiArICAgICByZXR1cm4gMDsKPiA+ICt9 Cj4gPiArCj4gPiArc3RhdGljIGludCB2ZHVzZV9kZXZfZ2V0X3ZxX3N0YXRlX3NwbGl0KHN0cnVj dCB2ZHVzZV9kZXYgKmRldiwKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgc3RydWN0IHZkdXNlX3ZpcnRxdWV1ZSAqdnEsCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHN0cnVjdCB2ZHBhX3ZxX3N0YXRlX3NwbGl0ICpzcGxpdCkKPiA+ICt7 Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2X21zZyBtc2cgPSB7IDAgfTsKPiA+ICsgICAgIGlu dCByZXQ7Cj4gPiArCj4gPiArICAgICBtc2cucmVxLnR5cGUgPSBWRFVTRV9HRVRfVlFfU1RBVEU7 Cj4gPiArICAgICBtc2cucmVxLnZxX3N0YXRlLmluZGV4ID0gdnEtPmluZGV4Owo+ID4gKwo+ID4g KyAgICAgcmV0ID0gdmR1c2VfZGV2X21zZ19zeW5jKGRldiwgJm1zZyk7Cj4gPiArICAgICBpZiAo cmV0KQo+ID4gKyAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ID4gKwo+ID4gKyAgICAgc3BsaXQt PmF2YWlsX2luZGV4ID0gbXNnLnJlc3AudnFfc3RhdGUuc3BsaXQuYXZhaWxfaW5kZXg7Cj4gPiAr Cj4gPiArICAgICByZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGludCB2ZHVzZV9k ZXZfc2V0X3N0YXR1cyhzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYsIHU4IHN0YXR1cykKPiA+ICt7Cj4g PiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2X21zZyBtc2cgPSB7IDAgfTsKPiA+ICsKPiA+ICsgICAg IG1zZy5yZXEudHlwZSA9IFZEVVNFX1NFVF9TVEFUVVM7Cj4gPiArICAgICBtc2cucmVxLnMuc3Rh dHVzID0gc3RhdHVzOwo+ID4gKwo+ID4gKyAgICAgcmV0dXJuIHZkdXNlX2Rldl9tc2dfc3luYyhk ZXYsICZtc2cpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IHZkdXNlX2Rldl91cGRhdGVf aW90bGIoc3RydWN0IHZkdXNlX2RldiAqZGV2LAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICB1NjQgc3RhcnQsIHU2NCBsYXN0KQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVz ZV9kZXZfbXNnIG1zZyA9IHsgMCB9Owo+ID4gKwo+ID4gKyAgICAgaWYgKGxhc3QgPCBzdGFydCkK PiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gPiArCj4gPiArICAgICBtc2cucmVx LnR5cGUgPSBWRFVTRV9VUERBVEVfSU9UTEI7Cj4gPiArICAgICBtc2cucmVxLmlvdmEuc3RhcnQg PSBzdGFydDsKPiA+ICsgICAgIG1zZy5yZXEuaW92YS5sYXN0ID0gbGFzdDsKPiA+ICsKPiA+ICsg ICAgIHJldHVybiB2ZHVzZV9kZXZfbXNnX3N5bmMoZGV2LCAmbXNnKTsKPiA+ICt9Cj4gPiArCj4g PiArc3RhdGljIHNzaXplX3QgdmR1c2VfZGV2X3JlYWRfaXRlcihzdHJ1Y3Qga2lvY2IgKmlvY2Is IHN0cnVjdCBpb3ZfaXRlciAqdG8pCj4gPiArewo+ID4gKyAgICAgc3RydWN0IGZpbGUgKmZpbGUg PSBpb2NiLT5raV9maWxwOwo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gZmlsZS0+ cHJpdmF0ZV9kYXRhOwo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2Rldl9tc2cgKm1zZzsKPiA+ICsg ICAgIGludCBzaXplID0gc2l6ZW9mKHN0cnVjdCB2ZHVzZV9kZXZfcmVxdWVzdCk7Cj4gPiArICAg ICBzc2l6ZV90IHJldDsKPiA+ICsKPiA+ICsgICAgIGlmIChpb3ZfaXRlcl9jb3VudCh0bykgPCBz aXplKQo+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiA+ICsKPiA+ICsgICAgIHNw aW5fbG9jaygmZGV2LT5tc2dfbG9jayk7Cj4gPiArICAgICB3aGlsZSAoMSkgewo+ID4gKyAgICAg ICAgICAgICBtc2cgPSB2ZHVzZV9kZXF1ZXVlX21zZygmZGV2LT5zZW5kX2xpc3QpOwo+ID4gKyAg ICAgICAgICAgICBpZiAobXNnKQo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4g Kwo+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUFHQUlOOwo+ID4gKyAgICAgICAgICAgICBpZiAo ZmlsZS0+Zl9mbGFncyAmIE9fTk9OQkxPQ0spCj4gPiArICAgICAgICAgICAgICAgICAgICAgZ290 byB1bmxvY2s7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHNwaW5fdW5sb2NrKCZkZXYtPm1zZ19s b2NrKTsKPiA+ICsgICAgICAgICAgICAgcmV0ID0gd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlX2V4 Y2x1c2l2ZShkZXYtPndhaXRxLAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAhbGlzdF9lbXB0eSgmZGV2LT5zZW5kX2xpc3QpKTsKPiA+ICsgICAgICAgICAgICAgaWYg KHJldCkKPiA+ICsgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ID4gKwo+ID4gKyAg ICAgICAgICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xvY2spOwo+ID4gKyAgICAgfQo+ID4gKyAg ICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ID4gKyAgICAgcmV0ID0gY29weV90b19p dGVyKCZtc2ctPnJlcSwgc2l6ZSwgdG8pOwo+ID4gKyAgICAgc3Bpbl9sb2NrKCZkZXYtPm1zZ19s b2NrKTsKPiA+ICsgICAgIGlmIChyZXQgIT0gc2l6ZSkgewo+ID4gKyAgICAgICAgICAgICByZXQg PSAtRUZBVUxUOwo+ID4gKyAgICAgICAgICAgICB2ZHVzZV9lbnF1ZXVlX21zZygmZGV2LT5zZW5k X2xpc3QsIG1zZyk7Cj4gPiArICAgICAgICAgICAgIGdvdG8gdW5sb2NrOwo+ID4gKyAgICAgfQo+ ID4gKyAgICAgdmR1c2VfZW5xdWV1ZV9tc2coJmRldi0+cmVjdl9saXN0LCBtc2cpOwo+ID4gK3Vu bG9jazoKPiA+ICsgICAgIHNwaW5fdW5sb2NrKCZkZXYtPm1zZ19sb2NrKTsKPiA+ICsKPiA+ICsg ICAgIHJldHVybiByZXQ7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBzc2l6ZV90IHZkdXNlX2Rl dl93cml0ZV9pdGVyKHN0cnVjdCBraW9jYiAqaW9jYiwgc3RydWN0IGlvdl9pdGVyICpmcm9tKQo+ ID4gK3sKPiA+ICsgICAgIHN0cnVjdCBmaWxlICpmaWxlID0gaW9jYi0+a2lfZmlscDsKPiA+ICsg ICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IGZpbGUtPnByaXZhdGVfZGF0YTsKPiA+ICsgICAg IHN0cnVjdCB2ZHVzZV9kZXZfcmVzcG9uc2UgcmVzcDsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9k ZXZfbXNnICptc2c7Cj4gPiArICAgICBzaXplX3QgcmV0Owo+ID4gKwo+ID4gKyAgICAgcmV0ID0g Y29weV9mcm9tX2l0ZXIoJnJlc3AsIHNpemVvZihyZXNwKSwgZnJvbSk7Cj4gPiArICAgICBpZiAo cmV0ICE9IHNpemVvZihyZXNwKSkKPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4g PiArCj4gPiArICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xvY2spOwo+ID4gKyAgICAgbXNnID0g dmR1c2VfZmluZF9tc2coJmRldi0+cmVjdl9saXN0LCByZXNwLnJlcXVlc3RfaWQpOwo+ID4gKyAg ICAgaWYgKCFtc2cpIHsKPiA+ICsgICAgICAgICAgICAgcmV0ID0gLUVOT0VOVDsKPiA+ICsgICAg ICAgICAgICAgZ290byB1bmxvY2s7Cj4gPiArICAgICB9Cj4gPiArCj4gPiArICAgICBtZW1jcHko Jm1zZy0+cmVzcCwgJnJlc3AsIHNpemVvZihyZXNwKSk7Cj4gPiArICAgICBtc2ctPmNvbXBsZXRl ZCA9IDE7Cj4gPiArICAgICB3YWtlX3VwKCZtc2ctPndhaXRxKTsKPiA+ICt1bmxvY2s6Cj4gPiAr ICAgICBzcGluX3VubG9jaygmZGV2LT5tc2dfbG9jayk7Cj4gPiArCj4gPiArICAgICByZXR1cm4g cmV0Owo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgX19wb2xsX3QgdmR1c2VfZGV2X3BvbGwoc3Ry dWN0IGZpbGUgKmZpbGUsIHBvbGxfdGFibGUgKndhaXQpCj4gPiArewo+ID4gKyAgICAgc3RydWN0 IHZkdXNlX2RldiAqZGV2ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ID4gKyAgICAgX19wb2xsX3Qg bWFzayA9IDA7Cj4gPiArCj4gPiArICAgICBwb2xsX3dhaXQoZmlsZSwgJmRldi0+d2FpdHEsIHdh aXQpOwo+ID4gKwo+ID4gKyAgICAgaWYgKCFsaXN0X2VtcHR5KCZkZXYtPnNlbmRfbGlzdCkpCj4g PiArICAgICAgICAgICAgIG1hc2sgfD0gRVBPTExJTiB8IEVQT0xMUkROT1JNOwo+ID4gKyAgICAg aWYgKCFsaXN0X2VtcHR5KCZkZXYtPnJlY3ZfbGlzdCkpCj4gPiArICAgICAgICAgICAgIG1hc2sg fD0gRVBPTExPVVQgfCBFUE9MTFdSTk9STTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiBtYXNrOwo+ ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2ZHVzZV9kZXZfcmVzZXQoc3RydWN0IHZkdXNl X2RldiAqZGV2KQo+ID4gK3sKPiA+ICsgICAgIGludCBpOwo+ID4gKyAgICAgc3RydWN0IHZkdXNl X2lvdmFfZG9tYWluICpkb21haW4gPSBkZXYtPmRvbWFpbjsKPiA+ICsKPiA+ICsgICAgIC8qIFRo ZSBjb2hlcmVudCBtYXBwaW5ncyBhcmUgaGFuZGxlZCBpbiB2ZHVzZV9kZXZfZnJlZV9jb2hlcmVu dCgpICovCj4gPiArICAgICBpZiAoZG9tYWluLT5ib3VuY2VfbWFwKQo+ID4gKyAgICAgICAgICAg ICB2ZHVzZV9kb21haW5fcmVzZXRfYm91bmNlX21hcChkb21haW4pOwo+ID4gKwo+ID4gKyAgICAg ZGV2LT5kcml2ZXJfZmVhdHVyZXMgPSAwOwo+ID4gKyAgICAgZGV2LT5nZW5lcmF0aW9uKys7Cj4g PiArICAgICBzcGluX2xvY2soJmRldi0+aXJxX2xvY2spOwo+ID4gKyAgICAgZGV2LT5jb25maWdf Y2IuY2FsbGJhY2sgPSBOVUxMOwo+ID4gKyAgICAgZGV2LT5jb25maWdfY2IucHJpdmF0ZSA9IE5V TEw7Cj4gPiArICAgICBzcGluX3VubG9jaygmZGV2LT5pcnFfbG9jayk7Cj4gPiArICAgICBmbHVz aF93b3JrKCZkZXYtPmluamVjdCk7Cj4gPiArCj4gPiArICAgICBmb3IgKGkgPSAwOyBpIDwgZGV2 LT52cV9udW07IGkrKykgewo+ID4gKyAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVl ICp2cSA9ICZkZXYtPnZxc1tpXTsKPiA+ICsKPiA+ICsgICAgICAgICAgICAgdnEtPnJlYWR5ID0g ZmFsc2U7Cj4gPiArICAgICAgICAgICAgIHZxLT5kZXNjX2FkZHIgPSAwOwo+ID4gKyAgICAgICAg ICAgICB2cS0+ZHJpdmVyX2FkZHIgPSAwOwo+ID4gKyAgICAgICAgICAgICB2cS0+ZGV2aWNlX2Fk ZHIgPSAwOwo+ID4gKyAgICAgICAgICAgICB2cS0+bnVtID0gMDsKPiA+ICsgICAgICAgICAgICAg bWVtc2V0KCZ2cS0+c3RhdGUsIDAsIHNpemVvZih2cS0+c3RhdGUpKTsKPiA+ICsKPiA+ICsgICAg ICAgICAgICAgc3Bpbl9sb2NrKCZ2cS0+a2lja19sb2NrKTsKPiA+ICsgICAgICAgICAgICAgdnEt PmtpY2tlZCA9IGZhbHNlOwo+ID4gKyAgICAgICAgICAgICBpZiAodnEtPmtpY2tmZCkKPiA+ICsg ICAgICAgICAgICAgICAgICAgICBldmVudGZkX2N0eF9wdXQodnEtPmtpY2tmZCk7Cj4gPiArICAg ICAgICAgICAgIHZxLT5raWNrZmQgPSBOVUxMOwo+ID4gKyAgICAgICAgICAgICBzcGluX3VubG9j aygmdnEtPmtpY2tfbG9jayk7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHNwaW5fbG9jaygmdnEt PmlycV9sb2NrKTsKPiA+ICsgICAgICAgICAgICAgdnEtPmNiLmNhbGxiYWNrID0gTlVMTDsKPiA+ ICsgICAgICAgICAgICAgdnEtPmNiLnByaXZhdGUgPSBOVUxMOwo+ID4gKyAgICAgICAgICAgICBz cGluX3VubG9jaygmdnEtPmlycV9sb2NrKTsKPiA+ICsgICAgICAgICAgICAgZmx1c2hfd29yaygm dnEtPmluamVjdCk7Cj4gPiArICAgICB9Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgdmR1 c2VfdmRwYV9zZXRfdnFfYWRkcmVzcyhzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEsIHUxNiBpZHgs Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1NjQgZGVzY19hcmVhLCB1NjQgZHJp dmVyX2FyZWEsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1NjQgZGV2aWNlX2Fy ZWEpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVz ZSh2ZHBhKTsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV92aXJ0cXVldWUgKnZxID0gJmRldi0+dnFz W2lkeF07Cj4gPiArCj4gPiArICAgICB2cS0+ZGVzY19hZGRyID0gZGVzY19hcmVhOwo+ID4gKyAg ICAgdnEtPmRyaXZlcl9hZGRyID0gZHJpdmVyX2FyZWE7Cj4gPiArICAgICB2cS0+ZGV2aWNlX2Fk ZHIgPSBkZXZpY2VfYXJlYTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiAwOwo+ID4gK30KPiA+ICsK PiA+ICtzdGF0aWMgdm9pZCB2ZHVzZV92ZHBhX2tpY2tfdnEoc3RydWN0IHZkcGFfZGV2aWNlICp2 ZHBhLCB1MTYgaWR4KQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZk cGFfdG9fdmR1c2UodmRwYSk7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSA9 ICZkZXYtPnZxc1tpZHhdOwo+ID4gKwo+ID4gKyAgICAgc3Bpbl9sb2NrKCZ2cS0+a2lja19sb2Nr KTsKPiA+ICsgICAgIGlmICghdnEtPnJlYWR5KQo+ID4gKyAgICAgICAgICAgICBnb3RvIHVubG9j azsKPiA+ICsKPiA+ICsgICAgIGlmICh2cS0+a2lja2ZkKQo+ID4gKyAgICAgICAgICAgICBldmVu dGZkX3NpZ25hbCh2cS0+a2lja2ZkLCAxKTsKPiA+ICsgICAgIGVsc2UKPiA+ICsgICAgICAgICAg ICAgdnEtPmtpY2tlZCA9IHRydWU7Cj4gPiArdW5sb2NrOgo+ID4gKyAgICAgc3Bpbl91bmxvY2so JnZxLT5raWNrX2xvY2spOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2ZHVzZV92ZHBh X3NldF92cV9jYihzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEsIHUxNiBpZHgsCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHZkcGFfY2FsbGJhY2sgKmNiKQo+ID4gK3sKPiA+ ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPiAr ICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSA9ICZkZXYtPnZxc1tpZHhdOwo+ID4gKwo+ ID4gKyAgICAgc3Bpbl9sb2NrKCZ2cS0+aXJxX2xvY2spOwo+ID4gKyAgICAgdnEtPmNiLmNhbGxi YWNrID0gY2ItPmNhbGxiYWNrOwo+ID4gKyAgICAgdnEtPmNiLnByaXZhdGUgPSBjYi0+cHJpdmF0 ZTsKPiA+ICsgICAgIHNwaW5fdW5sb2NrKCZ2cS0+aXJxX2xvY2spOwo+ID4gK30KPiA+ICsKPiA+ ICtzdGF0aWMgdm9pZCB2ZHVzZV92ZHBhX3NldF92cV9udW0oc3RydWN0IHZkcGFfZGV2aWNlICp2 ZHBhLCB1MTYgaWR4LCB1MzIgbnVtKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYg KmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1 ZXVlICp2cSA9ICZkZXYtPnZxc1tpZHhdOwo+ID4gKwo+ID4gKyAgICAgdnEtPm51bSA9IG51bTsK PiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgdmR1c2VfdmRwYV9zZXRfdnFfcmVhZHkoc3Ry dWN0IHZkcGFfZGV2aWNlICp2ZHBhLAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICB1MTYgaWR4LCBib29sIHJlYWR5KQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVz ZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2Vf dmlydHF1ZXVlICp2cSA9ICZkZXYtPnZxc1tpZHhdOwo+ID4gKwo+ID4gKyAgICAgdnEtPnJlYWR5 ID0gcmVhZHk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBib29sIHZkdXNlX3ZkcGFfZ2V0X3Zx X3JlYWR5KHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwgdTE2IGlkeCkKPiA+ICt7Cj4gPiArICAg ICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ID4gKyAgICAg c3RydWN0IHZkdXNlX3ZpcnRxdWV1ZSAqdnEgPSAmZGV2LT52cXNbaWR4XTsKPiA+ICsKPiA+ICsg ICAgIHJldHVybiB2cS0+cmVhZHk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgdmR1c2Vf dmRwYV9zZXRfdnFfc3RhdGUoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhLCB1MTYgaWR4LAo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IHZkcGFfdnFfc3RhdGUg KnN0YXRlKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9f dmR1c2UodmRwYSk7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfdmlydHF1ZXVlICp2cSA9ICZkZXYt PnZxc1tpZHhdOwo+ID4gKwo+ID4gKyAgICAgaWYgKGRldi0+ZHJpdmVyX2ZlYXR1cmVzICYgQklU X1VMTChWSVJUSU9fRl9SSU5HX1BBQ0tFRCkpIHsKPiA+ICsgICAgICAgICAgICAgdnEtPnN0YXRl LnBhY2tlZC5sYXN0X2F2YWlsX2NvdW50ZXIgPQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgc3RhdGUtPnBhY2tlZC5sYXN0X2F2YWlsX2NvdW50ZXI7Cj4gPiArICAgICAgICAgICAg IHZxLT5zdGF0ZS5wYWNrZWQubGFzdF9hdmFpbF9pZHggPSBzdGF0ZS0+cGFja2VkLmxhc3RfYXZh aWxfaWR4Owo+ID4gKyAgICAgICAgICAgICB2cS0+c3RhdGUucGFja2VkLmxhc3RfdXNlZF9jb3Vu dGVyID0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLT5wYWNrZWQubGFz dF91c2VkX2NvdW50ZXI7Cj4gPiArICAgICAgICAgICAgIHZxLT5zdGF0ZS5wYWNrZWQubGFzdF91 c2VkX2lkeCA9IHN0YXRlLT5wYWNrZWQubGFzdF91c2VkX2lkeDsKPiA+ICsgICAgIH0gZWxzZQo+ ID4gKyAgICAgICAgICAgICB2cS0+c3RhdGUuc3BsaXQuYXZhaWxfaW5kZXggPSBzdGF0ZS0+c3Bs aXQuYXZhaWxfaW5kZXg7Cj4gPiArCj4gPiArICAgICByZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4g PiArc3RhdGljIGludCB2ZHVzZV92ZHBhX2dldF92cV9zdGF0ZShzdHJ1Y3QgdmRwYV9kZXZpY2Ug KnZkcGEsIHUxNiBpZHgsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qg dmRwYV92cV9zdGF0ZSAqc3RhdGUpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAq ZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV92aXJ0cXVl dWUgKnZxID0gJmRldi0+dnFzW2lkeF07Cj4gPiArCj4gPiArICAgICBpZiAoZGV2LT5kcml2ZXJf ZmVhdHVyZXMgJiBCSVRfVUxMKFZJUlRJT19GX1JJTkdfUEFDS0VEKSkKPiA+ICsgICAgICAgICAg ICAgcmV0dXJuIHZkdXNlX2Rldl9nZXRfdnFfc3RhdGVfcGFja2VkKGRldiwgdnEsICZzdGF0ZS0+ cGFja2VkKTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiB2ZHVzZV9kZXZfZ2V0X3ZxX3N0YXRlX3Nw bGl0KGRldiwgdnEsICZzdGF0ZS0+c3BsaXQpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdTMy IHZkdXNlX3ZkcGFfZ2V0X3ZxX2FsaWduKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSkKPiA+ICt7 Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ ID4gKwo+ID4gKyAgICAgcmV0dXJuIGRldi0+dnFfYWxpZ247Cj4gPiArfQo+ID4gKwo+ID4gK3N0 YXRpYyB1NjQgdmR1c2VfdmRwYV9nZXRfZmVhdHVyZXMoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBh KQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2Uo dmRwYSk7Cj4gPiArCj4gPiArICAgICByZXR1cm4gZGV2LT5kZXZpY2VfZmVhdHVyZXM7Cj4gPiAr fQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgdmR1c2VfdmRwYV9zZXRfZmVhdHVyZXMoc3RydWN0IHZk cGFfZGV2aWNlICp2ZHBhLCB1NjQgZmVhdHVyZXMpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZk dXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ICsKPiA+ICsgICAgIGRldi0+ ZHJpdmVyX2ZlYXR1cmVzID0gZmVhdHVyZXM7Cj4gPiArICAgICByZXR1cm4gMDsKPiA+ICt9Cj4g PiArCj4gPiArc3RhdGljIHZvaWQgdmR1c2VfdmRwYV9zZXRfY29uZmlnX2NiKHN0cnVjdCB2ZHBh X2RldmljZSAqdmRwYSwKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0 IHZkcGFfY2FsbGJhY2sgKmNiKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRl diA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPiArCj4gPiArICAgICBzcGluX2xvY2soJmRldi0+ aXJxX2xvY2spOwo+ID4gKyAgICAgZGV2LT5jb25maWdfY2IuY2FsbGJhY2sgPSBjYi0+Y2FsbGJh Y2s7Cj4gPiArICAgICBkZXYtPmNvbmZpZ19jYi5wcml2YXRlID0gY2ItPnByaXZhdGU7Cj4gPiAr ICAgICBzcGluX3VubG9jaygmZGV2LT5pcnFfbG9jayk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRp YyB1MTYgdmR1c2VfdmRwYV9nZXRfdnFfbnVtX21heChzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEs IHUxNiBpZHgpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90 b192ZHVzZSh2ZHBhKTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiBkZXYtPnZxc1tpZHhdLm51bV9t YXg7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB1MzIgdmR1c2VfdmRwYV9nZXRfZGV2aWNlX2lk KHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSkKPiA+ICt7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2Vf ZGV2ICpkZXYgPSB2ZHBhX3RvX3ZkdXNlKHZkcGEpOwo+ID4gKwo+ID4gKyAgICAgcmV0dXJuIGRl di0+ZGV2aWNlX2lkOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdTMyIHZkdXNlX3ZkcGFfZ2V0 X3ZlbmRvcl9pZChzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEpCj4gPiArewo+ID4gKyAgICAgc3Ry dWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ICsKPiA+ICsgICAg IHJldHVybiBkZXYtPnZlbmRvcl9pZDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHU4IHZkdXNl X3ZkcGFfZ2V0X3N0YXR1cyhzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEpCj4gPiArewo+ID4gKyAg ICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ICsKPiA+ ICsgICAgIHJldHVybiBkZXYtPnN0YXR1czsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQg dmR1c2VfdmRwYV9zZXRfc3RhdHVzKHN0cnVjdCB2ZHBhX2RldmljZSAqdmRwYSwgdTggc3RhdHVz KQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2Uo dmRwYSk7Cj4gPiArCj4gPiArICAgICBpZiAodmR1c2VfZGV2X3NldF9zdGF0dXMoZGV2LCBzdGF0 dXMpKQo+ID4gKyAgICAgICAgICAgICByZXR1cm47Cj4gPiArCj4gPiArICAgICBkZXYtPnN0YXR1 cyA9IHN0YXR1czsKPgo+Cj4gSXQgbG9va3MgdG8gbWUgc3VjaCBkZXNpZ24gZXhjbHVkZSB0aGUg cG9zc2liaWxpdHkgb2YgbGV0dGluZyB1c2Vyc3BhY2UKPiBkZXZpY2UgdG8gc2V0IGJpdCBsaWtl IChORUVEU19SRVNFVCkgaW4gdGhlIGZ1dHVyZS4KPgoKTG9va3MgbGlrZSB3ZSBjYW4gYWNoaWV2 ZSB0aGF0IHZpYSB0aGUgaW9jdGwuCgo+IEkgd29uZGVyIGlmIGl0J3MgYmV0dGVyIHRvIGRvIHNv bWV0aGluZyBzaW1pbGFyIHRvIGNjdzoKPgo+IDEpIHJlcXVpcmVzIHRoZSB1c2Vyc3BhY2UgdG8g dXBkYXRlIHRoZSBzdGF0dXMgYml0IGluIHRoZSByZXNwb25zZQo+IDIpIHVwZGF0ZSB0aGUgZGV2 LT5zdGF0dXMgdG8gdGhlIHN0YXR1cyBpbiB0aGUgcmVzcG9uc2UgaWYgbm8gdGltZW91dAo+Cj4g VGhlbiB1c2Vyc3BhY2UgY291bGQgdGhlbiBzZXQgTkVFRFNfUkVTRVQgaWYgbmVjZXNzYXJ5Lgo+ CgpCdXQgTkVFRFNfUkVTRVQgZG9lcyBub3Qgb25seSBoYXBwZW4gaW4gdGhpcyBjYXNlLgoKPgo+ ID4gKyAgICAgaWYgKHN0YXR1cyA9PSAwKQo+ID4gKyAgICAgICAgICAgICB2ZHVzZV9kZXZfcmVz ZXQoZGV2KTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHNpemVfdCB2ZHVzZV92ZHBhX2dldF9j b25maWdfc2l6ZShzdHJ1Y3QgdmRwYV9kZXZpY2UgKnZkcGEpCj4gPiArewo+ID4gKyAgICAgc3Ry dWN0IHZkdXNlX2RldiAqZGV2ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ICsKPiA+ICsgICAg IHJldHVybiBkZXYtPmNvbmZpZ19zaXplOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2 ZHVzZV92ZHBhX2dldF9jb25maWcoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhLCB1bnNpZ25lZCBp bnQgb2Zmc2V0LAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpidWYs IHVuc2lnbmVkIGludCBsZW4pCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2 ID0gdmRwYV90b192ZHVzZSh2ZHBhKTsKPiA+ICsKPiA+ICsgICAgIGlmIChsZW4gPiBkZXYtPmNv bmZpZ19zaXplIC0gb2Zmc2V0KQo+ID4gKyAgICAgICAgICAgICByZXR1cm47Cj4gPiArCj4gPiAr ICAgICBtZW1jcHkoYnVmLCBkZXYtPmNvbmZpZyArIG9mZnNldCwgbGVuKTsKPiA+ICt9Cj4gPiAr Cj4gPiArc3RhdGljIHZvaWQgdmR1c2VfdmRwYV9zZXRfY29uZmlnKHN0cnVjdCB2ZHBhX2Rldmlj ZSAqdmRwYSwgdW5zaWduZWQgaW50IG9mZnNldCwKPiA+ICsgICAgICAgICAgICAgICAgICAgICBj b25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCj4gPiArewo+ID4gKyAgICAgLyogTm93 IHdlIG9ubHkgc3VwcG9ydCByZWFkLW9ubHkgY29uZmlndXJhdGlvbiBzcGFjZSAqLwo+ID4gK30K PiA+ICsKPiA+ICtzdGF0aWMgdTMyIHZkdXNlX3ZkcGFfZ2V0X2dlbmVyYXRpb24oc3RydWN0IHZk cGFfZGV2aWNlICp2ZHBhKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9 IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPiArCj4gPiArICAgICByZXR1cm4gZGV2LT5nZW5lcmF0 aW9uOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IHZkdXNlX3ZkcGFfc2V0X21hcChzdHJ1 Y3QgdmRwYV9kZXZpY2UgKnZkcGEsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBz dHJ1Y3Qgdmhvc3RfaW90bGIgKmlvdGxiKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9k ZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRwYSk7Cj4gPiArICAgICBpbnQgcmV0Owo+ID4gKwo+ ID4gKyAgICAgcmV0ID0gdmR1c2VfZG9tYWluX3NldF9tYXAoZGV2LT5kb21haW4sIGlvdGxiKTsK PiA+ICsgICAgIGlmIChyZXQpCj4gPiArICAgICAgICAgICAgIHJldHVybiByZXQ7Cj4gPiArCj4g PiArICAgICByZXQgPSB2ZHVzZV9kZXZfdXBkYXRlX2lvdGxiKGRldiwgMFVMTCwgVUxMT05HX01B WCk7Cj4gPiArICAgICBpZiAocmV0KSB7Cj4gPiArICAgICAgICAgICAgIHZkdXNlX2RvbWFpbl9j bGVhcl9tYXAoZGV2LT5kb21haW4sIGlvdGxiKTsKPiA+ICsgICAgICAgICAgICAgcmV0dXJuIHJl dDsKPiA+ICsgICAgIH0KPiA+ICsKPiA+ICsgICAgIHJldHVybiAwOwo+ID4gK30KPiA+ICsKPiA+ ICtzdGF0aWMgdm9pZCB2ZHVzZV92ZHBhX2ZyZWUoc3RydWN0IHZkcGFfZGV2aWNlICp2ZHBhKQo+ ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKmRldiA9IHZkcGFfdG9fdmR1c2UodmRw YSk7Cj4gPiArCj4gPiArICAgICBkZXYtPnZkZXYgPSBOVUxMOwo+ID4gK30KPiA+ICsKPiA+ICtz dGF0aWMgY29uc3Qgc3RydWN0IHZkcGFfY29uZmlnX29wcyB2ZHVzZV92ZHBhX2NvbmZpZ19vcHMg PSB7Cj4gPiArICAgICAuc2V0X3ZxX2FkZHJlc3MgICAgICAgICA9IHZkdXNlX3ZkcGFfc2V0X3Zx X2FkZHJlc3MsCj4gPiArICAgICAua2lja192cSAgICAgICAgICAgICAgICA9IHZkdXNlX3ZkcGFf a2lja192cSwKPiA+ICsgICAgIC5zZXRfdnFfY2IgICAgICAgICAgICAgID0gdmR1c2VfdmRwYV9z ZXRfdnFfY2IsCj4gPiArICAgICAuc2V0X3ZxX251bSAgICAgICAgICAgICA9IHZkdXNlX3ZkcGFf c2V0X3ZxX251bSwKPiA+ICsgICAgIC5zZXRfdnFfcmVhZHkgICAgICAgICAgID0gdmR1c2VfdmRw YV9zZXRfdnFfcmVhZHksCj4gPiArICAgICAuZ2V0X3ZxX3JlYWR5ICAgICAgICAgICA9IHZkdXNl X3ZkcGFfZ2V0X3ZxX3JlYWR5LAo+ID4gKyAgICAgLnNldF92cV9zdGF0ZSAgICAgICAgICAgPSB2 ZHVzZV92ZHBhX3NldF92cV9zdGF0ZSwKPiA+ICsgICAgIC5nZXRfdnFfc3RhdGUgICAgICAgICAg ID0gdmR1c2VfdmRwYV9nZXRfdnFfc3RhdGUsCj4gPiArICAgICAuZ2V0X3ZxX2FsaWduICAgICAg ICAgICA9IHZkdXNlX3ZkcGFfZ2V0X3ZxX2FsaWduLAo+ID4gKyAgICAgLmdldF9mZWF0dXJlcyAg ICAgICAgICAgPSB2ZHVzZV92ZHBhX2dldF9mZWF0dXJlcywKPiA+ICsgICAgIC5zZXRfZmVhdHVy ZXMgICAgICAgICAgID0gdmR1c2VfdmRwYV9zZXRfZmVhdHVyZXMsCj4gPiArICAgICAuc2V0X2Nv bmZpZ19jYiAgICAgICAgICA9IHZkdXNlX3ZkcGFfc2V0X2NvbmZpZ19jYiwKPiA+ICsgICAgIC5n ZXRfdnFfbnVtX21heCAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRfdnFfbnVtX21heCwKPiA+ICsg ICAgIC5nZXRfZGV2aWNlX2lkICAgICAgICAgID0gdmR1c2VfdmRwYV9nZXRfZGV2aWNlX2lkLAo+ ID4gKyAgICAgLmdldF92ZW5kb3JfaWQgICAgICAgICAgPSB2ZHVzZV92ZHBhX2dldF92ZW5kb3Jf aWQsCj4gPiArICAgICAuZ2V0X3N0YXR1cyAgICAgICAgICAgICA9IHZkdXNlX3ZkcGFfZ2V0X3N0 YXR1cywKPiA+ICsgICAgIC5zZXRfc3RhdHVzICAgICAgICAgICAgID0gdmR1c2VfdmRwYV9zZXRf c3RhdHVzLAo+ID4gKyAgICAgLmdldF9jb25maWdfc2l6ZSAgICAgICAgPSB2ZHVzZV92ZHBhX2dl dF9jb25maWdfc2l6ZSwKPiA+ICsgICAgIC5nZXRfY29uZmlnICAgICAgICAgICAgID0gdmR1c2Vf dmRwYV9nZXRfY29uZmlnLAo+ID4gKyAgICAgLnNldF9jb25maWcgICAgICAgICAgICAgPSB2ZHVz ZV92ZHBhX3NldF9jb25maWcsCj4gPiArICAgICAuZ2V0X2dlbmVyYXRpb24gICAgICAgICA9IHZk dXNlX3ZkcGFfZ2V0X2dlbmVyYXRpb24sCj4gPiArICAgICAuc2V0X21hcCAgICAgICAgICAgICAg ICA9IHZkdXNlX3ZkcGFfc2V0X21hcCwKPiA+ICsgICAgIC5mcmVlICAgICAgICAgICAgICAgICAg ID0gdmR1c2VfdmRwYV9mcmVlLAo+ID4gK307Cj4gPiArCj4gPiArc3RhdGljIGRtYV9hZGRyX3Qg dmR1c2VfZGV2X21hcF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHBhZ2UgKnBhZ2Us Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgb2Zm c2V0LCBzaXplX3Qgc2l6ZSwKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyLAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB1bnNpZ25lZCBsb25nIGF0dHJzKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2 ZHVzZV9kZXYgKnZkZXYgPSBkZXZfdG9fdmR1c2UoZGV2KTsKPiA+ICsgICAgIHN0cnVjdCB2ZHVz ZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRldi0+ZG9tYWluOwo+ID4gKwo+ID4gKyAgICAgcmV0 dXJuIHZkdXNlX2RvbWFpbl9tYXBfcGFnZShkb21haW4sIHBhZ2UsIG9mZnNldCwgc2l6ZSwgZGly LCBhdHRycyk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lkIHZkdXNlX2Rldl91bm1hcF9w YWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgZG1hX2FkZHJfdCBkbWFfYWRkciwKPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBzaXplLCBlbnVtIGRtYV9kYXRhX2RpcmVjdGlv biBkaXIsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGF0 dHJzKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKnZkZXYgPSBkZXZfdG9fdmR1 c2UoZGV2KTsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRl di0+ZG9tYWluOwo+ID4gKwo+ID4gKyAgICAgcmV0dXJuIHZkdXNlX2RvbWFpbl91bm1hcF9wYWdl KGRvbWFpbiwgZG1hX2FkZHIsIHNpemUsIGRpciwgYXR0cnMpOwo+ID4gK30KPiA+ICsKPiA+ICtz dGF0aWMgdm9pZCAqdmR1c2VfZGV2X2FsbG9jX2NvaGVyZW50KHN0cnVjdCBkZXZpY2UgKmRldiwg c2l6ZV90IHNpemUsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRt YV9hZGRyX3QgKmRtYV9hZGRyLCBnZnBfdCBmbGFnLAo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGF0dHJzKQo+ID4gK3sKPiA+ICsgICAgIHN0 cnVjdCB2ZHVzZV9kZXYgKnZkZXYgPSBkZXZfdG9fdmR1c2UoZGV2KTsKPiA+ICsgICAgIHN0cnVj dCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRldi0+ZG9tYWluOwo+ID4gKyAgICAgdW5z aWduZWQgbG9uZyBpb3ZhOwo+ID4gKyAgICAgdm9pZCAqYWRkcjsKPiA+ICsKPiA+ICsgICAgICpk bWFfYWRkciA9IERNQV9NQVBQSU5HX0VSUk9SOwo+ID4gKyAgICAgYWRkciA9IHZkdXNlX2RvbWFp bl9hbGxvY19jb2hlcmVudChkb21haW4sIHNpemUsCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAoZG1hX2FkZHJfdCAqKSZpb3ZhLCBmbGFnLCBhdHRycyk7Cj4gPiArICAgICBpZiAo IWFkZHIpCj4gPiArICAgICAgICAgICAgIHJldHVybiBOVUxMOwo+ID4gKwo+ID4gKyAgICAgKmRt YV9hZGRyID0gKGRtYV9hZGRyX3QpaW92YTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiBhZGRyOwo+ ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2ZHVzZV9kZXZfZnJlZV9jb2hlcmVudChzdHJ1 Y3QgZGV2aWNlICpkZXYsIHNpemVfdCBzaXplLAo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICB2b2lkICp2YWRkciwgZG1hX2FkZHJfdCBkbWFfYWRkciwKPiA+ICsgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBhdHRycykKPiA+ ICt7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICp2ZGV2ID0gZGV2X3RvX3ZkdXNlKGRldik7 Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbiA9IHZkZXYtPmRvbWFp bjsKPiA+ICsKPiA+ICsgICAgIHZkdXNlX2RvbWFpbl9mcmVlX2NvaGVyZW50KGRvbWFpbiwgc2l6 ZSwgdmFkZHIsIGRtYV9hZGRyLCBhdHRycyk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBzaXpl X3QgdmR1c2VfZGV2X21heF9tYXBwaW5nX3NpemUoc3RydWN0IGRldmljZSAqZGV2KQo+ID4gK3sK PiA+ICsgICAgIHN0cnVjdCB2ZHVzZV9kZXYgKnZkZXYgPSBkZXZfdG9fdmR1c2UoZGV2KTsKPiA+ ICsgICAgIHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdmRldi0+ZG9tYWluOwo+ ID4gKwo+ID4gKyAgICAgcmV0dXJuIGRvbWFpbi0+Ym91bmNlX3NpemU7Cj4gPiArfQo+ID4gKwo+ ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZG1hX21hcF9vcHMgdmR1c2VfZGV2X2RtYV9vcHMgPSB7 Cj4gPiArICAgICAubWFwX3BhZ2UgPSB2ZHVzZV9kZXZfbWFwX3BhZ2UsCj4gPiArICAgICAudW5t YXBfcGFnZSA9IHZkdXNlX2Rldl91bm1hcF9wYWdlLAo+ID4gKyAgICAgLmFsbG9jID0gdmR1c2Vf ZGV2X2FsbG9jX2NvaGVyZW50LAo+ID4gKyAgICAgLmZyZWUgPSB2ZHVzZV9kZXZfZnJlZV9jb2hl cmVudCwKPiA+ICsgICAgIC5tYXhfbWFwcGluZ19zaXplID0gdmR1c2VfZGV2X21heF9tYXBwaW5n X3NpemUsCj4gPiArfTsKPiA+ICsKPiA+ICtzdGF0aWMgdW5zaWduZWQgaW50IHBlcm1fdG9fZmls ZV9mbGFncyh1OCBwZXJtKQo+ID4gK3sKPiA+ICsgICAgIHVuc2lnbmVkIGludCBmbGFncyA9IDA7 Cj4gPiArCj4gPiArICAgICBzd2l0Y2ggKHBlcm0pIHsKPiA+ICsgICAgIGNhc2UgVkRVU0VfQUND RVNTX1dPOgo+ID4gKyAgICAgICAgICAgICBmbGFncyB8PSBPX1dST05MWTsKPiA+ICsgICAgICAg ICAgICAgYnJlYWs7Cj4gPiArICAgICBjYXNlIFZEVVNFX0FDQ0VTU19STzoKPiA+ICsgICAgICAg ICAgICAgZmxhZ3MgfD0gT19SRE9OTFk7Cj4gPiArICAgICAgICAgICAgIGJyZWFrOwo+ID4gKyAg ICAgY2FzZSBWRFVTRV9BQ0NFU1NfUlc6Cj4gPiArICAgICAgICAgICAgIGZsYWdzIHw9IE9fUkRX UjsKPiA+ICsgICAgICAgICAgICAgYnJlYWs7Cj4gPiArICAgICBkZWZhdWx0Ogo+ID4gKyAgICAg ICAgICAgICBXQVJOKDEsICJpbnZhbGlkYXRlIHZob3N0IElPVExCIHBlcm1pc3Npb25cbiIpOwo+ ID4gKyAgICAgICAgICAgICBicmVhazsKPiA+ICsgICAgIH0KPiA+ICsKPiA+ICsgICAgIHJldHVy biBmbGFnczsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGludCB2ZHVzZV9raWNrZmRfc2V0dXAo c3RydWN0IHZkdXNlX2RldiAqZGV2LAo+ID4gKyAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2 ZHVzZV92cV9ldmVudGZkICpldmVudGZkKQo+ID4gK3sKPiA+ICsgICAgIHN0cnVjdCBldmVudGZk X2N0eCAqY3R4ID0gTlVMTDsKPiA+ICsgICAgIHN0cnVjdCB2ZHVzZV92aXJ0cXVldWUgKnZxOwo+ ID4gKyAgICAgdTMyIGluZGV4Owo+ID4gKwo+ID4gKyAgICAgaWYgKGV2ZW50ZmQtPmluZGV4ID49 IGRldi0+dnFfbnVtKQo+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiA+ICsKPiA+ ICsgICAgIGluZGV4ID0gYXJyYXlfaW5kZXhfbm9zcGVjKGV2ZW50ZmQtPmluZGV4LCBkZXYtPnZx X251bSk7Cj4gPiArICAgICB2cSA9ICZkZXYtPnZxc1tpbmRleF07Cj4gPiArICAgICBpZiAoZXZl bnRmZC0+ZmQgPj0gMCkgewo+ID4gKyAgICAgICAgICAgICBjdHggPSBldmVudGZkX2N0eF9mZGdl dChldmVudGZkLT5mZCk7Cj4gPiArICAgICAgICAgICAgIGlmIChJU19FUlIoY3R4KSkKPiA+ICsg ICAgICAgICAgICAgICAgICAgICByZXR1cm4gUFRSX0VSUihjdHgpOwo+ID4gKyAgICAgfSBlbHNl IGlmIChldmVudGZkLT5mZCAhPSBWRFVTRV9FVkVOVEZEX0RFQVNTSUdOKQo+ID4gKyAgICAgICAg ICAgICByZXR1cm4gMDsKPiA+ICsKPiA+ICsgICAgIHNwaW5fbG9jaygmdnEtPmtpY2tfbG9jayk7 Cj4gPiArICAgICBpZiAodnEtPmtpY2tmZCkKPiA+ICsgICAgICAgICAgICAgZXZlbnRmZF9jdHhf cHV0KHZxLT5raWNrZmQpOwo+ID4gKyAgICAgdnEtPmtpY2tmZCA9IGN0eDsKPiA+ICsgICAgIGlm ICh2cS0+cmVhZHkgJiYgdnEtPmtpY2tlZCAmJiB2cS0+a2lja2ZkKSB7Cj4gPiArICAgICAgICAg ICAgIGV2ZW50ZmRfc2lnbmFsKHZxLT5raWNrZmQsIDEpOwo+ID4gKyAgICAgICAgICAgICB2cS0+ a2lja2VkID0gZmFsc2U7Cj4gPiArICAgICB9Cj4gPiArICAgICBzcGluX3VubG9jaygmdnEtPmtp Y2tfbG9jayk7Cj4gPiArCj4gPiArICAgICByZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiArc3Rh dGljIGJvb2wgdmR1c2VfZGV2X2lzX3JlYWR5KHN0cnVjdCB2ZHVzZV9kZXYgKmRldikKPiA+ICt7 Cj4gPiArICAgICBpbnQgaTsKPiA+ICsKPiA+ICsgICAgIGZvciAoaSA9IDA7IGkgPCBkZXYtPnZx X251bTsgaSsrKQo+ID4gKyAgICAgICAgICAgICBpZiAoIWRldi0+dnFzW2ldLm51bV9tYXgpCj4g PiArICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwo+ID4gKwo+ID4gKyAgICAgcmV0 dXJuIHRydWU7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lkIHZkdXNlX2Rldl9pcnFfaW5q ZWN0KHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKPiA+ICt7Cj4gPiArICAgICBzdHJ1Y3QgdmR1 c2VfZGV2ICpkZXYgPSBjb250YWluZXJfb2Yod29yaywgc3RydWN0IHZkdXNlX2RldiwgaW5qZWN0 KTsKPiA+ICsKPiA+ICsgICAgIHNwaW5fbG9ja19pcnEoJmRldi0+aXJxX2xvY2spOwo+ID4gKyAg ICAgaWYgKGRldi0+Y29uZmlnX2NiLmNhbGxiYWNrKQo+ID4gKyAgICAgICAgICAgICBkZXYtPmNv bmZpZ19jYi5jYWxsYmFjayhkZXYtPmNvbmZpZ19jYi5wcml2YXRlKTsKPiA+ICsgICAgIHNwaW5f dW5sb2NrX2lycSgmZGV2LT5pcnFfbG9jayk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2b2lk IHZkdXNlX3ZxX2lycV9pbmplY3Qoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+ID4gK3sKPiA+ ICsgICAgIHN0cnVjdCB2ZHVzZV92aXJ0cXVldWUgKnZxID0gY29udGFpbmVyX29mKHdvcmssCj4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2ZHVzZV92aXJ0 cXVldWUsIGluamVjdCk7Cj4gPiArCj4gPiArICAgICBzcGluX2xvY2tfaXJxKCZ2cS0+aXJxX2xv Y2spOwo+ID4gKyAgICAgaWYgKHZxLT5yZWFkeSAmJiB2cS0+Y2IuY2FsbGJhY2spCj4gPiArICAg ICAgICAgICAgIHZxLT5jYi5jYWxsYmFjayh2cS0+Y2IucHJpdmF0ZSk7Cj4gPiArICAgICBzcGlu X3VubG9ja19pcnEoJnZxLT5pcnFfbG9jayk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBsb25n IHZkdXNlX2Rldl9pb2N0bChzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwKPiA+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBhcmcpCj4gPiArewo+ID4g KyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ID4gKyAg ICAgdm9pZCBfX3VzZXIgKmFyZ3AgPSAodm9pZCBfX3VzZXIgKilhcmc7Cj4gPiArICAgICBpbnQg cmV0Owo+ID4gKwo+ID4gKyAgICAgc3dpdGNoIChjbWQpIHsKPiA+ICsgICAgIGNhc2UgVkRVU0Vf SU9UTEJfR0VUX0ZEOiB7Cj4gPiArICAgICAgICAgICAgIHN0cnVjdCB2ZHVzZV9pb3RsYl9lbnRy eSBlbnRyeTsKPiA+ICsgICAgICAgICAgICAgc3RydWN0IHZob3N0X2lvdGxiX21hcCAqbWFwOwo+ ID4gKyAgICAgICAgICAgICBzdHJ1Y3QgdmRwYV9tYXBfZmlsZSAqbWFwX2ZpbGU7Cj4gPiArICAg ICAgICAgICAgIHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gZGV2LT5kb21haW47 Cj4gPiArICAgICAgICAgICAgIHN0cnVjdCBmaWxlICpmID0gTlVMTDsKPiA+ICsKPiA+ICsgICAg ICAgICAgICAgcmV0ID0gLUVGQVVMVDsKPiA+ICsgICAgICAgICAgICAgaWYgKGNvcHlfZnJvbV91 c2VyKCZlbnRyeSwgYXJncCwgc2l6ZW9mKGVudHJ5KSkpCj4gPiArICAgICAgICAgICAgICAgICAg ICAgYnJlYWs7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHJldCA9IC1FSU5WQUw7Cj4gPiArICAg ICAgICAgICAgIGlmIChlbnRyeS5zdGFydCA+IGVudHJ5Lmxhc3QpCj4gPiArICAgICAgICAgICAg ICAgICAgICAgYnJlYWs7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHNwaW5fbG9jaygmZG9tYWlu LT5pb3RsYl9sb2NrKTsKPiA+ICsgICAgICAgICAgICAgbWFwID0gdmhvc3RfaW90bGJfaXRyZWVf Zmlyc3QoZG9tYWluLT5pb3RsYiwKPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgZW50cnkuc3RhcnQsIGVudHJ5Lmxhc3QpOwo+ID4gKyAgICAgICAgICAgICBp ZiAobWFwKSB7Cj4gPiArICAgICAgICAgICAgICAgICAgICAgbWFwX2ZpbGUgPSAoc3RydWN0IHZk cGFfbWFwX2ZpbGUgKiltYXAtPm9wYXF1ZTsKPiA+ICsgICAgICAgICAgICAgICAgICAgICBmID0g Z2V0X2ZpbGUobWFwX2ZpbGUtPmZpbGUpOwo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGVudHJ5 Lm9mZnNldCA9IG1hcF9maWxlLT5vZmZzZXQ7Cj4gPiArICAgICAgICAgICAgICAgICAgICAgZW50 cnkuc3RhcnQgPSBtYXAtPnN0YXJ0Owo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGVudHJ5Lmxh c3QgPSBtYXAtPmxhc3Q7Cj4gPiArICAgICAgICAgICAgICAgICAgICAgZW50cnkucGVybSA9IG1h cC0+cGVybTsKPiA+ICsgICAgICAgICAgICAgfQo+ID4gKyAgICAgICAgICAgICBzcGluX3VubG9j aygmZG9tYWluLT5pb3RsYl9sb2NrKTsKPiA+ICsgICAgICAgICAgICAgcmV0ID0gLUVJTlZBTDsK PiA+ICsgICAgICAgICAgICAgaWYgKCFmKQo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGJyZWFr Owo+ID4gKwo+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUZBVUxUOwo+ID4gKyAgICAgICAgICAg ICBpZiAoY29weV90b191c2VyKGFyZ3AsICZlbnRyeSwgc2l6ZW9mKGVudHJ5KSkpIHsKPiA+ICsg ICAgICAgICAgICAgICAgICAgICBmcHV0KGYpOwo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGJy ZWFrOwo+ID4gKyAgICAgICAgICAgICB9Cj4gPiArICAgICAgICAgICAgIHJldCA9IHJlY2VpdmVf ZmQoZiwgcGVybV90b19maWxlX2ZsYWdzKGVudHJ5LnBlcm0pKTsKPiA+ICsgICAgICAgICAgICAg ZnB1dChmKTsKPiA+ICsgICAgICAgICAgICAgYnJlYWs7Cj4gPiArICAgICB9Cj4gPiArICAgICBj YXNlIFZEVVNFX0RFVl9HRVRfRkVBVFVSRVM6Cj4KPgo+IExldCdzIGFkZCBhIGNvbW1lbnQgdG8g ZXhwbGFpbiBoZXJlLiBFLmcgd2UganVzdCBtaXJyb3Igd2hhdCBkcml2ZXIKPiB3cm90ZSBhbmQg dGhlIGRyaWVyIGlzIGV4cGVjdGVkIHRvIGNoZWNrIEZFQVRVUkVfT0suCj4KCkkgYWxyZWFkeSBk b2N1bWVudCBzb21lIGRldGFpbHMgaW4gaW5jbHVkZS91YXBpL2xpbnV4L3ZkdXNlLmggYW5kCkRv Y3VtZW50YXRpb24vdXNlcnNwYWNlLWFwaS92ZHVzZS5yc3QKCj4KPiA+ICsgICAgICAgICAgICAg cmV0ID0gcHV0X3VzZXIoZGV2LT5kcml2ZXJfZmVhdHVyZXMsICh1NjQgX191c2VyICopYXJncCk7 Cj4gPiArICAgICAgICAgICAgIGJyZWFrOwo+ID4gKyAgICAgY2FzZSBWRFVTRV9ERVZfU0VUX0NP TkZJRzogewo+ID4gKyAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2VfY29uZmlnX2RhdGEgY29uZmln Owo+ID4gKyAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIHNpemUgPSBvZmZzZXRvZihzdHJ1Y3Qg dmR1c2VfY29uZmlnX2RhdGEsCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGJ1ZmZlcik7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHJldCA9IC1FRkFVTFQ7 Cj4gPiArICAgICAgICAgICAgIGlmIChjb3B5X2Zyb21fdXNlcigmY29uZmlnLCBhcmdwLCBzaXpl KSkKPiA+ICsgICAgICAgICAgICAgICAgICAgICBicmVhazsKPiA+ICsKPiA+ICsgICAgICAgICAg ICAgcmV0ID0gLUVJTlZBTDsKPiA+ICsgICAgICAgICAgICAgaWYgKGNvbmZpZy5sZW5ndGggPT0g MCB8fAo+ID4gKyAgICAgICAgICAgICAgICAgY29uZmlnLmxlbmd0aCA+IGRldi0+Y29uZmlnX3Np emUgLSBjb25maWcub2Zmc2V0KQo+ID4gKyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4g Kwo+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUZBVUxUOwo+ID4gKyAgICAgICAgICAgICBpZiAo Y29weV9mcm9tX3VzZXIoZGV2LT5jb25maWcgKyBjb25maWcub2Zmc2V0LCBhcmdwICsgc2l6ZSwK PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5sZW5ndGgpKQo+ID4g KyAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4gKwo+ID4gKyAgICAgICAgICAgICByZXQg PSAwOwo+ID4gKyAgICAgICAgICAgICBicmVhazsKPiA+ICsgICAgIH0KPiA+ICsgICAgIGNhc2Ug VkRVU0VfREVWX0lOSkVDVF9JUlE6Cj4KPgo+IEl0J3MgYmV0dGVyIHRvIGhhdmUgImNvbmZpZyIg aW4gdGhlIG5hbWUuCj4KCk9LLgoKPgo+ID4gKyAgICAgICAgICAgICByZXQgPSAwOwo+ID4gKyAg ICAgICAgICAgICBxdWV1ZV93b3JrKHZkdXNlX2lycV93cSwgJmRldi0+aW5qZWN0KTsKPiA+ICsg ICAgICAgICAgICAgYnJlYWs7Cj4gPiArICAgICBjYXNlIFZEVVNFX1ZRX1NFVFVQOiB7Cj4gPiAr ICAgICAgICAgICAgIHN0cnVjdCB2ZHVzZV92cV9jb25maWcgY29uZmlnOwo+ID4gKyAgICAgICAg ICAgICB1MzIgaW5kZXg7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHJldCA9IC1FRkFVTFQ7Cj4g PiArICAgICAgICAgICAgIGlmIChjb3B5X2Zyb21fdXNlcigmY29uZmlnLCBhcmdwLCBzaXplb2Yo Y29uZmlnKSkpCj4gPiArICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4gPiArCj4gPiArICAg ICAgICAgICAgIHJldCA9IC1FSU5WQUw7Cj4gPiArICAgICAgICAgICAgIGlmIChjb25maWcuaW5k ZXggPj0gZGV2LT52cV9udW0pCj4gPiArICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4gPiAr Cj4gPiArICAgICAgICAgICAgIGluZGV4ID0gYXJyYXlfaW5kZXhfbm9zcGVjKGNvbmZpZy5pbmRl eCwgZGV2LT52cV9udW0pOwo+ID4gKyAgICAgICAgICAgICBkZXYtPnZxc1tpbmRleF0ubnVtX21h eCA9IGNvbmZpZy5tYXhfc2l6ZTsKPiA+ICsgICAgICAgICAgICAgcmV0ID0gMDsKPiA+ICsgICAg ICAgICAgICAgYnJlYWs7Cj4gPiArICAgICB9Cj4gPiArICAgICBjYXNlIFZEVVNFX1ZRX0dFVF9J TkZPOiB7Cj4gPiArICAgICAgICAgICAgIHN0cnVjdCB2ZHVzZV92cV9pbmZvIHZxX2luZm87Cj4g PiArICAgICAgICAgICAgIHN0cnVjdCB2ZHVzZV92aXJ0cXVldWUgKnZxOwo+ID4gKyAgICAgICAg ICAgICB1MzIgaW5kZXg7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHJldCA9IC1FRkFVTFQ7Cj4g PiArICAgICAgICAgICAgIGlmIChjb3B5X2Zyb21fdXNlcigmdnFfaW5mbywgYXJncCwgc2l6ZW9m KHZxX2luZm8pKSkKPiA+ICsgICAgICAgICAgICAgICAgICAgICBicmVhazsKPiA+ICsKPiA+ICsg ICAgICAgICAgICAgcmV0ID0gLUVJTlZBTDsKPiA+ICsgICAgICAgICAgICAgaWYgKHZxX2luZm8u aW5kZXggPj0gZGV2LT52cV9udW0pCj4gPiArICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4g PiArCj4gPiArICAgICAgICAgICAgIGluZGV4ID0gYXJyYXlfaW5kZXhfbm9zcGVjKHZxX2luZm8u aW5kZXgsIGRldi0+dnFfbnVtKTsKPiA+ICsgICAgICAgICAgICAgdnEgPSAmZGV2LT52cXNbaW5k ZXhdOwo+ID4gKyAgICAgICAgICAgICB2cV9pbmZvLmRlc2NfYWRkciA9IHZxLT5kZXNjX2FkZHI7 Cj4gPiArICAgICAgICAgICAgIHZxX2luZm8uZHJpdmVyX2FkZHIgPSB2cS0+ZHJpdmVyX2FkZHI7 Cj4gPiArICAgICAgICAgICAgIHZxX2luZm8uZGV2aWNlX2FkZHIgPSB2cS0+ZGV2aWNlX2FkZHI7 Cj4gPiArICAgICAgICAgICAgIHZxX2luZm8ubnVtID0gdnEtPm51bTsKPiA+ICsKPiA+ICsgICAg ICAgICAgICAgaWYgKGRldi0+ZHJpdmVyX2ZlYXR1cmVzICYgQklUX1VMTChWSVJUSU9fRl9SSU5H X1BBQ0tFRCkpIHsKPiA+ICsgICAgICAgICAgICAgICAgICAgICB2cV9pbmZvLnBhY2tlZC5sYXN0 X2F2YWlsX2NvdW50ZXIgPQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnEtPnN0 YXRlLnBhY2tlZC5sYXN0X2F2YWlsX2NvdW50ZXI7Cj4gPiArICAgICAgICAgICAgICAgICAgICAg dnFfaW5mby5wYWNrZWQubGFzdF9hdmFpbF9pZHggPQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgdnEtPnN0YXRlLnBhY2tlZC5sYXN0X2F2YWlsX2lkeDsKPiA+ICsgICAgICAgICAg ICAgICAgICAgICB2cV9pbmZvLnBhY2tlZC5sYXN0X3VzZWRfY291bnRlciA9Cj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB2cS0+c3RhdGUucGFja2VkLmxhc3RfdXNlZF9jb3VudGVy Owo+ID4gKyAgICAgICAgICAgICAgICAgICAgIHZxX2luZm8ucGFja2VkLmxhc3RfdXNlZF9pZHgg PQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnEtPnN0YXRlLnBhY2tlZC5sYXN0 X3VzZWRfaWR4Owo+ID4gKyAgICAgICAgICAgICB9IGVsc2UKPiA+ICsgICAgICAgICAgICAgICAg ICAgICB2cV9pbmZvLnNwbGl0LmF2YWlsX2luZGV4ID0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIHZxLT5zdGF0ZS5zcGxpdC5hdmFpbF9pbmRleDsKPiA+ICsKPiA+ICsgICAgICAg ICAgICAgdnFfaW5mby5yZWFkeSA9IHZxLT5yZWFkeTsKPiA+ICsKPiA+ICsgICAgICAgICAgICAg cmV0ID0gLUVGQVVMVDsKPiA+ICsgICAgICAgICAgICAgaWYgKGNvcHlfdG9fdXNlcihhcmdwLCAm dnFfaW5mbywgc2l6ZW9mKHZxX2luZm8pKSkKPiA+ICsgICAgICAgICAgICAgICAgICAgICBicmVh azsKPiA+ICsKPiA+ICsgICAgICAgICAgICAgcmV0ID0gMDsKPiA+ICsgICAgICAgICAgICAgYnJl YWs7Cj4gPiArICAgICB9Cj4gPiArICAgICBjYXNlIFZEVVNFX1ZRX1NFVFVQX0tJQ0tGRDogewo+ ID4gKyAgICAgICAgICAgICBzdHJ1Y3QgdmR1c2VfdnFfZXZlbnRmZCBldmVudGZkOwo+ID4gKwo+ ID4gKyAgICAgICAgICAgICByZXQgPSAtRUZBVUxUOwo+ID4gKyAgICAgICAgICAgICBpZiAoY29w eV9mcm9tX3VzZXIoJmV2ZW50ZmQsIGFyZ3AsIHNpemVvZihldmVudGZkKSkpCj4gPiArICAgICAg ICAgICAgICAgICAgICAgYnJlYWs7Cj4gPiArCj4gPiArICAgICAgICAgICAgIHJldCA9IHZkdXNl X2tpY2tmZF9zZXR1cChkZXYsICZldmVudGZkKTsKPiA+ICsgICAgICAgICAgICAgYnJlYWs7Cj4g PiArICAgICB9Cj4gPiArICAgICBjYXNlIFZEVVNFX1ZRX0lOSkVDVF9JUlE6IHsKPiA+ICsgICAg ICAgICAgICAgdTMyIGluZGV4Owo+ID4gKwo+ID4gKyAgICAgICAgICAgICByZXQgPSAtRUZBVUxU Owo+ID4gKyAgICAgICAgICAgICBpZiAoZ2V0X3VzZXIoaW5kZXgsICh1MzIgX191c2VyICopYXJn cCkpCj4gPiArICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Cj4gPiArCj4gPiArICAgICAgICAg ICAgIHJldCA9IC1FSU5WQUw7Cj4gPiArICAgICAgICAgICAgIGlmIChpbmRleCA+PSBkZXYtPnZx X251bSkKPiA+ICsgICAgICAgICAgICAgICAgICAgICBicmVhazsKPiA+ICsKPiA+ICsgICAgICAg ICAgICAgcmV0ID0gMDsKPiA+ICsgICAgICAgICAgICAgaW5kZXggPSBhcnJheV9pbmRleF9ub3Nw ZWMoaW5kZXgsIGRldi0+dnFfbnVtKTsKPiA+ICsgICAgICAgICAgICAgcXVldWVfd29yayh2ZHVz ZV9pcnFfd3EsICZkZXYtPnZxc1tpbmRleF0uaW5qZWN0KTsKPiA+ICsgICAgICAgICAgICAgYnJl YWs7Cj4gPiArICAgICB9Cj4gPiArICAgICBkZWZhdWx0Ogo+ID4gKyAgICAgICAgICAgICByZXQg PSAtRU5PSU9DVExDTUQ7Cj4gPiArICAgICAgICAgICAgIGJyZWFrOwo+ID4gKyAgICAgfQo+ID4g Kwo+ID4gKyAgICAgcmV0dXJuIHJldDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGludCB2ZHVz ZV9kZXZfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKPiA+ ICt7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYgPSBmaWxlLT5wcml2YXRlX2RhdGE7 Cj4gPiArCj4gPiArICAgICBzcGluX2xvY2soJmRldi0+bXNnX2xvY2spOwo+ID4gKyAgICAgLyog TWFrZSBzdXJlIHRoZSBpbmZsaWdodCBtZXNzYWdlcyBjYW4gcHJvY2Vzc2VkIGFmdGVyIHJlY29u bmNlY3Rpb24gKi8KPiA+ICsgICAgIGxpc3Rfc3BsaWNlX2luaXQoJmRldi0+cmVjdl9saXN0LCAm ZGV2LT5zZW5kX2xpc3QpOwo+ID4gKyAgICAgc3Bpbl91bmxvY2soJmRldi0+bXNnX2xvY2spOwo+ ID4gKyAgICAgZGV2LT5jb25uZWN0ZWQgPSBmYWxzZTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiAw Owo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgc3RydWN0IHZkdXNlX2RldiAqdmR1c2VfZGV2X2dl dF9mcm9tX21pbm9yKGludCBtaW5vcikKPiA+ICt7Cj4gPiArICAgICBzdHJ1Y3QgdmR1c2VfZGV2 ICpkZXY7Cj4gPiArCj4gPiArICAgICBtdXRleF9sb2NrKCZ2ZHVzZV9sb2NrKTsKPiA+ICsgICAg IGRldiA9IGlkcl9maW5kKCZ2ZHVzZV9pZHIsIG1pbm9yKTsKPiA+ICsgICAgIG11dGV4X3VubG9j aygmdmR1c2VfbG9jayk7Cj4gPiArCj4gPiArICAgICByZXR1cm4gZGV2Owo+ID4gK30KPiA+ICsK PiA+ICtzdGF0aWMgaW50IHZkdXNlX2Rldl9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVj dCBmaWxlICpmaWxlKQo+ID4gK3sKPiA+ICsgICAgIGludCByZXQ7Cj4gPiArICAgICBzdHJ1Y3Qg dmR1c2VfZGV2ICpkZXYgPSB2ZHVzZV9kZXZfZ2V0X2Zyb21fbWlub3IoaW1pbm9yKGlub2RlKSk7 Cj4gPiArCj4gPiArICAgICBpZiAoIWRldikKPiA+ICsgICAgICAgICAgICAgcmV0dXJuIC1FTk9E RVY7Cj4gPiArCj4gPiArICAgICByZXQgPSAtRUJVU1k7Cj4gPiArICAgICBtdXRleF9sb2NrKCZk ZXYtPmxvY2spOwo+ID4gKyAgICAgaWYgKGRldi0+Y29ubmVjdGVkKQo+ID4gKyAgICAgICAgICAg ICBnb3RvIHVubG9jazsKPiA+ICsKPiA+ICsgICAgIHJldCA9IDA7Cj4gPiArICAgICBkZXYtPmNv bm5lY3RlZCA9IHRydWU7Cj4gPiArICAgICBmaWxlLT5wcml2YXRlX2RhdGEgPSBkZXY7Cj4gPiAr dW5sb2NrOgo+ID4gKyAgICAgbXV0ZXhfdW5sb2NrKCZkZXYtPmxvY2spOwo+ID4gKwo+ID4gKyAg ICAgcmV0dXJuIHJldDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxl X29wZXJhdGlvbnMgdmR1c2VfZGV2X2ZvcHMgPSB7Cj4gPiArICAgICAub3duZXIgICAgICAgICAg PSBUSElTX01PRFVMRSwKPiA+ICsgICAgIC5vcGVuICAgICAgICAgICA9IHZkdXNlX2Rldl9vcGVu LAo+ID4gKyAgICAgLnJlbGVhc2UgICAgICAgID0gdmR1c2VfZGV2X3JlbGVhc2UsCj4gPiArICAg ICAucmVhZF9pdGVyICAgICAgPSB2ZHVzZV9kZXZfcmVhZF9pdGVyLAo+ID4gKyAgICAgLndyaXRl X2l0ZXIgICAgID0gdmR1c2VfZGV2X3dyaXRlX2l0ZXIsCj4gPiArICAgICAucG9sbCAgICAgICAg ICAgPSB2ZHVzZV9kZXZfcG9sbCwKPiA+ICsgICAgIC51bmxvY2tlZF9pb2N0bCA9IHZkdXNlX2Rl dl9pb2N0bCwKPiA+ICsgICAgIC5jb21wYXRfaW9jdGwgICA9IGNvbXBhdF9wdHJfaW9jdGwsCj4g PiArICAgICAubGxzZWVrICAgICAgICAgPSBub29wX2xsc2VlaywKPiA+ICt9Owo+ID4gKwo+ID4g K3N0YXRpYyBzdHJ1Y3QgdmR1c2VfZGV2ICp2ZHVzZV9kZXZfY3JlYXRlKHZvaWQpCj4gPiArewo+ ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2ID0ga3phbGxvYyhzaXplb2YoKmRldiksIEdG UF9LRVJORUwpOwo+ID4gKwo+ID4gKyAgICAgaWYgKCFkZXYpCj4gPiArICAgICAgICAgICAgIHJl dHVybiBOVUxMOwo+ID4gKwo+ID4gKyAgICAgbXV0ZXhfaW5pdCgmZGV2LT5sb2NrKTsKPiA+ICsg ICAgIHNwaW5fbG9ja19pbml0KCZkZXYtPm1zZ19sb2NrKTsKPiA+ICsgICAgIElOSVRfTElTVF9I RUFEKCZkZXYtPnNlbmRfbGlzdCk7Cj4gPiArICAgICBJTklUX0xJU1RfSEVBRCgmZGV2LT5yZWN2 X2xpc3QpOwo+ID4gKyAgICAgc3Bpbl9sb2NrX2luaXQoJmRldi0+aXJxX2xvY2spOwo+ID4gKwo+ ID4gKyAgICAgSU5JVF9XT1JLKCZkZXYtPmluamVjdCwgdmR1c2VfZGV2X2lycV9pbmplY3QpOwo+ ID4gKyAgICAgaW5pdF93YWl0cXVldWVfaGVhZCgmZGV2LT53YWl0cSk7Cj4gPiArCj4gPiArICAg ICByZXR1cm4gZGV2Owo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgdm9pZCB2ZHVzZV9kZXZfZGVz dHJveShzdHJ1Y3QgdmR1c2VfZGV2ICpkZXYpCj4gPiArewo+ID4gKyAgICAga2ZyZWUoZGV2KTsK PiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHN0cnVjdCB2ZHVzZV9kZXYgKnZkdXNlX2ZpbmRfZGV2 KGNvbnN0IGNoYXIgKm5hbWUpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAqZGV2 Owo+ID4gKyAgICAgaW50IGlkOwo+ID4gKwo+ID4gKyAgICAgaWRyX2Zvcl9lYWNoX2VudHJ5KCZ2 ZHVzZV9pZHIsIGRldiwgaWQpCj4gPiArICAgICAgICAgICAgIGlmICghc3RyY21wKGRldi0+bmFt ZSwgbmFtZSkpCj4gPiArICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRldjsKPiA+ICsKPiA+ ICsgICAgIHJldHVybiBOVUxMOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgaW50IHZkdXNlX2Rl c3Ryb3lfZGV2KGNoYXIgKm5hbWUpCj4gPiArewo+ID4gKyAgICAgc3RydWN0IHZkdXNlX2RldiAq ZGV2ID0gdmR1c2VfZmluZF9kZXYobmFtZSk7Cj4gPiArCj4gPiArICAgICBpZiAoIWRldikKPiA+ ICsgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gPiArCj4gPiArICAgICBtdXRleF9sb2Nr KCZkZXYtPmxvY2spOwo+ID4gKyAgICAgaWYgKGRldi0+dmRldiB8fCBkZXYtPmNvbm5lY3RlZCkg ewo+ID4gKyAgICAgICAgICAgICBtdXRleF91bmxvY2soJmRldi0+bG9jayk7Cj4gPiArICAgICAg ICAgICAgIHJldHVybiAtRUJVU1k7Cj4gPiArICAgICB9Cj4gPiArICAgICBkZXYtPmNvbm5lY3Rl ZCA9IHRydWU7Cj4gPiArICAgICBtdXRleF91bmxvY2soJmRldi0+bG9jayk7Cj4gPiArCj4gPiAr ICAgICB2ZHVzZV9kZXZfcmVzZXQoZGV2KTsKPiA+ICsgICAgIGRldmljZV9kZXN0cm95KHZkdXNl X2NsYXNzLCBNS0RFVihNQUpPUih2ZHVzZV9tYWpvciksIGRldi0+bWlub3IpKTsKPiA+ICsgICAg IGlkcl9yZW1vdmUoJnZkdXNlX2lkciwgZGV2LT5taW5vcik7Cj4gPiArICAgICBrdmZyZWUoZGV2 LT5jb25maWcpOwo+ID4gKyAgICAga2ZyZWUoZGV2LT52cXMpOwo+ID4gKyAgICAgdmR1c2VfZG9t YWluX2Rlc3Ryb3koZGV2LT5kb21haW4pOwo+ID4gKyAgICAga2ZyZWUoZGV2LT5uYW1lKTsKPiA+ ICsgICAgIHZkdXNlX2Rldl9kZXN0cm95KGRldik7Cj4gPiArICAgICBtb2R1bGVfcHV0KFRISVNf TU9EVUxFKTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiAwOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0 aWMgYm9vbCBkZXZpY2VfaXNfYWxsb3dlZCh1MzIgZGV2aWNlX2lkKQo+ID4gK3sKPiA+ICsgICAg IGludCBpOwo+ID4gKwo+ID4gKyAgICAgZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUoYWxsb3dl ZF9kZXZpY2VfaWQpOyBpKyspCj4gPiArICAgICAgICAgICAgIGlmIChhbGxvd2VkX2RldmljZV9p ZFtpXSA9PSBkZXZpY2VfaWQpCj4gPiArICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7 Cj4gPiArCj4gPiArICAgICByZXR1cm4gZmFsc2U7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBi b29sIGZlYXR1cmVzX2lzX3ZhbGlkKHU2NCBmZWF0dXJlcykKPiA+ICt7Cj4gPiArICAgICBpZiAo IShmZWF0dXJlcyAmICgxVUxMIDw8IFZJUlRJT19GX0FDQ0VTU19QTEFURk9STSkpKQo+ID4gKyAg ICAgICAgICAgICByZXR1cm4gZmFsc2U7Cj4gPiArCj4gPiArICAgICAvKiBOb3cgd2Ugb25seSBz dXBwb3J0IHJlYWQtb25seSBjb25maWd1cmF0aW9uIHNwYWNlICovCj4gPiArICAgICBpZiAoZmVh dHVyZXMgJiAoMVVMTCA8PCBWSVJUSU9fQkxLX0ZfQ09ORklHX1dDRSkpCj4gPiArICAgICAgICAg ICAgIHJldHVybiBmYWxzZTsKPiA+ICsKPiA+ICsgICAgIHJldHVybiB0cnVlOwo+ID4gK30KPiA+ ICsKPiA+ICtzdGF0aWMgYm9vbCB2ZHVzZV92YWxpZGF0ZV9jb25maWcoc3RydWN0IHZkdXNlX2Rl dl9jb25maWcgKmNvbmZpZykKPiA+ICt7Cj4gPiArICAgICBpZiAoY29uZmlnLT5ib3VuY2Vfc2l6 ZSA+IFZEVVNFX01BWF9CT1VOQ0VfU0laRSkKPiA+ICsgICAgICAgICAgICAgcmV0dXJuIGZhbHNl Owo+ID4gKwo+ID4gKyAgICAgaWYgKGNvbmZpZy0+dnFfYWxpZ24gPiBQQUdFX1NJWkUpCj4gPiAr ICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKPiA+ICsKPiA+ICsgICAgIGlmIChjb25maWctPmNv bmZpZ19zaXplID4gUEFHRV9TSVpFKQo+ID4gKyAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Cj4K Pgo+IEFueSByZWFzb24gZm9yIHRoaXMgY2hlY2s/Cj4KClRvIGxpbWl0IHRoZSBrZXJuZWwgYnVm ZmVyIHNpemUgZm9yIGNvbmZpZ3VyYXRpb24gc3BhY2UuIElzIHRoZQpQQUdFX1NJWkUgZW5vdWdo PwoKVGhhbmtzLApZb25namkKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fCmlvbW11IG1haWxpbmcgbGlzdAppb21tdUBsaXN0cy5saW51eC1mb3VuZGF0aW9u Lm9yZwpodHRwczovL2xpc3RzLmxpbnV4Zm91bmRhdGlvbi5vcmcvbWFpbG1hbi9saXN0aW5mby9p b21tdQ==