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 9719EFA372A for ; Thu, 17 Oct 2019 10:52:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5974620869 for ; Thu, 17 Oct 2019 10:52:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2409167AbfJQKwO (ORCPT ); Thu, 17 Oct 2019 06:52:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58836 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2409089AbfJQKwO (ORCPT ); Thu, 17 Oct 2019 06:52:14 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 067098A1C85; Thu, 17 Oct 2019 10:52:13 +0000 (UTC) Received: from jason-ThinkPad-X1-Carbon-6th.redhat.com (ovpn-12-185.pek2.redhat.com [10.72.12.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id 047875D70D; Thu, 17 Oct 2019 10:51:48 +0000 (UTC) From: Jason Wang To: 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, mst@redhat.com, tiwei.bie@intel.com Cc: 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, Jason Wang Subject: [PATCH V4 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework Date: Thu, 17 Oct 2019 18:48:36 +0800 Message-Id: <20191017104836.32464-7-jasowang@redhat.com> In-Reply-To: <20191017104836.32464-1-jasowang@redhat.com> References: <20191017104836.32464-1-jasowang@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.69]); Thu, 17 Oct 2019 10:52:13 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. Signed-off-by: Jason Wang --- MAINTAINERS | 1 + samples/Kconfig | 7 + samples/vfio-mdev/Makefile | 1 + samples/vfio-mdev/mvnet.c | 691 +++++++++++++++++++++++++++++++++++++ 4 files changed, 700 insertions(+) create mode 100644 samples/vfio-mdev/mvnet.c diff --git a/MAINTAINERS b/MAINTAINERS index 3d196a023b5e..cb51351cd5c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17254,6 +17254,7 @@ F: include/linux/virtio*.h F: include/uapi/linux/virtio_*.h F: drivers/crypto/virtio/ F: mm/balloon_compaction.c +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..a1a1ca2c00b7 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -131,6 +131,13 @@ 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 mdev net example mediated device sample code -- loadable modules only" + depends on VIRTIO_MDEV_DEVICE && VHOST_RING && m + help + Build a networking sample device for use as a virtio + mediated device. + 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..19e823a449cd --- /dev/null +++ b/samples/vfio-mdev/mvnet.c @@ -0,0 +1,691 @@ +// 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_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 == NULL) + *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 virtio_mdev_device_ops virtio_mdev_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(struct mvnet_state), GFP_KERNEL); + if (mvnet == NULL) + 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, &virtio_mdev_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 u64 mvnet_get_mdev_features(struct mdev_device *mdev) +{ + return VIRTIO_MDEV_F_VERSION_1; +} + +static u32 mvnet_get_generation(struct mdev_device *mdev) +{ + struct mvnet_state *mvnet = mdev_get_drvdata(mdev); + + return mvnet->generation; +} + +static const struct virtio_mdev_device_ops virtio_mdev_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_mdev_features = mvnet_get_mdev_features, + .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: Jason Wang Subject: [PATCH V4 6/6] docs: sample driver to demonstrate how to implement virtio-mdev framework Date: Thu, 17 Oct 2019 18:48:36 +0800 Message-ID: <20191017104836.32464-7-jasowang@redhat.com> References: <20191017104836.32464-1-jasowang@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20191017104836.32464-1-jasowang@redhat.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: 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, mst@redhat.com, tiwei.bie@intel.com Cc: christophe.de.dinechin@gmail.com, sebott@linux.ibm.com, airlied@linux.ie, Jason Wang , heiko.carstens@de.ibm.com, virtualization@lists.linux-foundation.org, rob.miller@broadcom.com, lulu@redhat.com, eperezma@redhat.com, pasic@linux.ibm.com, borntraeger@de.ibm.com, haotian.wang@sifive.com, farman@linux.ibm.com, idos@mellanox.com, gor@linux.ibm.com, cunming.liang@intel.com, xiao.w.wang@intel.com, freude@linux.ibm.com, parav@mellanox.com, zhihong.wang@intel.com, stefanha@redhat.com, akrowiak@linux.ibm.com, netdev@vger.kernel.org, cohuck@redhat.com, oberpar@linux.ibm.com, maxime.coquelin@redhat.com, lingshan.zhu@intel.com List-Id: dri-devel@lists.freedesktop.org VGhpcyBzYW1wbGUgZHJpdmVyIGNyZWF0ZXMgbWRldiBkZXZpY2UgdGhhdCBzaW11bGF0ZSB2aXJ0 aW8gbmV0IGRldmljZQpvdmVyIHZpcnRpbyBtZGV2IHRyYW5zcG9ydC4gVGhlIGRldmljZSBpcyBp bXBsZW1lbnRlZCB0aHJvdWdoIHZyaW5naAphbmQgd29ya3F1ZXVlLiBBIGRldmljZSBzcGVjaWZp YyBkbWEgb3BzIGlzIHRvIG1ha2Ugc3VyZSBIVkEgaXMgdXNlZApkaXJlY3RseSBhcyB0aGUgSU9W QS4gVGhpcyBzaG91bGQgYmUgc3VmZmljaWVudCBmb3Iga2VybmVsIHZpcnRpbwpkcml2ZXIgdG8g d29yay4KCk9ubHkgJ3ZpcnRpbycgdHlwZSBpcyBzdXBwb3J0ZWQgcmlnaHQgbm93LiBJIHBsYW4g dG8gYWRkICd2aG9zdCcgdHlwZQpvbiB0b3Agd2hpY2ggcmVxdWlyZXMgc29tZSB2aXJ0dWFsIElP TU1VIGltcGxlbWVudGVkIGluIHRoaXMgc2FtcGxlCmRyaXZlci4KClNpZ25lZC1vZmYtYnk6IEph c29uIFdhbmcgPGphc293YW5nQHJlZGhhdC5jb20+Ci0tLQogTUFJTlRBSU5FUlMgICAgICAgICAg ICAgICAgfCAgIDEgKwogc2FtcGxlcy9LY29uZmlnICAgICAgICAgICAgfCAgIDcgKwogc2FtcGxl cy92ZmlvLW1kZXYvTWFrZWZpbGUgfCAgIDEgKwogc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYyAg fCA2OTEgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogNCBmaWxlcyBjaGFu Z2VkLCA3MDAgaW5zZXJ0aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IHNhbXBsZXMvdmZpby1t ZGV2L212bmV0LmMKCmRpZmYgLS1naXQgYS9NQUlOVEFJTkVSUyBiL01BSU5UQUlORVJTCmluZGV4 IDNkMTk2YTAyM2I1ZS4uY2I1MTM1MWNkNWM5IDEwMDY0NAotLS0gYS9NQUlOVEFJTkVSUworKysg Yi9NQUlOVEFJTkVSUwpAQCAtMTcyNTQsNiArMTcyNTQsNyBAQCBGOglpbmNsdWRlL2xpbnV4L3Zp cnRpbyouaAogRjoJaW5jbHVkZS91YXBpL2xpbnV4L3ZpcnRpb18qLmgKIEY6CWRyaXZlcnMvY3J5 cHRvL3ZpcnRpby8KIEY6CW1tL2JhbGxvb25fY29tcGFjdGlvbi5jCitGOglzYW1wbGVzL3ZmaW8t bWRldi9tdm5ldC5jCiAKIFZJUlRJTyBCTE9DSyBBTkQgU0NTSSBEUklWRVJTCiBNOgkiTWljaGFl bCBTLiBUc2lya2luIiA8bXN0QHJlZGhhdC5jb20+CmRpZmYgLS1naXQgYS9zYW1wbGVzL0tjb25m aWcgYi9zYW1wbGVzL0tjb25maWcKaW5kZXggYzhkYWNiNGRkYTgwLi5hMWExY2EyYzAwYjcgMTAw NjQ0Ci0tLSBhL3NhbXBsZXMvS2NvbmZpZworKysgYi9zYW1wbGVzL0tjb25maWcKQEAgLTEzMSw2 ICsxMzEsMTMgQEAgY29uZmlnIFNBTVBMRV9WRklPX01ERVZfTURQWQogCSAgbWVkaWF0ZWQgZGV2 aWNlLiAgSXQgaXMgYSBzaW1wbGUgZnJhbWVidWZmZXIgYW5kIHN1cHBvcnRzCiAJICB0aGUgcmVn aW9uIGRpc3BsYXkgaW50ZXJmYWNlIChWRklPX0dGWF9QTEFORV9UWVBFX1JFR0lPTikuCiAKK2Nv bmZpZyBTQU1QTEVfVklSVElPX01ERVZfTkVUCisgICAgICAgIHRyaXN0YXRlICJCdWlsZCB2aXJ0 aW8gbWRldiBuZXQgZXhhbXBsZSBtZWRpYXRlZCBkZXZpY2Ugc2FtcGxlIGNvZGUgLS0gbG9hZGFi bGUgbW9kdWxlcyBvbmx5IgorCWRlcGVuZHMgb24gVklSVElPX01ERVZfREVWSUNFICYmIFZIT1NU X1JJTkcgJiYgbQorCWhlbHAKKwkgIEJ1aWxkIGEgbmV0d29ya2luZyBzYW1wbGUgZGV2aWNlIGZv ciB1c2UgYXMgYSB2aXJ0aW8KKwkgIG1lZGlhdGVkIGRldmljZS4KKwogY29uZmlnIFNBTVBMRV9W RklPX01ERVZfTURQWV9GQgogCXRyaXN0YXRlICJCdWlsZCBWRklPIG1kcHkgZXhhbXBsZSBndWVz dCBmYmRldiBkcml2ZXIgLS0gbG9hZGFibGUgbW9kdWxlIG9ubHkiCiAJZGVwZW5kcyBvbiBGQiAm JiBtCmRpZmYgLS1naXQgYS9zYW1wbGVzL3ZmaW8tbWRldi9NYWtlZmlsZSBiL3NhbXBsZXMvdmZp by1tZGV2L01ha2VmaWxlCmluZGV4IDEwZDE3OWM0ZmRlYi4uZjM0YWY5MGVkMGEwIDEwMDY0NAot LS0gYS9zYW1wbGVzL3ZmaW8tbWRldi9NYWtlZmlsZQorKysgYi9zYW1wbGVzL3ZmaW8tbWRldi9N YWtlZmlsZQpAQCAtMywzICszLDQgQEAgb2JqLSQoQ09ORklHX1NBTVBMRV9WRklPX01ERVZfTVRU WSkgKz0gbXR0eS5vCiBvYmotJChDT05GSUdfU0FNUExFX1ZGSU9fTURFVl9NRFBZKSArPSBtZHB5 Lm8KIG9iai0kKENPTkZJR19TQU1QTEVfVkZJT19NREVWX01EUFlfRkIpICs9IG1kcHktZmIubwog b2JqLSQoQ09ORklHX1NBTVBMRV9WRklPX01ERVZfTUJPQ0hTKSArPSBtYm9jaHMubworb2JqLSQo Q09ORklHX1NBTVBMRV9WSVJUSU9fTURFVl9ORVQpICs9IG12bmV0Lm8KZGlmZiAtLWdpdCBhL3Nh bXBsZXMvdmZpby1tZGV2L212bmV0LmMgYi9zYW1wbGVzL3ZmaW8tbWRldi9tdm5ldC5jCm5ldyBm aWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uMTllODIzYTQ0OWNkCi0tLSAvZGV2 L251bGwKKysrIGIvc2FtcGxlcy92ZmlvLW1kZXYvbXZuZXQuYwpAQCAtMCwwICsxLDY5MSBAQAor Ly8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQorLyoKKyAqIE1lZGlhdGVk IHZpcnR1YWwgdmlydGlvLW5ldCBkZXZpY2UgZHJpdmVyLgorICoKKyAqIENvcHlyaWdodCAoYykg MjAxOSwgUmVkIEhhdCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiAgICAgQXV0aG9yOiBK YXNvbiBXYW5nIDxqYXNvd2FuZ0ByZWRoYXQuY29tPgorICoKKyAqIFNhbXBsZSBkcml2ZXIgdGhh dCBjcmVhdGVzIG1kZXYgZGV2aWNlIHRoYXQgc2ltdWxhdGVzIGV0aGVybmV0IGxvb3BiYWNrCisg KiBkZXZpY2UuCisgKgorICogVXNhZ2U6CisgKgorICogIyBtb2Rwcm9iZSB2aXJ0aW9fbWRldgor ICogIyBtb2Rwcm9iZSBtdm5ldAorICogIyBjZCAvc3lzL2RldmljZXMvdmlydHVhbC9tdm5ldC9t dm5ldC9tZGV2X3N1cHBvcnRlZF90eXBlcy9tdm5ldC12aXJ0aW8KKyAqICMgZWNobyAiODNiOGY0 ZjItNTA5Zi0zODJmLTNjMWUtZTZiZmUwZmExMDAxIiA+IC4vY3JlYXRlCisgKiAjIGNkIGRldmlj ZXMvODNiOGY0ZjItNTA5Zi0zODJmLTNjMWUtZTZiZmUwZmExMDAxCisgKiAjIGxzIC1kIHZpcnRp bzAKKyAqIHZpcnRpbzAKKyAqLworCisjaW5jbHVkZSA8bGludXgvaW5pdC5oPgorI2luY2x1ZGUg PGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L2RldmljZS5oPgorI2luY2x1ZGUgPGxp bnV4L2tlcm5lbC5oPgorI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CisjaW5jbHVkZSA8bGludXgvcG9s bC5oPgorI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KKyNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgor I2luY2x1ZGUgPGxpbnV4L3dhaXQuaD4KKyNpbmNsdWRlIDxsaW51eC91dWlkLmg+CisjaW5jbHVk ZSA8bGludXgvaW9tbXUuaD4KKyNpbmNsdWRlIDxsaW51eC9zeXNmcy5oPgorI2luY2x1ZGUgPGxp bnV4L2ZpbGUuaD4KKyNpbmNsdWRlIDxsaW51eC9ldGhlcmRldmljZS5oPgorI2luY2x1ZGUgPGxp bnV4L21kZXYuaD4KKyNpbmNsdWRlIDxsaW51eC92cmluZ2guaD4KKyNpbmNsdWRlIDxsaW51eC92 aXJ0aW9fbWRldi5oPgorI2luY2x1ZGUgPHVhcGkvbGludXgvdmlydGlvX2NvbmZpZy5oPgorI2lu Y2x1ZGUgPHVhcGkvbGludXgvdmlydGlvX25ldC5oPgorCisjZGVmaW5lIFZFUlNJT05fU1RSSU5H ICAiMC4xIgorI2RlZmluZSBEUklWRVJfQVVUSE9SICAgIlJlZCBIYXQgQ29ycG9yYXRpb24iCisK KyNkZWZpbmUgTVZORVRfQ0xBU1NfTkFNRSAibXZuZXQiCisjZGVmaW5lIE1WTkVUX05BTUUgICAg ICAgIm12bmV0IgorCisvKgorICogR2xvYmFsIFN0cnVjdHVyZXMKKyAqLworCitzdGF0aWMgc3Ry dWN0IG12bmV0X2RldiB7CisJc3RydWN0IGNsYXNzCSp2ZF9jbGFzczsKKwlzdHJ1Y3QgaWRyCXZk X2lkcjsKKwlzdHJ1Y3QgZGV2aWNlCWRldjsKK30gbXZuZXRfZGV2OworCitzdHJ1Y3QgbXZuZXRf dmlydHF1ZXVlIHsKKwlzdHJ1Y3QgdnJpbmdoIHZyaW5nOworCXN0cnVjdCB2cmluZ2hfa2lvdiBp b3Y7CisJdW5zaWduZWQgc2hvcnQgaGVhZDsKKwlib29sIHJlYWR5OworCXU2NCBkZXNjX2FkZHI7 CisJdTY0IGRldmljZV9hZGRyOworCXU2NCBkcml2ZXJfYWRkcjsKKwl1MzIgbnVtOworCXZvaWQg KnByaXZhdGU7CisJaXJxcmV0dXJuX3QgKCpjYikodm9pZCAqZGF0YSk7Cit9OworCisjZGVmaW5l IE1WTkVUX1FVRVVFX0FMSUdOIFBBR0VfU0laRQorI2RlZmluZSBNVk5FVF9RVUVVRV9NQVggMjU2 CisjZGVmaW5lIE1WTkVUX0RFVklDRV9JRCAweDEKKyNkZWZpbmUgTVZORVRfVkVORE9SX0lEIDAK KwordTY0IG12bmV0X2ZlYXR1cmVzID0gKDFVTEwgPDwgVklSVElPX0ZfQU5ZX0xBWU9VVCkgfAor CQkgICAgICgxVUxMIDw8IFZJUlRJT19GX1ZFUlNJT05fMSkgfAorCQkgICAgICgxVUxMIDw8IFZJ UlRJT19GX0lPTU1VX1BMQVRGT1JNKTsKKworLyogU3RhdGUgb2YgZWFjaCBtZGV2IGRldmljZSAq Lworc3RydWN0IG12bmV0X3N0YXRlIHsKKwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlIHZxc1syXTsK KwlzdHJ1Y3Qgd29ya19zdHJ1Y3Qgd29yazsKKwlzcGlubG9ja190IGxvY2s7CisJc3RydWN0IG1k ZXZfZGV2aWNlICptZGV2OworCXN0cnVjdCB2aXJ0aW9fbmV0X2NvbmZpZyBjb25maWc7CisJdm9p ZCAqYnVmZmVyOworCXUzMiBzdGF0dXM7CisJdTMyIGdlbmVyYXRpb247CisJdTY0IGZlYXR1cmVz OworCXN0cnVjdCBsaXN0X2hlYWQgbmV4dDsKK307CisKK3N0YXRpYyBzdHJ1Y3QgbXV0ZXggbWRl dl9saXN0X2xvY2s7CitzdGF0aWMgc3RydWN0IGxpc3RfaGVhZCBtZGV2X2RldmljZXNfbGlzdDsK Kworc3RhdGljIHZvaWQgbXZuZXRfcXVldWVfcmVhZHkoc3RydWN0IG12bmV0X3N0YXRlICptdm5l dCwgdW5zaWduZWQgaW50IGlkeCkKK3sKKwlzdHJ1Y3QgbXZuZXRfdmlydHF1ZXVlICp2cSA9ICZt dm5ldC0+dnFzW2lkeF07CisJaW50IHJldDsKKworCXJldCA9IHZyaW5naF9pbml0X2tlcm4oJnZx LT52cmluZywgbXZuZXRfZmVhdHVyZXMsIE1WTkVUX1FVRVVFX01BWCwKKwkJCSAgICAgICBmYWxz ZSwgKHN0cnVjdCB2cmluZ19kZXNjICopdnEtPmRlc2NfYWRkciwKKwkJCSAgICAgICAoc3RydWN0 IHZyaW5nX2F2YWlsICopdnEtPmRyaXZlcl9hZGRyLAorCQkJICAgICAgIChzdHJ1Y3QgdnJpbmdf dXNlZCAqKXZxLT5kZXZpY2VfYWRkcik7Cit9CisKK3N0YXRpYyB2b2lkIG12bmV0X3ZxX3Jlc2V0 KHN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnZxKQoreworCXZxLT5yZWFkeSA9IDA7CisJdnEtPmRl c2NfYWRkciA9IDA7CisJdnEtPmRyaXZlcl9hZGRyID0gMDsKKwl2cS0+ZGV2aWNlX2FkZHIgPSAw OworCXZxLT5jYiA9IE5VTEw7CisJdnEtPnByaXZhdGUgPSBOVUxMOworCXZyaW5naF9pbml0X2tl cm4oJnZxLT52cmluZywgbXZuZXRfZmVhdHVyZXMsIE1WTkVUX1FVRVVFX01BWCwKKwkJCWZhbHNl LCAwLCAwLCAwKTsKK30KKworc3RhdGljIHZvaWQgbXZuZXRfcmVzZXQoc3RydWN0IG12bmV0X3N0 YXRlICptdm5ldCkKK3sKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7IGkgPCAyOyBpKyspCisJCW12 bmV0X3ZxX3Jlc2V0KCZtdm5ldC0+dnFzW2ldKTsKKworCW12bmV0LT5mZWF0dXJlcyA9IDA7CisJ bXZuZXQtPnN0YXR1cyA9IDA7CisJKyttdm5ldC0+Z2VuZXJhdGlvbjsKK30KKworc3RhdGljIHZv aWQgbXZuZXRfd29yayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCit7CisJc3RydWN0IG12bmV0 X3N0YXRlICptdm5ldCA9IGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QKKwkJCQkJCSBtdm5ldF9z dGF0ZSwgd29yayk7CisJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqdHhxID0gJm12bmV0LT52cXNb MV07CisJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqcnhxID0gJm12bmV0LT52cXNbMF07CisJc2l6 ZV90IHJlYWQsIHdyaXRlLCB0b3RhbF93cml0ZTsKKwlpbnQgZXJyOworCWludCBwa3RzID0gMDsK KworCXNwaW5fbG9jaygmbXZuZXQtPmxvY2spOworCisJaWYgKCF0eHEtPnJlYWR5IHx8ICFyeHEt PnJlYWR5KQorCQlnb3RvIG91dDsKKworCXdoaWxlICh0cnVlKSB7CisJCXRvdGFsX3dyaXRlID0g MDsKKwkJZXJyID0gdnJpbmdoX2dldGRlc2Nfa2VybigmdHhxLT52cmluZywgJnR4cS0+aW92LCBO VUxMLAorCQkJCQkgICZ0eHEtPmhlYWQsIEdGUF9BVE9NSUMpOworCQlpZiAoZXJyIDw9IDApCisJ CQlicmVhazsKKworCQllcnIgPSB2cmluZ2hfZ2V0ZGVzY19rZXJuKCZyeHEtPnZyaW5nLCBOVUxM LCAmcnhxLT5pb3YsCisJCQkJCSAgJnJ4cS0+aGVhZCwgR0ZQX0FUT01JQyk7CisJCWlmIChlcnIg PD0gMCkgeworCQkJdnJpbmdoX2NvbXBsZXRlX2tlcm4oJnR4cS0+dnJpbmcsIHR4cS0+aGVhZCwg MCk7CisJCQlicmVhazsKKwkJfQorCisJCXdoaWxlICh0cnVlKSB7CisJCQlyZWFkID0gdnJpbmdo X2lvdl9wdWxsX2tlcm4oJnR4cS0+aW92LCBtdm5ldC0+YnVmZmVyLAorCQkJCQkJICAgIFBBR0Vf U0laRSk7CisJCQlpZiAocmVhZCA8PSAwKQorCQkJCWJyZWFrOworCisJCQl3cml0ZSA9IHZyaW5n aF9pb3ZfcHVzaF9rZXJuKCZyeHEtPmlvdiwgbXZuZXQtPmJ1ZmZlciwKKwkJCQkJCSAgICAgcmVh ZCk7CisJCQlpZiAod3JpdGUgPD0gMCkKKwkJCQlicmVhazsKKworCQkJdG90YWxfd3JpdGUgKz0g d3JpdGU7CisJCX0KKworCQkvKiBNYWtlIHN1cmUgZGF0YSBpcyB3cm90ZSBiZWZvcmUgYWR2YW5j aW5nIGluZGV4ICovCisJCXNtcF93bWIoKTsKKworCQl2cmluZ2hfY29tcGxldGVfa2VybigmdHhx LT52cmluZywgdHhxLT5oZWFkLCAwKTsKKwkJdnJpbmdoX2NvbXBsZXRlX2tlcm4oJnJ4cS0+dnJp bmcsIHJ4cS0+aGVhZCwgdG90YWxfd3JpdGUpOworCisJCS8qIE1ha2Ugc3VyZSB1c2VkIGlzIHZp c2libGUgYmVmb3JlIHJhc2luZyB0aGUgaW50ZXJydXB0LiAqLworCQlzbXBfd21iKCk7CisKKwkJ bG9jYWxfYmhfZGlzYWJsZSgpOworCQlpZiAodHhxLT5jYikKKwkJCXR4cS0+Y2IodHhxLT5wcml2 YXRlKTsKKwkJaWYgKHJ4cS0+Y2IpCisJCQlyeHEtPmNiKHJ4cS0+cHJpdmF0ZSk7CisJCWxvY2Fs X2JoX2VuYWJsZSgpOworCisJCWlmICgrK3BrdHMgPiA0KSB7CisJCQlzY2hlZHVsZV93b3JrKCZt dm5ldC0+d29yayk7CisJCQlnb3RvIG91dDsKKwkJfQorCX0KKworb3V0OgorCXNwaW5fdW5sb2Nr KCZtdm5ldC0+bG9jayk7Cit9CisKK3N0YXRpYyBkbWFfYWRkcl90IG12bmV0X21hcF9wYWdlKHN0 cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IHBhZ2UgKnBhZ2UsCisJCQkJIHVuc2lnbmVkIGxvbmcg b2Zmc2V0LCBzaXplX3Qgc2l6ZSwKKwkJCQkgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyLAor CQkJCSB1bnNpZ25lZCBsb25nIGF0dHJzKQoreworCS8qIFZyaW5naCBjYW4gb25seSB1c2UgSFZB ICovCisJcmV0dXJuIChkbWFfYWRkcl90KShwYWdlX2FkZHJlc3MocGFnZSkgKyBvZmZzZXQpOwor fQorCitzdGF0aWMgdm9pZCBtdm5ldF91bm1hcF9wYWdlKHN0cnVjdCBkZXZpY2UgKmRldiwgZG1h X2FkZHJfdCBkbWFfYWRkciwKKwkJCSAgICAgc2l6ZV90IHNpemUsIGVudW0gZG1hX2RhdGFfZGly ZWN0aW9uIGRpciwKKwkJCSAgICAgdW5zaWduZWQgbG9uZyBhdHRycykKK3sKK30KKworc3RhdGlj IHZvaWQgKm12bmV0X2FsbG9jX2NvaGVyZW50KHN0cnVjdCBkZXZpY2UgKmRldiwgc2l6ZV90IHNp emUsCisJCQkJICBkbWFfYWRkcl90ICpkbWFfYWRkciwgZ2ZwX3QgZmxhZywKKwkJCQkgIHVuc2ln bmVkIGxvbmcgYXR0cnMpCit7CisJdm9pZCAqYWRkciA9IGttYWxsb2Moc2l6ZSwgZmxhZyk7CisK KwlpZiAoYWRkciA9PSBOVUxMKQorCQkqZG1hX2FkZHIgPSBETUFfTUFQUElOR19FUlJPUjsKKwll bHNlCisJCSpkbWFfYWRkciA9IChkbWFfYWRkcl90KSBhZGRyOworCisJcmV0dXJuIGFkZHI7Cit9 CisKK3N0YXRpYyB2b2lkIG12bmV0X2ZyZWVfY29oZXJlbnQoc3RydWN0IGRldmljZSAqZGV2LCBz aXplX3Qgc2l6ZSwKKwkJCQl2b2lkICp2YWRkciwgZG1hX2FkZHJfdCBkbWFfYWRkciwKKwkJCQl1 bnNpZ25lZCBsb25nIGF0dHJzKQoreworCWtmcmVlKCh2b2lkICopZG1hX2FkZHIpOworfQorCitz dGF0aWMgY29uc3Qgc3RydWN0IGRtYV9tYXBfb3BzIG12bmV0X2RtYV9vcHMgPSB7CisJLm1hcF9w YWdlID0gbXZuZXRfbWFwX3BhZ2UsCisJLnVubWFwX3BhZ2UgPSBtdm5ldF91bm1hcF9wYWdlLAor CS5hbGxvYyA9IG12bmV0X2FsbG9jX2NvaGVyZW50LAorCS5mcmVlID0gbXZuZXRfZnJlZV9jb2hl cmVudCwKK307CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdmlydGlvX21kZXZfZGV2aWNlX29wcyB2 aXJ0aW9fbWRldl9vcHM7CisKK3N0YXRpYyBpbnQgbXZuZXRfY3JlYXRlKHN0cnVjdCBrb2JqZWN0 ICprb2JqLCBzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYpCit7CisJc3RydWN0IG12bmV0X3N0YXRl ICptdm5ldDsKKwlzdHJ1Y3QgdmlydGlvX25ldF9jb25maWcgKmNvbmZpZzsKKwlzdHJ1Y3QgZGV2 aWNlICpkZXYgPSBtZGV2X2RldihtZGV2KTsKKworCWlmICghbWRldikKKwkJcmV0dXJuIC1FSU5W QUw7CisKKwltdm5ldCA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBtdm5ldF9zdGF0ZSksIEdGUF9L RVJORUwpOworCWlmIChtdm5ldCA9PSBOVUxMKQorCQlyZXR1cm4gLUVOT01FTTsKKworCW12bmV0 LT5idWZmZXIgPSBrbWFsbG9jKFBBR0VfU0laRSwgR0ZQX0tFUk5FTCk7CisJaWYgKCFtdm5ldC0+ YnVmZmVyKSB7CisJCWtmcmVlKG12bmV0KTsKKwkJcmV0dXJuIC1FTk9NRU07CisJfQorCisJY29u ZmlnID0gJm12bmV0LT5jb25maWc7CisJY29uZmlnLT5tdHUgPSAxNTAwOworCWNvbmZpZy0+c3Rh dHVzID0gVklSVElPX05FVF9TX0xJTktfVVA7CisJZXRoX3JhbmRvbV9hZGRyKGNvbmZpZy0+bWFj KTsKKworCUlOSVRfV09SSygmbXZuZXQtPndvcmssIG12bmV0X3dvcmspOworCisJc3Bpbl9sb2Nr X2luaXQoJm12bmV0LT5sb2NrKTsKKwltdm5ldC0+bWRldiA9IG1kZXY7CisJbWRldl9zZXRfZHJ2 ZGF0YShtZGV2LCBtdm5ldCk7CisKKwltdXRleF9sb2NrKCZtZGV2X2xpc3RfbG9jayk7CisJbGlz dF9hZGQoJm12bmV0LT5uZXh0LCAmbWRldl9kZXZpY2VzX2xpc3QpOworCW11dGV4X3VubG9jaygm bWRldl9saXN0X2xvY2spOworCisJZGV2LT5jb2hlcmVudF9kbWFfbWFzayA9IERNQV9CSVRfTUFT Syg2NCk7CisJc2V0X2RtYV9vcHMoZGV2LCAmbXZuZXRfZG1hX29wcyk7CisKKwltZGV2X3NldF92 aXJ0aW9fb3BzKG1kZXYsICZ2aXJ0aW9fbWRldl9vcHMpOworCisJcmV0dXJuIDA7Cit9CisKK3N0 YXRpYyBpbnQgbXZuZXRfcmVtb3ZlKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKK3sKKwlzdHJ1 Y3QgbXZuZXRfc3RhdGUgKm1kcywgKnRtcF9tZHM7CisJc3RydWN0IG12bmV0X3N0YXRlICptdm5l dCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7CisJaW50IHJldCA9IC1FSU5WQUw7CisKKwltdXRl eF9sb2NrKCZtZGV2X2xpc3RfbG9jayk7CisJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKG1kcywg dG1wX21kcywgJm1kZXZfZGV2aWNlc19saXN0LCBuZXh0KSB7CisJCWlmIChtdm5ldCA9PSBtZHMp IHsKKwkJCWxpc3RfZGVsKCZtdm5ldC0+bmV4dCk7CisJCQltZGV2X3NldF9kcnZkYXRhKG1kZXYs IE5VTEwpOworCQkJa2ZyZWUobXZuZXQtPmJ1ZmZlcik7CisJCQlrZnJlZShtdm5ldCk7CisJCQly ZXQgPSAwOworCQkJYnJlYWs7CisJCX0KKwl9CisJbXV0ZXhfdW5sb2NrKCZtZGV2X2xpc3RfbG9j ayk7CisKKwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgc3NpemVfdAorc2FtcGxlX212bmV0X2Rl dl9zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIs CisJCSAgICAgY2hhciAqYnVmKQoreworCWlmIChtZGV2X2Zyb21fZGV2KGRldikpCisJCXJldHVy biBzcHJpbnRmKGJ1ZiwgIlRoaXMgaXMgTURFViAlc1xuIiwgZGV2X25hbWUoZGV2KSk7CisKKwly ZXR1cm4gc3ByaW50ZihidWYsICJcbiIpOworfQorCitzdGF0aWMgREVWSUNFX0FUVFJfUk8oc2Ft cGxlX212bmV0X2Rldik7CisKK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICptdm5ldF9kZXZfYXR0 cnNbXSA9IHsKKwkmZGV2X2F0dHJfc2FtcGxlX212bmV0X2Rldi5hdHRyLAorCU5VTEwsCit9Owor CitzdGF0aWMgY29uc3Qgc3RydWN0IGF0dHJpYnV0ZV9ncm91cCBtdm5ldF9kZXZfZ3JvdXAgPSB7 CisJLm5hbWUgID0gIm12bmV0X2RldiIsCisJLmF0dHJzID0gbXZuZXRfZGV2X2F0dHJzLAorfTsK Kworc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKm12bmV0X2Rldl9ncm91cHNb XSA9IHsKKwkmbXZuZXRfZGV2X2dyb3VwLAorCU5VTEwsCit9OworCitzdGF0aWMgc3NpemVfdAor c2FtcGxlX21kZXZfZGV2X3Nob3coc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0 dHJpYnV0ZSAqYXR0ciwKKwkJICAgICBjaGFyICpidWYpCit7CisJaWYgKG1kZXZfZnJvbV9kZXYo ZGV2KSkKKwkJcmV0dXJuIHNwcmludGYoYnVmLCAiVGhpcyBpcyBNREVWICVzXG4iLCBkZXZfbmFt ZShkZXYpKTsKKworCXJldHVybiBzcHJpbnRmKGJ1ZiwgIlxuIik7Cit9CisKK3N0YXRpYyBERVZJ Q0VfQVRUUl9STyhzYW1wbGVfbWRldl9kZXYpOworCitzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAq bWRldl9kZXZfYXR0cnNbXSA9IHsKKwkmZGV2X2F0dHJfc2FtcGxlX21kZXZfZGV2LmF0dHIsCisJ TlVMTCwKK307CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgYXR0cmlidXRlX2dyb3VwIG1kZXZfZGV2 X2dyb3VwID0geworCS5uYW1lICA9ICJ2ZW5kb3IiLAorCS5hdHRycyA9IG1kZXZfZGV2X2F0dHJz LAorfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKm1kZXZfZGV2X2dy b3Vwc1tdID0geworCSZtZGV2X2Rldl9ncm91cCwKKwlOVUxMLAorfTsKKworI2RlZmluZSBNVk5F VF9TVFJJTkdfTEVOIDE2CisKK3N0YXRpYyBzc2l6ZV90CituYW1lX3Nob3coc3RydWN0IGtvYmpl Y3QgKmtvYmosIHN0cnVjdCBkZXZpY2UgKmRldiwgY2hhciAqYnVmKQoreworCWNoYXIgbmFtZVtN Vk5FVF9TVFJJTkdfTEVOXTsKKwljb25zdCBjaGFyICpuYW1lX3N0ciA9ICJ2aXJ0aW8tbmV0IjsK KworCXNucHJpbnRmKG5hbWUsIE1WTkVUX1NUUklOR19MRU4sICIlcyIsIGRldl9kcml2ZXJfc3Ry aW5nKGRldikpOworCWlmICghc3RyY21wKGtvYmotPm5hbWUsIG5hbWUpKQorCQlyZXR1cm4gc3By aW50ZihidWYsICIlc1xuIiwgbmFtZV9zdHIpOworCisJcmV0dXJuIC1FSU5WQUw7Cit9CisKK3N0 YXRpYyBNREVWX1RZUEVfQVRUUl9STyhuYW1lKTsKKworc3RhdGljIHNzaXplX3QKK2F2YWlsYWJs ZV9pbnN0YW5jZXNfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0IGRldmljZSAqZGV2 LCBjaGFyICpidWYpCit7CisJcmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIElOVF9NQVgpOwor fQorCitzdGF0aWMgTURFVl9UWVBFX0FUVFJfUk8oYXZhaWxhYmxlX2luc3RhbmNlcyk7CisKK3N0 YXRpYyBzc2l6ZV90IGRldmljZV9hcGlfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29iaiwgc3RydWN0 IGRldmljZSAqZGV2LAorCQkJICAgICAgIGNoYXIgKmJ1ZikKK3sKKwlyZXR1cm4gc3ByaW50Zihi dWYsICIlc1xuIiwgVklSVElPX01ERVZfREVWSUNFX0FQSV9TVFJJTkcpOworfQorCitzdGF0aWMg TURFVl9UWVBFX0FUVFJfUk8oZGV2aWNlX2FwaSk7CisKK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRl ICptZGV2X3R5cGVzX2F0dHJzW10gPSB7CisJJm1kZXZfdHlwZV9hdHRyX25hbWUuYXR0ciwKKwkm bWRldl90eXBlX2F0dHJfZGV2aWNlX2FwaS5hdHRyLAorCSZtZGV2X3R5cGVfYXR0cl9hdmFpbGFi bGVfaW5zdGFuY2VzLmF0dHIsCisJTlVMTCwKK307CisKK3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRl X2dyb3VwIG1kZXZfdHlwZV9ncm91cCA9IHsKKwkubmFtZSAgPSAidmlydGlvIiwKKwkuYXR0cnMg PSBtZGV2X3R5cGVzX2F0dHJzLAorfTsKKworLyogVEJEOiAidmhvc3QiIHR5cGUgKi8KKworc3Rh dGljIHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKm1kZXZfdHlwZV9ncm91cHNbXSA9IHsKKwkmbWRl dl90eXBlX2dyb3VwLAorCU5VTEwsCit9OworCitzdGF0aWMgaW50IG12bmV0X3NldF92cV9hZGRy ZXNzKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwgdTE2IGlkeCwKKwkJCQl1NjQgZGVzY19hcmVh LCB1NjQgZHJpdmVyX2FyZWEsIHU2NCBkZXZpY2VfYXJlYSkKK3sKKwlzdHJ1Y3QgbXZuZXRfc3Rh dGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2KTsKKwlzdHJ1Y3QgbXZuZXRfdmlydHF1 ZXVlICp2cSA9ICZtdm5ldC0+dnFzW2lkeF07CisKKwl2cS0+ZGVzY19hZGRyID0gZGVzY19hcmVh OworCXZxLT5kcml2ZXJfYWRkciA9IGRyaXZlcl9hcmVhOworCXZxLT5kZXZpY2VfYWRkciA9IGRl dmljZV9hcmVhOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIG12bmV0X3NldF92cV9u dW0oc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4LCB1MzIgbnVtKQoreworCXN0cnVj dCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYpOworCXN0cnVjdCBt dm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKKworCXZxLT5udW0gPSBudW07 Cit9CisKK3N0YXRpYyB2b2lkIG12bmV0X2tpY2tfdnEoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2 LCB1MTYgaWR4KQoreworCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZk YXRhKG1kZXYpOworCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4 XTsKKworCWlmICh2cS0+cmVhZHkpCisJCXNjaGVkdWxlX3dvcmsoJm12bmV0LT53b3JrKTsKK30K Kworc3RhdGljIHZvaWQgbXZuZXRfc2V0X3ZxX2NiKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwg dTE2IGlkeCwKKwkJCSAgICBzdHJ1Y3QgdmlydGlvX21kZXZfY2FsbGJhY2sgKmNiKQoreworCXN0 cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYpOworCXN0cnVj dCBtdm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4XTsKKworCXZxLT5jYiA9IGNi LT5jYWxsYmFjazsKKwl2cS0+cHJpdmF0ZSA9IGNiLT5wcml2YXRlOworfQorCitzdGF0aWMgdm9p ZCBtdm5ldF9zZXRfdnFfcmVhZHkoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYgaWR4LCBi b29sIHJlYWR5KQoreworCXN0cnVjdCBtdm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZk YXRhKG1kZXYpOworCXN0cnVjdCBtdm5ldF92aXJ0cXVldWUgKnZxID0gJm12bmV0LT52cXNbaWR4 XTsKKworCXNwaW5fbG9jaygmbXZuZXQtPmxvY2spOworCXZxLT5yZWFkeSA9IHJlYWR5OworCWlm ICh2cS0+cmVhZHkpCisJCW12bmV0X3F1ZXVlX3JlYWR5KG12bmV0LCBpZHgpOworCXNwaW5fdW5s b2NrKCZtdm5ldC0+bG9jayk7Cit9CisKK3N0YXRpYyBib29sIG12bmV0X2dldF92cV9yZWFkeShz dHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsIHUxNiBpZHgpCit7CisJc3RydWN0IG12bmV0X3N0YXRl ICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7CisJc3RydWN0IG12bmV0X3ZpcnRxdWV1 ZSAqdnEgPSAmbXZuZXQtPnZxc1tpZHhdOworCisJcmV0dXJuIHZxLT5yZWFkeTsKK30KKworc3Rh dGljIGludCBtdm5ldF9zZXRfdnFfc3RhdGUoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2LCB1MTYg aWR4LCB1NjQgc3RhdGUpCit7CisJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0 X2RydmRhdGEobWRldik7CisJc3RydWN0IG12bmV0X3ZpcnRxdWV1ZSAqdnEgPSAmbXZuZXQtPnZx c1tpZHhdOworCXN0cnVjdCB2cmluZ2ggKnZyaCA9ICZ2cS0+dnJpbmc7CisKKwlzcGluX2xvY2so Jm12bmV0LT5sb2NrKTsKKwl2cmgtPmxhc3RfYXZhaWxfaWR4ID0gc3RhdGU7CisJc3Bpbl91bmxv Y2soJm12bmV0LT5sb2NrKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgdTY0IG12bmV0X2dl dF92cV9zdGF0ZShzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsIHUxNiBpZHgpCit7CisJc3RydWN0 IG12bmV0X3N0YXRlICptdm5ldCA9IG1kZXZfZ2V0X2RydmRhdGEobWRldik7CisJc3RydWN0IG12 bmV0X3ZpcnRxdWV1ZSAqdnEgPSAmbXZuZXQtPnZxc1tpZHhdOworCXN0cnVjdCB2cmluZ2ggKnZy aCA9ICZ2cS0+dnJpbmc7CisKKwlyZXR1cm4gdnJoLT5sYXN0X2F2YWlsX2lkeDsKK30KKworc3Rh dGljIHUxNiBtdm5ldF9nZXRfdnFfYWxpZ24oc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KQorewor CXJldHVybiBNVk5FVF9RVUVVRV9BTElHTjsKK30KKworc3RhdGljIHU2NCBtdm5ldF9nZXRfZmVh dHVyZXMoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KQoreworCXJldHVybiBtdm5ldF9mZWF0dXJl czsKK30KKworc3RhdGljIGludCBtdm5ldF9zZXRfZmVhdHVyZXMoc3RydWN0IG1kZXZfZGV2aWNl ICptZGV2LCB1NjQgZmVhdHVyZXMpCit7CisJc3RydWN0IG12bmV0X3N0YXRlICptdm5ldCA9IG1k ZXZfZ2V0X2RydmRhdGEobWRldik7CisKKwkvKiBETUEgbWFwcGluZyBtdXN0IGJlIGRvbmUgYnkg ZHJpdmVyICovCisJaWYgKCEoZmVhdHVyZXMgJiAoMVVMTCA8PCBWSVJUSU9fRl9JT01NVV9QTEFU Rk9STSkpKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCW12bmV0LT5mZWF0dXJlcyA9IGZlYXR1cmVz ICYgbXZuZXRfZmVhdHVyZXM7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgbXZuZXRf c2V0X2NvbmZpZ19jYihzdHJ1Y3QgbWRldl9kZXZpY2UgKm1kZXYsCisJCQkJc3RydWN0IHZpcnRp b19tZGV2X2NhbGxiYWNrICpjYikKK3sKKwkvKiBXZSBkb24ndCBzdXBwb3J0IGNvbmZpZyBpbnRl cnJ1cHQgKi8KK30KKworc3RhdGljIHUxNiBtdm5ldF9nZXRfdnFfbnVtX21heChzdHJ1Y3QgbWRl dl9kZXZpY2UgKm1kZXYpCit7CisJcmV0dXJuIE1WTkVUX1FVRVVFX01BWDsKK30KKworc3RhdGlj IHUzMiBtdm5ldF9nZXRfZGV2aWNlX2lkKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldikKK3sKKwly ZXR1cm4gTVZORVRfREVWSUNFX0lEOworfQorCitzdGF0aWMgdTMyIG12bmV0X2dldF92ZW5kb3Jf aWQoc3RydWN0IG1kZXZfZGV2aWNlICptZGV2KQoreworCXJldHVybiBNVk5FVF9WRU5ET1JfSUQ7 Cit9CisKK3N0YXRpYyB1OCBtdm5ldF9nZXRfc3RhdHVzKHN0cnVjdCBtZGV2X2RldmljZSAqbWRl dikKK3sKKwlzdHJ1Y3QgbXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YShtZGV2 KTsKKworCXJldHVybiBtdm5ldC0+c3RhdHVzOworfQorCitzdGF0aWMgdm9pZCBtdm5ldF9zZXRf c3RhdHVzKHN0cnVjdCBtZGV2X2RldmljZSAqbWRldiwgdTggc3RhdHVzKQoreworCXN0cnVjdCBt dm5ldF9zdGF0ZSAqbXZuZXQgPSBtZGV2X2dldF9kcnZkYXRhKG1kZXYpOworCisJbXZuZXQtPnN0 YXR1cyA9IHN0YXR1czsKKworCWlmIChzdGF0dXMgPT0gMCkgeworCQlzcGluX2xvY2soJm12bmV0 LT5sb2NrKTsKKwkJbXZuZXRfcmVzZXQobXZuZXQpOworCQlzcGluX3VubG9jaygmbXZuZXQtPmxv Y2spOworCX0KK30KKworc3RhdGljIHZvaWQgbXZuZXRfZ2V0X2NvbmZpZyhzdHJ1Y3QgbWRldl9k ZXZpY2UgKm1kZXYsIHVuc2lnbmVkIGludCBvZmZzZXQsCisJCQkgICAgIHZvaWQgKmJ1ZiwgdW5z aWduZWQgaW50IGxlbikKK3sKKwlzdHJ1Y3QgbXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRf ZHJ2ZGF0YShtZGV2KTsKKworCWlmIChvZmZzZXQgKyBsZW4gPCBzaXplb2Yoc3RydWN0IHZpcnRp b19uZXRfY29uZmlnKSkKKwkJbWVtY3B5KGJ1ZiwgJm12bmV0LT5jb25maWcgKyBvZmZzZXQsIGxl bik7Cit9CisKK3N0YXRpYyB2b2lkIG12bmV0X3NldF9jb25maWcoc3RydWN0IG1kZXZfZGV2aWNl ICptZGV2LCB1bnNpZ25lZCBpbnQgb2Zmc2V0LAorCQkJICAgICBjb25zdCB2b2lkICpidWYsIHVu c2lnbmVkIGludCBsZW4pCit7CisJLyogTm8gd3JpdGFibGUgY29uZmlnIHN1cHBvcnR0ZWQgYnkg bXZuZXQgKi8KK30KKworc3RhdGljIHU2NCBtdm5ldF9nZXRfbWRldl9mZWF0dXJlcyhzdHJ1Y3Qg bWRldl9kZXZpY2UgKm1kZXYpCit7CisJcmV0dXJuIFZJUlRJT19NREVWX0ZfVkVSU0lPTl8xOwor fQorCitzdGF0aWMgdTMyIG12bmV0X2dldF9nZW5lcmF0aW9uKHN0cnVjdCBtZGV2X2RldmljZSAq bWRldikKK3sKKwlzdHJ1Y3QgbXZuZXRfc3RhdGUgKm12bmV0ID0gbWRldl9nZXRfZHJ2ZGF0YSht ZGV2KTsKKworCXJldHVybiBtdm5ldC0+Z2VuZXJhdGlvbjsKK30KKworc3RhdGljIGNvbnN0IHN0 cnVjdCB2aXJ0aW9fbWRldl9kZXZpY2Vfb3BzIHZpcnRpb19tZGV2X29wcyA9IHsKKwkuc2V0X3Zx X2FkZHJlc3MgICAgICAgICA9IG12bmV0X3NldF92cV9hZGRyZXNzLAorCS5zZXRfdnFfbnVtICAg ICAgICAgICAgID0gbXZuZXRfc2V0X3ZxX251bSwKKwkua2lja192cSAgICAgICAgICAgICAgICA9 IG12bmV0X2tpY2tfdnEsCisJLnNldF92cV9jYiAgICAgICAgICAgICAgPSBtdm5ldF9zZXRfdnFf Y2IsCisJLnNldF92cV9yZWFkeSAgICAgICAgICAgPSBtdm5ldF9zZXRfdnFfcmVhZHksCisJLmdl dF92cV9yZWFkeSAgICAgICAgICAgPSBtdm5ldF9nZXRfdnFfcmVhZHksCisJLnNldF92cV9zdGF0 ZSAgICAgICAgICAgPSBtdm5ldF9zZXRfdnFfc3RhdGUsCisJLmdldF92cV9zdGF0ZSAgICAgICAg ICAgPSBtdm5ldF9nZXRfdnFfc3RhdGUsCisJLmdldF92cV9hbGlnbiAgICAgICAgICAgPSBtdm5l dF9nZXRfdnFfYWxpZ24sCisJLmdldF9mZWF0dXJlcyAgICAgICAgICAgPSBtdm5ldF9nZXRfZmVh dHVyZXMsCisJLnNldF9mZWF0dXJlcyAgICAgICAgICAgPSBtdm5ldF9zZXRfZmVhdHVyZXMsCisJ LnNldF9jb25maWdfY2IgICAgICAgICAgPSBtdm5ldF9zZXRfY29uZmlnX2NiLAorCS5nZXRfdnFf bnVtX21heCAgICAgICAgID0gbXZuZXRfZ2V0X3ZxX251bV9tYXgsCisJLmdldF9kZXZpY2VfaWQg ICAgICAgICAgPSBtdm5ldF9nZXRfZGV2aWNlX2lkLAorCS5nZXRfdmVuZG9yX2lkICAgICAgICAg ID0gbXZuZXRfZ2V0X3ZlbmRvcl9pZCwKKwkuZ2V0X3N0YXR1cyAgICAgICAgICAgICA9IG12bmV0 X2dldF9zdGF0dXMsCisJLnNldF9zdGF0dXMgICAgICAgICAgICAgPSBtdm5ldF9zZXRfc3RhdHVz LAorCS5nZXRfY29uZmlnICAgICAgICAgICAgID0gbXZuZXRfZ2V0X2NvbmZpZywKKwkuc2V0X2Nv bmZpZyAgICAgICAgICAgICA9IG12bmV0X3NldF9jb25maWcsCisJLmdldF9tZGV2X2ZlYXR1cmVz ICAgICAgPSBtdm5ldF9nZXRfbWRldl9mZWF0dXJlcywKKwkuZ2V0X2dlbmVyYXRpb24gICAgICAg ICA9IG12bmV0X2dldF9nZW5lcmF0aW9uLAorfTsKKworc3RhdGljIGNvbnN0IHN0cnVjdCBtZGV2 X3BhcmVudF9vcHMgbWRldl9mb3BzID0geworCS5vd25lciAgICAgICAgICAgICAgICAgID0gVEhJ U19NT0RVTEUsCisJLmRldl9hdHRyX2dyb3VwcyAgICAgICAgPSBtdm5ldF9kZXZfZ3JvdXBzLAor CS5tZGV2X2F0dHJfZ3JvdXBzICAgICAgID0gbWRldl9kZXZfZ3JvdXBzLAorCS5zdXBwb3J0ZWRf dHlwZV9ncm91cHMgID0gbWRldl90eXBlX2dyb3VwcywKKwkuY3JlYXRlICAgICAgICAgICAgICAg ICA9IG12bmV0X2NyZWF0ZSwKKwkucmVtb3ZlCQkJPSBtdm5ldF9yZW1vdmUsCit9OworCitzdGF0 aWMgdm9pZCBtdm5ldF9kZXZpY2VfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJZGV2 X2RiZyhkZXYsICJtdm5ldDogcmVsZWFzZWRcbiIpOworfQorCitzdGF0aWMgaW50IF9faW5pdCBt dm5ldF9kZXZfaW5pdCh2b2lkKQoreworCWludCByZXQgPSAwOworCisJcHJfaW5mbygibXZuZXRf ZGV2OiAlc1xuIiwgX19mdW5jX18pOworCisJbWVtc2V0KCZtdm5ldF9kZXYsIDAsIHNpemVvZiht dm5ldF9kZXYpKTsKKworCWlkcl9pbml0KCZtdm5ldF9kZXYudmRfaWRyKTsKKworCW12bmV0X2Rl di52ZF9jbGFzcyA9IGNsYXNzX2NyZWF0ZShUSElTX01PRFVMRSwgTVZORVRfQ0xBU1NfTkFNRSk7 CisKKwlpZiAoSVNfRVJSKG12bmV0X2Rldi52ZF9jbGFzcykpIHsKKwkJcHJfZXJyKCJFcnJvcjog ZmFpbGVkIHRvIHJlZ2lzdGVyIG12bmV0X2RldiBjbGFzc1xuIik7CisJCXJldCA9IFBUUl9FUlIo bXZuZXRfZGV2LnZkX2NsYXNzKTsKKwkJZ290byBmYWlsZWQxOworCX0KKworCW12bmV0X2Rldi5k ZXYuY2xhc3MgPSBtdm5ldF9kZXYudmRfY2xhc3M7CisJbXZuZXRfZGV2LmRldi5yZWxlYXNlID0g bXZuZXRfZGV2aWNlX3JlbGVhc2U7CisJZGV2X3NldF9uYW1lKCZtdm5ldF9kZXYuZGV2LCAiJXMi LCBNVk5FVF9OQU1FKTsKKworCXJldCA9IGRldmljZV9yZWdpc3RlcigmbXZuZXRfZGV2LmRldik7 CisJaWYgKHJldCkKKwkJZ290byBmYWlsZWQyOworCisJcmV0ID0gbWRldl9yZWdpc3Rlcl9kZXZp Y2UoJm12bmV0X2Rldi5kZXYsICZtZGV2X2ZvcHMpOworCWlmIChyZXQpCisJCWdvdG8gZmFpbGVk MzsKKworCW11dGV4X2luaXQoJm1kZXZfbGlzdF9sb2NrKTsKKwlJTklUX0xJU1RfSEVBRCgmbWRl dl9kZXZpY2VzX2xpc3QpOworCisJZ290byBhbGxfZG9uZTsKKworZmFpbGVkMzoKKworCWRldmlj ZV91bnJlZ2lzdGVyKCZtdm5ldF9kZXYuZGV2KTsKK2ZhaWxlZDI6CisJY2xhc3NfZGVzdHJveSht dm5ldF9kZXYudmRfY2xhc3MpOworCitmYWlsZWQxOgorYWxsX2RvbmU6CisJcmV0dXJuIHJldDsK K30KKworc3RhdGljIHZvaWQgX19leGl0IG12bmV0X2Rldl9leGl0KHZvaWQpCit7CisJbXZuZXRf ZGV2LmRldi5idXMgPSBOVUxMOworCW1kZXZfdW5yZWdpc3Rlcl9kZXZpY2UoJm12bmV0X2Rldi5k ZXYpOworCisJZGV2aWNlX3VucmVnaXN0ZXIoJm12bmV0X2Rldi5kZXYpOworCWlkcl9kZXN0cm95 KCZtdm5ldF9kZXYudmRfaWRyKTsKKwljbGFzc19kZXN0cm95KG12bmV0X2Rldi52ZF9jbGFzcyk7 CisJbXZuZXRfZGV2LnZkX2NsYXNzID0gTlVMTDsKKwlwcl9pbmZvKCJtdm5ldF9kZXY6IFVubG9h ZGVkIVxuIik7Cit9CisKK21vZHVsZV9pbml0KG12bmV0X2Rldl9pbml0KQorbW9kdWxlX2V4aXQo bXZuZXRfZGV2X2V4aXQpCisKK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKK01PRFVMRV9JTkZP KHN1cHBvcnRlZCwgIlNpbXVsYXRlIGxvb3BiYWNrIGV0aGVybmV0IGRldmljZSBvdmVyIG1kZXYi KTsKK01PRFVMRV9WRVJTSU9OKFZFUlNJT05fU1RSSU5HKTsKK01PRFVMRV9BVVRIT1IoRFJJVkVS X0FVVEhPUik7Ci0tIAoyLjE5LjEKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fCkludGVsLWdmeCBtYWlsaW5nIGxpc3QKSW50ZWwtZ2Z4QGxpc3RzLmZyZWVk ZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZv L2ludGVsLWdmeA==