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=-17.3 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 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 1B5ABC433E9 for ; Thu, 4 Mar 2021 04:23:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E36F664EF8 for ; Thu, 4 Mar 2021 04:23:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233391AbhCDEXE (ORCPT ); Wed, 3 Mar 2021 23:23:04 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:60178 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233387AbhCDEWt (ORCPT ); Wed, 3 Mar 2021 23:22:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1614831684; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ql4/2JdGvyiU2L0vSjfNkpvS5Y9CbZX+WsSes4XDNzY=; b=RTGuyTe7CrFI3sBXj96qrdSHDPHIDnMPovfWffJNhmgwOJHjAPcyJ7A6GYIRkCrszuuHoY DQog247XFyeCIj/YzpBE2ZWD0dNg9FwyTj45mruRQ17vQxr59XPR8MCtZWdV4Yo6jXWeKP R7VfGv+JUTri7ks1s62tUmEvtDPrcTI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-243-33vzA97_Ozq5yZMm7O-LgQ-1; Wed, 03 Mar 2021 23:21:20 -0500 X-MC-Unique: 33vzA97_Ozq5yZMm7O-LgQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 02CC21936B78; Thu, 4 Mar 2021 04:21:18 +0000 (UTC) Received: from wangxiaodeMacBook-Air.local (ovpn-13-244.pek2.redhat.com [10.72.13.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id C5E5A6F92F; Thu, 4 Mar 2021 04:20:43 +0000 (UTC) Subject: Re: [RFC v4 06/11] vduse: Implement an MMU-based IOMMU driver To: Xie Yongji , mst@redhat.com, stefanha@redhat.com, sgarzare@redhat.com, parav@nvidia.com, bob.liu@oracle.com, hch@infradead.org, rdunlap@infradead.org, willy@infradead.org, viro@zeniv.linux.org.uk, axboe@kernel.dk, bcrl@kvack.org, corbet@lwn.net Cc: virtualization@lists.linux-foundation.org, netdev@vger.kernel.org, kvm@vger.kernel.org, linux-aio@kvack.org, linux-fsdevel@vger.kernel.org References: <20210223115048.435-1-xieyongji@bytedance.com> <20210223115048.435-7-xieyongji@bytedance.com> From: Jason Wang Message-ID: <573ab913-55ce-045a-478f-1200bd78cf7b@redhat.com> Date: Thu, 4 Mar 2021 12:20:42 +0800 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210223115048.435-7-xieyongji@bytedance.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-GB X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On 2021/2/23 7:50 下午, Xie Yongji wrote: > This implements a MMU-based IOMMU driver to support mapping > kernel dma buffer into userspace. The basic idea behind it is > treating MMU (VA->PA) as IOMMU (IOVA->PA). The driver will set > up MMU mapping instead of IOMMU mapping for the DMA transfer so > that the userspace process is able to use its virtual address to > access the dma buffer in kernel. > > And to avoid security issue, a bounce-buffering mechanism is > introduced to prevent userspace accessing the original buffer > directly. > > Signed-off-by: Xie Yongji > --- > drivers/vdpa/vdpa_user/iova_domain.c | 486 +++++++++++++++++++++++++++++++++++ > drivers/vdpa/vdpa_user/iova_domain.h | 61 +++++ > 2 files changed, 547 insertions(+) > create mode 100644 drivers/vdpa/vdpa_user/iova_domain.c > create mode 100644 drivers/vdpa/vdpa_user/iova_domain.h > > diff --git a/drivers/vdpa/vdpa_user/iova_domain.c b/drivers/vdpa/vdpa_user/iova_domain.c > new file mode 100644 > index 000000000000..9285d430d486 > --- /dev/null > +++ b/drivers/vdpa/vdpa_user/iova_domain.c > @@ -0,0 +1,486 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * MMU-based IOMMU implementation > + * > + * Copyright (C) 2020 Bytedance Inc. and/or its affiliates. All rights reserved. > + * > + * Author: Xie Yongji > + * > + */ > + > +#include > +#include > +#include > +#include > + > +#include "iova_domain.h" > + > +#define IOVA_START_PFN 1 > +#define IOVA_ALLOC_ORDER 12 > +#define IOVA_ALLOC_SIZE (1 << IOVA_ALLOC_ORDER) > + > +static inline struct page * > +vduse_domain_get_bounce_page(struct vduse_iova_domain *domain, u64 iova) > +{ > + u64 index = iova >> PAGE_SHIFT; > + > + return domain->bounce_pages[index]; > +} > + > +static inline void > +vduse_domain_set_bounce_page(struct vduse_iova_domain *domain, > + u64 iova, struct page *page) > +{ > + u64 index = iova >> PAGE_SHIFT; > + > + domain->bounce_pages[index] = page; > +} > + > +static enum dma_data_direction perm_to_dir(int perm) > +{ > + enum dma_data_direction dir; > + > + switch (perm) { > + case VHOST_MAP_WO: > + dir = DMA_FROM_DEVICE; > + break; > + case VHOST_MAP_RO: > + dir = DMA_TO_DEVICE; > + break; > + case VHOST_MAP_RW: > + dir = DMA_BIDIRECTIONAL; > + break; > + default: > + break; > + } > + > + return dir; > +} > + > +static int dir_to_perm(enum dma_data_direction dir) > +{ > + int perm = -EFAULT; > + > + switch (dir) { > + case DMA_FROM_DEVICE: > + perm = VHOST_MAP_WO; > + break; > + case DMA_TO_DEVICE: > + perm = VHOST_MAP_RO; > + break; > + case DMA_BIDIRECTIONAL: > + perm = VHOST_MAP_RW; > + break; > + default: > + break; > + } > + > + return perm; > +} Let's move the above two helpers to vhost_iotlb.h so they could be used by other driver e.g (vpda_sim) > + > +static void do_bounce(phys_addr_t orig, void *addr, size_t size, > + enum dma_data_direction dir) > +{ > + unsigned long pfn = PFN_DOWN(orig); > + > + if (PageHighMem(pfn_to_page(pfn))) { > + unsigned int offset = offset_in_page(orig); > + char *buffer; > + unsigned int sz = 0; > + unsigned long flags; > + > + while (size) { > + sz = min_t(size_t, PAGE_SIZE - offset, size); > + > + local_irq_save(flags); > + buffer = kmap_atomic(pfn_to_page(pfn)); > + if (dir == DMA_TO_DEVICE) > + memcpy(addr, buffer + offset, sz); > + else > + memcpy(buffer + offset, addr, sz); > + kunmap_atomic(buffer); > + local_irq_restore(flags); I wonder why we need to deal with highmem and irq flags explicitly like this. Doesn't kmap_atomic() will take care all of those? > + > + size -= sz; > + pfn++; > + addr += sz; > + offset = 0; > + } > + } else if (dir == DMA_TO_DEVICE) { > + memcpy(addr, phys_to_virt(orig), size); > + } else { > + memcpy(phys_to_virt(orig), addr, size); > + } > +} > + > +static struct page * > +vduse_domain_get_mapping_page(struct vduse_iova_domain *domain, u64 iova) > +{ > + u64 start = iova & PAGE_MASK; > + u64 last = start + PAGE_SIZE - 1; > + struct vhost_iotlb_map *map; > + struct page *page = NULL; > + > + spin_lock(&domain->iotlb_lock); > + map = vhost_iotlb_itree_first(domain->iotlb, start, last); > + if (!map) > + goto out; > + > + page = pfn_to_page((map->addr + iova - map->start) >> PAGE_SHIFT); > + get_page(page); > +out: > + spin_unlock(&domain->iotlb_lock); > + > + return page; > +} > + > +static struct page * > +vduse_domain_alloc_bounce_page(struct vduse_iova_domain *domain, u64 iova) > +{ > + u64 start = iova & PAGE_MASK; > + u64 last = start + PAGE_SIZE - 1; > + struct vhost_iotlb_map *map; > + struct page *page = NULL, *new_page = alloc_page(GFP_KERNEL); > + > + if (!new_page) > + return NULL; > + > + spin_lock(&domain->iotlb_lock); > + if (!vhost_iotlb_itree_first(domain->iotlb, start, last)) { > + __free_page(new_page); > + goto out; > + } > + page = vduse_domain_get_bounce_page(domain, iova); > + if (page) { > + get_page(page); > + __free_page(new_page); > + goto out; > + } > + vduse_domain_set_bounce_page(domain, iova, new_page); > + get_page(new_page); > + page = new_page; > + > + for (map = vhost_iotlb_itree_first(domain->iotlb, start, last); map; > + map = vhost_iotlb_itree_next(map, start, last)) { > + unsigned int src_offset = 0, dst_offset = 0; > + phys_addr_t src; > + void *dst; > + size_t sz; > + > + if (perm_to_dir(map->perm) == DMA_FROM_DEVICE) > + continue; > + > + if (start > map->start) > + src_offset = start - map->start; > + else > + dst_offset = map->start - start; > + > + src = map->addr + src_offset; > + dst = page_address(page) + dst_offset; > + sz = min_t(size_t, map->size - src_offset, > + PAGE_SIZE - dst_offset); > + do_bounce(src, dst, sz, DMA_TO_DEVICE); > + } > +out: > + spin_unlock(&domain->iotlb_lock); > + > + return page; > +} > + > +static void > +vduse_domain_free_bounce_pages(struct vduse_iova_domain *domain, > + u64 iova, size_t size) > +{ > + struct page *page; > + > + spin_lock(&domain->iotlb_lock); > + if (WARN_ON(vhost_iotlb_itree_first(domain->iotlb, iova, > + iova + size - 1))) > + goto out; > + > + while (size > 0) { > + page = vduse_domain_get_bounce_page(domain, iova); > + if (page) { > + vduse_domain_set_bounce_page(domain, iova, NULL); > + __free_page(page); > + } > + size -= PAGE_SIZE; > + iova += PAGE_SIZE; > + } > +out: > + spin_unlock(&domain->iotlb_lock); > +} > + > +static void vduse_domain_bounce(struct vduse_iova_domain *domain, > + dma_addr_t iova, phys_addr_t orig, > + size_t size, enum dma_data_direction dir) > +{ > + unsigned int offset = offset_in_page(iova); > + > + while (size) { > + struct page *p = vduse_domain_get_bounce_page(domain, iova); > + size_t sz = min_t(size_t, PAGE_SIZE - offset, size); > + > + WARN_ON(!p && dir == DMA_FROM_DEVICE); > + > + if (p) > + do_bounce(orig, page_address(p) + offset, sz, dir); > + > + size -= sz; > + orig += sz; > + iova += sz; > + offset = 0; > + } > +} > + > +static dma_addr_t vduse_domain_alloc_iova(struct iova_domain *iovad, > + unsigned long size, unsigned long limit) > +{ > + unsigned long shift = iova_shift(iovad); > + unsigned long iova_len = iova_align(iovad, size) >> shift; > + unsigned long iova_pfn; > + > + if (iova_len < (1 << (IOVA_RANGE_CACHE_MAX_SIZE - 1))) > + iova_len = roundup_pow_of_two(iova_len); > + iova_pfn = alloc_iova_fast(iovad, iova_len, limit >> shift, true); > + > + return iova_pfn << shift; > +} > + > +static void vduse_domain_free_iova(struct iova_domain *iovad, > + dma_addr_t iova, size_t size) > +{ > + unsigned long shift = iova_shift(iovad); > + unsigned long iova_len = iova_align(iovad, size) >> shift; > + > + free_iova_fast(iovad, iova >> shift, iova_len); > +} > + > +dma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain, > + struct page *page, unsigned long offset, > + size_t size, enum dma_data_direction dir, > + unsigned long attrs) > +{ > + struct iova_domain *iovad = &domain->stream_iovad; > + unsigned long limit = domain->bounce_size - 1; > + phys_addr_t pa = page_to_phys(page) + offset; > + dma_addr_t iova = vduse_domain_alloc_iova(iovad, size, limit); > + int ret; > + > + if (!iova) > + return DMA_MAPPING_ERROR; > + > + spin_lock(&domain->iotlb_lock); > + ret = vhost_iotlb_add_range(domain->iotlb, (u64)iova, > + (u64)iova + size - 1, > + pa, dir_to_perm(dir)); > + spin_unlock(&domain->iotlb_lock); > + if (ret) { > + vduse_domain_free_iova(iovad, iova, size); > + return DMA_MAPPING_ERROR; > + } > + if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) > + vduse_domain_bounce(domain, iova, pa, size, DMA_TO_DEVICE); > + > + return iova; > +} > + > +void vduse_domain_unmap_page(struct vduse_iova_domain *domain, > + dma_addr_t dma_addr, size_t size, > + enum dma_data_direction dir, unsigned long attrs) > +{ > + struct iova_domain *iovad = &domain->stream_iovad; > + struct vhost_iotlb_map *map; > + phys_addr_t pa; > + > + spin_lock(&domain->iotlb_lock); > + map = vhost_iotlb_itree_first(domain->iotlb, (u64)dma_addr, > + (u64)dma_addr + size - 1); > + if (WARN_ON(!map)) { > + spin_unlock(&domain->iotlb_lock); > + return; > + } > + pa = map->addr; > + vhost_iotlb_map_free(domain->iotlb, map); > + spin_unlock(&domain->iotlb_lock); > + > + if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) > + vduse_domain_bounce(domain, dma_addr, pa, > + size, DMA_FROM_DEVICE); > + > + vduse_domain_free_iova(iovad, dma_addr, size); > +} > + > +void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, > + size_t size, dma_addr_t *dma_addr, > + gfp_t flag, unsigned long attrs) > +{ > + struct iova_domain *iovad = &domain->consistent_iovad; > + unsigned long limit = domain->iova_limit; > + dma_addr_t iova = vduse_domain_alloc_iova(iovad, size, limit); > + void *orig = alloc_pages_exact(size, flag); > + int ret; > + > + if (!iova || !orig) > + goto err; > + > + spin_lock(&domain->iotlb_lock); > + ret = vhost_iotlb_add_range(domain->iotlb, (u64)iova, > + (u64)iova + size - 1, > + virt_to_phys(orig), VHOST_MAP_RW); > + spin_unlock(&domain->iotlb_lock); > + if (ret) > + goto err; > + > + *dma_addr = iova; > + > + return orig; > +err: > + *dma_addr = DMA_MAPPING_ERROR; > + if (orig) > + free_pages_exact(orig, size); > + if (iova) > + vduse_domain_free_iova(iovad, iova, size); > + > + return NULL; > +} > + > +void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size, > + void *vaddr, dma_addr_t dma_addr, > + unsigned long attrs) > +{ > + struct iova_domain *iovad = &domain->consistent_iovad; > + struct vhost_iotlb_map *map; > + phys_addr_t pa; > + > + spin_lock(&domain->iotlb_lock); > + map = vhost_iotlb_itree_first(domain->iotlb, (u64)dma_addr, > + (u64)dma_addr + size - 1); > + if (WARN_ON(!map)) { > + spin_unlock(&domain->iotlb_lock); > + return; > + } > + pa = map->addr; > + vhost_iotlb_map_free(domain->iotlb, map); > + spin_unlock(&domain->iotlb_lock); > + > + vduse_domain_free_iova(iovad, dma_addr, size); > + free_pages_exact(phys_to_virt(pa), size); > +} > + > +static vm_fault_t vduse_domain_mmap_fault(struct vm_fault *vmf) > +{ > + struct vduse_iova_domain *domain = vmf->vma->vm_private_data; > + unsigned long iova = vmf->pgoff << PAGE_SHIFT; > + struct page *page; > + > + if (!domain) > + return VM_FAULT_SIGBUS; > + > + if (iova < domain->bounce_size) > + page = vduse_domain_alloc_bounce_page(domain, iova); > + else > + page = vduse_domain_get_mapping_page(domain, iova); > + > + if (!page) > + return VM_FAULT_SIGBUS; > + > + vmf->page = page; > + > + return 0; > +} > + > +static const struct vm_operations_struct vduse_domain_mmap_ops = { > + .fault = vduse_domain_mmap_fault, > +}; > + > +static int vduse_domain_mmap(struct file *file, struct vm_area_struct *vma) > +{ > + struct vduse_iova_domain *domain = file->private_data; > + > + vma->vm_flags |= VM_DONTDUMP | VM_DONTEXPAND; > + vma->vm_private_data = domain; > + vma->vm_ops = &vduse_domain_mmap_ops; > + > + return 0; > +} > + > +static int vduse_domain_release(struct inode *inode, struct file *file) > +{ > + struct vduse_iova_domain *domain = file->private_data; > + > + vduse_domain_free_bounce_pages(domain, 0, domain->bounce_size); > + put_iova_domain(&domain->stream_iovad); > + put_iova_domain(&domain->consistent_iovad); > + vhost_iotlb_free(domain->iotlb); > + vfree(domain->bounce_pages); > + kfree(domain); > + > + return 0; > +} > + > +static const struct file_operations vduse_domain_fops = { > + .mmap = vduse_domain_mmap, > + .release = vduse_domain_release, > +}; > + > +void vduse_domain_destroy(struct vduse_iova_domain *domain) > +{ > + fput(domain->file); > +} > + > +struct vduse_iova_domain * > +vduse_domain_create(unsigned long iova_limit, size_t bounce_size) > +{ > + struct vduse_iova_domain *domain; > + struct file *file; > + unsigned long bounce_pfns = PAGE_ALIGN(bounce_size) >> PAGE_SHIFT; > + > + if (iova_limit <= bounce_size) > + return NULL; > + > + domain = kzalloc(sizeof(*domain), GFP_KERNEL); > + if (!domain) > + return NULL; > + > + domain->iotlb = vhost_iotlb_alloc(0, 0); > + if (!domain->iotlb) > + goto err_iotlb; > + > + domain->iova_limit = iova_limit; > + domain->bounce_size = PAGE_ALIGN(bounce_size); > + domain->bounce_pages = vzalloc(bounce_pfns * sizeof(struct page *)); > + if (!domain->bounce_pages) > + goto err_page; > + > + file = anon_inode_getfile("[vduse-domain]", &vduse_domain_fops, > + domain, O_RDWR); > + if (IS_ERR(file)) > + goto err_file; > + > + domain->file = file; > + spin_lock_init(&domain->iotlb_lock); > + init_iova_domain(&domain->stream_iovad, > + IOVA_ALLOC_SIZE, IOVA_START_PFN); > + init_iova_domain(&domain->consistent_iovad, > + PAGE_SIZE, bounce_pfns); > + > + return domain; > +err_file: > + vfree(domain->bounce_pages); > +err_page: > + vhost_iotlb_free(domain->iotlb); > +err_iotlb: > + kfree(domain); > + return NULL; > +} > + > +int vduse_domain_init(void) > +{ > + return iova_cache_get(); > +} > + > +void vduse_domain_exit(void) > +{ > + iova_cache_put(); > +} > diff --git a/drivers/vdpa/vdpa_user/iova_domain.h b/drivers/vdpa/vdpa_user/iova_domain.h > new file mode 100644 > index 000000000000..9c85d8346626 > --- /dev/null > +++ b/drivers/vdpa/vdpa_user/iova_domain.h > @@ -0,0 +1,61 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * MMU-based IOMMU implementation > + * > + * Copyright (C) 2020 Bytedance Inc. and/or its affiliates. All rights reserved. > + * > + * Author: Xie Yongji > + * > + */ > + > +#ifndef _VDUSE_IOVA_DOMAIN_H > +#define _VDUSE_IOVA_DOMAIN_H > + > +#include > +#include > +#include > + > +struct vduse_iova_domain { > + struct iova_domain stream_iovad; > + struct iova_domain consistent_iovad; > + struct page **bounce_pages; > + size_t bounce_size; > + unsigned long iova_limit; > + struct vhost_iotlb *iotlb; Sorry if I've asked this before. But what's the reason for maintaing a dedicated IOTLB here? I think we could reuse vduse_dev->iommu since the device can not be used by both virtio and vhost in the same time or use vduse_iova_domain->iotlb for set_map(). Also, since vhost IOTLB support per mapping token (opauqe), can we use that instead of the bounce_pages *? Thanks > + spinlock_t iotlb_lock; > + struct file *file; > +}; > + > +static inline struct file * > +vduse_domain_file(struct vduse_iova_domain *domain) > +{ > + return domain->file; > +} > + > +dma_addr_t vduse_domain_map_page(struct vduse_iova_domain *domain, > + struct page *page, unsigned long offset, > + size_t size, enum dma_data_direction dir, > + unsigned long attrs); > + > +void vduse_domain_unmap_page(struct vduse_iova_domain *domain, > + dma_addr_t dma_addr, size_t size, > + enum dma_data_direction dir, unsigned long attrs); > + > +void *vduse_domain_alloc_coherent(struct vduse_iova_domain *domain, > + size_t size, dma_addr_t *dma_addr, > + gfp_t flag, unsigned long attrs); > + > +void vduse_domain_free_coherent(struct vduse_iova_domain *domain, size_t size, > + void *vaddr, dma_addr_t dma_addr, > + unsigned long attrs); > + > +void vduse_domain_destroy(struct vduse_iova_domain *domain); > + > +struct vduse_iova_domain *vduse_domain_create(unsigned long iova_limit, > + size_t bounce_size); > + > +int vduse_domain_init(void); > + > +void vduse_domain_exit(void); > + > +#endif /* _VDUSE_IOVA_DOMAIN_H */ 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=-15.1 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_SANE_1 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 43586C433DB for ; Thu, 4 Mar 2021 04:21:30 +0000 (UTC) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (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 BB1D364E89 for ; Thu, 4 Mar 2021 04:21:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BB1D364E89 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=virtualization-bounces@lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 638796F5B2; Thu, 4 Mar 2021 04:21:29 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5BULJHsp8hMR; Thu, 4 Mar 2021 04:21:28 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTP id 887356F500; Thu, 4 Mar 2021 04:21:27 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6C544C000A; Thu, 4 Mar 2021 04:21:27 +0000 (UTC) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6D8DEC0001 for ; Thu, 4 Mar 2021 04:21:25 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 680124EBD1 for ; Thu, 4 Mar 2021 04:21:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp4.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 28CSVGFjQLum for ; Thu, 4 Mar 2021 04:21:23 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 6C3EA4CB02 for ; Thu, 4 Mar 2021 04:21:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1614831682; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ql4/2JdGvyiU2L0vSjfNkpvS5Y9CbZX+WsSes4XDNzY=; b=V3uzKeHAiN32MDgY4xC5ZdfVRxUdVMop+8e5XEb1Kf23+nXidKNpY7MO2Ve0BK2RKjJWVN GswOeSA17yxO6BvV0RgkH0azfUQ7N+ZbvClVzer51DMiS9Pn9Rk083N3XNS+1H9HOGFS6h un1Q7HOZhyGGtYUDOVqoAEXWm5hRmlU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-243-33vzA97_Ozq5yZMm7O-LgQ-1; Wed, 03 Mar 2021 23:21:20 -0500 X-MC-Unique: 33vzA97_Ozq5yZMm7O-LgQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 02CC21936B78; Thu, 4 Mar 2021 04:21:18 +0000 (UTC) Received: from wangxiaodeMacBook-Air.local (ovpn-13-244.pek2.redhat.com [10.72.13.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id C5E5A6F92F; Thu, 4 Mar 2021 04:20:43 +0000 (UTC) Subject: Re: [RFC v4 06/11] vduse: Implement an MMU-based IOMMU driver To: Xie Yongji , mst@redhat.com, stefanha@redhat.com, sgarzare@redhat.com, parav@nvidia.com, bob.liu@oracle.com, hch@infradead.org, rdunlap@infradead.org, willy@infradead.org, viro@zeniv.linux.org.uk, axboe@kernel.dk, bcrl@kvack.org, corbet@lwn.net References: <20210223115048.435-1-xieyongji@bytedance.com> <20210223115048.435-7-xieyongji@bytedance.com> From: Jason Wang Message-ID: <573ab913-55ce-045a-478f-1200bd78cf7b@redhat.com> Date: Thu, 4 Mar 2021 12:20:42 +0800 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210223115048.435-7-xieyongji@bytedance.com> Content-Language: en-GB X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Cc: linux-aio@kvack.org, netdev@vger.kernel.org, linux-fsdevel@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org X-BeenThere: virtualization@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux virtualization List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: virtualization-bounces@lists.linux-foundation.org Sender: "Virtualization" Ck9uIDIwMjEvMi8yMyA3OjUwIOS4i+WNiCwgWGllIFlvbmdqaSB3cm90ZToKPiBUaGlzIGltcGxl bWVudHMgYSBNTVUtYmFzZWQgSU9NTVUgZHJpdmVyIHRvIHN1cHBvcnQgbWFwcGluZwo+IGtlcm5l bCBkbWEgYnVmZmVyIGludG8gdXNlcnNwYWNlLiBUaGUgYmFzaWMgaWRlYSBiZWhpbmQgaXQgaXMK PiB0cmVhdGluZyBNTVUgKFZBLT5QQSkgYXMgSU9NTVUgKElPVkEtPlBBKS4gVGhlIGRyaXZlciB3 aWxsIHNldAo+IHVwIE1NVSBtYXBwaW5nIGluc3RlYWQgb2YgSU9NTVUgbWFwcGluZyBmb3IgdGhl IERNQSB0cmFuc2ZlciBzbwo+IHRoYXQgdGhlIHVzZXJzcGFjZSBwcm9jZXNzIGlzIGFibGUgdG8g dXNlIGl0cyB2aXJ0dWFsIGFkZHJlc3MgdG8KPiBhY2Nlc3MgdGhlIGRtYSBidWZmZXIgaW4ga2Vy bmVsLgo+Cj4gQW5kIHRvIGF2b2lkIHNlY3VyaXR5IGlzc3VlLCBhIGJvdW5jZS1idWZmZXJpbmcg bWVjaGFuaXNtIGlzCj4gaW50cm9kdWNlZCB0byBwcmV2ZW50IHVzZXJzcGFjZSBhY2Nlc3Npbmcg dGhlIG9yaWdpbmFsIGJ1ZmZlcgo+IGRpcmVjdGx5Lgo+Cj4gU2lnbmVkLW9mZi1ieTogWGllIFlv bmdqaSA8eGlleW9uZ2ppQGJ5dGVkYW5jZS5jb20+Cj4gLS0tCj4gICBkcml2ZXJzL3ZkcGEvdmRw YV91c2VyL2lvdmFfZG9tYWluLmMgfCA0ODYgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysKPiAgIGRyaXZlcnMvdmRwYS92ZHBhX3VzZXIvaW92YV9kb21haW4uaCB8ICA2MSArKysr Kwo+ICAgMiBmaWxlcyBjaGFuZ2VkLCA1NDcgaW5zZXJ0aW9ucygrKQo+ICAgY3JlYXRlIG1vZGUg MTAwNjQ0IGRyaXZlcnMvdmRwYS92ZHBhX3VzZXIvaW92YV9kb21haW4uYwo+ICAgY3JlYXRlIG1v ZGUgMTAwNjQ0IGRyaXZlcnMvdmRwYS92ZHBhX3VzZXIvaW92YV9kb21haW4uaAo+Cj4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvdmRwYS92ZHBhX3VzZXIvaW92YV9kb21haW4uYyBiL2RyaXZlcnMvdmRw YS92ZHBhX3VzZXIvaW92YV9kb21haW4uYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXgg MDAwMDAwMDAwMDAwLi45Mjg1ZDQzMGQ0ODYKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvZHJpdmVy cy92ZHBhL3ZkcGFfdXNlci9pb3ZhX2RvbWFpbi5jCj4gQEAgLTAsMCArMSw0ODYgQEAKPiArLy8g U1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seQo+ICsvKgo+ICsgKiBNTVUtYmFz ZWQgSU9NTVUgaW1wbGVtZW50YXRpb24KPiArICoKPiArICogQ29weXJpZ2h0IChDKSAyMDIwIEJ5 dGVkYW5jZSBJbmMuIGFuZC9vciBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4K PiArICoKPiArICogQXV0aG9yOiBYaWUgWW9uZ2ppIDx4aWV5b25namlAYnl0ZWRhbmNlLmNvbT4K PiArICoKPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPgo+ICsjaW5jbHVkZSA8 bGludXgvZmlsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvYW5vbl9pbm9kZXMuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L2hpZ2htZW0uaD4KPiArCj4gKyNpbmNsdWRlICJpb3ZhX2RvbWFpbi5oIgo+ICsK PiArI2RlZmluZSBJT1ZBX1NUQVJUX1BGTiAxCj4gKyNkZWZpbmUgSU9WQV9BTExPQ19PUkRFUiAx Mgo+ICsjZGVmaW5lIElPVkFfQUxMT0NfU0laRSAoMSA8PCBJT1ZBX0FMTE9DX09SREVSKQo+ICsK PiArc3RhdGljIGlubGluZSBzdHJ1Y3QgcGFnZSAqCj4gK3ZkdXNlX2RvbWFpbl9nZXRfYm91bmNl X3BhZ2Uoc3RydWN0IHZkdXNlX2lvdmFfZG9tYWluICpkb21haW4sIHU2NCBpb3ZhKQo+ICt7Cj4g Kwl1NjQgaW5kZXggPSBpb3ZhID4+IFBBR0VfU0hJRlQ7Cj4gKwo+ICsJcmV0dXJuIGRvbWFpbi0+ Ym91bmNlX3BhZ2VzW2luZGV4XTsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSB2b2lkCj4gK3Zk dXNlX2RvbWFpbl9zZXRfYm91bmNlX3BhZ2Uoc3RydWN0IHZkdXNlX2lvdmFfZG9tYWluICpkb21h aW4sCj4gKwkJCQl1NjQgaW92YSwgc3RydWN0IHBhZ2UgKnBhZ2UpCj4gK3sKPiArCXU2NCBpbmRl eCA9IGlvdmEgPj4gUEFHRV9TSElGVDsKPiArCj4gKwlkb21haW4tPmJvdW5jZV9wYWdlc1tpbmRl eF0gPSBwYWdlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gcGVy bV90b19kaXIoaW50IHBlcm0pCj4gK3sKPiArCWVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpcjsK PiArCj4gKwlzd2l0Y2ggKHBlcm0pIHsKPiArCWNhc2UgVkhPU1RfTUFQX1dPOgo+ICsJCWRpciA9 IERNQV9GUk9NX0RFVklDRTsKPiArCQlicmVhazsKPiArCWNhc2UgVkhPU1RfTUFQX1JPOgo+ICsJ CWRpciA9IERNQV9UT19ERVZJQ0U7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIFZIT1NUX01BUF9SVzoK PiArCQlkaXIgPSBETUFfQklESVJFQ1RJT05BTDsKPiArCQlicmVhazsKPiArCWRlZmF1bHQ6Cj4g KwkJYnJlYWs7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIGRpcjsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBkaXJfdG9fcGVybShlbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIpCj4gK3sKPiArCWludCBw ZXJtID0gLUVGQVVMVDsKPiArCj4gKwlzd2l0Y2ggKGRpcikgewo+ICsJY2FzZSBETUFfRlJPTV9E RVZJQ0U6Cj4gKwkJcGVybSA9IFZIT1NUX01BUF9XTzsKPiArCQlicmVhazsKPiArCWNhc2UgRE1B X1RPX0RFVklDRToKPiArCQlwZXJtID0gVkhPU1RfTUFQX1JPOwo+ICsJCWJyZWFrOwo+ICsJY2Fz ZSBETUFfQklESVJFQ1RJT05BTDoKPiArCQlwZXJtID0gVkhPU1RfTUFQX1JXOwo+ICsJCWJyZWFr Owo+ICsJZGVmYXVsdDoKPiArCQlicmVhazsKPiArCX0KPiArCj4gKwlyZXR1cm4gcGVybTsKPiAr fQoKCkxldCdzIG1vdmUgdGhlIGFib3ZlIHR3byBoZWxwZXJzIHRvIHZob3N0X2lvdGxiLmggc28g dGhleSBjb3VsZCBiZSB1c2VkIApieSBvdGhlciBkcml2ZXIgZS5nICh2cGRhX3NpbSkKCgo+ICsK PiArc3RhdGljIHZvaWQgZG9fYm91bmNlKHBoeXNfYWRkcl90IG9yaWcsIHZvaWQgKmFkZHIsIHNp emVfdCBzaXplLAo+ICsJCQllbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkaXIpCj4gK3sKPiArCXVu c2lnbmVkIGxvbmcgcGZuID0gUEZOX0RPV04ob3JpZyk7Cj4gKwo+ICsJaWYgKFBhZ2VIaWdoTWVt KHBmbl90b19wYWdlKHBmbikpKSB7Cj4gKwkJdW5zaWduZWQgaW50IG9mZnNldCA9IG9mZnNldF9p bl9wYWdlKG9yaWcpOwo+ICsJCWNoYXIgKmJ1ZmZlcjsKPiArCQl1bnNpZ25lZCBpbnQgc3ogPSAw Owo+ICsJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwo+ICsJCXdoaWxlIChzaXplKSB7Cj4gKwkJ CXN6ID0gbWluX3Qoc2l6ZV90LCBQQUdFX1NJWkUgLSBvZmZzZXQsIHNpemUpOwo+ICsKPiArCQkJ bG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwo+ICsJCQlidWZmZXIgPSBrbWFwX2F0b21pYyhwZm5fdG9f cGFnZShwZm4pKTsKPiArCQkJaWYgKGRpciA9PSBETUFfVE9fREVWSUNFKQo+ICsJCQkJbWVtY3B5 KGFkZHIsIGJ1ZmZlciArIG9mZnNldCwgc3opOwo+ICsJCQllbHNlCj4gKwkJCQltZW1jcHkoYnVm ZmVyICsgb2Zmc2V0LCBhZGRyLCBzeik7Cj4gKwkJCWt1bm1hcF9hdG9taWMoYnVmZmVyKTsKPiAr CQkJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwoKCkkgd29uZGVyIHdoeSB3ZSBuZWVkIHRvIGRl YWwgd2l0aCBoaWdobWVtIGFuZCBpcnEgZmxhZ3MgZXhwbGljaXRseSBsaWtlIAp0aGlzLiBEb2Vz bid0IGttYXBfYXRvbWljKCkgd2lsbCB0YWtlIGNhcmUgYWxsIG9mIHRob3NlPwoKCj4gKwo+ICsJ CQlzaXplIC09IHN6Owo+ICsJCQlwZm4rKzsKPiArCQkJYWRkciArPSBzejsKPiArCQkJb2Zmc2V0 ID0gMDsKPiArCQl9Cj4gKwl9IGVsc2UgaWYgKGRpciA9PSBETUFfVE9fREVWSUNFKSB7Cj4gKwkJ bWVtY3B5KGFkZHIsIHBoeXNfdG9fdmlydChvcmlnKSwgc2l6ZSk7Cj4gKwl9IGVsc2Ugewo+ICsJ CW1lbWNweShwaHlzX3RvX3ZpcnQob3JpZyksIGFkZHIsIHNpemUpOwo+ICsJfQo+ICt9Cj4gKwo+ ICtzdGF0aWMgc3RydWN0IHBhZ2UgKgo+ICt2ZHVzZV9kb21haW5fZ2V0X21hcHBpbmdfcGFnZShz dHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbiwgdTY0IGlvdmEpCj4gK3sKPiArCXU2NCBz dGFydCA9IGlvdmEgJiBQQUdFX01BU0s7Cj4gKwl1NjQgbGFzdCA9IHN0YXJ0ICsgUEFHRV9TSVpF IC0gMTsKPiArCXN0cnVjdCB2aG9zdF9pb3RsYl9tYXAgKm1hcDsKPiArCXN0cnVjdCBwYWdlICpw YWdlID0gTlVMTDsKPiArCj4gKwlzcGluX2xvY2soJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwlt YXAgPSB2aG9zdF9pb3RsYl9pdHJlZV9maXJzdChkb21haW4tPmlvdGxiLCBzdGFydCwgbGFzdCk7 Cj4gKwlpZiAoIW1hcCkKPiArCQlnb3RvIG91dDsKPiArCj4gKwlwYWdlID0gcGZuX3RvX3BhZ2Uo KG1hcC0+YWRkciArIGlvdmEgLSBtYXAtPnN0YXJ0KSA+PiBQQUdFX1NISUZUKTsKPiArCWdldF9w YWdlKHBhZ2UpOwo+ICtvdXQ6Cj4gKwlzcGluX3VubG9jaygmZG9tYWluLT5pb3RsYl9sb2NrKTsK PiArCj4gKwlyZXR1cm4gcGFnZTsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBwYWdlICoKPiAr dmR1c2VfZG9tYWluX2FsbG9jX2JvdW5jZV9wYWdlKHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAq ZG9tYWluLCB1NjQgaW92YSkKPiArewo+ICsJdTY0IHN0YXJ0ID0gaW92YSAmIFBBR0VfTUFTSzsK PiArCXU2NCBsYXN0ID0gc3RhcnQgKyBQQUdFX1NJWkUgLSAxOwo+ICsJc3RydWN0IHZob3N0X2lv dGxiX21hcCAqbWFwOwo+ICsJc3RydWN0IHBhZ2UgKnBhZ2UgPSBOVUxMLCAqbmV3X3BhZ2UgPSBh bGxvY19wYWdlKEdGUF9LRVJORUwpOwo+ICsKPiArCWlmICghbmV3X3BhZ2UpCj4gKwkJcmV0dXJu IE5VTEw7Cj4gKwo+ICsJc3Bpbl9sb2NrKCZkb21haW4tPmlvdGxiX2xvY2spOwo+ICsJaWYgKCF2 aG9zdF9pb3RsYl9pdHJlZV9maXJzdChkb21haW4tPmlvdGxiLCBzdGFydCwgbGFzdCkpIHsKPiAr CQlfX2ZyZWVfcGFnZShuZXdfcGFnZSk7Cj4gKwkJZ290byBvdXQ7Cj4gKwl9Cj4gKwlwYWdlID0g dmR1c2VfZG9tYWluX2dldF9ib3VuY2VfcGFnZShkb21haW4sIGlvdmEpOwo+ICsJaWYgKHBhZ2Up IHsKPiArCQlnZXRfcGFnZShwYWdlKTsKPiArCQlfX2ZyZWVfcGFnZShuZXdfcGFnZSk7Cj4gKwkJ Z290byBvdXQ7Cj4gKwl9Cj4gKwl2ZHVzZV9kb21haW5fc2V0X2JvdW5jZV9wYWdlKGRvbWFpbiwg aW92YSwgbmV3X3BhZ2UpOwo+ICsJZ2V0X3BhZ2UobmV3X3BhZ2UpOwo+ICsJcGFnZSA9IG5ld19w YWdlOwo+ICsKPiArCWZvciAobWFwID0gdmhvc3RfaW90bGJfaXRyZWVfZmlyc3QoZG9tYWluLT5p b3RsYiwgc3RhcnQsIGxhc3QpOyBtYXA7Cj4gKwkgICAgIG1hcCA9IHZob3N0X2lvdGxiX2l0cmVl X25leHQobWFwLCBzdGFydCwgbGFzdCkpIHsKPiArCQl1bnNpZ25lZCBpbnQgc3JjX29mZnNldCA9 IDAsIGRzdF9vZmZzZXQgPSAwOwo+ICsJCXBoeXNfYWRkcl90IHNyYzsKPiArCQl2b2lkICpkc3Q7 Cj4gKwkJc2l6ZV90IHN6Owo+ICsKPiArCQlpZiAocGVybV90b19kaXIobWFwLT5wZXJtKSA9PSBE TUFfRlJPTV9ERVZJQ0UpCj4gKwkJCWNvbnRpbnVlOwo+ICsKPiArCQlpZiAoc3RhcnQgPiBtYXAt PnN0YXJ0KQo+ICsJCQlzcmNfb2Zmc2V0ID0gc3RhcnQgLSBtYXAtPnN0YXJ0Owo+ICsJCWVsc2UK PiArCQkJZHN0X29mZnNldCA9IG1hcC0+c3RhcnQgLSBzdGFydDsKPiArCj4gKwkJc3JjID0gbWFw LT5hZGRyICsgc3JjX29mZnNldDsKPiArCQlkc3QgPSBwYWdlX2FkZHJlc3MocGFnZSkgKyBkc3Rf b2Zmc2V0Owo+ICsJCXN6ID0gbWluX3Qoc2l6ZV90LCBtYXAtPnNpemUgLSBzcmNfb2Zmc2V0LAo+ ICsJCQkJUEFHRV9TSVpFIC0gZHN0X29mZnNldCk7Cj4gKwkJZG9fYm91bmNlKHNyYywgZHN0LCBz eiwgRE1BX1RPX0RFVklDRSk7Cj4gKwl9Cj4gK291dDoKPiArCXNwaW5fdW5sb2NrKCZkb21haW4t PmlvdGxiX2xvY2spOwo+ICsKPiArCXJldHVybiBwYWdlOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9p ZAo+ICt2ZHVzZV9kb21haW5fZnJlZV9ib3VuY2VfcGFnZXMoc3RydWN0IHZkdXNlX2lvdmFfZG9t YWluICpkb21haW4sCj4gKwkJCQl1NjQgaW92YSwgc2l6ZV90IHNpemUpCj4gK3sKPiArCXN0cnVj dCBwYWdlICpwYWdlOwo+ICsKPiArCXNwaW5fbG9jaygmZG9tYWluLT5pb3RsYl9sb2NrKTsKPiAr CWlmIChXQVJOX09OKHZob3N0X2lvdGxiX2l0cmVlX2ZpcnN0KGRvbWFpbi0+aW90bGIsIGlvdmEs Cj4gKwkJCQkJCWlvdmEgKyBzaXplIC0gMSkpKQo+ICsJCWdvdG8gb3V0Owo+ICsKPiArCXdoaWxl IChzaXplID4gMCkgewo+ICsJCXBhZ2UgPSB2ZHVzZV9kb21haW5fZ2V0X2JvdW5jZV9wYWdlKGRv bWFpbiwgaW92YSk7Cj4gKwkJaWYgKHBhZ2UpIHsKPiArCQkJdmR1c2VfZG9tYWluX3NldF9ib3Vu Y2VfcGFnZShkb21haW4sIGlvdmEsIE5VTEwpOwo+ICsJCQlfX2ZyZWVfcGFnZShwYWdlKTsKPiAr CQl9Cj4gKwkJc2l6ZSAtPSBQQUdFX1NJWkU7Cj4gKwkJaW92YSArPSBQQUdFX1NJWkU7Cj4gKwl9 Cj4gK291dDoKPiArCXNwaW5fdW5sb2NrKCZkb21haW4tPmlvdGxiX2xvY2spOwo+ICt9Cj4gKwo+ ICtzdGF0aWMgdm9pZCB2ZHVzZV9kb21haW5fYm91bmNlKHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFp biAqZG9tYWluLAo+ICsJCQkJZG1hX2FkZHJfdCBpb3ZhLCBwaHlzX2FkZHJfdCBvcmlnLAo+ICsJ CQkJc2l6ZV90IHNpemUsIGVudW0gZG1hX2RhdGFfZGlyZWN0aW9uIGRpcikKPiArewo+ICsJdW5z aWduZWQgaW50IG9mZnNldCA9IG9mZnNldF9pbl9wYWdlKGlvdmEpOwo+ICsKPiArCXdoaWxlIChz aXplKSB7Cj4gKwkJc3RydWN0IHBhZ2UgKnAgPSB2ZHVzZV9kb21haW5fZ2V0X2JvdW5jZV9wYWdl KGRvbWFpbiwgaW92YSk7Cj4gKwkJc2l6ZV90IHN6ID0gbWluX3Qoc2l6ZV90LCBQQUdFX1NJWkUg LSBvZmZzZXQsIHNpemUpOwo+ICsKPiArCQlXQVJOX09OKCFwICYmIGRpciA9PSBETUFfRlJPTV9E RVZJQ0UpOwo+ICsKPiArCQlpZiAocCkKPiArCQkJZG9fYm91bmNlKG9yaWcsIHBhZ2VfYWRkcmVz cyhwKSArIG9mZnNldCwgc3osIGRpcik7Cj4gKwo+ICsJCXNpemUgLT0gc3o7Cj4gKwkJb3JpZyAr PSBzejsKPiArCQlpb3ZhICs9IHN6Owo+ICsJCW9mZnNldCA9IDA7Cj4gKwl9Cj4gK30KPiArCj4g K3N0YXRpYyBkbWFfYWRkcl90IHZkdXNlX2RvbWFpbl9hbGxvY19pb3ZhKHN0cnVjdCBpb3ZhX2Rv bWFpbiAqaW92YWQsCj4gKwkJCQl1bnNpZ25lZCBsb25nIHNpemUsIHVuc2lnbmVkIGxvbmcgbGlt aXQpCj4gK3sKPiArCXVuc2lnbmVkIGxvbmcgc2hpZnQgPSBpb3ZhX3NoaWZ0KGlvdmFkKTsKPiAr CXVuc2lnbmVkIGxvbmcgaW92YV9sZW4gPSBpb3ZhX2FsaWduKGlvdmFkLCBzaXplKSA+PiBzaGlm dDsKPiArCXVuc2lnbmVkIGxvbmcgaW92YV9wZm47Cj4gKwo+ICsJaWYgKGlvdmFfbGVuIDwgKDEg PDwgKElPVkFfUkFOR0VfQ0FDSEVfTUFYX1NJWkUgLSAxKSkpCj4gKwkJaW92YV9sZW4gPSByb3Vu ZHVwX3Bvd19vZl90d28oaW92YV9sZW4pOwo+ICsJaW92YV9wZm4gPSBhbGxvY19pb3ZhX2Zhc3Qo aW92YWQsIGlvdmFfbGVuLCBsaW1pdCA+PiBzaGlmdCwgdHJ1ZSk7Cj4gKwo+ICsJcmV0dXJuIGlv dmFfcGZuIDw8IHNoaWZ0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2ZHVzZV9kb21haW5fZnJl ZV9pb3ZhKHN0cnVjdCBpb3ZhX2RvbWFpbiAqaW92YWQsCj4gKwkJCQlkbWFfYWRkcl90IGlvdmEs IHNpemVfdCBzaXplKQo+ICt7Cj4gKwl1bnNpZ25lZCBsb25nIHNoaWZ0ID0gaW92YV9zaGlmdChp b3ZhZCk7Cj4gKwl1bnNpZ25lZCBsb25nIGlvdmFfbGVuID0gaW92YV9hbGlnbihpb3ZhZCwgc2l6 ZSkgPj4gc2hpZnQ7Cj4gKwo+ICsJZnJlZV9pb3ZhX2Zhc3QoaW92YWQsIGlvdmEgPj4gc2hpZnQs IGlvdmFfbGVuKTsKPiArfQo+ICsKPiArZG1hX2FkZHJfdCB2ZHVzZV9kb21haW5fbWFwX3BhZ2Uo c3RydWN0IHZkdXNlX2lvdmFfZG9tYWluICpkb21haW4sCj4gKwkJCQlzdHJ1Y3QgcGFnZSAqcGFn ZSwgdW5zaWduZWQgbG9uZyBvZmZzZXQsCj4gKwkJCQlzaXplX3Qgc2l6ZSwgZW51bSBkbWFfZGF0 YV9kaXJlY3Rpb24gZGlyLAo+ICsJCQkJdW5zaWduZWQgbG9uZyBhdHRycykKPiArewo+ICsJc3Ry dWN0IGlvdmFfZG9tYWluICppb3ZhZCA9ICZkb21haW4tPnN0cmVhbV9pb3ZhZDsKPiArCXVuc2ln bmVkIGxvbmcgbGltaXQgPSBkb21haW4tPmJvdW5jZV9zaXplIC0gMTsKPiArCXBoeXNfYWRkcl90 IHBhID0gcGFnZV90b19waHlzKHBhZ2UpICsgb2Zmc2V0Owo+ICsJZG1hX2FkZHJfdCBpb3ZhID0g dmR1c2VfZG9tYWluX2FsbG9jX2lvdmEoaW92YWQsIHNpemUsIGxpbWl0KTsKPiArCWludCByZXQ7 Cj4gKwo+ICsJaWYgKCFpb3ZhKQo+ICsJCXJldHVybiBETUFfTUFQUElOR19FUlJPUjsKPiArCj4g KwlzcGluX2xvY2soJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwlyZXQgPSB2aG9zdF9pb3RsYl9h ZGRfcmFuZ2UoZG9tYWluLT5pb3RsYiwgKHU2NClpb3ZhLAo+ICsJCQkJICAgICh1NjQpaW92YSAr IHNpemUgLSAxLAo+ICsJCQkJICAgIHBhLCBkaXJfdG9fcGVybShkaXIpKTsKPiArCXNwaW5fdW5s b2NrKCZkb21haW4tPmlvdGxiX2xvY2spOwo+ICsJaWYgKHJldCkgewo+ICsJCXZkdXNlX2RvbWFp bl9mcmVlX2lvdmEoaW92YWQsIGlvdmEsIHNpemUpOwo+ICsJCXJldHVybiBETUFfTUFQUElOR19F UlJPUjsKPiArCX0KPiArCWlmIChkaXIgPT0gRE1BX1RPX0RFVklDRSB8fCBkaXIgPT0gRE1BX0JJ RElSRUNUSU9OQUwpCj4gKwkJdmR1c2VfZG9tYWluX2JvdW5jZShkb21haW4sIGlvdmEsIHBhLCBz aXplLCBETUFfVE9fREVWSUNFKTsKPiArCj4gKwlyZXR1cm4gaW92YTsKPiArfQo+ICsKPiArdm9p ZCB2ZHVzZV9kb21haW5fdW5tYXBfcGFnZShzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFp biwKPiArCQkJZG1hX2FkZHJfdCBkbWFfYWRkciwgc2l6ZV90IHNpemUsCj4gKwkJCWVudW0gZG1h X2RhdGFfZGlyZWN0aW9uIGRpciwgdW5zaWduZWQgbG9uZyBhdHRycykKPiArewo+ICsJc3RydWN0 IGlvdmFfZG9tYWluICppb3ZhZCA9ICZkb21haW4tPnN0cmVhbV9pb3ZhZDsKPiArCXN0cnVjdCB2 aG9zdF9pb3RsYl9tYXAgKm1hcDsKPiArCXBoeXNfYWRkcl90IHBhOwo+ICsKPiArCXNwaW5fbG9j aygmZG9tYWluLT5pb3RsYl9sb2NrKTsKPiArCW1hcCA9IHZob3N0X2lvdGxiX2l0cmVlX2ZpcnN0 KGRvbWFpbi0+aW90bGIsICh1NjQpZG1hX2FkZHIsCj4gKwkJCQkgICAgICAodTY0KWRtYV9hZGRy ICsgc2l6ZSAtIDEpOwo+ICsJaWYgKFdBUk5fT04oIW1hcCkpIHsKPiArCQlzcGluX3VubG9jaygm ZG9tYWluLT5pb3RsYl9sb2NrKTsKPiArCQlyZXR1cm47Cj4gKwl9Cj4gKwlwYSA9IG1hcC0+YWRk cjsKPiArCXZob3N0X2lvdGxiX21hcF9mcmVlKGRvbWFpbi0+aW90bGIsIG1hcCk7Cj4gKwlzcGlu X3VubG9jaygmZG9tYWluLT5pb3RsYl9sb2NrKTsKPiArCj4gKwlpZiAoZGlyID09IERNQV9GUk9N X0RFVklDRSB8fCBkaXIgPT0gRE1BX0JJRElSRUNUSU9OQUwpCj4gKwkJdmR1c2VfZG9tYWluX2Jv dW5jZShkb21haW4sIGRtYV9hZGRyLCBwYSwKPiArCQkJCQlzaXplLCBETUFfRlJPTV9ERVZJQ0Up Owo+ICsKPiArCXZkdXNlX2RvbWFpbl9mcmVlX2lvdmEoaW92YWQsIGRtYV9hZGRyLCBzaXplKTsK PiArfQo+ICsKPiArdm9pZCAqdmR1c2VfZG9tYWluX2FsbG9jX2NvaGVyZW50KHN0cnVjdCB2ZHVz ZV9pb3ZhX2RvbWFpbiAqZG9tYWluLAo+ICsJCQkJc2l6ZV90IHNpemUsIGRtYV9hZGRyX3QgKmRt YV9hZGRyLAo+ICsJCQkJZ2ZwX3QgZmxhZywgdW5zaWduZWQgbG9uZyBhdHRycykKPiArewo+ICsJ c3RydWN0IGlvdmFfZG9tYWluICppb3ZhZCA9ICZkb21haW4tPmNvbnNpc3RlbnRfaW92YWQ7Cj4g Kwl1bnNpZ25lZCBsb25nIGxpbWl0ID0gZG9tYWluLT5pb3ZhX2xpbWl0Owo+ICsJZG1hX2FkZHJf dCBpb3ZhID0gdmR1c2VfZG9tYWluX2FsbG9jX2lvdmEoaW92YWQsIHNpemUsIGxpbWl0KTsKPiAr CXZvaWQgKm9yaWcgPSBhbGxvY19wYWdlc19leGFjdChzaXplLCBmbGFnKTsKPiArCWludCByZXQ7 Cj4gKwo+ICsJaWYgKCFpb3ZhIHx8ICFvcmlnKQo+ICsJCWdvdG8gZXJyOwo+ICsKPiArCXNwaW5f bG9jaygmZG9tYWluLT5pb3RsYl9sb2NrKTsKPiArCXJldCA9IHZob3N0X2lvdGxiX2FkZF9yYW5n ZShkb21haW4tPmlvdGxiLCAodTY0KWlvdmEsCj4gKwkJCQkgICAgKHU2NClpb3ZhICsgc2l6ZSAt IDEsCj4gKwkJCQkgICAgdmlydF90b19waHlzKG9yaWcpLCBWSE9TVF9NQVBfUlcpOwo+ICsJc3Bp bl91bmxvY2soJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8gZXJy Owo+ICsKPiArCSpkbWFfYWRkciA9IGlvdmE7Cj4gKwo+ICsJcmV0dXJuIG9yaWc7Cj4gK2VycjoK PiArCSpkbWFfYWRkciA9IERNQV9NQVBQSU5HX0VSUk9SOwo+ICsJaWYgKG9yaWcpCj4gKwkJZnJl ZV9wYWdlc19leGFjdChvcmlnLCBzaXplKTsKPiArCWlmIChpb3ZhKQo+ICsJCXZkdXNlX2RvbWFp bl9mcmVlX2lvdmEoaW92YWQsIGlvdmEsIHNpemUpOwo+ICsKPiArCXJldHVybiBOVUxMOwo+ICt9 Cj4gKwo+ICt2b2lkIHZkdXNlX2RvbWFpbl9mcmVlX2NvaGVyZW50KHN0cnVjdCB2ZHVzZV9pb3Zh X2RvbWFpbiAqZG9tYWluLCBzaXplX3Qgc2l6ZSwKPiArCQkJCXZvaWQgKnZhZGRyLCBkbWFfYWRk cl90IGRtYV9hZGRyLAo+ICsJCQkJdW5zaWduZWQgbG9uZyBhdHRycykKPiArewo+ICsJc3RydWN0 IGlvdmFfZG9tYWluICppb3ZhZCA9ICZkb21haW4tPmNvbnNpc3RlbnRfaW92YWQ7Cj4gKwlzdHJ1 Y3Qgdmhvc3RfaW90bGJfbWFwICptYXA7Cj4gKwlwaHlzX2FkZHJfdCBwYTsKPiArCj4gKwlzcGlu X2xvY2soJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwltYXAgPSB2aG9zdF9pb3RsYl9pdHJlZV9m aXJzdChkb21haW4tPmlvdGxiLCAodTY0KWRtYV9hZGRyLAo+ICsJCQkJICAgICAgKHU2NClkbWFf YWRkciArIHNpemUgLSAxKTsKPiArCWlmIChXQVJOX09OKCFtYXApKSB7Cj4gKwkJc3Bpbl91bmxv Y2soJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwkJcmV0dXJuOwo+ICsJfQo+ICsJcGEgPSBtYXAt PmFkZHI7Cj4gKwl2aG9zdF9pb3RsYl9tYXBfZnJlZShkb21haW4tPmlvdGxiLCBtYXApOwo+ICsJ c3Bpbl91bmxvY2soJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwo+ICsJdmR1c2VfZG9tYWluX2Zy ZWVfaW92YShpb3ZhZCwgZG1hX2FkZHIsIHNpemUpOwo+ICsJZnJlZV9wYWdlc19leGFjdChwaHlz X3RvX3ZpcnQocGEpLCBzaXplKTsKPiArfQo+ICsKPiArc3RhdGljIHZtX2ZhdWx0X3QgdmR1c2Vf ZG9tYWluX21tYXBfZmF1bHQoc3RydWN0IHZtX2ZhdWx0ICp2bWYpCj4gK3sKPiArCXN0cnVjdCB2 ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0gdm1mLT52bWEtPnZtX3ByaXZhdGVfZGF0YTsKPiAr CXVuc2lnbmVkIGxvbmcgaW92YSA9IHZtZi0+cGdvZmYgPDwgUEFHRV9TSElGVDsKPiArCXN0cnVj dCBwYWdlICpwYWdlOwo+ICsKPiArCWlmICghZG9tYWluKQo+ICsJCXJldHVybiBWTV9GQVVMVF9T SUdCVVM7Cj4gKwo+ICsJaWYgKGlvdmEgPCBkb21haW4tPmJvdW5jZV9zaXplKQo+ICsJCXBhZ2Ug PSB2ZHVzZV9kb21haW5fYWxsb2NfYm91bmNlX3BhZ2UoZG9tYWluLCBpb3ZhKTsKPiArCWVsc2UK PiArCQlwYWdlID0gdmR1c2VfZG9tYWluX2dldF9tYXBwaW5nX3BhZ2UoZG9tYWluLCBpb3ZhKTsK PiArCj4gKwlpZiAoIXBhZ2UpCj4gKwkJcmV0dXJuIFZNX0ZBVUxUX1NJR0JVUzsKPiArCj4gKwl2 bWYtPnBhZ2UgPSBwYWdlOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29u c3Qgc3RydWN0IHZtX29wZXJhdGlvbnNfc3RydWN0IHZkdXNlX2RvbWFpbl9tbWFwX29wcyA9IHsK PiArCS5mYXVsdCA9IHZkdXNlX2RvbWFpbl9tbWFwX2ZhdWx0LAo+ICt9Owo+ICsKPiArc3RhdGlj IGludCB2ZHVzZV9kb21haW5fbW1hcChzdHJ1Y3QgZmlsZSAqZmlsZSwgc3RydWN0IHZtX2FyZWFf c3RydWN0ICp2bWEpCj4gK3sKPiArCXN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluID0g ZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ICsKPiArCXZtYS0+dm1fZmxhZ3MgfD0gVk1fRE9OVERVTVAg fCBWTV9ET05URVhQQU5EOwo+ICsJdm1hLT52bV9wcml2YXRlX2RhdGEgPSBkb21haW47Cj4gKwl2 bWEtPnZtX29wcyA9ICZ2ZHVzZV9kb21haW5fbW1hcF9vcHM7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4g K30KPiArCj4gK3N0YXRpYyBpbnQgdmR1c2VfZG9tYWluX3JlbGVhc2Uoc3RydWN0IGlub2RlICpp bm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCj4gK3sKPiArCXN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFp biAqZG9tYWluID0gZmlsZS0+cHJpdmF0ZV9kYXRhOwo+ICsKPiArCXZkdXNlX2RvbWFpbl9mcmVl X2JvdW5jZV9wYWdlcyhkb21haW4sIDAsIGRvbWFpbi0+Ym91bmNlX3NpemUpOwo+ICsJcHV0X2lv dmFfZG9tYWluKCZkb21haW4tPnN0cmVhbV9pb3ZhZCk7Cj4gKwlwdXRfaW92YV9kb21haW4oJmRv bWFpbi0+Y29uc2lzdGVudF9pb3ZhZCk7Cj4gKwl2aG9zdF9pb3RsYl9mcmVlKGRvbWFpbi0+aW90 bGIpOwo+ICsJdmZyZWUoZG9tYWluLT5ib3VuY2VfcGFnZXMpOwo+ICsJa2ZyZWUoZG9tYWluKTsK PiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29w ZXJhdGlvbnMgdmR1c2VfZG9tYWluX2ZvcHMgPSB7Cj4gKwkubW1hcCA9IHZkdXNlX2RvbWFpbl9t bWFwLAo+ICsJLnJlbGVhc2UgPSB2ZHVzZV9kb21haW5fcmVsZWFzZSwKPiArfTsKPiArCj4gK3Zv aWQgdmR1c2VfZG9tYWluX2Rlc3Ryb3koc3RydWN0IHZkdXNlX2lvdmFfZG9tYWluICpkb21haW4p Cj4gK3sKPiArCWZwdXQoZG9tYWluLT5maWxlKTsKPiArfQo+ICsKPiArc3RydWN0IHZkdXNlX2lv dmFfZG9tYWluICoKPiArdmR1c2VfZG9tYWluX2NyZWF0ZSh1bnNpZ25lZCBsb25nIGlvdmFfbGlt aXQsIHNpemVfdCBib3VuY2Vfc2l6ZSkKPiArewo+ICsJc3RydWN0IHZkdXNlX2lvdmFfZG9tYWlu ICpkb21haW47Cj4gKwlzdHJ1Y3QgZmlsZSAqZmlsZTsKPiArCXVuc2lnbmVkIGxvbmcgYm91bmNl X3BmbnMgPSBQQUdFX0FMSUdOKGJvdW5jZV9zaXplKSA+PiBQQUdFX1NISUZUOwo+ICsKPiArCWlm IChpb3ZhX2xpbWl0IDw9IGJvdW5jZV9zaXplKQo+ICsJCXJldHVybiBOVUxMOwo+ICsKPiArCWRv bWFpbiA9IGt6YWxsb2Moc2l6ZW9mKCpkb21haW4pLCBHRlBfS0VSTkVMKTsKPiArCWlmICghZG9t YWluKQo+ICsJCXJldHVybiBOVUxMOwo+ICsKPiArCWRvbWFpbi0+aW90bGIgPSB2aG9zdF9pb3Rs Yl9hbGxvYygwLCAwKTsKPiArCWlmICghZG9tYWluLT5pb3RsYikKPiArCQlnb3RvIGVycl9pb3Rs YjsKPiArCj4gKwlkb21haW4tPmlvdmFfbGltaXQgPSBpb3ZhX2xpbWl0Owo+ICsJZG9tYWluLT5i b3VuY2Vfc2l6ZSA9IFBBR0VfQUxJR04oYm91bmNlX3NpemUpOwo+ICsJZG9tYWluLT5ib3VuY2Vf cGFnZXMgPSB2emFsbG9jKGJvdW5jZV9wZm5zICogc2l6ZW9mKHN0cnVjdCBwYWdlICopKTsKPiAr CWlmICghZG9tYWluLT5ib3VuY2VfcGFnZXMpCj4gKwkJZ290byBlcnJfcGFnZTsKPiArCj4gKwlm aWxlID0gYW5vbl9pbm9kZV9nZXRmaWxlKCJbdmR1c2UtZG9tYWluXSIsICZ2ZHVzZV9kb21haW5f Zm9wcywKPiArCQkJCWRvbWFpbiwgT19SRFdSKTsKPiArCWlmIChJU19FUlIoZmlsZSkpCj4gKwkJ Z290byBlcnJfZmlsZTsKPiArCj4gKwlkb21haW4tPmZpbGUgPSBmaWxlOwo+ICsJc3Bpbl9sb2Nr X2luaXQoJmRvbWFpbi0+aW90bGJfbG9jayk7Cj4gKwlpbml0X2lvdmFfZG9tYWluKCZkb21haW4t PnN0cmVhbV9pb3ZhZCwKPiArCQkJSU9WQV9BTExPQ19TSVpFLCBJT1ZBX1NUQVJUX1BGTik7Cj4g Kwlpbml0X2lvdmFfZG9tYWluKCZkb21haW4tPmNvbnNpc3RlbnRfaW92YWQsCj4gKwkJCVBBR0Vf U0laRSwgYm91bmNlX3BmbnMpOwo+ICsKPiArCXJldHVybiBkb21haW47Cj4gK2Vycl9maWxlOgo+ ICsJdmZyZWUoZG9tYWluLT5ib3VuY2VfcGFnZXMpOwo+ICtlcnJfcGFnZToKPiArCXZob3N0X2lv dGxiX2ZyZWUoZG9tYWluLT5pb3RsYik7Cj4gK2Vycl9pb3RsYjoKPiArCWtmcmVlKGRvbWFpbik7 Cj4gKwlyZXR1cm4gTlVMTDsKPiArfQo+ICsKPiAraW50IHZkdXNlX2RvbWFpbl9pbml0KHZvaWQp Cj4gK3sKPiArCXJldHVybiBpb3ZhX2NhY2hlX2dldCgpOwo+ICt9Cj4gKwo+ICt2b2lkIHZkdXNl X2RvbWFpbl9leGl0KHZvaWQpCj4gK3sKPiArCWlvdmFfY2FjaGVfcHV0KCk7Cj4gK30KPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy92ZHBhL3ZkcGFfdXNlci9pb3ZhX2RvbWFpbi5oIGIvZHJpdmVycy92 ZHBhL3ZkcGFfdXNlci9pb3ZhX2RvbWFpbi5oCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRl eCAwMDAwMDAwMDAwMDAuLjljODVkODM0NjYyNgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2 ZXJzL3ZkcGEvdmRwYV91c2VyL2lvdmFfZG9tYWluLmgKPiBAQCAtMCwwICsxLDYxIEBACj4gKy8q IFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkgKi8KPiArLyoKPiArICogTU1V LWJhc2VkIElPTU1VIGltcGxlbWVudGF0aW9uCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAy MCBCeXRlZGFuY2UgSW5jLiBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2 ZWQuCj4gKyAqCj4gKyAqIEF1dGhvcjogWGllIFlvbmdqaSA8eGlleW9uZ2ppQGJ5dGVkYW5jZS5j b20+Cj4gKyAqCj4gKyAqLwo+ICsKPiArI2lmbmRlZiBfVkRVU0VfSU9WQV9ET01BSU5fSAo+ICsj ZGVmaW5lIF9WRFVTRV9JT1ZBX0RPTUFJTl9ICj4gKwo+ICsjaW5jbHVkZSA8bGludXgvaW92YS5o Pgo+ICsjaW5jbHVkZSA8bGludXgvZG1hLW1hcHBpbmcuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3Zo b3N0X2lvdGxiLmg+Cj4gKwo+ICtzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gewo+ICsJc3RydWN0 IGlvdmFfZG9tYWluIHN0cmVhbV9pb3ZhZDsKPiArCXN0cnVjdCBpb3ZhX2RvbWFpbiBjb25zaXN0 ZW50X2lvdmFkOwo+ICsJc3RydWN0IHBhZ2UgKipib3VuY2VfcGFnZXM7Cj4gKwlzaXplX3QgYm91 bmNlX3NpemU7Cj4gKwl1bnNpZ25lZCBsb25nIGlvdmFfbGltaXQ7Cj4gKwlzdHJ1Y3Qgdmhvc3Rf aW90bGIgKmlvdGxiOwoKClNvcnJ5IGlmIEkndmUgYXNrZWQgdGhpcyBiZWZvcmUuCgpCdXQgd2hh dCdzIHRoZSByZWFzb24gZm9yIG1haW50YWluZyBhIGRlZGljYXRlZCBJT1RMQiBoZXJlPyBJIHRo aW5rIHdlIApjb3VsZCByZXVzZSB2ZHVzZV9kZXYtPmlvbW11IHNpbmNlIHRoZSBkZXZpY2UgY2Fu IG5vdCBiZSB1c2VkIGJ5IGJvdGggCnZpcnRpbyBhbmQgdmhvc3QgaW4gdGhlIHNhbWUgdGltZSBv ciB1c2UgdmR1c2VfaW92YV9kb21haW4tPmlvdGxiIGZvciAKc2V0X21hcCgpLgoKQWxzbywgc2lu Y2Ugdmhvc3QgSU9UTEIgc3VwcG9ydCBwZXIgbWFwcGluZyB0b2tlbiAob3BhdXFlKSwgY2FuIHdl IHVzZSAKdGhhdCBpbnN0ZWFkIG9mIHRoZSBib3VuY2VfcGFnZXMgKj8KClRoYW5rcwoKCj4gKwlz cGlubG9ja190IGlvdGxiX2xvY2s7Cj4gKwlzdHJ1Y3QgZmlsZSAqZmlsZTsKPiArfTsKPiArCj4g K3N0YXRpYyBpbmxpbmUgc3RydWN0IGZpbGUgKgo+ICt2ZHVzZV9kb21haW5fZmlsZShzdHJ1Y3Qg dmR1c2VfaW92YV9kb21haW4gKmRvbWFpbikKPiArewo+ICsJcmV0dXJuIGRvbWFpbi0+ZmlsZTsK PiArfQo+ICsKPiArZG1hX2FkZHJfdCB2ZHVzZV9kb21haW5fbWFwX3BhZ2Uoc3RydWN0IHZkdXNl X2lvdmFfZG9tYWluICpkb21haW4sCj4gKwkJCQlzdHJ1Y3QgcGFnZSAqcGFnZSwgdW5zaWduZWQg bG9uZyBvZmZzZXQsCj4gKwkJCQlzaXplX3Qgc2l6ZSwgZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24g ZGlyLAo+ICsJCQkJdW5zaWduZWQgbG9uZyBhdHRycyk7Cj4gKwo+ICt2b2lkIHZkdXNlX2RvbWFp bl91bm1hcF9wYWdlKHN0cnVjdCB2ZHVzZV9pb3ZhX2RvbWFpbiAqZG9tYWluLAo+ICsJCQlkbWFf YWRkcl90IGRtYV9hZGRyLCBzaXplX3Qgc2l6ZSwKPiArCQkJZW51bSBkbWFfZGF0YV9kaXJlY3Rp b24gZGlyLCB1bnNpZ25lZCBsb25nIGF0dHJzKTsKPiArCj4gK3ZvaWQgKnZkdXNlX2RvbWFpbl9h bGxvY19jb2hlcmVudChzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbiwKPiArCQkJCXNp emVfdCBzaXplLCBkbWFfYWRkcl90ICpkbWFfYWRkciwKPiArCQkJCWdmcF90IGZsYWcsIHVuc2ln bmVkIGxvbmcgYXR0cnMpOwo+ICsKPiArdm9pZCB2ZHVzZV9kb21haW5fZnJlZV9jb2hlcmVudChz dHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKmRvbWFpbiwgc2l6ZV90IHNpemUsCj4gKwkJCQl2b2lk ICp2YWRkciwgZG1hX2FkZHJfdCBkbWFfYWRkciwKPiArCQkJCXVuc2lnbmVkIGxvbmcgYXR0cnMp Owo+ICsKPiArdm9pZCB2ZHVzZV9kb21haW5fZGVzdHJveShzdHJ1Y3QgdmR1c2VfaW92YV9kb21h aW4gKmRvbWFpbik7Cj4gKwo+ICtzdHJ1Y3QgdmR1c2VfaW92YV9kb21haW4gKnZkdXNlX2RvbWFp bl9jcmVhdGUodW5zaWduZWQgbG9uZyBpb3ZhX2xpbWl0LAo+ICsJCQkJCQlzaXplX3QgYm91bmNl X3NpemUpOwo+ICsKPiAraW50IHZkdXNlX2RvbWFpbl9pbml0KHZvaWQpOwo+ICsKPiArdm9pZCB2 ZHVzZV9kb21haW5fZXhpdCh2b2lkKTsKPiArCj4gKyNlbmRpZiAvKiBfVkRVU0VfSU9WQV9ET01B SU5fSCAqLwoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18K VmlydHVhbGl6YXRpb24gbWFpbGluZyBsaXN0ClZpcnR1YWxpemF0aW9uQGxpc3RzLmxpbnV4LWZv dW5kYXRpb24ub3JnCmh0dHBzOi8vbGlzdHMubGludXhmb3VuZGF0aW9uLm9yZy9tYWlsbWFuL2xp c3RpbmZvL3ZpcnR1YWxpemF0aW9u