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=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS 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 1959AC5DF61 for ; Thu, 7 Nov 2019 09:08:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B45812187F for ; Thu, 7 Nov 2019 09:08:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387800AbfKGJIx (ORCPT ); Thu, 7 Nov 2019 04:08:53 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42714 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727120AbfKGJIw (ORCPT ); Thu, 7 Nov 2019 04:08:52 -0500 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1DDA05AFE0 for ; Thu, 7 Nov 2019 09:08:52 +0000 (UTC) Received: by mail-qt1-f198.google.com with SMTP id l8so1793941qtq.9 for ; Thu, 07 Nov 2019 01:08:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=y3kSmNPFNr1syqaEwVgmtYdBZ7wSJEKV0NnWLNNW74g=; b=KJ+E/5+VA+Uvea9N9X54KaxwlZwxF5os+5Rf1PEpJfeNSUsQv7yWGJ/y4WvBFyKtyl bg2AaiZKn1hD5lWkQq2uPqMsHnu0bZSrHZxBz2SxPsC6wIms0VxcgxO/n2aMTD+MEvzR UUDW+2HdrlKbc6/7+MaLXUWuvrC+Zpvq7M9ATT+YHtQ/3nxTVTEGs6ZdpQMQUdCugg1C gUiR07ntdQYEWU8w7IrnbklJa00BU9JMhmWo0KDL0QJDp9UB3S4I95ASjTXp+ajQ2wN5 fFkyNWRxcE85V5cLX3CZX4uJY3ylOYexs8pgThI/CEME41SN5bdL2z4/+1Ga0EUFwMx/ JEJg== X-Gm-Message-State: APjAAAV0/c2xyFbXCfwoao1glG//pV6MGWNWGOjk2x8dX49XEDmLdc7u cdvT0pItgHOON2NwXeHly0qz2ZaOT9dlPXkqrtBt5s1GJ2g+Rk9UwVwvWgYpnnqalvUh7PCD/1F KW2B9XyVkXhvhB4c3er0cCQFs X-Received: by 2002:aed:3762:: with SMTP id i89mr2711591qtb.69.1573117731120; Thu, 07 Nov 2019 01:08:51 -0800 (PST) X-Google-Smtp-Source: APXvYqweC4n74z/ghU3aODI0O03qx4TNMZLpGEG3t2lFq0mpTiNcnn1UrlGFUzbl5VMo/050oDK8bw== X-Received: by 2002:aed:3762:: with SMTP id i89mr2711543qtb.69.1573117730668; Thu, 07 Nov 2019 01:08:50 -0800 (PST) Received: from redhat.com (bzq-79-178-12-128.red.bezeqint.net. [79.178.12.128]) by smtp.gmail.com with ESMTPSA id c195sm928750qkg.6.2019.11.07.01.08.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2019 01:08:49 -0800 (PST) Date: Thu, 7 Nov 2019 04:08:37 -0500 From: "Michael S. Tsirkin" To: Jason Wang Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org, kwankhede@nvidia.com, alex.williamson@redhat.com, tiwei.bie@intel.com, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, cohuck@redhat.com, maxime.coquelin@redhat.com, cunming.liang@intel.com, zhihong.wang@intel.com, rob.miller@broadcom.com, xiao.w.wang@intel.com, haotian.wang@sifive.com, zhenyuw@linux.intel.com, zhi.a.wang@intel.com, jani.nikula@linux.intel.com, joonas.lahtinen@linux.intel.com, rodrigo.vivi@intel.com, airlied@linux.ie, daniel@ffwll.ch, farman@linux.ibm.com, pasic@linux.ibm.com, sebott@linux.ibm.com, oberpar@linux.ibm.com, heiko.carstens@de.ibm.com, gor@linux.ibm.com, borntraeger@de.ibm.com, akrowiak@linux.ibm.com, freude@linux.ibm.com, lingshan.zhu@intel.com, idos@mellanox.com, eperezma@redhat.com, lulu@redhat.com, parav@mellanox.com, christophe.de.dinechin@gmail.com, kevin.tian@intel.com, stefanha@redhat.com Subject: Re: [PATCH V10 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework Message-ID: <20191107040700-mutt-send-email-mst@kernel.org> References: <20191106133531.693-1-jasowang@redhat.com> <20191106133531.693-7-jasowang@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191106133531.693-7-jasowang@redhat.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Nov 06, 2019 at 09:35:31PM +0800, Jason Wang wrote: > This sample driver creates mdev device that simulate virtio net device > over virtio mdev transport. The device is implemented through vringh > and workqueue. A device specific dma ops is to make sure HVA is used > directly as the IOVA. This should be sufficient for kernel virtio > driver to work. > > Only 'virtio' type is supported right now. I plan to add 'vhost' type > on top which requires some virtual IOMMU implemented in this sample > driver. > > Acked-by: Cornelia Huck > Signed-off-by: Jason Wang I'd prefer it that we call this something else, e.g. mvnet-loopback. Just so people don't expect a fully functional device somehow. Can be renamed when applying? > --- > MAINTAINERS | 1 + > samples/Kconfig | 10 + > samples/vfio-mdev/Makefile | 1 + > samples/vfio-mdev/mvnet.c | 686 +++++++++++++++++++++++++++++++++++++ > 4 files changed, 698 insertions(+) > create mode 100644 samples/vfio-mdev/mvnet.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 4997957443df..6e9ad105a28f 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -17249,6 +17249,7 @@ F: include/uapi/linux/virtio_*.h > F: drivers/crypto/virtio/ > F: mm/balloon_compaction.c > F: include/linux/mdev_virtio_ops.h > +F: samples/vfio-mdev/mvnet.c > > VIRTIO BLOCK AND SCSI DRIVERS > M: "Michael S. Tsirkin" > diff --git a/samples/Kconfig b/samples/Kconfig > index c8dacb4dda80..13a2443e18e0 100644 > --- a/samples/Kconfig > +++ b/samples/Kconfig > @@ -131,6 +131,16 @@ config SAMPLE_VFIO_MDEV_MDPY > mediated device. It is a simple framebuffer and supports > the region display interface (VFIO_GFX_PLANE_TYPE_REGION). > > +config SAMPLE_VIRTIO_MDEV_NET > + tristate "Build VIRTIO net example mediated device sample code -- loadable modules only" > + depends on VIRTIO_MDEV && VHOST_RING && m > + help > + Build a networking sample device for use as a virtio > + mediated device. The device coopreates with virtio-mdev bus > + driver to present an virtio ethernet driver for > + kernel. It simply loopbacks all packets from its TX > + virtqueue to its RX virtqueue. > + > config SAMPLE_VFIO_MDEV_MDPY_FB > tristate "Build VFIO mdpy example guest fbdev driver -- loadable module only" > depends on FB && m > diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile > index 10d179c4fdeb..f34af90ed0a0 100644 > --- a/samples/vfio-mdev/Makefile > +++ b/samples/vfio-mdev/Makefile > @@ -3,3 +3,4 @@ obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o > obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY) += mdpy.o > obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB) += mdpy-fb.o > obj-$(CONFIG_SAMPLE_VFIO_MDEV_MBOCHS) += mbochs.o > +obj-$(CONFIG_SAMPLE_VIRTIO_MDEV_NET) += mvnet.o > diff --git a/samples/vfio-mdev/mvnet.c b/samples/vfio-mdev/mvnet.c > new file mode 100644 > index 000000000000..a89aecfab68a > --- /dev/null > +++ b/samples/vfio-mdev/mvnet.c > @@ -0,0 +1,686 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Mediated virtual virtio-net device driver. > + * > + * Copyright (c) 2019, Red Hat Inc. All rights reserved. > + * Author: Jason Wang > + * > + * Sample driver that creates mdev device that simulates ethernet loopback > + * device. > + * > + * Usage: > + * > + * # modprobe virtio_mdev > + * # modprobe mvnet > + * # cd /sys/devices/virtual/mvnet/mvnet/mdev_supported_types/mvnet-virtio > + * # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" > ./create > + * # cd devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001 > + * # ls -d virtio0 > + * virtio0 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define VERSION_STRING "0.1" > +#define DRIVER_AUTHOR "Red Hat Corporation" > + > +#define MVNET_CLASS_NAME "mvnet" > +#define MVNET_NAME "mvnet" > + > +/* > + * Global Structures > + */ > + > +static struct mvnet_dev { > + struct class *vd_class; > + struct idr vd_idr; > + struct device dev; > +} mvnet_dev; > + > +struct mvnet_virtqueue { > + struct vringh vring; > + struct vringh_kiov iov; > + unsigned short head; > + bool ready; > + u64 desc_addr; > + u64 device_addr; > + u64 driver_addr; > + u32 num; > + void *private; > + irqreturn_t (*cb)(void *data); > +}; > + > +#define MVNET_QUEUE_ALIGN PAGE_SIZE > +#define MVNET_QUEUE_MAX 256 > +#define MVNET_DEVICE_ID 0x1 > +#define MVNET_VENDOR_ID 0 > + > +u64 mvnet_features = (1ULL << VIRTIO_F_ANY_LAYOUT) | > + (1ULL << VIRTIO_F_VERSION_1) | > + (1ULL << VIRTIO_F_IOMMU_PLATFORM); > + > +/* State of each mdev device */ > +struct mvnet_state { > + struct mvnet_virtqueue vqs[2]; > + struct work_struct work; > + /* spinlock to synchronize virtqueue state */ > + spinlock_t lock; > + struct mdev_device *mdev; > + struct virtio_net_config config; > + void *buffer; > + u32 status; > + u32 generation; > + u64 features; > + struct list_head next; > +}; > + > +static struct mutex mdev_list_lock; > +static struct list_head mdev_devices_list; > + > +static void mvnet_queue_ready(struct mvnet_state *mvnet, unsigned int idx) > +{ > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + int ret; > + > + ret = vringh_init_kern(&vq->vring, mvnet_features, MVNET_QUEUE_MAX, > + false, (struct vring_desc *)vq->desc_addr, > + (struct vring_avail *)vq->driver_addr, > + (struct vring_used *)vq->device_addr); > +} > + > +static void mvnet_vq_reset(struct mvnet_virtqueue *vq) > +{ > + vq->ready = 0; > + vq->desc_addr = 0; > + vq->driver_addr = 0; > + vq->device_addr = 0; > + vq->cb = NULL; > + vq->private = NULL; > + vringh_init_kern(&vq->vring, mvnet_features, MVNET_QUEUE_MAX, > + false, 0, 0, 0); > +} > + > +static void mvnet_reset(struct mvnet_state *mvnet) > +{ > + int i; > + > + for (i = 0; i < 2; i++) > + mvnet_vq_reset(&mvnet->vqs[i]); > + > + mvnet->features = 0; > + mvnet->status = 0; > + ++mvnet->generation; > +} > + > +static void mvnet_work(struct work_struct *work) > +{ > + struct mvnet_state *mvnet = container_of(work, struct > + mvnet_state, work); > + struct mvnet_virtqueue *txq = &mvnet->vqs[1]; > + struct mvnet_virtqueue *rxq = &mvnet->vqs[0]; > + size_t read, write, total_write; > + int err; > + int pkts = 0; > + > + spin_lock(&mvnet->lock); > + > + if (!txq->ready || !rxq->ready) > + goto out; > + > + while (true) { > + total_write = 0; > + err = vringh_getdesc_kern(&txq->vring, &txq->iov, NULL, > + &txq->head, GFP_ATOMIC); > + if (err <= 0) > + break; > + > + err = vringh_getdesc_kern(&rxq->vring, NULL, &rxq->iov, > + &rxq->head, GFP_ATOMIC); > + if (err <= 0) { > + vringh_complete_kern(&txq->vring, txq->head, 0); > + break; > + } > + > + while (true) { > + read = vringh_iov_pull_kern(&txq->iov, mvnet->buffer, > + PAGE_SIZE); > + if (read <= 0) > + break; > + > + write = vringh_iov_push_kern(&rxq->iov, mvnet->buffer, > + read); > + if (write <= 0) > + break; > + > + total_write += write; > + } > + > + /* Make sure data is wrote before advancing index */ > + smp_wmb(); > + > + vringh_complete_kern(&txq->vring, txq->head, 0); > + vringh_complete_kern(&rxq->vring, rxq->head, total_write); > + > + /* Make sure used is visible before rasing the interrupt. */ > + smp_wmb(); > + > + local_bh_disable(); > + if (txq->cb) > + txq->cb(txq->private); > + if (rxq->cb) > + rxq->cb(rxq->private); > + local_bh_enable(); > + > + if (++pkts > 4) { > + schedule_work(&mvnet->work); > + goto out; > + } > + } > + > +out: > + spin_unlock(&mvnet->lock); > +} > + > +static dma_addr_t mvnet_map_page(struct device *dev, struct page *page, > + unsigned long offset, size_t size, > + enum dma_data_direction dir, > + unsigned long attrs) > +{ > + /* Vringh can only use HVA */ > + return (dma_addr_t)(page_address(page) + offset); > +} > + > +static void mvnet_unmap_page(struct device *dev, dma_addr_t dma_addr, > + size_t size, enum dma_data_direction dir, > + unsigned long attrs) > +{ > +} > + > +static void *mvnet_alloc_coherent(struct device *dev, size_t size, > + dma_addr_t *dma_addr, gfp_t flag, > + unsigned long attrs) > +{ > + void *addr = kmalloc(size, flag); > + > + if (!addr) > + *dma_addr = DMA_MAPPING_ERROR; > + else > + *dma_addr = (dma_addr_t)addr; > + > + return addr; > +} > + > +static void mvnet_free_coherent(struct device *dev, size_t size, > + void *vaddr, dma_addr_t dma_addr, > + unsigned long attrs) > +{ > + kfree((void *)dma_addr); > +} > + > +static const struct dma_map_ops mvnet_dma_ops = { > + .map_page = mvnet_map_page, > + .unmap_page = mvnet_unmap_page, > + .alloc = mvnet_alloc_coherent, > + .free = mvnet_free_coherent, > +}; > + > +static const struct mdev_virtio_device_ops mdev_virtio_ops; > + > +static int mvnet_create(struct kobject *kobj, struct mdev_device *mdev) > +{ > + struct mvnet_state *mvnet; > + struct virtio_net_config *config; > + struct device *dev = mdev_dev(mdev); > + > + if (!mdev) > + return -EINVAL; > + > + mvnet = kzalloc(sizeof(*mvnet), GFP_KERNEL); > + if (!mvnet) > + return -ENOMEM; > + > + mvnet->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); > + if (!mvnet->buffer) { > + kfree(mvnet); > + return -ENOMEM; > + } > + > + config = &mvnet->config; > + config->mtu = 1500; > + config->status = VIRTIO_NET_S_LINK_UP; > + eth_random_addr(config->mac); > + > + INIT_WORK(&mvnet->work, mvnet_work); > + > + spin_lock_init(&mvnet->lock); > + mvnet->mdev = mdev; > + mdev_set_drvdata(mdev, mvnet); > + > + mutex_lock(&mdev_list_lock); > + list_add(&mvnet->next, &mdev_devices_list); > + mutex_unlock(&mdev_list_lock); > + > + dev->coherent_dma_mask = DMA_BIT_MASK(64); > + set_dma_ops(dev, &mvnet_dma_ops); > + > + mdev_set_virtio_ops(mdev, &mdev_virtio_ops); > + > + return 0; > +} > + > +static int mvnet_remove(struct mdev_device *mdev) > +{ > + struct mvnet_state *mds, *tmp_mds; > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + int ret = -EINVAL; > + > + mutex_lock(&mdev_list_lock); > + list_for_each_entry_safe(mds, tmp_mds, &mdev_devices_list, next) { > + if (mvnet == mds) { > + list_del(&mvnet->next); > + mdev_set_drvdata(mdev, NULL); > + kfree(mvnet->buffer); > + kfree(mvnet); > + ret = 0; > + break; > + } > + } > + mutex_unlock(&mdev_list_lock); > + > + return ret; > +} > + > +static ssize_t > +sample_mvnet_dev_show(struct device *dev, struct device_attribute *attr, > + char *buf) > +{ > + if (mdev_from_dev(dev)) > + return sprintf(buf, "This is MDEV %s\n", dev_name(dev)); > + > + return sprintf(buf, "\n"); > +} > + > +static DEVICE_ATTR_RO(sample_mvnet_dev); > + > +static struct attribute *mvnet_dev_attrs[] = { > + &dev_attr_sample_mvnet_dev.attr, > + NULL, > +}; > + > +static const struct attribute_group mvnet_dev_group = { > + .name = "mvnet_dev", > + .attrs = mvnet_dev_attrs, > +}; > + > +static const struct attribute_group *mvnet_dev_groups[] = { > + &mvnet_dev_group, > + NULL, > +}; > + > +static ssize_t > +sample_mdev_dev_show(struct device *dev, struct device_attribute *attr, > + char *buf) > +{ > + if (mdev_from_dev(dev)) > + return sprintf(buf, "This is MDEV %s\n", dev_name(dev)); > + > + return sprintf(buf, "\n"); > +} > + > +static DEVICE_ATTR_RO(sample_mdev_dev); > + > +static struct attribute *mdev_dev_attrs[] = { > + &dev_attr_sample_mdev_dev.attr, > + NULL, > +}; > + > +static const struct attribute_group mdev_dev_group = { > + .name = "vendor", > + .attrs = mdev_dev_attrs, > +}; > + > +static const struct attribute_group *mdev_dev_groups[] = { > + &mdev_dev_group, > + NULL, > +}; > + > +#define MVNET_STRING_LEN 16 > + > +static ssize_t > +name_show(struct kobject *kobj, struct device *dev, char *buf) > +{ > + char name[MVNET_STRING_LEN]; > + const char *name_str = "virtio-net"; > + > + snprintf(name, MVNET_STRING_LEN, "%s", dev_driver_string(dev)); > + if (!strcmp(kobj->name, name)) > + return sprintf(buf, "%s\n", name_str); > + > + return -EINVAL; > +} > + > +static MDEV_TYPE_ATTR_RO(name); > + > +static ssize_t > +available_instances_show(struct kobject *kobj, struct device *dev, char *buf) > +{ > + return sprintf(buf, "%d\n", INT_MAX); > +} > + > +static MDEV_TYPE_ATTR_RO(available_instances); > + > +static ssize_t device_api_show(struct kobject *kobj, struct device *dev, > + char *buf) > +{ > + return sprintf(buf, "%s\n", VIRTIO_MDEV_DEVICE_API_STRING); > +} > + > +static MDEV_TYPE_ATTR_RO(device_api); > + > +static struct attribute *mdev_types_attrs[] = { > + &mdev_type_attr_name.attr, > + &mdev_type_attr_device_api.attr, > + &mdev_type_attr_available_instances.attr, > + NULL, > +}; > + > +static struct attribute_group mdev_type_group = { > + .name = "virtio", > + .attrs = mdev_types_attrs, > +}; > + > +/* TBD: "vhost" type */ > + > +static struct attribute_group *mdev_type_groups[] = { > + &mdev_type_group, > + NULL, > +}; > + > +static int mvnet_set_vq_address(struct mdev_device *mdev, u16 idx, > + u64 desc_area, u64 driver_area, u64 device_area) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + vq->desc_addr = desc_area; > + vq->driver_addr = driver_area; > + vq->device_addr = device_area; > + > + return 0; > +} > + > +static void mvnet_set_vq_num(struct mdev_device *mdev, u16 idx, u32 num) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + vq->num = num; > +} > + > +static void mvnet_kick_vq(struct mdev_device *mdev, u16 idx) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + if (vq->ready) > + schedule_work(&mvnet->work); > +} > + > +static void mvnet_set_vq_cb(struct mdev_device *mdev, u16 idx, > + struct virtio_mdev_callback *cb) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + vq->cb = cb->callback; > + vq->private = cb->private; > +} > + > +static void mvnet_set_vq_ready(struct mdev_device *mdev, u16 idx, bool ready) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + spin_lock(&mvnet->lock); > + vq->ready = ready; > + if (vq->ready) > + mvnet_queue_ready(mvnet, idx); > + spin_unlock(&mvnet->lock); > +} > + > +static bool mvnet_get_vq_ready(struct mdev_device *mdev, u16 idx) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + return vq->ready; > +} > + > +static int mvnet_set_vq_state(struct mdev_device *mdev, u16 idx, u64 state) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + struct vringh *vrh = &vq->vring; > + > + spin_lock(&mvnet->lock); > + vrh->last_avail_idx = state; > + spin_unlock(&mvnet->lock); > + > + return 0; > +} > + > +static u64 mvnet_get_vq_state(struct mdev_device *mdev, u16 idx) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + struct vringh *vrh = &vq->vring; > + > + return vrh->last_avail_idx; > +} > + > +static u16 mvnet_get_vq_align(struct mdev_device *mdev) > +{ > + return MVNET_QUEUE_ALIGN; > +} > + > +static u64 mvnet_get_features(struct mdev_device *mdev) > +{ > + return mvnet_features; > +} > + > +static int mvnet_set_features(struct mdev_device *mdev, u64 features) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + /* DMA mapping must be done by driver */ > + if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))) > + return -EINVAL; > + > + mvnet->features = features & mvnet_features; > + > + return 0; > +} > + > +static void mvnet_set_config_cb(struct mdev_device *mdev, > + struct virtio_mdev_callback *cb) > +{ > + /* We don't support config interrupt */ > +} > + > +static u16 mvnet_get_vq_num_max(struct mdev_device *mdev) > +{ > + return MVNET_QUEUE_MAX; > +} > + > +static u32 mvnet_get_device_id(struct mdev_device *mdev) > +{ > + return MVNET_DEVICE_ID; > +} > + > +static u32 mvnet_get_vendor_id(struct mdev_device *mdev) > +{ > + return MVNET_VENDOR_ID; > +} > + > +static u8 mvnet_get_status(struct mdev_device *mdev) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + return mvnet->status; > +} > + > +static void mvnet_set_status(struct mdev_device *mdev, u8 status) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + mvnet->status = status; > + > + if (status == 0) { > + spin_lock(&mvnet->lock); > + mvnet_reset(mvnet); > + spin_unlock(&mvnet->lock); > + } > +} > + > +static void mvnet_get_config(struct mdev_device *mdev, unsigned int offset, > + void *buf, unsigned int len) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + if (offset + len < sizeof(struct virtio_net_config)) > + memcpy(buf, &mvnet->config + offset, len); > +} > + > +static void mvnet_set_config(struct mdev_device *mdev, unsigned int offset, > + const void *buf, unsigned int len) > +{ > + /* No writable config supportted by mvnet */ > +} > + > +static u32 mvnet_get_generation(struct mdev_device *mdev) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + return mvnet->generation; > +} > + > +static const struct mdev_virtio_device_ops mdev_virtio_ops = { > + .set_vq_address = mvnet_set_vq_address, > + .set_vq_num = mvnet_set_vq_num, > + .kick_vq = mvnet_kick_vq, > + .set_vq_cb = mvnet_set_vq_cb, > + .set_vq_ready = mvnet_set_vq_ready, > + .get_vq_ready = mvnet_get_vq_ready, > + .set_vq_state = mvnet_set_vq_state, > + .get_vq_state = mvnet_get_vq_state, > + .get_vq_align = mvnet_get_vq_align, > + .get_features = mvnet_get_features, > + .set_features = mvnet_set_features, > + .set_config_cb = mvnet_set_config_cb, > + .get_vq_num_max = mvnet_get_vq_num_max, > + .get_device_id = mvnet_get_device_id, > + .get_vendor_id = mvnet_get_vendor_id, > + .get_status = mvnet_get_status, > + .set_status = mvnet_set_status, > + .get_config = mvnet_get_config, > + .set_config = mvnet_set_config, > + .get_generation = mvnet_get_generation, > +}; > + > +static const struct mdev_parent_ops mdev_fops = { > + .owner = THIS_MODULE, > + .dev_attr_groups = mvnet_dev_groups, > + .mdev_attr_groups = mdev_dev_groups, > + .supported_type_groups = mdev_type_groups, > + .create = mvnet_create, > + .remove = mvnet_remove, > +}; > + > +static void mvnet_device_release(struct device *dev) > +{ > + dev_dbg(dev, "mvnet: released\n"); > +} > + > +static int __init mvnet_dev_init(void) > +{ > + int ret = 0; > + > + pr_info("mvnet_dev: %s\n", __func__); > + > + memset(&mvnet_dev, 0, sizeof(mvnet_dev)); > + > + idr_init(&mvnet_dev.vd_idr); > + > + mvnet_dev.vd_class = class_create(THIS_MODULE, MVNET_CLASS_NAME); > + > + if (IS_ERR(mvnet_dev.vd_class)) { > + pr_err("Error: failed to register mvnet_dev class\n"); > + ret = PTR_ERR(mvnet_dev.vd_class); > + goto failed1; > + } > + > + mvnet_dev.dev.class = mvnet_dev.vd_class; > + mvnet_dev.dev.release = mvnet_device_release; > + dev_set_name(&mvnet_dev.dev, "%s", MVNET_NAME); > + > + ret = device_register(&mvnet_dev.dev); > + if (ret) > + goto failed2; > + > + ret = mdev_register_device(&mvnet_dev.dev, &mdev_fops); > + if (ret) > + goto failed3; > + > + mutex_init(&mdev_list_lock); > + INIT_LIST_HEAD(&mdev_devices_list); > + > + goto all_done; > + > +failed3: > + > + device_unregister(&mvnet_dev.dev); > +failed2: > + class_destroy(mvnet_dev.vd_class); > + > +failed1: > +all_done: > + return ret; > +} > + > +static void __exit mvnet_dev_exit(void) > +{ > + mvnet_dev.dev.bus = NULL; > + mdev_unregister_device(&mvnet_dev.dev); > + > + device_unregister(&mvnet_dev.dev); > + idr_destroy(&mvnet_dev.vd_idr); > + class_destroy(mvnet_dev.vd_class); > + mvnet_dev.vd_class = NULL; > + pr_info("mvnet_dev: Unloaded!\n"); > +} > + > +module_init(mvnet_dev_init) > +module_exit(mvnet_dev_exit) > + > +MODULE_LICENSE("GPL v2"); > +MODULE_INFO(supported, "Simulate loopback ethernet device over mdev"); > +MODULE_VERSION(VERSION_STRING); > +MODULE_AUTHOR(DRIVER_AUTHOR); > -- > 2.19.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael S. Tsirkin" Subject: Re: [PATCH V10 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework Date: Thu, 7 Nov 2019 04:08:37 -0500 Message-ID: <20191107040700-mutt-send-email-mst@kernel.org> References: <20191106133531.693-1-jasowang@redhat.com> <20191106133531.693-7-jasowang@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline In-Reply-To: <20191106133531.693-7-jasowang@redhat.com> Sender: linux-kernel-owner@vger.kernel.org To: Jason Wang Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, intel-gvt-dev@lists.freedesktop.org, kwankhede@nvidia.com, alex.williamson@redhat.com, tiwei.bie@intel.com, virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, cohuck@redhat.com, maxime.coquelin@redhat.com, cunming.liang@intel.com, zhihong.wang@intel.com, rob.miller@broadcom.com, xiao.w.wang@intel.com, haotian.wang@sifive.com, zhenyuw@linux.intel.com, zhi.a.wang@intel.com, jani.nikula@linux.intel.com, joonas.lahtinen@linux.intel.com, rodrigo.vivi@intel.com, airlied@linux.ie, daniel@ffwll.ch, farman@linux.ibm.com, pasic@linux.ibm.com, sebott@linux.ibm.com, oberpar@linux.ibm.com, heiko.carstens@de.ibm.com, gor@linux.ib List-Id: dri-devel@lists.freedesktop.org On Wed, Nov 06, 2019 at 09:35:31PM +0800, Jason Wang wrote: > This sample driver creates mdev device that simulate virtio net device > over virtio mdev transport. The device is implemented through vringh > and workqueue. A device specific dma ops is to make sure HVA is used > directly as the IOVA. This should be sufficient for kernel virtio > driver to work. > > Only 'virtio' type is supported right now. I plan to add 'vhost' type > on top which requires some virtual IOMMU implemented in this sample > driver. > > Acked-by: Cornelia Huck > Signed-off-by: Jason Wang I'd prefer it that we call this something else, e.g. mvnet-loopback. Just so people don't expect a fully functional device somehow. Can be renamed when applying? > --- > MAINTAINERS | 1 + > samples/Kconfig | 10 + > samples/vfio-mdev/Makefile | 1 + > samples/vfio-mdev/mvnet.c | 686 +++++++++++++++++++++++++++++++++++++ > 4 files changed, 698 insertions(+) > create mode 100644 samples/vfio-mdev/mvnet.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 4997957443df..6e9ad105a28f 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -17249,6 +17249,7 @@ F: include/uapi/linux/virtio_*.h > F: drivers/crypto/virtio/ > F: mm/balloon_compaction.c > F: include/linux/mdev_virtio_ops.h > +F: samples/vfio-mdev/mvnet.c > > VIRTIO BLOCK AND SCSI DRIVERS > M: "Michael S. Tsirkin" > diff --git a/samples/Kconfig b/samples/Kconfig > index c8dacb4dda80..13a2443e18e0 100644 > --- a/samples/Kconfig > +++ b/samples/Kconfig > @@ -131,6 +131,16 @@ config SAMPLE_VFIO_MDEV_MDPY > mediated device. It is a simple framebuffer and supports > the region display interface (VFIO_GFX_PLANE_TYPE_REGION). > > +config SAMPLE_VIRTIO_MDEV_NET > + tristate "Build VIRTIO net example mediated device sample code -- loadable modules only" > + depends on VIRTIO_MDEV && VHOST_RING && m > + help > + Build a networking sample device for use as a virtio > + mediated device. The device coopreates with virtio-mdev bus > + driver to present an virtio ethernet driver for > + kernel. It simply loopbacks all packets from its TX > + virtqueue to its RX virtqueue. > + > config SAMPLE_VFIO_MDEV_MDPY_FB > tristate "Build VFIO mdpy example guest fbdev driver -- loadable module only" > depends on FB && m > diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile > index 10d179c4fdeb..f34af90ed0a0 100644 > --- a/samples/vfio-mdev/Makefile > +++ b/samples/vfio-mdev/Makefile > @@ -3,3 +3,4 @@ obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o > obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY) += mdpy.o > obj-$(CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB) += mdpy-fb.o > obj-$(CONFIG_SAMPLE_VFIO_MDEV_MBOCHS) += mbochs.o > +obj-$(CONFIG_SAMPLE_VIRTIO_MDEV_NET) += mvnet.o > diff --git a/samples/vfio-mdev/mvnet.c b/samples/vfio-mdev/mvnet.c > new file mode 100644 > index 000000000000..a89aecfab68a > --- /dev/null > +++ b/samples/vfio-mdev/mvnet.c > @@ -0,0 +1,686 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Mediated virtual virtio-net device driver. > + * > + * Copyright (c) 2019, Red Hat Inc. All rights reserved. > + * Author: Jason Wang > + * > + * Sample driver that creates mdev device that simulates ethernet loopback > + * device. > + * > + * Usage: > + * > + * # modprobe virtio_mdev > + * # modprobe mvnet > + * # cd /sys/devices/virtual/mvnet/mvnet/mdev_supported_types/mvnet-virtio > + * # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" > ./create > + * # cd devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001 > + * # ls -d virtio0 > + * virtio0 > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define VERSION_STRING "0.1" > +#define DRIVER_AUTHOR "Red Hat Corporation" > + > +#define MVNET_CLASS_NAME "mvnet" > +#define MVNET_NAME "mvnet" > + > +/* > + * Global Structures > + */ > + > +static struct mvnet_dev { > + struct class *vd_class; > + struct idr vd_idr; > + struct device dev; > +} mvnet_dev; > + > +struct mvnet_virtqueue { > + struct vringh vring; > + struct vringh_kiov iov; > + unsigned short head; > + bool ready; > + u64 desc_addr; > + u64 device_addr; > + u64 driver_addr; > + u32 num; > + void *private; > + irqreturn_t (*cb)(void *data); > +}; > + > +#define MVNET_QUEUE_ALIGN PAGE_SIZE > +#define MVNET_QUEUE_MAX 256 > +#define MVNET_DEVICE_ID 0x1 > +#define MVNET_VENDOR_ID 0 > + > +u64 mvnet_features = (1ULL << VIRTIO_F_ANY_LAYOUT) | > + (1ULL << VIRTIO_F_VERSION_1) | > + (1ULL << VIRTIO_F_IOMMU_PLATFORM); > + > +/* State of each mdev device */ > +struct mvnet_state { > + struct mvnet_virtqueue vqs[2]; > + struct work_struct work; > + /* spinlock to synchronize virtqueue state */ > + spinlock_t lock; > + struct mdev_device *mdev; > + struct virtio_net_config config; > + void *buffer; > + u32 status; > + u32 generation; > + u64 features; > + struct list_head next; > +}; > + > +static struct mutex mdev_list_lock; > +static struct list_head mdev_devices_list; > + > +static void mvnet_queue_ready(struct mvnet_state *mvnet, unsigned int idx) > +{ > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + int ret; > + > + ret = vringh_init_kern(&vq->vring, mvnet_features, MVNET_QUEUE_MAX, > + false, (struct vring_desc *)vq->desc_addr, > + (struct vring_avail *)vq->driver_addr, > + (struct vring_used *)vq->device_addr); > +} > + > +static void mvnet_vq_reset(struct mvnet_virtqueue *vq) > +{ > + vq->ready = 0; > + vq->desc_addr = 0; > + vq->driver_addr = 0; > + vq->device_addr = 0; > + vq->cb = NULL; > + vq->private = NULL; > + vringh_init_kern(&vq->vring, mvnet_features, MVNET_QUEUE_MAX, > + false, 0, 0, 0); > +} > + > +static void mvnet_reset(struct mvnet_state *mvnet) > +{ > + int i; > + > + for (i = 0; i < 2; i++) > + mvnet_vq_reset(&mvnet->vqs[i]); > + > + mvnet->features = 0; > + mvnet->status = 0; > + ++mvnet->generation; > +} > + > +static void mvnet_work(struct work_struct *work) > +{ > + struct mvnet_state *mvnet = container_of(work, struct > + mvnet_state, work); > + struct mvnet_virtqueue *txq = &mvnet->vqs[1]; > + struct mvnet_virtqueue *rxq = &mvnet->vqs[0]; > + size_t read, write, total_write; > + int err; > + int pkts = 0; > + > + spin_lock(&mvnet->lock); > + > + if (!txq->ready || !rxq->ready) > + goto out; > + > + while (true) { > + total_write = 0; > + err = vringh_getdesc_kern(&txq->vring, &txq->iov, NULL, > + &txq->head, GFP_ATOMIC); > + if (err <= 0) > + break; > + > + err = vringh_getdesc_kern(&rxq->vring, NULL, &rxq->iov, > + &rxq->head, GFP_ATOMIC); > + if (err <= 0) { > + vringh_complete_kern(&txq->vring, txq->head, 0); > + break; > + } > + > + while (true) { > + read = vringh_iov_pull_kern(&txq->iov, mvnet->buffer, > + PAGE_SIZE); > + if (read <= 0) > + break; > + > + write = vringh_iov_push_kern(&rxq->iov, mvnet->buffer, > + read); > + if (write <= 0) > + break; > + > + total_write += write; > + } > + > + /* Make sure data is wrote before advancing index */ > + smp_wmb(); > + > + vringh_complete_kern(&txq->vring, txq->head, 0); > + vringh_complete_kern(&rxq->vring, rxq->head, total_write); > + > + /* Make sure used is visible before rasing the interrupt. */ > + smp_wmb(); > + > + local_bh_disable(); > + if (txq->cb) > + txq->cb(txq->private); > + if (rxq->cb) > + rxq->cb(rxq->private); > + local_bh_enable(); > + > + if (++pkts > 4) { > + schedule_work(&mvnet->work); > + goto out; > + } > + } > + > +out: > + spin_unlock(&mvnet->lock); > +} > + > +static dma_addr_t mvnet_map_page(struct device *dev, struct page *page, > + unsigned long offset, size_t size, > + enum dma_data_direction dir, > + unsigned long attrs) > +{ > + /* Vringh can only use HVA */ > + return (dma_addr_t)(page_address(page) + offset); > +} > + > +static void mvnet_unmap_page(struct device *dev, dma_addr_t dma_addr, > + size_t size, enum dma_data_direction dir, > + unsigned long attrs) > +{ > +} > + > +static void *mvnet_alloc_coherent(struct device *dev, size_t size, > + dma_addr_t *dma_addr, gfp_t flag, > + unsigned long attrs) > +{ > + void *addr = kmalloc(size, flag); > + > + if (!addr) > + *dma_addr = DMA_MAPPING_ERROR; > + else > + *dma_addr = (dma_addr_t)addr; > + > + return addr; > +} > + > +static void mvnet_free_coherent(struct device *dev, size_t size, > + void *vaddr, dma_addr_t dma_addr, > + unsigned long attrs) > +{ > + kfree((void *)dma_addr); > +} > + > +static const struct dma_map_ops mvnet_dma_ops = { > + .map_page = mvnet_map_page, > + .unmap_page = mvnet_unmap_page, > + .alloc = mvnet_alloc_coherent, > + .free = mvnet_free_coherent, > +}; > + > +static const struct mdev_virtio_device_ops mdev_virtio_ops; > + > +static int mvnet_create(struct kobject *kobj, struct mdev_device *mdev) > +{ > + struct mvnet_state *mvnet; > + struct virtio_net_config *config; > + struct device *dev = mdev_dev(mdev); > + > + if (!mdev) > + return -EINVAL; > + > + mvnet = kzalloc(sizeof(*mvnet), GFP_KERNEL); > + if (!mvnet) > + return -ENOMEM; > + > + mvnet->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); > + if (!mvnet->buffer) { > + kfree(mvnet); > + return -ENOMEM; > + } > + > + config = &mvnet->config; > + config->mtu = 1500; > + config->status = VIRTIO_NET_S_LINK_UP; > + eth_random_addr(config->mac); > + > + INIT_WORK(&mvnet->work, mvnet_work); > + > + spin_lock_init(&mvnet->lock); > + mvnet->mdev = mdev; > + mdev_set_drvdata(mdev, mvnet); > + > + mutex_lock(&mdev_list_lock); > + list_add(&mvnet->next, &mdev_devices_list); > + mutex_unlock(&mdev_list_lock); > + > + dev->coherent_dma_mask = DMA_BIT_MASK(64); > + set_dma_ops(dev, &mvnet_dma_ops); > + > + mdev_set_virtio_ops(mdev, &mdev_virtio_ops); > + > + return 0; > +} > + > +static int mvnet_remove(struct mdev_device *mdev) > +{ > + struct mvnet_state *mds, *tmp_mds; > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + int ret = -EINVAL; > + > + mutex_lock(&mdev_list_lock); > + list_for_each_entry_safe(mds, tmp_mds, &mdev_devices_list, next) { > + if (mvnet == mds) { > + list_del(&mvnet->next); > + mdev_set_drvdata(mdev, NULL); > + kfree(mvnet->buffer); > + kfree(mvnet); > + ret = 0; > + break; > + } > + } > + mutex_unlock(&mdev_list_lock); > + > + return ret; > +} > + > +static ssize_t > +sample_mvnet_dev_show(struct device *dev, struct device_attribute *attr, > + char *buf) > +{ > + if (mdev_from_dev(dev)) > + return sprintf(buf, "This is MDEV %s\n", dev_name(dev)); > + > + return sprintf(buf, "\n"); > +} > + > +static DEVICE_ATTR_RO(sample_mvnet_dev); > + > +static struct attribute *mvnet_dev_attrs[] = { > + &dev_attr_sample_mvnet_dev.attr, > + NULL, > +}; > + > +static const struct attribute_group mvnet_dev_group = { > + .name = "mvnet_dev", > + .attrs = mvnet_dev_attrs, > +}; > + > +static const struct attribute_group *mvnet_dev_groups[] = { > + &mvnet_dev_group, > + NULL, > +}; > + > +static ssize_t > +sample_mdev_dev_show(struct device *dev, struct device_attribute *attr, > + char *buf) > +{ > + if (mdev_from_dev(dev)) > + return sprintf(buf, "This is MDEV %s\n", dev_name(dev)); > + > + return sprintf(buf, "\n"); > +} > + > +static DEVICE_ATTR_RO(sample_mdev_dev); > + > +static struct attribute *mdev_dev_attrs[] = { > + &dev_attr_sample_mdev_dev.attr, > + NULL, > +}; > + > +static const struct attribute_group mdev_dev_group = { > + .name = "vendor", > + .attrs = mdev_dev_attrs, > +}; > + > +static const struct attribute_group *mdev_dev_groups[] = { > + &mdev_dev_group, > + NULL, > +}; > + > +#define MVNET_STRING_LEN 16 > + > +static ssize_t > +name_show(struct kobject *kobj, struct device *dev, char *buf) > +{ > + char name[MVNET_STRING_LEN]; > + const char *name_str = "virtio-net"; > + > + snprintf(name, MVNET_STRING_LEN, "%s", dev_driver_string(dev)); > + if (!strcmp(kobj->name, name)) > + return sprintf(buf, "%s\n", name_str); > + > + return -EINVAL; > +} > + > +static MDEV_TYPE_ATTR_RO(name); > + > +static ssize_t > +available_instances_show(struct kobject *kobj, struct device *dev, char *buf) > +{ > + return sprintf(buf, "%d\n", INT_MAX); > +} > + > +static MDEV_TYPE_ATTR_RO(available_instances); > + > +static ssize_t device_api_show(struct kobject *kobj, struct device *dev, > + char *buf) > +{ > + return sprintf(buf, "%s\n", VIRTIO_MDEV_DEVICE_API_STRING); > +} > + > +static MDEV_TYPE_ATTR_RO(device_api); > + > +static struct attribute *mdev_types_attrs[] = { > + &mdev_type_attr_name.attr, > + &mdev_type_attr_device_api.attr, > + &mdev_type_attr_available_instances.attr, > + NULL, > +}; > + > +static struct attribute_group mdev_type_group = { > + .name = "virtio", > + .attrs = mdev_types_attrs, > +}; > + > +/* TBD: "vhost" type */ > + > +static struct attribute_group *mdev_type_groups[] = { > + &mdev_type_group, > + NULL, > +}; > + > +static int mvnet_set_vq_address(struct mdev_device *mdev, u16 idx, > + u64 desc_area, u64 driver_area, u64 device_area) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + vq->desc_addr = desc_area; > + vq->driver_addr = driver_area; > + vq->device_addr = device_area; > + > + return 0; > +} > + > +static void mvnet_set_vq_num(struct mdev_device *mdev, u16 idx, u32 num) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + vq->num = num; > +} > + > +static void mvnet_kick_vq(struct mdev_device *mdev, u16 idx) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + if (vq->ready) > + schedule_work(&mvnet->work); > +} > + > +static void mvnet_set_vq_cb(struct mdev_device *mdev, u16 idx, > + struct virtio_mdev_callback *cb) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + vq->cb = cb->callback; > + vq->private = cb->private; > +} > + > +static void mvnet_set_vq_ready(struct mdev_device *mdev, u16 idx, bool ready) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + spin_lock(&mvnet->lock); > + vq->ready = ready; > + if (vq->ready) > + mvnet_queue_ready(mvnet, idx); > + spin_unlock(&mvnet->lock); > +} > + > +static bool mvnet_get_vq_ready(struct mdev_device *mdev, u16 idx) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + > + return vq->ready; > +} > + > +static int mvnet_set_vq_state(struct mdev_device *mdev, u16 idx, u64 state) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + struct vringh *vrh = &vq->vring; > + > + spin_lock(&mvnet->lock); > + vrh->last_avail_idx = state; > + spin_unlock(&mvnet->lock); > + > + return 0; > +} > + > +static u64 mvnet_get_vq_state(struct mdev_device *mdev, u16 idx) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + struct mvnet_virtqueue *vq = &mvnet->vqs[idx]; > + struct vringh *vrh = &vq->vring; > + > + return vrh->last_avail_idx; > +} > + > +static u16 mvnet_get_vq_align(struct mdev_device *mdev) > +{ > + return MVNET_QUEUE_ALIGN; > +} > + > +static u64 mvnet_get_features(struct mdev_device *mdev) > +{ > + return mvnet_features; > +} > + > +static int mvnet_set_features(struct mdev_device *mdev, u64 features) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + /* DMA mapping must be done by driver */ > + if (!(features & (1ULL << VIRTIO_F_IOMMU_PLATFORM))) > + return -EINVAL; > + > + mvnet->features = features & mvnet_features; > + > + return 0; > +} > + > +static void mvnet_set_config_cb(struct mdev_device *mdev, > + struct virtio_mdev_callback *cb) > +{ > + /* We don't support config interrupt */ > +} > + > +static u16 mvnet_get_vq_num_max(struct mdev_device *mdev) > +{ > + return MVNET_QUEUE_MAX; > +} > + > +static u32 mvnet_get_device_id(struct mdev_device *mdev) > +{ > + return MVNET_DEVICE_ID; > +} > + > +static u32 mvnet_get_vendor_id(struct mdev_device *mdev) > +{ > + return MVNET_VENDOR_ID; > +} > + > +static u8 mvnet_get_status(struct mdev_device *mdev) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + return mvnet->status; > +} > + > +static void mvnet_set_status(struct mdev_device *mdev, u8 status) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + mvnet->status = status; > + > + if (status == 0) { > + spin_lock(&mvnet->lock); > + mvnet_reset(mvnet); > + spin_unlock(&mvnet->lock); > + } > +} > + > +static void mvnet_get_config(struct mdev_device *mdev, unsigned int offset, > + void *buf, unsigned int len) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + if (offset + len < sizeof(struct virtio_net_config)) > + memcpy(buf, &mvnet->config + offset, len); > +} > + > +static void mvnet_set_config(struct mdev_device *mdev, unsigned int offset, > + const void *buf, unsigned int len) > +{ > + /* No writable config supportted by mvnet */ > +} > + > +static u32 mvnet_get_generation(struct mdev_device *mdev) > +{ > + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); > + > + return mvnet->generation; > +} > + > +static const struct mdev_virtio_device_ops mdev_virtio_ops = { > + .set_vq_address = mvnet_set_vq_address, > + .set_vq_num = mvnet_set_vq_num, > + .kick_vq = mvnet_kick_vq, > + .set_vq_cb = mvnet_set_vq_cb, > + .set_vq_ready = mvnet_set_vq_ready, > + .get_vq_ready = mvnet_get_vq_ready, > + .set_vq_state = mvnet_set_vq_state, > + .get_vq_state = mvnet_get_vq_state, > + .get_vq_align = mvnet_get_vq_align, > + .get_features = mvnet_get_features, > + .set_features = mvnet_set_features, > + .set_config_cb = mvnet_set_config_cb, > + .get_vq_num_max = mvnet_get_vq_num_max, > + .get_device_id = mvnet_get_device_id, > + .get_vendor_id = mvnet_get_vendor_id, > + .get_status = mvnet_get_status, > + .set_status = mvnet_set_status, > + .get_config = mvnet_get_config, > + .set_config = mvnet_set_config, > + .get_generation = mvnet_get_generation, > +}; > + > +static const struct mdev_parent_ops mdev_fops = { > + .owner = THIS_MODULE, > + .dev_attr_groups = mvnet_dev_groups, > + .mdev_attr_groups = mdev_dev_groups, > + .supported_type_groups = mdev_type_groups, > + .create = mvnet_create, > + .remove = mvnet_remove, > +}; > + > +static void mvnet_device_release(struct device *dev) > +{ > + dev_dbg(dev, "mvnet: released\n"); > +} > + > +static int __init mvnet_dev_init(void) > +{ > + int ret = 0; > + > + pr_info("mvnet_dev: %s\n", __func__); > + > + memset(&mvnet_dev, 0, sizeof(mvnet_dev)); > + > + idr_init(&mvnet_dev.vd_idr); > + > + mvnet_dev.vd_class = class_create(THIS_MODULE, MVNET_CLASS_NAME); > + > + if (IS_ERR(mvnet_dev.vd_class)) { > + pr_err("Error: failed to register mvnet_dev class\n"); > + ret = PTR_ERR(mvnet_dev.vd_class); > + goto failed1; > + } > + > + mvnet_dev.dev.class = mvnet_dev.vd_class; > + mvnet_dev.dev.release = mvnet_device_release; > + dev_set_name(&mvnet_dev.dev, "%s", MVNET_NAME); > + > + ret = device_register(&mvnet_dev.dev); > + if (ret) > + goto failed2; > + > + ret = mdev_register_device(&mvnet_dev.dev, &mdev_fops); > + if (ret) > + goto failed3; > + > + mutex_init(&mdev_list_lock); > + INIT_LIST_HEAD(&mdev_devices_list); > + > + goto all_done; > + > +failed3: > + > + device_unregister(&mvnet_dev.dev); > +failed2: > + class_destroy(mvnet_dev.vd_class); > + > +failed1: > +all_done: > + return ret; > +} > + > +static void __exit mvnet_dev_exit(void) > +{ > + mvnet_dev.dev.bus = NULL; > + mdev_unregister_device(&mvnet_dev.dev); > + > + device_unregister(&mvnet_dev.dev); > + idr_destroy(&mvnet_dev.vd_idr); > + class_destroy(mvnet_dev.vd_class); > + mvnet_dev.vd_class = NULL; > + pr_info("mvnet_dev: Unloaded!\n"); > +} > + > +module_init(mvnet_dev_init) > +module_exit(mvnet_dev_exit) > + > +MODULE_LICENSE("GPL v2"); > +MODULE_INFO(supported, "Simulate loopback ethernet device over mdev"); > +MODULE_VERSION(VERSION_STRING); > +MODULE_AUTHOR(DRIVER_AUTHOR); > -- > 2.19.1 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=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS 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 64033FA372C for ; Thu, 7 Nov 2019 09:08:54 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (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 3D6AD2178F for ; Thu, 7 Nov 2019 09:08:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3D6AD2178F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 973AE6F3AB; Thu, 7 Nov 2019 09:08:53 +0000 (UTC) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id B4FB86F3B1 for ; Thu, 7 Nov 2019 09:08:52 +0000 (UTC) Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 27C0083F42 for ; Thu, 7 Nov 2019 09:08:52 +0000 (UTC) Received: by mail-qt1-f199.google.com with SMTP id f5so1798296qtm.10 for ; Thu, 07 Nov 2019 01:08:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=y3kSmNPFNr1syqaEwVgmtYdBZ7wSJEKV0NnWLNNW74g=; b=T1vxNJOAKka0YNvS2FDPrIqXb2IlcIIByzoPhcxO6SSSifTwp+X6zP6laMbKnlBBtt /NGTPn8HG9dlb4/Z7MUfd2Alj2Gdw12pWUzz8qCoqzBCokbNlnD8HgSsFx+kHDw6f12M +UoTtFNLyQ5bFgcN8ih7ivC1j+z1Jna9OJOB/N8PtczP3KYqljMmECVOVBaBoxj9sERX XMXHtBa1fDhfVubovl+ikLJWqTP54RBM+mU2apQeUI5j1QRQ3soTPbpRJ3p767zR4m1a 8uNBNmlhzzRpDI9k8VaCLCz89SL/gztHaDcHTk2qURQ/DGHCLu19KCFoWTVMuuYZkidU sofg== X-Gm-Message-State: APjAAAWOhHJwNSTHxCCXiC3APsUg3xg7XbAWAQwjuf2qY1m6zraJ//Fc FR8oaBWR5CtzeMjbd5htpmtv5bpElP4Nl+8srLk/SyCdqi9WTHI4JIN0h/a9vH1yIv2FEgNVqb9 w00ZuDlyWBA1cBD1zQUswL28a2oBm X-Received: by 2002:aed:3762:: with SMTP id i89mr2711590qtb.69.1573117731126; Thu, 07 Nov 2019 01:08:51 -0800 (PST) X-Google-Smtp-Source: APXvYqweC4n74z/ghU3aODI0O03qx4TNMZLpGEG3t2lFq0mpTiNcnn1UrlGFUzbl5VMo/050oDK8bw== X-Received: by 2002:aed:3762:: with SMTP id i89mr2711543qtb.69.1573117730668; Thu, 07 Nov 2019 01:08:50 -0800 (PST) Received: from redhat.com (bzq-79-178-12-128.red.bezeqint.net. [79.178.12.128]) by smtp.gmail.com with ESMTPSA id c195sm928750qkg.6.2019.11.07.01.08.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2019 01:08:49 -0800 (PST) Date: Thu, 7 Nov 2019 04:08:37 -0500 From: "Michael S. Tsirkin" To: Jason Wang Subject: Re: [PATCH V10 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework Message-ID: <20191107040700-mutt-send-email-mst@kernel.org> References: <20191106133531.693-1-jasowang@redhat.com> <20191106133531.693-7-jasowang@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191106133531.693-7-jasowang@redhat.com> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stefanha@redhat.com, christophe.de.dinechin@gmail.com, kvm@vger.kernel.org, airlied@linux.ie, heiko.carstens@de.ibm.com, kevin.tian@intel.com, dri-devel@lists.freedesktop.org, virtualization@lists.linux-foundation.org, kwankhede@nvidia.com, rob.miller@broadcom.com, linux-s390@vger.kernel.org, sebott@linux.ibm.com, lulu@redhat.com, eperezma@redhat.com, pasic@linux.ibm.com, borntraeger@de.ibm.com, haotian.wang@sifive.com, cunming.liang@intel.com, zhi.a.wang@intel.com, farman@linux.ibm.com, idos@mellanox.com, gor@linux.ibm.com, intel-gfx@lists.freedesktop.org, alex.williamson@redhat.com, xiao.w.wang@intel.com, freude@linux.ibm.com, parav@mellanox.com, zhihong.wang@intel.com, rodrigo.vivi@intel.com, intel-gvt-dev@lists.freedesktop.org, akrowiak@linux.ibm.com, oberpar@linux.ibm.com, tiwei.bie@intel.com, netdev@vger.kernel.org, cohuck@redhat.com, linux-kernel@vger.kernel.org, maxime.coquelin@redhat.com, lingshan.zhu@intel.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Message-ID: <20191107090837.S1F741Fuj0eNsoLoP0OmjKl2Qo_64LRAH-50FopyEW8@z> T24gV2VkLCBOb3YgMDYsIDIwMTkgYXQgMDk6MzU6MzFQTSArMDgwMCwgSmFzb24gV2FuZyB3cm90 ZToKPiBUaGlzIHNhbXBsZSBkcml2ZXIgY3JlYXRlcyBtZGV2IGRldmljZSB0aGF0IHNpbXVsYXRl IHZpcnRpbyBuZXQgZGV2aWNlCj4gb3ZlciB2aXJ0aW8gbWRldiB0cmFuc3BvcnQuIFRoZSBkZXZp Y2UgaXMgaW1wbGVtZW50ZWQgdGhyb3VnaCB2cmluZ2gKPiBhbmQgd29ya3F1ZXVlLiBBIGRldmlj ZSBzcGVjaWZpYyBkbWEgb3BzIGlzIHRvIG1ha2Ugc3VyZSBIVkEgaXMgdXNlZAo+IGRpcmVjdGx5 IGFzIHRoZSBJT1ZBLiBUaGlzIHNob3VsZCBiZSBzdWZmaWNpZW50IGZvciBrZXJuZWwgdmlydGlv Cj4gZHJpdmVyIHRvIHdvcmsuCj4gCj4gT25seSAndmlydGlvJyB0eXBlIGlzIHN1cHBvcnRlZCBy aWdodCBub3cuIEkgcGxhbiB0byBhZGQgJ3Zob3N0JyB0eXBlCj4gb24gdG9wIHdoaWNoIHJlcXVp cmVzIHNvbWUgdmlydHVhbCBJT01NVSBpbXBsZW1lbnRlZCBpbiB0aGlzIHNhbXBsZQo+IGRyaXZl ci4KPiAKPiBBY2tlZC1ieTogQ29ybmVsaWEgSHVjayA8Y29odWNrQHJlZGhhdC5jb20+Cj4gU2ln bmVkLW9mZi1ieTogSmFzb24gV2FuZyA8amFzb3dhbmdAcmVkaGF0LmNvbT4KCgpJJ2QgcHJlZmVy IGl0IHRoYXQgd2UgY2FsbCB0aGlzIHNvbWV0aGluZyBlbHNlLCBlLmcuCm12bmV0LWxvb3BiYWNr LiBKdXN0IHNvIHBlb3BsZSBkb24ndCBleHBlY3QgYSBmdWxseQpmdW5jdGlvbmFsIGRldmljZSBz b21laG93LiBDYW4gYmUgcmVuYW1lZCB3aGVuIGFwcGx5aW5nPwoKCj4gLS0tCj4gIE1BSU5UQUlO RVJTICAgICAgICAgICAgICAgIHwgICAxICsKPiAgc2FtcGxlcy9LY29uZmlnICAgICAgICAgICAg fCAgMTAgKwo+ICBzYW1wbGVzL3ZmaW8tbWRldi9NYWtlZmlsZSB8ICAgMSArCj4gIHNhbXBsZXMv dmZpby1tZGV2L212bmV0LmMgIHwgNjg2ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysKPiAgNCBmaWxlcyBjaGFuZ2VkLCA2OTggaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9k ZSAxMDA2NDQgc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwo+IAo+IGRpZmYgLS1naXQgYS9NQUlO VEFJTkVSUyBiL01BSU5UQUlORVJTCj4gaW5kZXggNDk5Nzk1NzQ0M2RmLi42ZTlhZDEwNWEyOGYg MTAwNjQ0Cj4gLS0tIGEvTUFJTlRBSU5FUlMKPiArKysgYi9NQUlOVEFJTkVSUwo+IEBAIC0xNzI0 OSw2ICsxNzI0OSw3IEBAIEY6CWluY2x1ZGUvdWFwaS9saW51eC92aXJ0aW9fKi5oCj4gIEY6CWRy aXZlcnMvY3J5cHRvL3ZpcnRpby8KPiAgRjoJbW0vYmFsbG9vbl9jb21wYWN0aW9uLmMKPiAgRjoJ aW5jbHVkZS9saW51eC9tZGV2X3ZpcnRpb19vcHMuaAo+ICtGOglzYW1wbGVzL3ZmaW8tbWRldi9t dm5ldC5jCj4gIAo+ICBWSVJUSU8gQkxPQ0sgQU5EIFNDU0kgRFJJVkVSUwo+ICBNOgkiTWljaGFl bCBTLiBUc2lya2luIiA8bXN0QHJlZGhhdC5jb20+Cj4gZGlmZiAtLWdpdCBhL3NhbXBsZXMvS2Nv bmZpZyBiL3NhbXBsZXMvS2NvbmZpZwo+IGluZGV4IGM4ZGFjYjRkZGE4MC4uMTNhMjQ0M2UxOGUw IDEwMDY0NAo+IC0tLSBhL3NhbXBsZXMvS2NvbmZpZwo+ICsrKyBiL3NhbXBsZXMvS2NvbmZpZwo+ IEBAIC0xMzEsNiArMTMxLDE2IEBAIGNvbmZpZyBTQU1QTEVfVkZJT19NREVWX01EUFkKPiAgCSAg bWVkaWF0ZWQgZGV2aWNlLiAgSXQgaXMgYSBzaW1wbGUgZnJhbWVidWZmZXIgYW5kIHN1cHBvcnRz Cj4gIAkgIHRoZSByZWdpb24gZGlzcGxheSBpbnRlcmZhY2UgKFZGSU9fR0ZYX1BMQU5FX1RZUEVf UkVHSU9OKS4KPiAgCj4gK2NvbmZpZyBTQU1QTEVfVklSVElPX01ERVZfTkVUCj4gKwl0cmlzdGF0 ZSAiQnVpbGQgVklSVElPIG5ldCBleGFtcGxlIG1lZGlhdGVkIGRldmljZSBzYW1wbGUgY29kZSAt LSBsb2FkYWJsZSBtb2R1bGVzIG9ubHkiCj4gKwlkZXBlbmRzIG9uIFZJUlRJT19NREVWICYmIFZI T1NUX1JJTkcgJiYgbQo+ICsJaGVscAo+ICsJICBCdWlsZCBhIG5ldHdvcmtpbmcgc2FtcGxlIGRl dmljZSBmb3IgdXNlIGFzIGEgdmlydGlvCj4gKwkgIG1lZGlhdGVkIGRldmljZS4gVGhlIGRldmlj ZSBjb29wcmVhdGVzIHdpdGggdmlydGlvLW1kZXYgYnVzCj4gKwkgIGRyaXZlciB0byBwcmVzZW50 IGFuIHZpcnRpbyBldGhlcm5ldCBkcml2ZXIgZm9yCj4gKwkgIGtlcm5lbC4gSXQgc2ltcGx5IGxv b3BiYWNrcyBhbGwgcGFja2V0cyBmcm9tIGl0cyBUWAo+ICsJICB2aXJ0cXVldWUgdG8gaXRzIFJY IHZpcnRxdWV1ZS4KPiArCj4gIGNvbmZpZyBTQU1QTEVfVkZJT19NREVWX01EUFlfRkIKPiAgCXRy aXN0YXRlICJCdWlsZCBWRklPIG1kcHkgZXhhbXBsZSBndWVzdCBmYmRldiBkcml2ZXIgLS0gbG9h ZGFibGUgbW9kdWxlIG9ubHkiCj4gIAlkZXBlbmRzIG9uIEZCICYmIG0KPiBkaWZmIC0tZ2l0IGEv c2FtcGxlcy92ZmlvLW1kZXYvTWFrZWZpbGUgYi9zYW1wbGVzL3ZmaW8tbWRldi9NYWtlZmlsZQo+ IGluZGV4IDEwZDE3OWM0ZmRlYi4uZjM0YWY5MGVkMGEwIDEwMDY0NAo+IC0tLSBhL3NhbXBsZXMv dmZpby1tZGV2L01ha2VmaWxlCj4gKysrIGIvc2FtcGxlcy92ZmlvLW1kZXYvTWFrZWZpbGUKPiBA QCAtMywzICszLDQgQEAgb2JqLSQoQ09ORklHX1NBTVBMRV9WRklPX01ERVZfTVRUWSkgKz0gbXR0 eS5vCj4gIG9iai0kKENPTkZJR19TQU1QTEVfVkZJT19NREVWX01EUFkpICs9IG1kcHkubwo+ICBv YmotJChDT05GSUdfU0FNUExFX1ZGSU9fTURFVl9NRFBZX0ZCKSArPSBtZHB5LWZiLm8KPiAgb2Jq LSQoQ09ORklHX1NBTVBMRV9WRklPX01ERVZfTUJPQ0hTKSArPSBtYm9jaHMubwo+ICtvYmotJChD T05GSUdfU0FNUExFX1ZJUlRJT19NREVWX05FVCkgKz0gbXZuZXQubwo+IGRpZmYgLS1naXQgYS9z YW1wbGVzL3ZmaW8tbWRldi9tdm5ldC5jIGIvc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwo+IG5l dyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi5hODlhZWNmYWI2OGEKPiAt LS0gL2Rldi9udWxsCj4gKysrIGIvc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwo+IEBAIC0wLDAg KzEsNjg2IEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPiAr LyoKPiArICogTWVkaWF0ZWQgdmlydHVhbCB2aXJ0aW8tbmV0IGRldmljZSBkcml2ZXIuCj4gKyAq Cj4gKyAqIENvcHlyaWdodCAoYykgMjAxOSwgUmVkIEhhdCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2 ZWQuCj4gKyAqICAgICBBdXRob3I6IEphc29uIFdhbmcgPGphc293YW5nQHJlZGhhdC5jb20+Cj4g KyAqCj4gKyAqIFNhbXBsZSBkcml2ZXIgdGhhdCBjcmVhdGVzIG1kZXYgZGV2aWNlIHRoYXQgc2lt dWxhdGVzIGV0aGVybmV0IGxvb3BiYWNrCj4gKyAqIGRldmljZS4KPiArICoKPiArICogVXNhZ2U6 Cj4gKyAqCj4gKyAqICMgbW9kcHJvYmUgdmlydGlvX21kZXYKPiArICogIyBtb2Rwcm9iZSBtdm5l dAo+ICsgKiAjIGNkIC9zeXMvZGV2aWNlcy92aXJ0dWFsL212bmV0L212bmV0L21kZXZfc3VwcG9y dGVkX3R5cGVzL212bmV0LXZpcnRpbwo+ICsgKiAjIGVjaG8gIjgzYjhmNGYyLTUwOWYtMzgyZi0z YzFlLWU2YmZlMGZhMTAwMSIgPiAuL2NyZWF0ZQo+ICsgKiAjIGNkIGRldmljZXMvODNiOGY0ZjIt NTA5Zi0zODJmLTNjMWUtZTZiZmUwZmExMDAxCj4gKyAqICMgbHMgLWQgdmlydGlvMAo+ICsgKiB2 aXJ0aW8wCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUg PGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9rZXJuZWwuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2ZzLmg+Cj4gKyNpbmNsdWRlIDxs aW51eC9wb2xsLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9zY2hlZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvd2FpdC5oPgo+ICsjaW5jbHVkZSA8bGludXgv dXVpZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW9tbXUuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3N5 c2ZzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9maWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9ldGhl cmRldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvbWRldi5oPgo+ICsjaW5jbHVkZSA8bGludXgv dnJpbmdoLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tZGV2X3ZpcnRpb19vcHMuaD4KPiArI2luY2x1 ZGUgPHVhcGkvbGludXgvdmlydGlvX2NvbmZpZy5oPgo+ICsjaW5jbHVkZSA8dWFwaS9saW51eC92 aXJ0aW9fbmV0Lmg+Cj4gKwo+ICsjZGVmaW5lIFZFUlNJT05fU1RSSU5HICAiMC4xIgo+ICsjZGVm aW5lIERSSVZFUl9BVVRIT1IgICAiUmVkIEhhdCBDb3Jwb3JhdGlvbiIKPiArCj4gKyNkZWZpbmUg TVZORVRfQ0xBU1NfTkFNRSAibXZuZXQiCj4gKyNkZWZpbmUgTVZORVRfTkFNRSAgICAgICAibXZu ZXQiCj4gKwo+ICsvKgo+ICsgKiBHbG9iYWwgU3RydWN0dXJlcwo+ICsgKi8KPiArCj4gK3N0YXRp YyBzdHJ1Y3QgbXZuZXRfZGV2IHsKPiArCXN0cnVjdCBjbGFzcwkqdmRfY2xhc3M7Cj4gKwlzdHJ1 Y3QgaWRyCXZkX2lkcjsKPiArCXN0cnVjdCBkZXZpY2UJZGV2Owo+ICt9IG12bmV0X2RldjsKPiAr Cj4gK3N0cnVjdCBtdm5ldF92aXJ0cXVldWUgewo+ICsJc3RydWN0IHZyaW5naCB2cmluZzsKPiAr CXN0cnVjdCB2cmluZ2hfa2lvdiBpb3Y7Cj4gKwl1bnNpZ25lZCBzaG9ydCBoZWFkOwo+ICsJYm9v bCByZWFkeTsKPiArCXU2NCBkZXNjX2FkZHI7Cj4gKwl1NjQgZGV2aWNlX2FkZHI7Cj4gKwl1NjQg ZHJpdmVyX2FkZHI7Cj4gKwl1MzIgbnVtOwo+ICsJdm9pZCAqcHJpdmF0ZTsKPiArCWlycXJldHVy bl90ICgqY2IpKHZvaWQgKmRhdGEpOwo+ICt9Owo+ICsKPiArI2RlZmluZSBNVk5FVF9RVUVVRV9B TElHTiBQQUdFX1NJWkUKPiArI2RlZmluZSBNVk5FVF9RVUVVRV9NQVggMjU2Cj4gKyNkZWZpbmUg TVZORVRfREVWSUNFX0lEIDB4MQo+ICsjZGVmaW5lIE1WTkVUX1ZFTkRPUl9JRCAwCj4gKwo+ICt1 NjQgbXZuZXRfZmVhdHVyZXMgPSAoMVVMTCA8PCBWSVJUSU9fRl9BTllfTEFZT1VUKSB8Cj4gKwkJ ICAgICAoMVVMTCA8PCBWSVJUSU9fRl9WRVJTSU9OXzEpIHwKPiArCQkgICAgICgxVUxMIDw8IFZJ UlRJT19GX0lPTU1VX1BMQVRGT1JNKTsKPiArCj4gKy8qIFN0YXRlIG9mIGVhY2ggbWRldiBkZXZp Y2UgKi8KPiArc3RydWN0IG12bmV0X3N0YXRlIHsKPiArCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUg dnFzWzJdOwo+ICsJc3RydWN0IHdvcmtfc3RydWN0IHdvcms7Cj4gKwkvKiBzcGlubG9jayB0byBz eW5jaHJvbml6ZSB2aXJ0cXVldWUgc3RhdGUgKi8KPiArCXNwaW5sb2NrX3QgbG9jazsKPiArCXN0 cnVjdCBtZGV2X2RldmljZSAqbWRldjsKPiArCXN0cnVjdCB2aXJ0aW9fbmV0X2NvbmZpZyBjb25m aWc7Cj4gKwl2b2lkICpidWZmZXI7Cj4gKwl1MzIgc3RhdHVzOwo+ICsJdTMyIGdlbmVyYXRpb247 Cj4gKwl1NjQgZmVhdHVyZXM7Cj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIG5leHQ7Cj4gK307Cj4gKwo+ ICtzdGF0aWMgc3RydWN0IG11dGV4IG1kZXZfbGlzdF9sb2NrOwo+ICtzdGF0aWMgc3RydWN0IGxp c3RfaGVhZCBtZGV2X2RldmljZXNfbGlzdDsKPiArCj4gK3N0YXRpYyB2b2lkIG12bmV0X3F1ZXVl X3JlYWR5KHN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQsIHVuc2lnbmVkIGludCBpZHgpCj4gK3sK PiArCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKPiArCWlu dCByZXQ7Cj4gKwo+ICsJcmV0ID0gdnJpbmdoX2luaXRfa2VybigmdnEtPnZyaW5nLCBtdm5ldF9m ZWF0dXJlcywgTVZORVRfUVVFVUVfTUFYLAo+ICsJCQkgICAgICAgZmFsc2UsIChzdHJ1Y3QgdnJp bmdfZGVzYyAqKXZxLT5kZXNjX2FkZHIsCj4gKwkJCSAgICAgICAoc3RydWN0IHZyaW5nX2F2YWls ICopdnEtPmRyaXZlcl9hZGRyLAo+ICsJCQkgICAgICAgKHN0cnVjdCB2cmluZ191c2VkICopdnEt PmRldmljZV9hZGRyKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfdnFfcmVzZXQoc3Ry dWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEpCj4gK3sKPiArCXZxLT5yZWFkeSA9IDA7Cj4gKwl2cS0+ ZGVzY19hZGRyID0gMDsKPiArCXZxLT5kcml2ZXJfYWRkciA9IDA7Cj4gKwl2cS0+ZGV2aWNlX2Fk ZHIgPSAwOwo+ICsJdnEtPmNiID0gTlVMTDsKPiArCXZxLT5wcml2YXRlID0gTlVMTDsKPiArCXZy aW5naF9pbml0X2tlcm4oJnZxLT52cmluZywgbXZuZXRfZmVhdHVyZXMsIE1WTkVUX1FVRVVFX01B WCwKPiArCQkJIGZhbHNlLCAwLCAwLCAwKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRf cmVzZXQoc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCkKPiArewo+ICsJaW50IGk7Cj4gKwo+ICsJ Zm9yIChpID0gMDsgaSA8IDI7IGkrKykKPiArCQltdm5ldF92cV9yZXNldCgmbXZuZXQtPnZxc1tp XSk7Cj4gKwo+ICsJbXZuZXQtPmZlYXR1cmVzID0gMDsKPiArCW12bmV0LT5zdGF0dXMgPSAwOwo+ ICsJKyttdm5ldC0+Z2VuZXJhdGlvbjsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfd29y ayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCj4gK3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAq bXZuZXQgPSBjb250YWluZXJfb2Yod29yaywgc3RydWN0Cj4gKwkJCQkJCSBtdm5ldF9zdGF0ZSwg d29yayk7Cj4gKwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp0eHEgPSAmbXZuZXQtPnZxc1sxXTsK PiArCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnJ4cSA9ICZtdm5ldC0+dnFzWzBdOwo+ICsJc2l6 ZV90IHJlYWQsIHdyaXRlLCB0b3RhbF93cml0ZTsKPiArCWludCBlcnI7Cj4gKwlpbnQgcGt0cyA9 IDA7Cj4gKwo+ICsJc3Bpbl9sb2NrKCZtdm5ldC0+bG9jayk7Cj4gKwo+ICsJaWYgKCF0eHEtPnJl YWR5IHx8ICFyeHEtPnJlYWR5KQo+ICsJCWdvdG8gb3V0Owo+ICsKPiArCXdoaWxlICh0cnVlKSB7 Cj4gKwkJdG90YWxfd3JpdGUgPSAwOwo+ICsJCWVyciA9IHZyaW5naF9nZXRkZXNjX2tlcm4oJnR4 cS0+dnJpbmcsICZ0eHEtPmlvdiwgTlVMTCwKPiArCQkJCQkgICZ0eHEtPmhlYWQsIEdGUF9BVE9N SUMpOwo+ICsJCWlmIChlcnIgPD0gMCkKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWVyciA9IHZyaW5n aF9nZXRkZXNjX2tlcm4oJnJ4cS0+dnJpbmcsIE5VTEwsICZyeHEtPmlvdiwKPiArCQkJCQkgICZy eHEtPmhlYWQsIEdGUF9BVE9NSUMpOwo+ICsJCWlmIChlcnIgPD0gMCkgewo+ICsJCQl2cmluZ2hf Y29tcGxldGVfa2VybigmdHhxLT52cmluZywgdHhxLT5oZWFkLCAwKTsKPiArCQkJYnJlYWs7Cj4g KwkJfQo+ICsKPiArCQl3aGlsZSAodHJ1ZSkgewo+ICsJCQlyZWFkID0gdnJpbmdoX2lvdl9wdWxs X2tlcm4oJnR4cS0+aW92LCBtdm5ldC0+YnVmZmVyLAo+ICsJCQkJCQkgICAgUEFHRV9TSVpFKTsK PiArCQkJaWYgKHJlYWQgPD0gMCkKPiArCQkJCWJyZWFrOwo+ICsKPiArCQkJd3JpdGUgPSB2cmlu Z2hfaW92X3B1c2hfa2VybigmcnhxLT5pb3YsIG12bmV0LT5idWZmZXIsCj4gKwkJCQkJCSAgICAg cmVhZCk7Cj4gKwkJCWlmICh3cml0ZSA8PSAwKQo+ICsJCQkJYnJlYWs7Cj4gKwo+ICsJCQl0b3Rh bF93cml0ZSArPSB3cml0ZTsKPiArCQl9Cj4gKwo+ICsJCS8qIE1ha2Ugc3VyZSBkYXRhIGlzIHdy b3RlIGJlZm9yZSBhZHZhbmNpbmcgaW5kZXggKi8KPiArCQlzbXBfd21iKCk7Cj4gKwo+ICsJCXZy aW5naF9jb21wbGV0ZV9rZXJuKCZ0eHEtPnZyaW5nLCB0eHEtPmhlYWQsIDApOwo+ICsJCXZyaW5n aF9jb21wbGV0ZV9rZXJuKCZyeHEtPnZyaW5nLCByeHEtPmhlYWQsIHRvdGFsX3dyaXRlKTsKPiAr Cj4gKwkJLyogTWFrZSBzdXJlIHVzZWQgaXMgdmlzaWJsZSBiZWZvcmUgcmFzaW5nIHRoZSBpbnRl cnJ1cHQuICovCj4gKwkJc21wX3dtYigpOwo+ICsKPiArCQlsb2NhbF9iaF9kaXNhYmxlKCk7Cj4g KwkJaWYgKHR4cS0+Y2IpCj4gKwkJCXR4cS0+Y2IodHhxLT5wcml2YXRlKTsKPiArCQlpZiAocnhx LT5jYikKPiArCQkJcnhxLT5jYihyeHEtPnByaXZhdGUpOwo+ICsJCWxvY2FsX2JoX2VuYWJsZSgp Owo+ICsKPiArCQlpZiAoKytwa3RzID4gNCkgewo+ICsJCQlzY2hlZHVsZV93b3JrKCZtdm5ldC0+ d29yayk7Cj4gKwkJCWdvdG8gb3V0Owo+ICsJCX0KPiArCX0KPiArCj4gK291dDoKPiArCXNwaW5f dW5sb2NrKCZtdm5ldC0+bG9jayk7Cj4gK30KPiArCj4gK3N0YXRpYyBkbWFfYWRkcl90IG12bmV0 X21hcF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHBhZ2UgKnBhZ2UsCj4gKwkJCQkg dW5zaWduZWQgbG9uZyBvZmZzZXQsIHNpemVfdCBzaXplLAo+ICsJCQkJIGVudW0gZG1hX2RhdGFf ZGlyZWN0aW9uIGRpciwKPiArCQkJCSB1bnNpZ25lZCBsb25nIGF0dHJzKQo+ICt7Cj4gKwkvKiBW cmluZ2ggY2FuIG9ubHkgdXNlIEhWQSAqLwo+ICsJcmV0dXJuIChkbWFfYWRkcl90KShwYWdlX2Fk ZHJlc3MocGFnZSkgKyBvZmZzZXQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF91bm1h cF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgZG1hX2FkZHJfdCBkbWFfYWRkciwKPiArCQkJICAg ICBzaXplX3Qgc2l6ZSwgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyLAo+ICsJCQkgICAgIHVu c2lnbmVkIGxvbmcgYXR0cnMpCj4gK3sKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgKm12bmV0X2Fs bG9jX2NvaGVyZW50KHN0cnVjdCBkZXZpY2UgKmRldiwgc2l6ZV90IHNpemUsCj4gKwkJCQkgIGRt YV9hZGRyX3QgKmRtYV9hZGRyLCBnZnBfdCBmbGFnLAo+ICsJCQkJICB1bnNpZ25lZCBsb25nIGF0 dHJzKQo+ICt7Cj4gKwl2b2lkICphZGRyID0ga21hbGxvYyhzaXplLCBmbGFnKTsKPiArCj4gKwlp ZiAoIWFkZHIpCj4gKwkJKmRtYV9hZGRyID0gRE1BX01BUFBJTkdfRVJST1I7Cj4gKwllbHNlCj4g KwkJKmRtYV9hZGRyID0gKGRtYV9hZGRyX3QpYWRkcjsKPiArCj4gKwlyZXR1cm4gYWRkcjsKPiAr fQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfZnJlZV9jb2hlcmVudChzdHJ1Y3QgZGV2aWNlICpk ZXYsIHNpemVfdCBzaXplLAo+ICsJCQkJdm9pZCAqdmFkZHIsIGRtYV9hZGRyX3QgZG1hX2FkZHIs Cj4gKwkJCQl1bnNpZ25lZCBsb25nIGF0dHJzKQo+ICt7Cj4gKwlrZnJlZSgodm9pZCAqKWRtYV9h ZGRyKTsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBkbWFfbWFwX29wcyBtdm5ldF9k bWFfb3BzID0gewo+ICsJLm1hcF9wYWdlID0gbXZuZXRfbWFwX3BhZ2UsCj4gKwkudW5tYXBfcGFn ZSA9IG12bmV0X3VubWFwX3BhZ2UsCj4gKwkuYWxsb2MgPSBtdm5ldF9hbGxvY19jb2hlcmVudCwK PiArCS5mcmVlID0gbXZuZXRfZnJlZV9jb2hlcmVudCwKPiArfTsKPiArCj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgbWRldl92aXJ0aW9fZGV2aWNlX29wcyBtZGV2X3ZpcnRpb19vcHM7Cj4gKwo+ICtz dGF0aWMgaW50IG12bmV0X2NyZWF0ZShzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IG1kZXZf ZGV2aWNlICptZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgbXZuZXRfc3RhdGUgKm12bmV0Owo+ICsJc3Ry dWN0IHZpcnRpb19uZXRfY29uZmlnICpjb25maWc7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBt ZGV2X2RldihtZGV2KTsKPiArCj4gKwlpZiAoIW1kZXYpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4g Kwo+ICsJbXZuZXQgPSBremFsbG9jKHNpemVvZigqbXZuZXQpLCBHRlBfS0VSTkVMKTsKPiArCWlm ICghbXZuZXQpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJbXZuZXQtPmJ1ZmZlciA9IGtt YWxsb2MoUEFHRV9TSVpFLCBHRlBfS0VSTkVMKTsKPiArCWlmICghbXZuZXQtPmJ1ZmZlcikgewo+ ICsJCWtmcmVlKG12bmV0KTsKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCX0KPiArCj4gKwljb25m aWcgPSAmbXZuZXQtPmNvbmZpZzsKPiArCWNvbmZpZy0+bXR1ID0gMTUwMDsKPiArCWNvbmZpZy0+ c3RhdHVzID0gVklSVElPX05FVF9TX0xJTktfVVA7Cj4gKwlldGhfcmFuZG9tX2FkZHIoY29uZmln LT5tYWMpOwo+ICsKPiArCUlOSVRfV09SSygmbXZuZXQtPndvcmssIG12bmV0X3dvcmspOwo+ICsK PiArCXNwaW5fbG9ja19pbml0KCZtdm5ldC0+bG9jayk7Cj4gKwltdm5ldC0+bWRldiA9IG1kZXY7 Cj4gKwltZGV2X3NldF9kcnZkYXRhKG1kZXYsIG12bmV0KTsKPiArCj4gKwltdXRleF9sb2NrKCZt ZGV2X2xpc3RfbG9jayk7Cj4gKwlsaXN0X2FkZCgmbXZuZXQtPm5leHQsICZtZGV2X2RldmljZXNf bGlzdCk7Cj4gKwltdXRleF91bmxvY2soJm1kZXZfbGlzdF9sb2NrKTsKPiArCj4gKwlkZXYtPmNv aGVyZW50X2RtYV9tYXNrID0gRE1BX0JJVF9NQVNLKDY0KTsKPiArCXNldF9kbWFfb3BzKGRldiwg Jm12bmV0X2RtYV9vcHMpOwo+ICsKPiArCW1kZXZfc2V0X3ZpcnRpb19vcHMobWRldiwgJm1kZXZf dmlydGlvX29wcyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXZu ZXRfcmVtb3ZlKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKPiArewo+ICsJc3RydWN0IG12bmV0 X3N0YXRlICptZHMsICp0bXBfbWRzOwo+ICsJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1k ZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwlpbnQgcmV0ID0gLUVJTlZBTDsKPiArCj4gKwltdXRl eF9sb2NrKCZtZGV2X2xpc3RfbG9jayk7Cj4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUobWRz LCB0bXBfbWRzLCAmbWRldl9kZXZpY2VzX2xpc3QsIG5leHQpIHsKPiArCQlpZiAobXZuZXQgPT0g bWRzKSB7Cj4gKwkJCWxpc3RfZGVsKCZtdm5ldC0+bmV4dCk7Cj4gKwkJCW1kZXZfc2V0X2RydmRh dGEobWRldiwgTlVMTCk7Cj4gKwkJCWtmcmVlKG12bmV0LT5idWZmZXIpOwo+ICsJCQlrZnJlZSht dm5ldCk7Cj4gKwkJCXJldCA9IDA7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCX0KPiArCW11dGV4 X3VubG9jaygmbWRldl9saXN0X2xvY2spOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4g K3N0YXRpYyBzc2l6ZV90Cj4gK3NhbXBsZV9tdm5ldF9kZXZfc2hvdyhzdHJ1Y3QgZGV2aWNlICpk ZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+ICsJCSAgICAgIGNoYXIgKmJ1ZikK PiArewo+ICsJaWYgKG1kZXZfZnJvbV9kZXYoZGV2KSkKPiArCQlyZXR1cm4gc3ByaW50ZihidWYs ICJUaGlzIGlzIE1ERVYgJXNcbiIsIGRldl9uYW1lKGRldikpOwo+ICsKPiArCXJldHVybiBzcHJp bnRmKGJ1ZiwgIlxuIik7Cj4gK30KPiArCj4gK3N0YXRpYyBERVZJQ0VfQVRUUl9STyhzYW1wbGVf bXZuZXRfZGV2KTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICptdm5ldF9kZXZfYXR0 cnNbXSA9IHsKPiArCSZkZXZfYXR0cl9zYW1wbGVfbXZuZXRfZGV2LmF0dHIsCj4gKwlOVUxMLAo+ ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgbXZuZXRfZGV2 X2dyb3VwID0gewo+ICsJLm5hbWUgID0gIm12bmV0X2RldiIsCj4gKwkuYXR0cnMgPSBtdm5ldF9k ZXZfYXR0cnMsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91 cCAqbXZuZXRfZGV2X2dyb3Vwc1tdID0gewo+ICsJJm12bmV0X2Rldl9ncm91cCwKPiArCU5VTEws Cj4gK307Cj4gKwo+ICtzdGF0aWMgc3NpemVfdAo+ICtzYW1wbGVfbWRldl9kZXZfc2hvdyhzdHJ1 Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+ICsJCSAgICAg Y2hhciAqYnVmKQo+ICt7Cj4gKwlpZiAobWRldl9mcm9tX2RldihkZXYpKQo+ICsJCXJldHVybiBz cHJpbnRmKGJ1ZiwgIlRoaXMgaXMgTURFViAlc1xuIiwgZGV2X25hbWUoZGV2KSk7Cj4gKwo+ICsJ cmV0dXJuIHNwcmludGYoYnVmLCAiXG4iKTsKPiArfQo+ICsKPiArc3RhdGljIERFVklDRV9BVFRS X1JPKHNhbXBsZV9tZGV2X2Rldik7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqbWRl dl9kZXZfYXR0cnNbXSA9IHsKPiArCSZkZXZfYXR0cl9zYW1wbGVfbWRldl9kZXYuYXR0ciwKPiAr CU5VTEwsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBt ZGV2X2Rldl9ncm91cCA9IHsKPiArCS5uYW1lICA9ICJ2ZW5kb3IiLAo+ICsJLmF0dHJzID0gbWRl dl9kZXZfYXR0cnMsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9n cm91cCAqbWRldl9kZXZfZ3JvdXBzW10gPSB7Cj4gKwkmbWRldl9kZXZfZ3JvdXAsCj4gKwlOVUxM LAo+ICt9Owo+ICsKPiArI2RlZmluZSBNVk5FVF9TVFJJTkdfTEVOIDE2Cj4gKwo+ICtzdGF0aWMg c3NpemVfdAo+ICtuYW1lX3Nob3coc3RydWN0IGtvYmplY3QgKmtvYmosIHN0cnVjdCBkZXZpY2Ug KmRldiwgY2hhciAqYnVmKQo+ICt7Cj4gKwljaGFyIG5hbWVbTVZORVRfU1RSSU5HX0xFTl07Cj4g Kwljb25zdCBjaGFyICpuYW1lX3N0ciA9ICJ2aXJ0aW8tbmV0IjsKPiArCj4gKwlzbnByaW50Zihu YW1lLCBNVk5FVF9TVFJJTkdfTEVOLCAiJXMiLCBkZXZfZHJpdmVyX3N0cmluZyhkZXYpKTsKPiAr CWlmICghc3RyY21wKGtvYmotPm5hbWUsIG5hbWUpKQo+ICsJCXJldHVybiBzcHJpbnRmKGJ1Ziwg IiVzXG4iLCBuYW1lX3N0cik7Cj4gKwo+ICsJcmV0dXJuIC1FSU5WQUw7Cj4gK30KPiArCj4gK3N0 YXRpYyBNREVWX1RZUEVfQVRUUl9STyhuYW1lKTsKPiArCj4gK3N0YXRpYyBzc2l6ZV90Cj4gK2F2 YWlsYWJsZV9pbnN0YW5jZXNfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IGRldmlj ZSAqZGV2LCBjaGFyICpidWYpCj4gK3sKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkXG4iLCBJ TlRfTUFYKTsKPiArfQo+ICsKPiArc3RhdGljIE1ERVZfVFlQRV9BVFRSX1JPKGF2YWlsYWJsZV9p bnN0YW5jZXMpOwo+ICsKPiArc3RhdGljIHNzaXplX3QgZGV2aWNlX2FwaV9zaG93KHN0cnVjdCBr b2JqZWN0ICprb2JqLCBzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gKwkJCSAgICAgICBjaGFyICpidWYp Cj4gK3sKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBWSVJUSU9fTURFVl9ERVZJQ0Vf QVBJX1NUUklORyk7Cj4gK30KPiArCj4gK3N0YXRpYyBNREVWX1RZUEVfQVRUUl9STyhkZXZpY2Vf YXBpKTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICptZGV2X3R5cGVzX2F0dHJzW10g PSB7Cj4gKwkmbWRldl90eXBlX2F0dHJfbmFtZS5hdHRyLAo+ICsJJm1kZXZfdHlwZV9hdHRyX2Rl dmljZV9hcGkuYXR0ciwKPiArCSZtZGV2X3R5cGVfYXR0cl9hdmFpbGFibGVfaW5zdGFuY2VzLmF0 dHIsCj4gKwlOVUxMLAo+ICt9Owo+ICsKPiArc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAg bWRldl90eXBlX2dyb3VwID0gewo+ICsJLm5hbWUgID0gInZpcnRpbyIsCj4gKwkuYXR0cnMgPSBt ZGV2X3R5cGVzX2F0dHJzLAo+ICt9Owo+ICsKPiArLyogVEJEOiAidmhvc3QiIHR5cGUgKi8KPiAr Cj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwICptZGV2X3R5cGVfZ3JvdXBzW10gPSB7 Cj4gKwkmbWRldl90eXBlX2dyb3VwLAo+ICsJTlVMTCwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQg bXZuZXRfc2V0X3ZxX2FkZHJlc3Moc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4LAo+ ICsJCQkJdTY0IGRlc2NfYXJlYSwgdTY0IGRyaXZlcl9hcmVhLCB1NjQgZGV2aWNlX2FyZWEpCj4g K3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYp Owo+ICsJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEgPSAmbXZuZXQtPnZxc1tpZHhdOwo+ICsK PiArCXZxLT5kZXNjX2FkZHIgPSBkZXNjX2FyZWE7Cj4gKwl2cS0+ZHJpdmVyX2FkZHIgPSBkcml2 ZXJfYXJlYTsKPiArCXZxLT5kZXZpY2VfYWRkciA9IGRldmljZV9hcmVhOwo+ICsKPiArCXJldHVy biAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF9zZXRfdnFfbnVtKHN0cnVjdCBtZGV2 X2RldmljZSAqbWRldiwgdTE2IGlkeCwgdTMyIG51bSkKPiArewo+ICsJc3RydWN0IG12bmV0X3N0 YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwlzdHJ1Y3QgbXZuZXRfdmly dHF1ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07Cj4gKwo+ICsJdnEtPm51bSA9IG51bTsKPiAr fQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfa2lja192cShzdHJ1Y3QgbWRldl9kZXZpY2UgKm1k ZXYsIHUxNiBpZHgpCj4gK3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dl dF9kcnZkYXRhKG1kZXYpOwo+ICsJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEgPSAmbXZuZXQt PnZxc1tpZHhdOwo+ICsKPiArCWlmICh2cS0+cmVhZHkpCj4gKwkJc2NoZWR1bGVfd29yaygmbXZu ZXQtPndvcmspOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF9zZXRfdnFfY2Ioc3RydWN0 IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4LAo+ICsJCQkgICAgc3RydWN0IHZpcnRpb19tZGV2 X2NhbGxiYWNrICpjYikKPiArewo+ICsJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZf Z2V0X2RydmRhdGEobWRldik7Cj4gKwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp2cSA9ICZtdm5l dC0+dnFzW2lkeF07Cj4gKwo+ICsJdnEtPmNiID0gY2ItPmNhbGxiYWNrOwo+ICsJdnEtPnByaXZh dGUgPSBjYi0+cHJpdmF0ZTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfc2V0X3ZxX3Jl YWR5KHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwgdTE2IGlkeCwgYm9vbCByZWFkeSkKPiArewo+ ICsJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4g KwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07Cj4gKwo+ICsJ c3Bpbl9sb2NrKCZtdm5ldC0+bG9jayk7Cj4gKwl2cS0+cmVhZHkgPSByZWFkeTsKPiArCWlmICh2 cS0+cmVhZHkpCj4gKwkJbXZuZXRfcXVldWVfcmVhZHkobXZuZXQsIGlkeCk7Cj4gKwlzcGluX3Vu bG9jaygmbXZuZXQtPmxvY2spOwo+ICt9Cj4gKwo+ICtzdGF0aWMgYm9vbCBtdm5ldF9nZXRfdnFf cmVhZHkoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4KQo+ICt7Cj4gKwlzdHJ1Y3Qg bXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCXN0cnVjdCBt dm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKPiArCj4gKwlyZXR1cm4gdnEt PnJlYWR5Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG12bmV0X3NldF92cV9zdGF0ZShzdHJ1Y3Qg bWRldl9kZXZpY2UgKm1kZXYsIHUxNiBpZHgsIHU2NCBzdGF0ZSkKPiArewo+ICsJc3RydWN0IG12 bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwlzdHJ1Y3QgbXZu ZXRfdmlydHF1ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07Cj4gKwlzdHJ1Y3QgdnJpbmdoICp2 cmggPSAmdnEtPnZyaW5nOwo+ICsKPiArCXNwaW5fbG9jaygmbXZuZXQtPmxvY2spOwo+ICsJdnJo LT5sYXN0X2F2YWlsX2lkeCA9IHN0YXRlOwo+ICsJc3Bpbl91bmxvY2soJm12bmV0LT5sb2NrKTsK PiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHU2NCBtdm5ldF9nZXRfdnFfc3Rh dGUoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4KQo+ICt7Cj4gKwlzdHJ1Y3QgbXZu ZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCXN0cnVjdCBtdm5l dF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKPiArCXN0cnVjdCB2cmluZ2ggKnZy aCA9ICZ2cS0+dnJpbmc7Cj4gKwo+ICsJcmV0dXJuIHZyaC0+bGFzdF9hdmFpbF9pZHg7Cj4gK30K PiArCj4gK3N0YXRpYyB1MTYgbXZuZXRfZ2V0X3ZxX2FsaWduKHN0cnVjdCBtZGV2X2RldmljZSAq bWRldikKPiArewo+ICsJcmV0dXJuIE1WTkVUX1FVRVVFX0FMSUdOOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgdTY0IG12bmV0X2dldF9mZWF0dXJlcyhzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYpCj4gK3sK PiArCXJldHVybiBtdm5ldF9mZWF0dXJlczsKPiArfQo+ICsKPiArc3RhdGljIGludCBtdm5ldF9z ZXRfZmVhdHVyZXMoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1NjQgZmVhdHVyZXMpCj4gK3sK PiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYpOwo+ ICsKPiArCS8qIERNQSBtYXBwaW5nIG11c3QgYmUgZG9uZSBieSBkcml2ZXIgKi8KPiArCWlmICgh KGZlYXR1cmVzICYgKDFVTEwgPDwgVklSVElPX0ZfSU9NTVVfUExBVEZPUk0pKSkKPiArCQlyZXR1 cm4gLUVJTlZBTDsKPiArCj4gKwltdm5ldC0+ZmVhdHVyZXMgPSBmZWF0dXJlcyAmIG12bmV0X2Zl YXR1cmVzOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF9z ZXRfY29uZmlnX2NiKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwKPiArCQkJCXN0cnVjdCB2aXJ0 aW9fbWRldl9jYWxsYmFjayAqY2IpCj4gK3sKPiArCS8qIFdlIGRvbid0IHN1cHBvcnQgY29uZmln IGludGVycnVwdCAqLwo+ICt9Cj4gKwo+ICtzdGF0aWMgdTE2IG12bmV0X2dldF92cV9udW1fbWF4 KHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKPiArewo+ICsJcmV0dXJuIE1WTkVUX1FVRVVFX01B WDsKPiArfQo+ICsKPiArc3RhdGljIHUzMiBtdm5ldF9nZXRfZGV2aWNlX2lkKHN0cnVjdCBtZGV2 X2RldmljZSAqbWRldikKPiArewo+ICsJcmV0dXJuIE1WTkVUX0RFVklDRV9JRDsKPiArfQo+ICsK PiArc3RhdGljIHUzMiBtdm5ldF9nZXRfdmVuZG9yX2lkKHN0cnVjdCBtZGV2X2RldmljZSAqbWRl dikKPiArewo+ICsJcmV0dXJuIE1WTkVUX1ZFTkRPUl9JRDsKPiArfQo+ICsKPiArc3RhdGljIHU4 IG12bmV0X2dldF9zdGF0dXMoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KQo+ICt7Cj4gKwlzdHJ1 Y3QgbXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCj4gKwly ZXR1cm4gbXZuZXQtPnN0YXR1czsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfc2V0X3N0 YXR1cyhzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsIHU4IHN0YXR1cykKPiArewo+ICsJc3RydWN0 IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwo+ICsJbXZu ZXQtPnN0YXR1cyA9IHN0YXR1czsKPiArCj4gKwlpZiAoc3RhdHVzID09IDApIHsKPiArCQlzcGlu X2xvY2soJm12bmV0LT5sb2NrKTsKPiArCQltdm5ldF9yZXNldChtdm5ldCk7Cj4gKwkJc3Bpbl91 bmxvY2soJm12bmV0LT5sb2NrKTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRf Z2V0X2NvbmZpZyhzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsIHVuc2lnbmVkIGludCBvZmZzZXQs Cj4gKwkJCSAgICAgdm9pZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQo+ICt7Cj4gKwlzdHJ1Y3Qg bXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCj4gKwlpZiAo b2Zmc2V0ICsgbGVuIDwgc2l6ZW9mKHN0cnVjdCB2aXJ0aW9fbmV0X2NvbmZpZykpCj4gKwkJbWVt Y3B5KGJ1ZiwgJm12bmV0LT5jb25maWcgKyBvZmZzZXQsIGxlbik7Cj4gK30KPiArCj4gK3N0YXRp YyB2b2lkIG12bmV0X3NldF9jb25maWcoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1bnNpZ25l ZCBpbnQgb2Zmc2V0LAo+ICsJCQkgICAgIGNvbnN0IHZvaWQgKmJ1ZiwgdW5zaWduZWQgaW50IGxl bikKPiArewo+ICsJLyogTm8gd3JpdGFibGUgY29uZmlnIHN1cHBvcnR0ZWQgYnkgbXZuZXQgKi8K PiArfQo+ICsKPiArc3RhdGljIHUzMiBtdm5ldF9nZXRfZ2VuZXJhdGlvbihzdHJ1Y3QgbWRldl9k ZXZpY2UgKm1kZXYpCj4gK3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dl dF9kcnZkYXRhKG1kZXYpOwo+ICsKPiArCXJldHVybiBtdm5ldC0+Z2VuZXJhdGlvbjsKPiArfQo+ ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBtZGV2X3ZpcnRpb19kZXZpY2Vfb3BzIG1kZXZfdmly dGlvX29wcyA9IHsKPiArCS5zZXRfdnFfYWRkcmVzcyAgICAgICAgID0gbXZuZXRfc2V0X3ZxX2Fk ZHJlc3MsCj4gKwkuc2V0X3ZxX251bSAgICAgICAgICAgICA9IG12bmV0X3NldF92cV9udW0sCj4g Kwkua2lja192cSAgICAgICAgICAgICAgICA9IG12bmV0X2tpY2tfdnEsCj4gKwkuc2V0X3ZxX2Ni ICAgICAgICAgICAgICA9IG12bmV0X3NldF92cV9jYiwKPiArCS5zZXRfdnFfcmVhZHkgICAgICAg ICAgID0gbXZuZXRfc2V0X3ZxX3JlYWR5LAo+ICsJLmdldF92cV9yZWFkeSAgICAgICAgICAgPSBt dm5ldF9nZXRfdnFfcmVhZHksCj4gKwkuc2V0X3ZxX3N0YXRlICAgICAgICAgICA9IG12bmV0X3Nl dF92cV9zdGF0ZSwKPiArCS5nZXRfdnFfc3RhdGUgICAgICAgICAgID0gbXZuZXRfZ2V0X3ZxX3N0 YXRlLAo+ICsJLmdldF92cV9hbGlnbiAgICAgICAgICAgPSBtdm5ldF9nZXRfdnFfYWxpZ24sCj4g KwkuZ2V0X2ZlYXR1cmVzICAgICAgICAgICA9IG12bmV0X2dldF9mZWF0dXJlcywKPiArCS5zZXRf ZmVhdHVyZXMgICAgICAgICAgID0gbXZuZXRfc2V0X2ZlYXR1cmVzLAo+ICsJLnNldF9jb25maWdf Y2IgICAgICAgICAgPSBtdm5ldF9zZXRfY29uZmlnX2NiLAo+ICsJLmdldF92cV9udW1fbWF4ICAg ICAgICAgPSBtdm5ldF9nZXRfdnFfbnVtX21heCwKPiArCS5nZXRfZGV2aWNlX2lkICAgICAgICAg ID0gbXZuZXRfZ2V0X2RldmljZV9pZCwKPiArCS5nZXRfdmVuZG9yX2lkICAgICAgICAgID0gbXZu ZXRfZ2V0X3ZlbmRvcl9pZCwKPiArCS5nZXRfc3RhdHVzICAgICAgICAgICAgID0gbXZuZXRfZ2V0 X3N0YXR1cywKPiArCS5zZXRfc3RhdHVzICAgICAgICAgICAgID0gbXZuZXRfc2V0X3N0YXR1cywK PiArCS5nZXRfY29uZmlnICAgICAgICAgICAgID0gbXZuZXRfZ2V0X2NvbmZpZywKPiArCS5zZXRf Y29uZmlnICAgICAgICAgICAgID0gbXZuZXRfc2V0X2NvbmZpZywKPiArCS5nZXRfZ2VuZXJhdGlv biAgICAgICAgID0gbXZuZXRfZ2V0X2dlbmVyYXRpb24sCj4gK307Cj4gKwo+ICtzdGF0aWMgY29u c3Qgc3RydWN0IG1kZXZfcGFyZW50X29wcyBtZGV2X2ZvcHMgPSB7Cj4gKwkub3duZXIgICAgICAg ICAgICAgICAgICA9IFRISVNfTU9EVUxFLAo+ICsJLmRldl9hdHRyX2dyb3VwcyAgICAgICAgPSBt dm5ldF9kZXZfZ3JvdXBzLAo+ICsJLm1kZXZfYXR0cl9ncm91cHMgICAgICAgPSBtZGV2X2Rldl9n cm91cHMsCj4gKwkuc3VwcG9ydGVkX3R5cGVfZ3JvdXBzICA9IG1kZXZfdHlwZV9ncm91cHMsCj4g KwkuY3JlYXRlICAgICAgICAgICAgICAgICA9IG12bmV0X2NyZWF0ZSwKPiArCS5yZW1vdmUJCQk9 IG12bmV0X3JlbW92ZSwKPiArfTsKPiArCj4gK3N0YXRpYyB2b2lkIG12bmV0X2RldmljZV9yZWxl YXNlKHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsJZGV2X2RiZyhkZXYsICJtdm5ldDogcmVs ZWFzZWRcbiIpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IF9faW5pdCBtdm5ldF9kZXZfaW5pdCh2 b2lkKQo+ICt7Cj4gKwlpbnQgcmV0ID0gMDsKPiArCj4gKwlwcl9pbmZvKCJtdm5ldF9kZXY6ICVz XG4iLCBfX2Z1bmNfXyk7Cj4gKwo+ICsJbWVtc2V0KCZtdm5ldF9kZXYsIDAsIHNpemVvZihtdm5l dF9kZXYpKTsKPiArCj4gKwlpZHJfaW5pdCgmbXZuZXRfZGV2LnZkX2lkcik7Cj4gKwo+ICsJbXZu ZXRfZGV2LnZkX2NsYXNzID0gY2xhc3NfY3JlYXRlKFRISVNfTU9EVUxFLCBNVk5FVF9DTEFTU19O QU1FKTsKPiArCj4gKwlpZiAoSVNfRVJSKG12bmV0X2Rldi52ZF9jbGFzcykpIHsKPiArCQlwcl9l cnIoIkVycm9yOiBmYWlsZWQgdG8gcmVnaXN0ZXIgbXZuZXRfZGV2IGNsYXNzXG4iKTsKPiArCQly ZXQgPSBQVFJfRVJSKG12bmV0X2Rldi52ZF9jbGFzcyk7Cj4gKwkJZ290byBmYWlsZWQxOwo+ICsJ fQo+ICsKPiArCW12bmV0X2Rldi5kZXYuY2xhc3MgPSBtdm5ldF9kZXYudmRfY2xhc3M7Cj4gKwlt dm5ldF9kZXYuZGV2LnJlbGVhc2UgPSBtdm5ldF9kZXZpY2VfcmVsZWFzZTsKPiArCWRldl9zZXRf bmFtZSgmbXZuZXRfZGV2LmRldiwgIiVzIiwgTVZORVRfTkFNRSk7Cj4gKwo+ICsJcmV0ID0gZGV2 aWNlX3JlZ2lzdGVyKCZtdm5ldF9kZXYuZGV2KTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBmYWls ZWQyOwo+ICsKPiArCXJldCA9IG1kZXZfcmVnaXN0ZXJfZGV2aWNlKCZtdm5ldF9kZXYuZGV2LCAm bWRldl9mb3BzKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBmYWlsZWQzOwo+ICsKPiArCW11dGV4 X2luaXQoJm1kZXZfbGlzdF9sb2NrKTsKPiArCUlOSVRfTElTVF9IRUFEKCZtZGV2X2RldmljZXNf bGlzdCk7Cj4gKwo+ICsJZ290byBhbGxfZG9uZTsKPiArCj4gK2ZhaWxlZDM6Cj4gKwo+ICsJZGV2 aWNlX3VucmVnaXN0ZXIoJm12bmV0X2Rldi5kZXYpOwo+ICtmYWlsZWQyOgo+ICsJY2xhc3NfZGVz dHJveShtdm5ldF9kZXYudmRfY2xhc3MpOwo+ICsKPiArZmFpbGVkMToKPiArYWxsX2RvbmU6Cj4g KwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBfX2V4aXQgbXZuZXRfZGV2X2V4 aXQodm9pZCkKPiArewo+ICsJbXZuZXRfZGV2LmRldi5idXMgPSBOVUxMOwo+ICsJbWRldl91bnJl Z2lzdGVyX2RldmljZSgmbXZuZXRfZGV2LmRldik7Cj4gKwo+ICsJZGV2aWNlX3VucmVnaXN0ZXIo Jm12bmV0X2Rldi5kZXYpOwo+ICsJaWRyX2Rlc3Ryb3koJm12bmV0X2Rldi52ZF9pZHIpOwo+ICsJ Y2xhc3NfZGVzdHJveShtdm5ldF9kZXYudmRfY2xhc3MpOwo+ICsJbXZuZXRfZGV2LnZkX2NsYXNz ID0gTlVMTDsKPiArCXByX2luZm8oIm12bmV0X2RldjogVW5sb2FkZWQhXG4iKTsKPiArfQo+ICsK PiArbW9kdWxlX2luaXQobXZuZXRfZGV2X2luaXQpCj4gK21vZHVsZV9leGl0KG12bmV0X2Rldl9l eGl0KQo+ICsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+ICtNT0RVTEVfSU5GTyhzdXBw b3J0ZWQsICJTaW11bGF0ZSBsb29wYmFjayBldGhlcm5ldCBkZXZpY2Ugb3ZlciBtZGV2Iik7Cj4g K01PRFVMRV9WRVJTSU9OKFZFUlNJT05fU1RSSU5HKTsKPiArTU9EVUxFX0FVVEhPUihEUklWRVJf QVVUSE9SKTsKPiAtLSAKPiAyLjE5LjEKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJl ZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGlu Zm8vZHJpLWRldmVs 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=-6.7 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 76385FC6197 for ; Thu, 7 Nov 2019 09:08:55 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (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 52D1E2187F for ; Thu, 7 Nov 2019 09:08:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 52D1E2187F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0A6626F3B1; Thu, 7 Nov 2019 09:08:54 +0000 (UTC) Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id 9DA816F3AB for ; Thu, 7 Nov 2019 09:08:52 +0000 (UTC) Received: from mail-qt1-f200.google.com (mail-qt1-f200.google.com [209.85.160.200]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 132F9C04BE1B for ; Thu, 7 Nov 2019 09:08:52 +0000 (UTC) Received: by mail-qt1-f200.google.com with SMTP id i9so1781889qtq.11 for ; Thu, 07 Nov 2019 01:08:52 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=y3kSmNPFNr1syqaEwVgmtYdBZ7wSJEKV0NnWLNNW74g=; b=LBoCZsNX/q8N7YFlGJgCwll2NtKkxwJ4sG1dBdGLr1MCveEWuVGyOdLYo66Bvq58Ye RldO/EkoUK8nW4yzEeoYkufzf92N0sAUcih67rOkdgFNetZyyylNRm/QwEPSlFOJAmqp e+mgXt1mvRZoEmySlLEmHP64OSnCHVgYFXfWVw0QFDr2CiQtem6xP5Fx/Ii+F/tEythY oWUBU+Dgz9SBZDLtk3/kWLTBpsN+2rx++FgRO4OhSS5jnkoBr9T8s/p7d5gTs4853y32 30XfThGsKywk3VTPla0ssCiUlxuBmlR5y/crbcJB2XoyTtn2/RThH2aJVMo1mr0utQMP VBbw== X-Gm-Message-State: APjAAAXsM+Ypza++8L9awWYmIXcgVSJy26bE1wBZ+SsWNsMILGkZtc5p UBxxudA3Rps+InId/pl/h+u4FTREYMLTzdrMxy/RxLDkmc/cMHICne7YkCX2p10FeldbyeovMm8 gScmkEDeIw6mw7Bge9o2IsFGhxXHm X-Received: by 2002:aed:3762:: with SMTP id i89mr2711594qtb.69.1573117731133; Thu, 07 Nov 2019 01:08:51 -0800 (PST) X-Google-Smtp-Source: APXvYqweC4n74z/ghU3aODI0O03qx4TNMZLpGEG3t2lFq0mpTiNcnn1UrlGFUzbl5VMo/050oDK8bw== X-Received: by 2002:aed:3762:: with SMTP id i89mr2711543qtb.69.1573117730668; Thu, 07 Nov 2019 01:08:50 -0800 (PST) Received: from redhat.com (bzq-79-178-12-128.red.bezeqint.net. [79.178.12.128]) by smtp.gmail.com with ESMTPSA id c195sm928750qkg.6.2019.11.07.01.08.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Nov 2019 01:08:49 -0800 (PST) Date: Thu, 7 Nov 2019 04:08:37 -0500 From: "Michael S. Tsirkin" To: Jason Wang Message-ID: <20191107040700-mutt-send-email-mst@kernel.org> References: <20191106133531.693-1-jasowang@redhat.com> <20191106133531.693-7-jasowang@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191106133531.693-7-jasowang@redhat.com> Subject: Re: [Intel-gfx] [PATCH V10 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: stefanha@redhat.com, christophe.de.dinechin@gmail.com, kvm@vger.kernel.org, airlied@linux.ie, heiko.carstens@de.ibm.com, dri-devel@lists.freedesktop.org, virtualization@lists.linux-foundation.org, kwankhede@nvidia.com, rob.miller@broadcom.com, linux-s390@vger.kernel.org, sebott@linux.ibm.com, lulu@redhat.com, eperezma@redhat.com, pasic@linux.ibm.com, borntraeger@de.ibm.com, haotian.wang@sifive.com, cunming.liang@intel.com, farman@linux.ibm.com, idos@mellanox.com, gor@linux.ibm.com, intel-gfx@lists.freedesktop.org, xiao.w.wang@intel.com, freude@linux.ibm.com, parav@mellanox.com, zhihong.wang@intel.com, intel-gvt-dev@lists.freedesktop.org, akrowiak@linux.ibm.com, oberpar@linux.ibm.com, tiwei.bie@intel.com, netdev@vger.kernel.org, cohuck@redhat.com, linux-kernel@vger.kernel.org, maxime.coquelin@redhat.com, lingshan.zhu@intel.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Message-ID: <20191107090837.4KuwGLvGLQX_L-78fLZRuD9vQ_mg7SJOypArovASFtU@z> T24gV2VkLCBOb3YgMDYsIDIwMTkgYXQgMDk6MzU6MzFQTSArMDgwMCwgSmFzb24gV2FuZyB3cm90 ZToKPiBUaGlzIHNhbXBsZSBkcml2ZXIgY3JlYXRlcyBtZGV2IGRldmljZSB0aGF0IHNpbXVsYXRl IHZpcnRpbyBuZXQgZGV2aWNlCj4gb3ZlciB2aXJ0aW8gbWRldiB0cmFuc3BvcnQuIFRoZSBkZXZp Y2UgaXMgaW1wbGVtZW50ZWQgdGhyb3VnaCB2cmluZ2gKPiBhbmQgd29ya3F1ZXVlLiBBIGRldmlj ZSBzcGVjaWZpYyBkbWEgb3BzIGlzIHRvIG1ha2Ugc3VyZSBIVkEgaXMgdXNlZAo+IGRpcmVjdGx5 IGFzIHRoZSBJT1ZBLiBUaGlzIHNob3VsZCBiZSBzdWZmaWNpZW50IGZvciBrZXJuZWwgdmlydGlv Cj4gZHJpdmVyIHRvIHdvcmsuCj4gCj4gT25seSAndmlydGlvJyB0eXBlIGlzIHN1cHBvcnRlZCBy aWdodCBub3cuIEkgcGxhbiB0byBhZGQgJ3Zob3N0JyB0eXBlCj4gb24gdG9wIHdoaWNoIHJlcXVp cmVzIHNvbWUgdmlydHVhbCBJT01NVSBpbXBsZW1lbnRlZCBpbiB0aGlzIHNhbXBsZQo+IGRyaXZl ci4KPiAKPiBBY2tlZC1ieTogQ29ybmVsaWEgSHVjayA8Y29odWNrQHJlZGhhdC5jb20+Cj4gU2ln bmVkLW9mZi1ieTogSmFzb24gV2FuZyA8amFzb3dhbmdAcmVkaGF0LmNvbT4KCgpJJ2QgcHJlZmVy IGl0IHRoYXQgd2UgY2FsbCB0aGlzIHNvbWV0aGluZyBlbHNlLCBlLmcuCm12bmV0LWxvb3BiYWNr LiBKdXN0IHNvIHBlb3BsZSBkb24ndCBleHBlY3QgYSBmdWxseQpmdW5jdGlvbmFsIGRldmljZSBz b21laG93LiBDYW4gYmUgcmVuYW1lZCB3aGVuIGFwcGx5aW5nPwoKCj4gLS0tCj4gIE1BSU5UQUlO RVJTICAgICAgICAgICAgICAgIHwgICAxICsKPiAgc2FtcGxlcy9LY29uZmlnICAgICAgICAgICAg fCAgMTAgKwo+ICBzYW1wbGVzL3ZmaW8tbWRldi9NYWtlZmlsZSB8ICAgMSArCj4gIHNhbXBsZXMv dmZpby1tZGV2L212bmV0LmMgIHwgNjg2ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysKPiAgNCBmaWxlcyBjaGFuZ2VkLCA2OTggaW5zZXJ0aW9ucygrKQo+ICBjcmVhdGUgbW9k ZSAxMDA2NDQgc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwo+IAo+IGRpZmYgLS1naXQgYS9NQUlO VEFJTkVSUyBiL01BSU5UQUlORVJTCj4gaW5kZXggNDk5Nzk1NzQ0M2RmLi42ZTlhZDEwNWEyOGYg MTAwNjQ0Cj4gLS0tIGEvTUFJTlRBSU5FUlMKPiArKysgYi9NQUlOVEFJTkVSUwo+IEBAIC0xNzI0 OSw2ICsxNzI0OSw3IEBAIEY6CWluY2x1ZGUvdWFwaS9saW51eC92aXJ0aW9fKi5oCj4gIEY6CWRy aXZlcnMvY3J5cHRvL3ZpcnRpby8KPiAgRjoJbW0vYmFsbG9vbl9jb21wYWN0aW9uLmMKPiAgRjoJ aW5jbHVkZS9saW51eC9tZGV2X3ZpcnRpb19vcHMuaAo+ICtGOglzYW1wbGVzL3ZmaW8tbWRldi9t dm5ldC5jCj4gIAo+ICBWSVJUSU8gQkxPQ0sgQU5EIFNDU0kgRFJJVkVSUwo+ICBNOgkiTWljaGFl bCBTLiBUc2lya2luIiA8bXN0QHJlZGhhdC5jb20+Cj4gZGlmZiAtLWdpdCBhL3NhbXBsZXMvS2Nv bmZpZyBiL3NhbXBsZXMvS2NvbmZpZwo+IGluZGV4IGM4ZGFjYjRkZGE4MC4uMTNhMjQ0M2UxOGUw IDEwMDY0NAo+IC0tLSBhL3NhbXBsZXMvS2NvbmZpZwo+ICsrKyBiL3NhbXBsZXMvS2NvbmZpZwo+ IEBAIC0xMzEsNiArMTMxLDE2IEBAIGNvbmZpZyBTQU1QTEVfVkZJT19NREVWX01EUFkKPiAgCSAg bWVkaWF0ZWQgZGV2aWNlLiAgSXQgaXMgYSBzaW1wbGUgZnJhbWVidWZmZXIgYW5kIHN1cHBvcnRz Cj4gIAkgIHRoZSByZWdpb24gZGlzcGxheSBpbnRlcmZhY2UgKFZGSU9fR0ZYX1BMQU5FX1RZUEVf UkVHSU9OKS4KPiAgCj4gK2NvbmZpZyBTQU1QTEVfVklSVElPX01ERVZfTkVUCj4gKwl0cmlzdGF0 ZSAiQnVpbGQgVklSVElPIG5ldCBleGFtcGxlIG1lZGlhdGVkIGRldmljZSBzYW1wbGUgY29kZSAt LSBsb2FkYWJsZSBtb2R1bGVzIG9ubHkiCj4gKwlkZXBlbmRzIG9uIFZJUlRJT19NREVWICYmIFZI T1NUX1JJTkcgJiYgbQo+ICsJaGVscAo+ICsJICBCdWlsZCBhIG5ldHdvcmtpbmcgc2FtcGxlIGRl dmljZSBmb3IgdXNlIGFzIGEgdmlydGlvCj4gKwkgIG1lZGlhdGVkIGRldmljZS4gVGhlIGRldmlj ZSBjb29wcmVhdGVzIHdpdGggdmlydGlvLW1kZXYgYnVzCj4gKwkgIGRyaXZlciB0byBwcmVzZW50 IGFuIHZpcnRpbyBldGhlcm5ldCBkcml2ZXIgZm9yCj4gKwkgIGtlcm5lbC4gSXQgc2ltcGx5IGxv b3BiYWNrcyBhbGwgcGFja2V0cyBmcm9tIGl0cyBUWAo+ICsJICB2aXJ0cXVldWUgdG8gaXRzIFJY IHZpcnRxdWV1ZS4KPiArCj4gIGNvbmZpZyBTQU1QTEVfVkZJT19NREVWX01EUFlfRkIKPiAgCXRy aXN0YXRlICJCdWlsZCBWRklPIG1kcHkgZXhhbXBsZSBndWVzdCBmYmRldiBkcml2ZXIgLS0gbG9h ZGFibGUgbW9kdWxlIG9ubHkiCj4gIAlkZXBlbmRzIG9uIEZCICYmIG0KPiBkaWZmIC0tZ2l0IGEv c2FtcGxlcy92ZmlvLW1kZXYvTWFrZWZpbGUgYi9zYW1wbGVzL3ZmaW8tbWRldi9NYWtlZmlsZQo+ IGluZGV4IDEwZDE3OWM0ZmRlYi4uZjM0YWY5MGVkMGEwIDEwMDY0NAo+IC0tLSBhL3NhbXBsZXMv dmZpby1tZGV2L01ha2VmaWxlCj4gKysrIGIvc2FtcGxlcy92ZmlvLW1kZXYvTWFrZWZpbGUKPiBA QCAtMywzICszLDQgQEAgb2JqLSQoQ09ORklHX1NBTVBMRV9WRklPX01ERVZfTVRUWSkgKz0gbXR0 eS5vCj4gIG9iai0kKENPTkZJR19TQU1QTEVfVkZJT19NREVWX01EUFkpICs9IG1kcHkubwo+ICBv YmotJChDT05GSUdfU0FNUExFX1ZGSU9fTURFVl9NRFBZX0ZCKSArPSBtZHB5LWZiLm8KPiAgb2Jq LSQoQ09ORklHX1NBTVBMRV9WRklPX01ERVZfTUJPQ0hTKSArPSBtYm9jaHMubwo+ICtvYmotJChD T05GSUdfU0FNUExFX1ZJUlRJT19NREVWX05FVCkgKz0gbXZuZXQubwo+IGRpZmYgLS1naXQgYS9z YW1wbGVzL3ZmaW8tbWRldi9tdm5ldC5jIGIvc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwo+IG5l dyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi5hODlhZWNmYWI2OGEKPiAt LS0gL2Rldi9udWxsCj4gKysrIGIvc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwo+IEBAIC0wLDAg KzEsNjg2IEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPiAr LyoKPiArICogTWVkaWF0ZWQgdmlydHVhbCB2aXJ0aW8tbmV0IGRldmljZSBkcml2ZXIuCj4gKyAq Cj4gKyAqIENvcHlyaWdodCAoYykgMjAxOSwgUmVkIEhhdCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2 ZWQuCj4gKyAqICAgICBBdXRob3I6IEphc29uIFdhbmcgPGphc293YW5nQHJlZGhhdC5jb20+Cj4g KyAqCj4gKyAqIFNhbXBsZSBkcml2ZXIgdGhhdCBjcmVhdGVzIG1kZXYgZGV2aWNlIHRoYXQgc2lt dWxhdGVzIGV0aGVybmV0IGxvb3BiYWNrCj4gKyAqIGRldmljZS4KPiArICoKPiArICogVXNhZ2U6 Cj4gKyAqCj4gKyAqICMgbW9kcHJvYmUgdmlydGlvX21kZXYKPiArICogIyBtb2Rwcm9iZSBtdm5l dAo+ICsgKiAjIGNkIC9zeXMvZGV2aWNlcy92aXJ0dWFsL212bmV0L212bmV0L21kZXZfc3VwcG9y dGVkX3R5cGVzL212bmV0LXZpcnRpbwo+ICsgKiAjIGVjaG8gIjgzYjhmNGYyLTUwOWYtMzgyZi0z YzFlLWU2YmZlMGZhMTAwMSIgPiAuL2NyZWF0ZQo+ICsgKiAjIGNkIGRldmljZXMvODNiOGY0ZjIt NTA5Zi0zODJmLTNjMWUtZTZiZmUwZmExMDAxCj4gKyAqICMgbHMgLWQgdmlydGlvMAo+ICsgKiB2 aXJ0aW8wCj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KPiArI2luY2x1ZGUg PGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9rZXJuZWwuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2ZzLmg+Cj4gKyNpbmNsdWRlIDxs aW51eC9wb2xsLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9zY2hlZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvd2FpdC5oPgo+ICsjaW5jbHVkZSA8bGludXgv dXVpZC5oPgo+ICsjaW5jbHVkZSA8bGludXgvaW9tbXUuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3N5 c2ZzLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9maWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9ldGhl cmRldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvbWRldi5oPgo+ICsjaW5jbHVkZSA8bGludXgv dnJpbmdoLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tZGV2X3ZpcnRpb19vcHMuaD4KPiArI2luY2x1 ZGUgPHVhcGkvbGludXgvdmlydGlvX2NvbmZpZy5oPgo+ICsjaW5jbHVkZSA8dWFwaS9saW51eC92 aXJ0aW9fbmV0Lmg+Cj4gKwo+ICsjZGVmaW5lIFZFUlNJT05fU1RSSU5HICAiMC4xIgo+ICsjZGVm aW5lIERSSVZFUl9BVVRIT1IgICAiUmVkIEhhdCBDb3Jwb3JhdGlvbiIKPiArCj4gKyNkZWZpbmUg TVZORVRfQ0xBU1NfTkFNRSAibXZuZXQiCj4gKyNkZWZpbmUgTVZORVRfTkFNRSAgICAgICAibXZu ZXQiCj4gKwo+ICsvKgo+ICsgKiBHbG9iYWwgU3RydWN0dXJlcwo+ICsgKi8KPiArCj4gK3N0YXRp YyBzdHJ1Y3QgbXZuZXRfZGV2IHsKPiArCXN0cnVjdCBjbGFzcwkqdmRfY2xhc3M7Cj4gKwlzdHJ1 Y3QgaWRyCXZkX2lkcjsKPiArCXN0cnVjdCBkZXZpY2UJZGV2Owo+ICt9IG12bmV0X2RldjsKPiAr Cj4gK3N0cnVjdCBtdm5ldF92aXJ0cXVldWUgewo+ICsJc3RydWN0IHZyaW5naCB2cmluZzsKPiAr CXN0cnVjdCB2cmluZ2hfa2lvdiBpb3Y7Cj4gKwl1bnNpZ25lZCBzaG9ydCBoZWFkOwo+ICsJYm9v bCByZWFkeTsKPiArCXU2NCBkZXNjX2FkZHI7Cj4gKwl1NjQgZGV2aWNlX2FkZHI7Cj4gKwl1NjQg ZHJpdmVyX2FkZHI7Cj4gKwl1MzIgbnVtOwo+ICsJdm9pZCAqcHJpdmF0ZTsKPiArCWlycXJldHVy bl90ICgqY2IpKHZvaWQgKmRhdGEpOwo+ICt9Owo+ICsKPiArI2RlZmluZSBNVk5FVF9RVUVVRV9B TElHTiBQQUdFX1NJWkUKPiArI2RlZmluZSBNVk5FVF9RVUVVRV9NQVggMjU2Cj4gKyNkZWZpbmUg TVZORVRfREVWSUNFX0lEIDB4MQo+ICsjZGVmaW5lIE1WTkVUX1ZFTkRPUl9JRCAwCj4gKwo+ICt1 NjQgbXZuZXRfZmVhdHVyZXMgPSAoMVVMTCA8PCBWSVJUSU9fRl9BTllfTEFZT1VUKSB8Cj4gKwkJ ICAgICAoMVVMTCA8PCBWSVJUSU9fRl9WRVJTSU9OXzEpIHwKPiArCQkgICAgICgxVUxMIDw8IFZJ UlRJT19GX0lPTU1VX1BMQVRGT1JNKTsKPiArCj4gKy8qIFN0YXRlIG9mIGVhY2ggbWRldiBkZXZp Y2UgKi8KPiArc3RydWN0IG12bmV0X3N0YXRlIHsKPiArCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUg dnFzWzJdOwo+ICsJc3RydWN0IHdvcmtfc3RydWN0IHdvcms7Cj4gKwkvKiBzcGlubG9jayB0byBz eW5jaHJvbml6ZSB2aXJ0cXVldWUgc3RhdGUgKi8KPiArCXNwaW5sb2NrX3QgbG9jazsKPiArCXN0 cnVjdCBtZGV2X2RldmljZSAqbWRldjsKPiArCXN0cnVjdCB2aXJ0aW9fbmV0X2NvbmZpZyBjb25m aWc7Cj4gKwl2b2lkICpidWZmZXI7Cj4gKwl1MzIgc3RhdHVzOwo+ICsJdTMyIGdlbmVyYXRpb247 Cj4gKwl1NjQgZmVhdHVyZXM7Cj4gKwlzdHJ1Y3QgbGlzdF9oZWFkIG5leHQ7Cj4gK307Cj4gKwo+ ICtzdGF0aWMgc3RydWN0IG11dGV4IG1kZXZfbGlzdF9sb2NrOwo+ICtzdGF0aWMgc3RydWN0IGxp c3RfaGVhZCBtZGV2X2RldmljZXNfbGlzdDsKPiArCj4gK3N0YXRpYyB2b2lkIG12bmV0X3F1ZXVl X3JlYWR5KHN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQsIHVuc2lnbmVkIGludCBpZHgpCj4gK3sK PiArCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKPiArCWlu dCByZXQ7Cj4gKwo+ICsJcmV0ID0gdnJpbmdoX2luaXRfa2VybigmdnEtPnZyaW5nLCBtdm5ldF9m ZWF0dXJlcywgTVZORVRfUVVFVUVfTUFYLAo+ICsJCQkgICAgICAgZmFsc2UsIChzdHJ1Y3QgdnJp bmdfZGVzYyAqKXZxLT5kZXNjX2FkZHIsCj4gKwkJCSAgICAgICAoc3RydWN0IHZyaW5nX2F2YWls ICopdnEtPmRyaXZlcl9hZGRyLAo+ICsJCQkgICAgICAgKHN0cnVjdCB2cmluZ191c2VkICopdnEt PmRldmljZV9hZGRyKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfdnFfcmVzZXQoc3Ry dWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEpCj4gK3sKPiArCXZxLT5yZWFkeSA9IDA7Cj4gKwl2cS0+ ZGVzY19hZGRyID0gMDsKPiArCXZxLT5kcml2ZXJfYWRkciA9IDA7Cj4gKwl2cS0+ZGV2aWNlX2Fk ZHIgPSAwOwo+ICsJdnEtPmNiID0gTlVMTDsKPiArCXZxLT5wcml2YXRlID0gTlVMTDsKPiArCXZy aW5naF9pbml0X2tlcm4oJnZxLT52cmluZywgbXZuZXRfZmVhdHVyZXMsIE1WTkVUX1FVRVVFX01B WCwKPiArCQkJIGZhbHNlLCAwLCAwLCAwKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRf cmVzZXQoc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCkKPiArewo+ICsJaW50IGk7Cj4gKwo+ICsJ Zm9yIChpID0gMDsgaSA8IDI7IGkrKykKPiArCQltdm5ldF92cV9yZXNldCgmbXZuZXQtPnZxc1tp XSk7Cj4gKwo+ICsJbXZuZXQtPmZlYXR1cmVzID0gMDsKPiArCW12bmV0LT5zdGF0dXMgPSAwOwo+ ICsJKyttdm5ldC0+Z2VuZXJhdGlvbjsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfd29y ayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCj4gK3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAq bXZuZXQgPSBjb250YWluZXJfb2Yod29yaywgc3RydWN0Cj4gKwkJCQkJCSBtdm5ldF9zdGF0ZSwg d29yayk7Cj4gKwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp0eHEgPSAmbXZuZXQtPnZxc1sxXTsK PiArCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnJ4cSA9ICZtdm5ldC0+dnFzWzBdOwo+ICsJc2l6 ZV90IHJlYWQsIHdyaXRlLCB0b3RhbF93cml0ZTsKPiArCWludCBlcnI7Cj4gKwlpbnQgcGt0cyA9 IDA7Cj4gKwo+ICsJc3Bpbl9sb2NrKCZtdm5ldC0+bG9jayk7Cj4gKwo+ICsJaWYgKCF0eHEtPnJl YWR5IHx8ICFyeHEtPnJlYWR5KQo+ICsJCWdvdG8gb3V0Owo+ICsKPiArCXdoaWxlICh0cnVlKSB7 Cj4gKwkJdG90YWxfd3JpdGUgPSAwOwo+ICsJCWVyciA9IHZyaW5naF9nZXRkZXNjX2tlcm4oJnR4 cS0+dnJpbmcsICZ0eHEtPmlvdiwgTlVMTCwKPiArCQkJCQkgICZ0eHEtPmhlYWQsIEdGUF9BVE9N SUMpOwo+ICsJCWlmIChlcnIgPD0gMCkKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWVyciA9IHZyaW5n aF9nZXRkZXNjX2tlcm4oJnJ4cS0+dnJpbmcsIE5VTEwsICZyeHEtPmlvdiwKPiArCQkJCQkgICZy eHEtPmhlYWQsIEdGUF9BVE9NSUMpOwo+ICsJCWlmIChlcnIgPD0gMCkgewo+ICsJCQl2cmluZ2hf Y29tcGxldGVfa2VybigmdHhxLT52cmluZywgdHhxLT5oZWFkLCAwKTsKPiArCQkJYnJlYWs7Cj4g KwkJfQo+ICsKPiArCQl3aGlsZSAodHJ1ZSkgewo+ICsJCQlyZWFkID0gdnJpbmdoX2lvdl9wdWxs X2tlcm4oJnR4cS0+aW92LCBtdm5ldC0+YnVmZmVyLAo+ICsJCQkJCQkgICAgUEFHRV9TSVpFKTsK PiArCQkJaWYgKHJlYWQgPD0gMCkKPiArCQkJCWJyZWFrOwo+ICsKPiArCQkJd3JpdGUgPSB2cmlu Z2hfaW92X3B1c2hfa2VybigmcnhxLT5pb3YsIG12bmV0LT5idWZmZXIsCj4gKwkJCQkJCSAgICAg cmVhZCk7Cj4gKwkJCWlmICh3cml0ZSA8PSAwKQo+ICsJCQkJYnJlYWs7Cj4gKwo+ICsJCQl0b3Rh bF93cml0ZSArPSB3cml0ZTsKPiArCQl9Cj4gKwo+ICsJCS8qIE1ha2Ugc3VyZSBkYXRhIGlzIHdy b3RlIGJlZm9yZSBhZHZhbmNpbmcgaW5kZXggKi8KPiArCQlzbXBfd21iKCk7Cj4gKwo+ICsJCXZy aW5naF9jb21wbGV0ZV9rZXJuKCZ0eHEtPnZyaW5nLCB0eHEtPmhlYWQsIDApOwo+ICsJCXZyaW5n aF9jb21wbGV0ZV9rZXJuKCZyeHEtPnZyaW5nLCByeHEtPmhlYWQsIHRvdGFsX3dyaXRlKTsKPiAr Cj4gKwkJLyogTWFrZSBzdXJlIHVzZWQgaXMgdmlzaWJsZSBiZWZvcmUgcmFzaW5nIHRoZSBpbnRl cnJ1cHQuICovCj4gKwkJc21wX3dtYigpOwo+ICsKPiArCQlsb2NhbF9iaF9kaXNhYmxlKCk7Cj4g KwkJaWYgKHR4cS0+Y2IpCj4gKwkJCXR4cS0+Y2IodHhxLT5wcml2YXRlKTsKPiArCQlpZiAocnhx LT5jYikKPiArCQkJcnhxLT5jYihyeHEtPnByaXZhdGUpOwo+ICsJCWxvY2FsX2JoX2VuYWJsZSgp Owo+ICsKPiArCQlpZiAoKytwa3RzID4gNCkgewo+ICsJCQlzY2hlZHVsZV93b3JrKCZtdm5ldC0+ d29yayk7Cj4gKwkJCWdvdG8gb3V0Owo+ICsJCX0KPiArCX0KPiArCj4gK291dDoKPiArCXNwaW5f dW5sb2NrKCZtdm5ldC0+bG9jayk7Cj4gK30KPiArCj4gK3N0YXRpYyBkbWFfYWRkcl90IG12bmV0 X21hcF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHBhZ2UgKnBhZ2UsCj4gKwkJCQkg dW5zaWduZWQgbG9uZyBvZmZzZXQsIHNpemVfdCBzaXplLAo+ICsJCQkJIGVudW0gZG1hX2RhdGFf ZGlyZWN0aW9uIGRpciwKPiArCQkJCSB1bnNpZ25lZCBsb25nIGF0dHJzKQo+ICt7Cj4gKwkvKiBW cmluZ2ggY2FuIG9ubHkgdXNlIEhWQSAqLwo+ICsJcmV0dXJuIChkbWFfYWRkcl90KShwYWdlX2Fk ZHJlc3MocGFnZSkgKyBvZmZzZXQpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF91bm1h cF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgZG1hX2FkZHJfdCBkbWFfYWRkciwKPiArCQkJICAg ICBzaXplX3Qgc2l6ZSwgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyLAo+ICsJCQkgICAgIHVu c2lnbmVkIGxvbmcgYXR0cnMpCj4gK3sKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgKm12bmV0X2Fs bG9jX2NvaGVyZW50KHN0cnVjdCBkZXZpY2UgKmRldiwgc2l6ZV90IHNpemUsCj4gKwkJCQkgIGRt YV9hZGRyX3QgKmRtYV9hZGRyLCBnZnBfdCBmbGFnLAo+ICsJCQkJICB1bnNpZ25lZCBsb25nIGF0 dHJzKQo+ICt7Cj4gKwl2b2lkICphZGRyID0ga21hbGxvYyhzaXplLCBmbGFnKTsKPiArCj4gKwlp ZiAoIWFkZHIpCj4gKwkJKmRtYV9hZGRyID0gRE1BX01BUFBJTkdfRVJST1I7Cj4gKwllbHNlCj4g KwkJKmRtYV9hZGRyID0gKGRtYV9hZGRyX3QpYWRkcjsKPiArCj4gKwlyZXR1cm4gYWRkcjsKPiAr fQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfZnJlZV9jb2hlcmVudChzdHJ1Y3QgZGV2aWNlICpk ZXYsIHNpemVfdCBzaXplLAo+ICsJCQkJdm9pZCAqdmFkZHIsIGRtYV9hZGRyX3QgZG1hX2FkZHIs Cj4gKwkJCQl1bnNpZ25lZCBsb25nIGF0dHJzKQo+ICt7Cj4gKwlrZnJlZSgodm9pZCAqKWRtYV9h ZGRyKTsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBkbWFfbWFwX29wcyBtdm5ldF9k bWFfb3BzID0gewo+ICsJLm1hcF9wYWdlID0gbXZuZXRfbWFwX3BhZ2UsCj4gKwkudW5tYXBfcGFn ZSA9IG12bmV0X3VubWFwX3BhZ2UsCj4gKwkuYWxsb2MgPSBtdm5ldF9hbGxvY19jb2hlcmVudCwK PiArCS5mcmVlID0gbXZuZXRfZnJlZV9jb2hlcmVudCwKPiArfTsKPiArCj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgbWRldl92aXJ0aW9fZGV2aWNlX29wcyBtZGV2X3ZpcnRpb19vcHM7Cj4gKwo+ICtz dGF0aWMgaW50IG12bmV0X2NyZWF0ZShzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IG1kZXZf ZGV2aWNlICptZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgbXZuZXRfc3RhdGUgKm12bmV0Owo+ICsJc3Ry dWN0IHZpcnRpb19uZXRfY29uZmlnICpjb25maWc7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBt ZGV2X2RldihtZGV2KTsKPiArCj4gKwlpZiAoIW1kZXYpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4g Kwo+ICsJbXZuZXQgPSBremFsbG9jKHNpemVvZigqbXZuZXQpLCBHRlBfS0VSTkVMKTsKPiArCWlm ICghbXZuZXQpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJbXZuZXQtPmJ1ZmZlciA9IGtt YWxsb2MoUEFHRV9TSVpFLCBHRlBfS0VSTkVMKTsKPiArCWlmICghbXZuZXQtPmJ1ZmZlcikgewo+ ICsJCWtmcmVlKG12bmV0KTsKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCX0KPiArCj4gKwljb25m aWcgPSAmbXZuZXQtPmNvbmZpZzsKPiArCWNvbmZpZy0+bXR1ID0gMTUwMDsKPiArCWNvbmZpZy0+ c3RhdHVzID0gVklSVElPX05FVF9TX0xJTktfVVA7Cj4gKwlldGhfcmFuZG9tX2FkZHIoY29uZmln LT5tYWMpOwo+ICsKPiArCUlOSVRfV09SSygmbXZuZXQtPndvcmssIG12bmV0X3dvcmspOwo+ICsK PiArCXNwaW5fbG9ja19pbml0KCZtdm5ldC0+bG9jayk7Cj4gKwltdm5ldC0+bWRldiA9IG1kZXY7 Cj4gKwltZGV2X3NldF9kcnZkYXRhKG1kZXYsIG12bmV0KTsKPiArCj4gKwltdXRleF9sb2NrKCZt ZGV2X2xpc3RfbG9jayk7Cj4gKwlsaXN0X2FkZCgmbXZuZXQtPm5leHQsICZtZGV2X2RldmljZXNf bGlzdCk7Cj4gKwltdXRleF91bmxvY2soJm1kZXZfbGlzdF9sb2NrKTsKPiArCj4gKwlkZXYtPmNv aGVyZW50X2RtYV9tYXNrID0gRE1BX0JJVF9NQVNLKDY0KTsKPiArCXNldF9kbWFfb3BzKGRldiwg Jm12bmV0X2RtYV9vcHMpOwo+ICsKPiArCW1kZXZfc2V0X3ZpcnRpb19vcHMobWRldiwgJm1kZXZf dmlydGlvX29wcyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXZu ZXRfcmVtb3ZlKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKPiArewo+ICsJc3RydWN0IG12bmV0 X3N0YXRlICptZHMsICp0bXBfbWRzOwo+ICsJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1k ZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwlpbnQgcmV0ID0gLUVJTlZBTDsKPiArCj4gKwltdXRl eF9sb2NrKCZtZGV2X2xpc3RfbG9jayk7Cj4gKwlsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUobWRz LCB0bXBfbWRzLCAmbWRldl9kZXZpY2VzX2xpc3QsIG5leHQpIHsKPiArCQlpZiAobXZuZXQgPT0g bWRzKSB7Cj4gKwkJCWxpc3RfZGVsKCZtdm5ldC0+bmV4dCk7Cj4gKwkJCW1kZXZfc2V0X2RydmRh dGEobWRldiwgTlVMTCk7Cj4gKwkJCWtmcmVlKG12bmV0LT5idWZmZXIpOwo+ICsJCQlrZnJlZSht dm5ldCk7Cj4gKwkJCXJldCA9IDA7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCX0KPiArCW11dGV4 X3VubG9jaygmbWRldl9saXN0X2xvY2spOwo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4g K3N0YXRpYyBzc2l6ZV90Cj4gK3NhbXBsZV9tdm5ldF9kZXZfc2hvdyhzdHJ1Y3QgZGV2aWNlICpk ZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+ICsJCSAgICAgIGNoYXIgKmJ1ZikK PiArewo+ICsJaWYgKG1kZXZfZnJvbV9kZXYoZGV2KSkKPiArCQlyZXR1cm4gc3ByaW50ZihidWYs ICJUaGlzIGlzIE1ERVYgJXNcbiIsIGRldl9uYW1lKGRldikpOwo+ICsKPiArCXJldHVybiBzcHJp bnRmKGJ1ZiwgIlxuIik7Cj4gK30KPiArCj4gK3N0YXRpYyBERVZJQ0VfQVRUUl9STyhzYW1wbGVf bXZuZXRfZGV2KTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICptdm5ldF9kZXZfYXR0 cnNbXSA9IHsKPiArCSZkZXZfYXR0cl9zYW1wbGVfbXZuZXRfZGV2LmF0dHIsCj4gKwlOVUxMLAo+ ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgbXZuZXRfZGV2 X2dyb3VwID0gewo+ICsJLm5hbWUgID0gIm12bmV0X2RldiIsCj4gKwkuYXR0cnMgPSBtdm5ldF9k ZXZfYXR0cnMsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91 cCAqbXZuZXRfZGV2X2dyb3Vwc1tdID0gewo+ICsJJm12bmV0X2Rldl9ncm91cCwKPiArCU5VTEws Cj4gK307Cj4gKwo+ICtzdGF0aWMgc3NpemVfdAo+ICtzYW1wbGVfbWRldl9kZXZfc2hvdyhzdHJ1 Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+ICsJCSAgICAg Y2hhciAqYnVmKQo+ICt7Cj4gKwlpZiAobWRldl9mcm9tX2RldihkZXYpKQo+ICsJCXJldHVybiBz cHJpbnRmKGJ1ZiwgIlRoaXMgaXMgTURFViAlc1xuIiwgZGV2X25hbWUoZGV2KSk7Cj4gKwo+ICsJ cmV0dXJuIHNwcmludGYoYnVmLCAiXG4iKTsKPiArfQo+ICsKPiArc3RhdGljIERFVklDRV9BVFRS X1JPKHNhbXBsZV9tZGV2X2Rldik7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqbWRl dl9kZXZfYXR0cnNbXSA9IHsKPiArCSZkZXZfYXR0cl9zYW1wbGVfbWRldl9kZXYuYXR0ciwKPiAr CU5VTEwsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBt ZGV2X2Rldl9ncm91cCA9IHsKPiArCS5uYW1lICA9ICJ2ZW5kb3IiLAo+ICsJLmF0dHJzID0gbWRl dl9kZXZfYXR0cnMsCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9n cm91cCAqbWRldl9kZXZfZ3JvdXBzW10gPSB7Cj4gKwkmbWRldl9kZXZfZ3JvdXAsCj4gKwlOVUxM LAo+ICt9Owo+ICsKPiArI2RlZmluZSBNVk5FVF9TVFJJTkdfTEVOIDE2Cj4gKwo+ICtzdGF0aWMg c3NpemVfdAo+ICtuYW1lX3Nob3coc3RydWN0IGtvYmplY3QgKmtvYmosIHN0cnVjdCBkZXZpY2Ug KmRldiwgY2hhciAqYnVmKQo+ICt7Cj4gKwljaGFyIG5hbWVbTVZORVRfU1RSSU5HX0xFTl07Cj4g Kwljb25zdCBjaGFyICpuYW1lX3N0ciA9ICJ2aXJ0aW8tbmV0IjsKPiArCj4gKwlzbnByaW50Zihu YW1lLCBNVk5FVF9TVFJJTkdfTEVOLCAiJXMiLCBkZXZfZHJpdmVyX3N0cmluZyhkZXYpKTsKPiAr CWlmICghc3RyY21wKGtvYmotPm5hbWUsIG5hbWUpKQo+ICsJCXJldHVybiBzcHJpbnRmKGJ1Ziwg IiVzXG4iLCBuYW1lX3N0cik7Cj4gKwo+ICsJcmV0dXJuIC1FSU5WQUw7Cj4gK30KPiArCj4gK3N0 YXRpYyBNREVWX1RZUEVfQVRUUl9STyhuYW1lKTsKPiArCj4gK3N0YXRpYyBzc2l6ZV90Cj4gK2F2 YWlsYWJsZV9pbnN0YW5jZXNfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IGRldmlj ZSAqZGV2LCBjaGFyICpidWYpCj4gK3sKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVkXG4iLCBJ TlRfTUFYKTsKPiArfQo+ICsKPiArc3RhdGljIE1ERVZfVFlQRV9BVFRSX1JPKGF2YWlsYWJsZV9p bnN0YW5jZXMpOwo+ICsKPiArc3RhdGljIHNzaXplX3QgZGV2aWNlX2FwaV9zaG93KHN0cnVjdCBr b2JqZWN0ICprb2JqLCBzdHJ1Y3QgZGV2aWNlICpkZXYsCj4gKwkJCSAgICAgICBjaGFyICpidWYp Cj4gK3sKPiArCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBWSVJUSU9fTURFVl9ERVZJQ0Vf QVBJX1NUUklORyk7Cj4gK30KPiArCj4gK3N0YXRpYyBNREVWX1RZUEVfQVRUUl9STyhkZXZpY2Vf YXBpKTsKPiArCj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICptZGV2X3R5cGVzX2F0dHJzW10g PSB7Cj4gKwkmbWRldl90eXBlX2F0dHJfbmFtZS5hdHRyLAo+ICsJJm1kZXZfdHlwZV9hdHRyX2Rl dmljZV9hcGkuYXR0ciwKPiArCSZtZGV2X3R5cGVfYXR0cl9hdmFpbGFibGVfaW5zdGFuY2VzLmF0 dHIsCj4gKwlOVUxMLAo+ICt9Owo+ICsKPiArc3RhdGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAg bWRldl90eXBlX2dyb3VwID0gewo+ICsJLm5hbWUgID0gInZpcnRpbyIsCj4gKwkuYXR0cnMgPSBt ZGV2X3R5cGVzX2F0dHJzLAo+ICt9Owo+ICsKPiArLyogVEJEOiAidmhvc3QiIHR5cGUgKi8KPiAr Cj4gK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwICptZGV2X3R5cGVfZ3JvdXBzW10gPSB7 Cj4gKwkmbWRldl90eXBlX2dyb3VwLAo+ICsJTlVMTCwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQg bXZuZXRfc2V0X3ZxX2FkZHJlc3Moc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4LAo+ ICsJCQkJdTY0IGRlc2NfYXJlYSwgdTY0IGRyaXZlcl9hcmVhLCB1NjQgZGV2aWNlX2FyZWEpCj4g K3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYp Owo+ICsJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEgPSAmbXZuZXQtPnZxc1tpZHhdOwo+ICsK PiArCXZxLT5kZXNjX2FkZHIgPSBkZXNjX2FyZWE7Cj4gKwl2cS0+ZHJpdmVyX2FkZHIgPSBkcml2 ZXJfYXJlYTsKPiArCXZxLT5kZXZpY2VfYWRkciA9IGRldmljZV9hcmVhOwo+ICsKPiArCXJldHVy biAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF9zZXRfdnFfbnVtKHN0cnVjdCBtZGV2 X2RldmljZSAqbWRldiwgdTE2IGlkeCwgdTMyIG51bSkKPiArewo+ICsJc3RydWN0IG12bmV0X3N0 YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwlzdHJ1Y3QgbXZuZXRfdmly dHF1ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07Cj4gKwo+ICsJdnEtPm51bSA9IG51bTsKPiAr fQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfa2lja192cShzdHJ1Y3QgbWRldl9kZXZpY2UgKm1k ZXYsIHUxNiBpZHgpCj4gK3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dl dF9kcnZkYXRhKG1kZXYpOwo+ICsJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEgPSAmbXZuZXQt PnZxc1tpZHhdOwo+ICsKPiArCWlmICh2cS0+cmVhZHkpCj4gKwkJc2NoZWR1bGVfd29yaygmbXZu ZXQtPndvcmspOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF9zZXRfdnFfY2Ioc3RydWN0 IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4LAo+ICsJCQkgICAgc3RydWN0IHZpcnRpb19tZGV2 X2NhbGxiYWNrICpjYikKPiArewo+ICsJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZf Z2V0X2RydmRhdGEobWRldik7Cj4gKwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp2cSA9ICZtdm5l dC0+dnFzW2lkeF07Cj4gKwo+ICsJdnEtPmNiID0gY2ItPmNhbGxiYWNrOwo+ICsJdnEtPnByaXZh dGUgPSBjYi0+cHJpdmF0ZTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfc2V0X3ZxX3Jl YWR5KHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwgdTE2IGlkeCwgYm9vbCByZWFkeSkKPiArewo+ ICsJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4g KwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07Cj4gKwo+ICsJ c3Bpbl9sb2NrKCZtdm5ldC0+bG9jayk7Cj4gKwl2cS0+cmVhZHkgPSByZWFkeTsKPiArCWlmICh2 cS0+cmVhZHkpCj4gKwkJbXZuZXRfcXVldWVfcmVhZHkobXZuZXQsIGlkeCk7Cj4gKwlzcGluX3Vu bG9jaygmbXZuZXQtPmxvY2spOwo+ICt9Cj4gKwo+ICtzdGF0aWMgYm9vbCBtdm5ldF9nZXRfdnFf cmVhZHkoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4KQo+ICt7Cj4gKwlzdHJ1Y3Qg bXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCXN0cnVjdCBt dm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKPiArCj4gKwlyZXR1cm4gdnEt PnJlYWR5Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG12bmV0X3NldF92cV9zdGF0ZShzdHJ1Y3Qg bWRldl9kZXZpY2UgKm1kZXYsIHUxNiBpZHgsIHU2NCBzdGF0ZSkKPiArewo+ICsJc3RydWN0IG12 bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwlzdHJ1Y3QgbXZu ZXRfdmlydHF1ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07Cj4gKwlzdHJ1Y3QgdnJpbmdoICp2 cmggPSAmdnEtPnZyaW5nOwo+ICsKPiArCXNwaW5fbG9jaygmbXZuZXQtPmxvY2spOwo+ICsJdnJo LT5sYXN0X2F2YWlsX2lkeCA9IHN0YXRlOwo+ICsJc3Bpbl91bmxvY2soJm12bmV0LT5sb2NrKTsK PiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHU2NCBtdm5ldF9nZXRfdnFfc3Rh dGUoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4KQo+ICt7Cj4gKwlzdHJ1Y3QgbXZu ZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCXN0cnVjdCBtdm5l dF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKPiArCXN0cnVjdCB2cmluZ2ggKnZy aCA9ICZ2cS0+dnJpbmc7Cj4gKwo+ICsJcmV0dXJuIHZyaC0+bGFzdF9hdmFpbF9pZHg7Cj4gK30K PiArCj4gK3N0YXRpYyB1MTYgbXZuZXRfZ2V0X3ZxX2FsaWduKHN0cnVjdCBtZGV2X2RldmljZSAq bWRldikKPiArewo+ICsJcmV0dXJuIE1WTkVUX1FVRVVFX0FMSUdOOwo+ICt9Cj4gKwo+ICtzdGF0 aWMgdTY0IG12bmV0X2dldF9mZWF0dXJlcyhzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYpCj4gK3sK PiArCXJldHVybiBtdm5ldF9mZWF0dXJlczsKPiArfQo+ICsKPiArc3RhdGljIGludCBtdm5ldF9z ZXRfZmVhdHVyZXMoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1NjQgZmVhdHVyZXMpCj4gK3sK PiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYpOwo+ ICsKPiArCS8qIERNQSBtYXBwaW5nIG11c3QgYmUgZG9uZSBieSBkcml2ZXIgKi8KPiArCWlmICgh KGZlYXR1cmVzICYgKDFVTEwgPDwgVklSVElPX0ZfSU9NTVVfUExBVEZPUk0pKSkKPiArCQlyZXR1 cm4gLUVJTlZBTDsKPiArCj4gKwltdm5ldC0+ZmVhdHVyZXMgPSBmZWF0dXJlcyAmIG12bmV0X2Zl YXR1cmVzOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBtdm5ldF9z ZXRfY29uZmlnX2NiKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwKPiArCQkJCXN0cnVjdCB2aXJ0 aW9fbWRldl9jYWxsYmFjayAqY2IpCj4gK3sKPiArCS8qIFdlIGRvbid0IHN1cHBvcnQgY29uZmln IGludGVycnVwdCAqLwo+ICt9Cj4gKwo+ICtzdGF0aWMgdTE2IG12bmV0X2dldF92cV9udW1fbWF4 KHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKPiArewo+ICsJcmV0dXJuIE1WTkVUX1FVRVVFX01B WDsKPiArfQo+ICsKPiArc3RhdGljIHUzMiBtdm5ldF9nZXRfZGV2aWNlX2lkKHN0cnVjdCBtZGV2 X2RldmljZSAqbWRldikKPiArewo+ICsJcmV0dXJuIE1WTkVUX0RFVklDRV9JRDsKPiArfQo+ICsK PiArc3RhdGljIHUzMiBtdm5ldF9nZXRfdmVuZG9yX2lkKHN0cnVjdCBtZGV2X2RldmljZSAqbWRl dikKPiArewo+ICsJcmV0dXJuIE1WTkVUX1ZFTkRPUl9JRDsKPiArfQo+ICsKPiArc3RhdGljIHU4 IG12bmV0X2dldF9zdGF0dXMoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KQo+ICt7Cj4gKwlzdHJ1 Y3QgbXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCj4gKwly ZXR1cm4gbXZuZXQtPnN0YXR1czsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRfc2V0X3N0 YXR1cyhzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsIHU4IHN0YXR1cykKPiArewo+ICsJc3RydWN0 IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7Cj4gKwo+ICsJbXZu ZXQtPnN0YXR1cyA9IHN0YXR1czsKPiArCj4gKwlpZiAoc3RhdHVzID09IDApIHsKPiArCQlzcGlu X2xvY2soJm12bmV0LT5sb2NrKTsKPiArCQltdm5ldF9yZXNldChtdm5ldCk7Cj4gKwkJc3Bpbl91 bmxvY2soJm12bmV0LT5sb2NrKTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIHZvaWQgbXZuZXRf Z2V0X2NvbmZpZyhzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsIHVuc2lnbmVkIGludCBvZmZzZXQs Cj4gKwkJCSAgICAgdm9pZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQo+ICt7Cj4gKwlzdHJ1Y3Qg bXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKPiArCj4gKwlpZiAo b2Zmc2V0ICsgbGVuIDwgc2l6ZW9mKHN0cnVjdCB2aXJ0aW9fbmV0X2NvbmZpZykpCj4gKwkJbWVt Y3B5KGJ1ZiwgJm12bmV0LT5jb25maWcgKyBvZmZzZXQsIGxlbik7Cj4gK30KPiArCj4gK3N0YXRp YyB2b2lkIG12bmV0X3NldF9jb25maWcoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1bnNpZ25l ZCBpbnQgb2Zmc2V0LAo+ICsJCQkgICAgIGNvbnN0IHZvaWQgKmJ1ZiwgdW5zaWduZWQgaW50IGxl bikKPiArewo+ICsJLyogTm8gd3JpdGFibGUgY29uZmlnIHN1cHBvcnR0ZWQgYnkgbXZuZXQgKi8K PiArfQo+ICsKPiArc3RhdGljIHUzMiBtdm5ldF9nZXRfZ2VuZXJhdGlvbihzdHJ1Y3QgbWRldl9k ZXZpY2UgKm1kZXYpCj4gK3sKPiArCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dl dF9kcnZkYXRhKG1kZXYpOwo+ICsKPiArCXJldHVybiBtdm5ldC0+Z2VuZXJhdGlvbjsKPiArfQo+ ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBtZGV2X3ZpcnRpb19kZXZpY2Vfb3BzIG1kZXZfdmly dGlvX29wcyA9IHsKPiArCS5zZXRfdnFfYWRkcmVzcyAgICAgICAgID0gbXZuZXRfc2V0X3ZxX2Fk ZHJlc3MsCj4gKwkuc2V0X3ZxX251bSAgICAgICAgICAgICA9IG12bmV0X3NldF92cV9udW0sCj4g Kwkua2lja192cSAgICAgICAgICAgICAgICA9IG12bmV0X2tpY2tfdnEsCj4gKwkuc2V0X3ZxX2Ni ICAgICAgICAgICAgICA9IG12bmV0X3NldF92cV9jYiwKPiArCS5zZXRfdnFfcmVhZHkgICAgICAg ICAgID0gbXZuZXRfc2V0X3ZxX3JlYWR5LAo+ICsJLmdldF92cV9yZWFkeSAgICAgICAgICAgPSBt dm5ldF9nZXRfdnFfcmVhZHksCj4gKwkuc2V0X3ZxX3N0YXRlICAgICAgICAgICA9IG12bmV0X3Nl dF92cV9zdGF0ZSwKPiArCS5nZXRfdnFfc3RhdGUgICAgICAgICAgID0gbXZuZXRfZ2V0X3ZxX3N0 YXRlLAo+ICsJLmdldF92cV9hbGlnbiAgICAgICAgICAgPSBtdm5ldF9nZXRfdnFfYWxpZ24sCj4g KwkuZ2V0X2ZlYXR1cmVzICAgICAgICAgICA9IG12bmV0X2dldF9mZWF0dXJlcywKPiArCS5zZXRf ZmVhdHVyZXMgICAgICAgICAgID0gbXZuZXRfc2V0X2ZlYXR1cmVzLAo+ICsJLnNldF9jb25maWdf Y2IgICAgICAgICAgPSBtdm5ldF9zZXRfY29uZmlnX2NiLAo+ICsJLmdldF92cV9udW1fbWF4ICAg ICAgICAgPSBtdm5ldF9nZXRfdnFfbnVtX21heCwKPiArCS5nZXRfZGV2aWNlX2lkICAgICAgICAg ID0gbXZuZXRfZ2V0X2RldmljZV9pZCwKPiArCS5nZXRfdmVuZG9yX2lkICAgICAgICAgID0gbXZu ZXRfZ2V0X3ZlbmRvcl9pZCwKPiArCS5nZXRfc3RhdHVzICAgICAgICAgICAgID0gbXZuZXRfZ2V0 X3N0YXR1cywKPiArCS5zZXRfc3RhdHVzICAgICAgICAgICAgID0gbXZuZXRfc2V0X3N0YXR1cywK PiArCS5nZXRfY29uZmlnICAgICAgICAgICAgID0gbXZuZXRfZ2V0X2NvbmZpZywKPiArCS5zZXRf Y29uZmlnICAgICAgICAgICAgID0gbXZuZXRfc2V0X2NvbmZpZywKPiArCS5nZXRfZ2VuZXJhdGlv biAgICAgICAgID0gbXZuZXRfZ2V0X2dlbmVyYXRpb24sCj4gK307Cj4gKwo+ICtzdGF0aWMgY29u c3Qgc3RydWN0IG1kZXZfcGFyZW50X29wcyBtZGV2X2ZvcHMgPSB7Cj4gKwkub3duZXIgICAgICAg ICAgICAgICAgICA9IFRISVNfTU9EVUxFLAo+ICsJLmRldl9hdHRyX2dyb3VwcyAgICAgICAgPSBt dm5ldF9kZXZfZ3JvdXBzLAo+ICsJLm1kZXZfYXR0cl9ncm91cHMgICAgICAgPSBtZGV2X2Rldl9n cm91cHMsCj4gKwkuc3VwcG9ydGVkX3R5cGVfZ3JvdXBzICA9IG1kZXZfdHlwZV9ncm91cHMsCj4g KwkuY3JlYXRlICAgICAgICAgICAgICAgICA9IG12bmV0X2NyZWF0ZSwKPiArCS5yZW1vdmUJCQk9 IG12bmV0X3JlbW92ZSwKPiArfTsKPiArCj4gK3N0YXRpYyB2b2lkIG12bmV0X2RldmljZV9yZWxl YXNlKHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsJZGV2X2RiZyhkZXYsICJtdm5ldDogcmVs ZWFzZWRcbiIpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IF9faW5pdCBtdm5ldF9kZXZfaW5pdCh2 b2lkKQo+ICt7Cj4gKwlpbnQgcmV0ID0gMDsKPiArCj4gKwlwcl9pbmZvKCJtdm5ldF9kZXY6ICVz XG4iLCBfX2Z1bmNfXyk7Cj4gKwo+ICsJbWVtc2V0KCZtdm5ldF9kZXYsIDAsIHNpemVvZihtdm5l dF9kZXYpKTsKPiArCj4gKwlpZHJfaW5pdCgmbXZuZXRfZGV2LnZkX2lkcik7Cj4gKwo+ICsJbXZu ZXRfZGV2LnZkX2NsYXNzID0gY2xhc3NfY3JlYXRlKFRISVNfTU9EVUxFLCBNVk5FVF9DTEFTU19O QU1FKTsKPiArCj4gKwlpZiAoSVNfRVJSKG12bmV0X2Rldi52ZF9jbGFzcykpIHsKPiArCQlwcl9l cnIoIkVycm9yOiBmYWlsZWQgdG8gcmVnaXN0ZXIgbXZuZXRfZGV2IGNsYXNzXG4iKTsKPiArCQly ZXQgPSBQVFJfRVJSKG12bmV0X2Rldi52ZF9jbGFzcyk7Cj4gKwkJZ290byBmYWlsZWQxOwo+ICsJ fQo+ICsKPiArCW12bmV0X2Rldi5kZXYuY2xhc3MgPSBtdm5ldF9kZXYudmRfY2xhc3M7Cj4gKwlt dm5ldF9kZXYuZGV2LnJlbGVhc2UgPSBtdm5ldF9kZXZpY2VfcmVsZWFzZTsKPiArCWRldl9zZXRf bmFtZSgmbXZuZXRfZGV2LmRldiwgIiVzIiwgTVZORVRfTkFNRSk7Cj4gKwo+ICsJcmV0ID0gZGV2 aWNlX3JlZ2lzdGVyKCZtdm5ldF9kZXYuZGV2KTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBmYWls ZWQyOwo+ICsKPiArCXJldCA9IG1kZXZfcmVnaXN0ZXJfZGV2aWNlKCZtdm5ldF9kZXYuZGV2LCAm bWRldl9mb3BzKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBmYWlsZWQzOwo+ICsKPiArCW11dGV4 X2luaXQoJm1kZXZfbGlzdF9sb2NrKTsKPiArCUlOSVRfTElTVF9IRUFEKCZtZGV2X2RldmljZXNf bGlzdCk7Cj4gKwo+ICsJZ290byBhbGxfZG9uZTsKPiArCj4gK2ZhaWxlZDM6Cj4gKwo+ICsJZGV2 aWNlX3VucmVnaXN0ZXIoJm12bmV0X2Rldi5kZXYpOwo+ICtmYWlsZWQyOgo+ICsJY2xhc3NfZGVz dHJveShtdm5ldF9kZXYudmRfY2xhc3MpOwo+ICsKPiArZmFpbGVkMToKPiArYWxsX2RvbmU6Cj4g KwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBfX2V4aXQgbXZuZXRfZGV2X2V4 aXQodm9pZCkKPiArewo+ICsJbXZuZXRfZGV2LmRldi5idXMgPSBOVUxMOwo+ICsJbWRldl91bnJl Z2lzdGVyX2RldmljZSgmbXZuZXRfZGV2LmRldik7Cj4gKwo+ICsJZGV2aWNlX3VucmVnaXN0ZXIo Jm12bmV0X2Rldi5kZXYpOwo+ICsJaWRyX2Rlc3Ryb3koJm12bmV0X2Rldi52ZF9pZHIpOwo+ICsJ Y2xhc3NfZGVzdHJveShtdm5ldF9kZXYudmRfY2xhc3MpOwo+ICsJbXZuZXRfZGV2LnZkX2NsYXNz ID0gTlVMTDsKPiArCXByX2luZm8oIm12bmV0X2RldjogVW5sb2FkZWQhXG4iKTsKPiArfQo+ICsK PiArbW9kdWxlX2luaXQobXZuZXRfZGV2X2luaXQpCj4gK21vZHVsZV9leGl0KG12bmV0X2Rldl9l eGl0KQo+ICsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwo+ICtNT0RVTEVfSU5GTyhzdXBw b3J0ZWQsICJTaW11bGF0ZSBsb29wYmFjayBldGhlcm5ldCBkZXZpY2Ugb3ZlciBtZGV2Iik7Cj4g K01PRFVMRV9WRVJTSU9OKFZFUlNJT05fU1RSSU5HKTsKPiArTU9EVUxFX0FVVEhPUihEUklWRVJf QVVUSE9SKTsKPiAtLSAKPiAyLjE5LjEKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX18KSW50ZWwtZ2Z4IG1haWxpbmcgbGlzdApJbnRlbC1nZnhAbGlzdHMuZnJl ZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGlu Zm8vaW50ZWwtZ2Z4