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=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,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 DDFF2CA9ECF for ; Thu, 31 Oct 2019 23:15:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A914B2080F for ; Thu, 31 Oct 2019 23:15:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728656AbfJaXPP (ORCPT ); Thu, 31 Oct 2019 19:15:15 -0400 Received: from mga01.intel.com ([192.55.52.88]:52440 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727423AbfJaXPO (ORCPT ); Thu, 31 Oct 2019 19:15:14 -0400 X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Oct 2019 16:15:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,253,1569308400"; d="scan'208";a="225867978" Received: from iweiny-desk2.sc.intel.com ([10.3.52.157]) by fmsmga004.fm.intel.com with ESMTP; 31 Oct 2019 16:15:04 -0700 Date: Thu, 31 Oct 2019 16:15:04 -0700 From: Ira Weiny To: John Hubbard Cc: Andrew Morton , Al Viro , Alex Williamson , Benjamin Herrenschmidt , =?iso-8859-1?Q?Bj=F6rn_T=F6pel?= , Christoph Hellwig , Dan Williams , Daniel Vetter , Dave Chinner , David Airlie , "David S . Miller" , Jan Kara , Jason Gunthorpe , Jens Axboe , Jonathan Corbet , =?iso-8859-1?B?Suly9G1l?= Glisse , Magnus Karlsson , Mauro Carvalho Chehab , Michael Ellerman , Michal Hocko , Mike Kravetz , Paul Mackerras , Shuah Khan , Vlastimil Babka , bpf@vger.kernel.org, dri-devel@lists.freedesktop.org, kvm@vger.kernel.org, linux-block@vger.kernel.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-media@vger.kernel.org, linux-rdma@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, netdev@vger.kernel.org, linux-mm@kvack.org, LKML Subject: Re: [PATCH 05/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN Message-ID: <20191031231503.GF14771@iweiny-DESK2.sc.intel.com> References: <20191030224930.3990755-1-jhubbard@nvidia.com> <20191030224930.3990755-6-jhubbard@nvidia.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191030224930.3990755-6-jhubbard@nvidia.com> User-Agent: Mutt/1.11.1 (2018-12-01) Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org On Wed, Oct 30, 2019 at 03:49:16PM -0700, John Hubbard wrote: > Introduce pin_user_pages*() variations of get_user_pages*() calls, > and also pin_longterm_pages*() variations. > > These variants all set FOLL_PIN, which is also introduced, and > basically documented. (An upcoming patch provides more extensive > documentation.) The second set (pin_longterm*) also sets > FOLL_LONGTERM: > > pin_user_pages() > pin_user_pages_remote() > pin_user_pages_fast() > > pin_longterm_pages() > pin_longterm_pages_remote() > pin_longterm_pages_fast() > > All pages that are pinned via the above calls, must be unpinned via > put_user_page(). > > The underlying rules are: > > * These are gup-internal flags, so the call sites should not directly > set FOLL_PIN nor FOLL_LONGTERM. That behavior is enforced with > assertions, for the new FOLL_PIN flag. However, for the pre-existing > FOLL_LONGTERM flag, which has some call sites that still directly > set FOLL_LONGTERM, there is no assertion yet. > > * Call sites that want to indicate that they are going to do DirectIO > ("DIO") or something with similar characteristics, should call a > get_user_pages()-like wrapper call that sets FOLL_PIN. These wrappers > will: > * Start with "pin_user_pages" instead of "get_user_pages". That > makes it easy to find and audit the call sites. > * Set FOLL_PIN > > * For pages that are received via FOLL_PIN, those pages must be returned > via put_user_page(). > > Signed-off-by: John Hubbard > --- > include/linux/mm.h | 53 ++++++++- > mm/gup.c | 284 +++++++++++++++++++++++++++++++++++++++++---- > 2 files changed, 311 insertions(+), 26 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index cc292273e6ba..62c838a3e6c7 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1526,9 +1526,23 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas, int *locked); > +long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked); > +long pin_longterm_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked); > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas); > +long pin_user_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas); > +long pin_longterm_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas); > long get_user_pages_locked(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, int *locked); > long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > @@ -1536,6 +1550,10 @@ long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > > int get_user_pages_fast(unsigned long start, int nr_pages, > unsigned int gup_flags, struct page **pages); > +int pin_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages); > +int pin_longterm_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages); > > int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); > int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, > @@ -2594,13 +2612,15 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, > #define FOLL_ANON 0x8000 /* don't do file mappings */ > #define FOLL_LONGTERM 0x10000 /* mapping lifetime is indefinite: see below */ > #define FOLL_SPLIT_PMD 0x20000 /* split huge pmd before returning */ > +#define FOLL_PIN 0x40000 /* pages must be released via put_user_page() */ > > /* > - * NOTE on FOLL_LONGTERM: > + * FOLL_PIN and FOLL_LONGTERM may be used in various combinations with each > + * other. Here is what they mean, and how to use them: > * > * FOLL_LONGTERM indicates that the page will be held for an indefinite time > - * period _often_ under userspace control. This is contrasted with > - * iov_iter_get_pages() where usages which are transient. > + * period _often_ under userspace control. This is in contrast to > + * iov_iter_get_pages(), where usages which are transient. > * > * FIXME: For pages which are part of a filesystem, mappings are subject to the > * lifetime enforced by the filesystem and we need guarantees that longterm > @@ -2615,11 +2635,32 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, > * Currently only get_user_pages() and get_user_pages_fast() support this flag > * and calls to get_user_pages_[un]locked are specifically not allowed. This > * is due to an incompatibility with the FS DAX check and > - * FAULT_FLAG_ALLOW_RETRY > + * FAULT_FLAG_ALLOW_RETRY. > * > - * In the CMA case: longterm pins in a CMA region would unnecessarily fragment > - * that region. And so CMA attempts to migrate the page before pinning when > + * In the CMA case: long term pins in a CMA region would unnecessarily fragment > + * that region. And so, CMA attempts to migrate the page before pinning, when > * FOLL_LONGTERM is specified. > + * > + * FOLL_PIN indicates that a special kind of tracking (not just page->_refcount, > + * but an additional pin counting system) will be invoked. This is intended for > + * anything that gets a page reference and then touches page data (for example, > + * Direct IO). This lets the filesystem know that some non-file-system entity is > + * potentially changing the pages' data. In contrast to FOLL_GET (whose pages > + * are released via put_page()), FOLL_PIN pages must be released, ultimately, by > + * a call to put_user_page(). > + * > + * FOLL_PIN is similar to FOLL_GET: both of these pin pages. They use different > + * and separate refcounting mechanisms, however, and that means that each has > + * its own acquire and release mechanisms: > + * > + * FOLL_GET: get_user_pages*() to acquire, and put_page() to release. > + * > + * FOLL_PIN: pin_user_pages*() or pin_longterm_pages*() to acquire, and > + * put_user_pages to release. > + * > + * FOLL_PIN and FOLL_GET are mutually exclusive. You mean the flags are mutually exclusive for any single call, correct? Because my first thought was that you meant that a page which was pin'ed can't be "got". Which I don't think is true or necessary... > + * > + * Please see Documentation/vm/pin_user_pages.rst for more information. NIT: I think we should include this file as part of this patch... > */ > > static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags) > diff --git a/mm/gup.c b/mm/gup.c > index 8fb0d9cdfaf5..8694bc7b3df3 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -179,6 +179,10 @@ static struct page *follow_page_pte(struct vm_area_struct *vma, > spinlock_t *ptl; > pte_t *ptep, pte; > > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) == > + (FOLL_PIN | FOLL_GET))) > + return ERR_PTR(-EINVAL); > retry: > if (unlikely(pmd_bad(*pmd))) > return no_page_table(vma, flags); > @@ -790,7 +794,7 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, > > start = untagged_addr(start); > > - VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET)); > + VM_BUG_ON(!!pages != !!(gup_flags & (FOLL_GET | FOLL_PIN))); > > /* > * If FOLL_FORCE is set then do not force a full fault as the hinting > @@ -1014,7 +1018,16 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, > BUG_ON(*locked != 1); > } > > - if (pages) > + /* > + * FOLL_PIN and FOLL_GET are mutually exclusive. Traditional behavior > + * is to set FOLL_GET if the caller wants pages[] filled in (but has > + * carelessly failed to specify FOLL_GET), so keep doing that, but only > + * for FOLL_GET, not for the newer FOLL_PIN. > + * > + * FOLL_PIN always expects pages to be non-null, but no need to assert > + * that here, as any failures will be obvious enough. > + */ > + if (pages && !(flags & FOLL_PIN)) > flags |= FOLL_GET; > > pages_done = 0; > @@ -1133,6 +1146,12 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, > * is written to, set_page_dirty (or set_page_dirty_lock, as appropriate) must > * be called after the page is finished with, and before put_page is called. > * > + * A note on gup_flags: FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the caller. > + * That's in order to help avoid mismatches when releasing pages: > + * get_user_pages*() pages must be released via put_page(), while > + * pin_user_pages*() pages must be released via put_user_page(). > + * > * get_user_pages is typically used for fewer-copy IO operations, to get a > * handle on the memory by some means other than accesses via the user virtual > * addresses. The pages may be submitted for DMA to devices or accessed via > @@ -1151,6 +1170,14 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas, int *locked) > { > + /* > + * As detailed above, FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the > + * caller, so enforce that with an assertion: > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) > + return -EINVAL; > + > /* > * FIXME: Current FOLL_LONGTERM behavior is incompatible with > * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on > @@ -1603,11 +1630,25 @@ static __always_inline long __gup_longterm_locked(struct task_struct *tsk, > * and mm being operated on are the current task's and don't allow > * passing of a locked parameter. We also obviously don't pass > * FOLL_REMOTE in here. > + * > + * A note on gup_flags: FOLL_PIN should only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the caller. > + * That's in order to help avoid mismatches when releasing pages: > + * get_user_pages*() pages must be released via put_page(), while > + * pin_user_pages*() pages must be released via put_user_page(). Rather than put this here should we put it next to the definition of FOLL_PIN? Because now we have this text 2x... :-/ > */ > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas) > { > + /* > + * As detailed above, FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the > + * caller, so enforce that with an assertion: > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) > + return -EINVAL; > + > return __gup_longterm_locked(current, current->mm, start, nr_pages, > pages, vmas, gup_flags | FOLL_TOUCH); > } > @@ -2366,24 +2407,9 @@ static int __gup_longterm_unlocked(unsigned long start, int nr_pages, > return ret; > } > > -/** > - * get_user_pages_fast() - pin user pages in memory > - * @start: starting user address > - * @nr_pages: number of pages from start to pin > - * @gup_flags: flags modifying pin behaviour > - * @pages: array that receives pointers to the pages pinned. > - * Should be at least nr_pages long. > - * > - * Attempt to pin user pages in memory without taking mm->mmap_sem. > - * If not successful, it will fall back to taking the lock and > - * calling get_user_pages(). > - * > - * Returns number of pages pinned. This may be fewer than the number > - * requested. If nr_pages is 0 or negative, returns 0. If no pages > - * were pinned, returns -errno. > - */ > -int get_user_pages_fast(unsigned long start, int nr_pages, > - unsigned int gup_flags, struct page **pages) > +static int internal_get_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, > + struct page **pages) > { > unsigned long addr, len, end; > int nr = 0, ret = 0; > @@ -2428,4 +2454,222 @@ int get_user_pages_fast(unsigned long start, int nr_pages, > > return ret; > } > + > +/** > + * get_user_pages_fast() - pin user pages in memory > + * @start: starting user address > + * @nr_pages: number of pages from start to pin > + * @gup_flags: flags modifying pin behaviour > + * @pages: array that receives pointers to the pages pinned. > + * Should be at least nr_pages long. > + * > + * Attempt to pin user pages in memory without taking mm->mmap_sem. > + * If not successful, it will fall back to taking the lock and > + * calling get_user_pages(). > + * > + * A note on gup_flags: FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the caller. > + * That's in order to help avoid mismatches when releasing pages: > + * get_user_pages*() pages must be released via put_page(), while > + * pin_user_pages*() pages must be released via put_user_page(). > + * > + * Returns number of pages pinned. This may be fewer than the number requested. > + * If nr_pages is 0 or negative, returns 0. If no pages were pinned, returns > + * -errno. > + */ > +int get_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages) > +{ > + /* > + * As detailed above, FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the > + * caller, so enforce that: > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) > + return -EINVAL; > + > + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); > +} > EXPORT_SYMBOL_GPL(get_user_pages_fast); > + > +/** > + * pin_user_pages_fast() - pin user pages in memory without taking locks > + * > + * Nearly the same as get_user_pages_fast(), except that FOLL_PIN is set. See > + * get_user_pages_fast() for documentation on the function arguments, because > + * the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It > + * is NOT intended for Case 2 (RDMA: long-term pins). > + */ > +int pin_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN; > + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); > +} > +EXPORT_SYMBOL_GPL(pin_user_pages_fast); > + > +/** > + * pin_longterm_pages_fast() - pin user pages in memory without taking locks > + * > + * Nearly the same as get_user_pages_fast(), except that FOLL_PIN and > + * FOLL_LONGTERM are set. See get_user_pages_fast() for documentation on the > + * function arguments, because the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * FOLL_LONGTERM means that the pages are being pinned for "long term" use, > + * typically by a non-CPU device, and we cannot be sure that waiting for a > + * pinned page to become unpin will be effective. > + * > + * This is intended for Case 2 (RDMA: long-term pins) of the FOLL_PIN > + * documentation. > + */ > +int pin_longterm_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= (FOLL_PIN | FOLL_LONGTERM); > + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); > +} > +EXPORT_SYMBOL_GPL(pin_longterm_pages_fast); > + > +/** > + * pin_user_pages_remote() - pin pages for (typically) use by Direct IO, and > + * return the pages to the user. > + * > + * Nearly the same as get_user_pages_remote(), except that FOLL_PIN is set. See > + * get_user_pages_remote() for documentation on the function arguments, because > + * the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for details. > + * > + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It > + * is NOT intended for Case 2 (RDMA: long-term pins). > + */ > +long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_TOUCH | FOLL_REMOTE | FOLL_PIN; > + > + return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, > + locked, gup_flags); > +} > +EXPORT_SYMBOL(pin_user_pages_remote); > + > +/** > + * pin_longterm_pages_remote() - pin pages for (typically) use by Direct IO, and > + * return the pages to the user. > + * > + * Nearly the same as get_user_pages_remote(), but note that FOLL_TOUCH is not > + * set, and FOLL_PIN and FOLL_LONGTERM are set. See get_user_pages_remote() for > + * documentation on the function arguments, because the arguments here are > + * identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * FOLL_LONGTERM means that the pages are being pinned for "long term" use, > + * typically by a non-CPU device, and we cannot be sure that waiting for a > + * pinned page to become unpin will be effective. > + * > + * This is intended for Case 2 (RDMA: long-term pins) in > + * Documentation/vm/pin_user_pages.rst. > + */ > +long pin_longterm_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + /* > + * FIXME: as noted in the get_user_pages_remote() implementation, it > + * is not yet possible to safely set FOLL_LONGTERM here. FOLL_LONGTERM > + * needs to be set, but for now the best we can do is a "TODO" item. > + */ Wait? Why can't we set FOLL_LONGTERM here? pin_* are new calls which are not used yet right? You set it in the other new pin_* functions? Ira > + gup_flags |= FOLL_REMOTE | FOLL_PIN; > + > + return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, > + locked, gup_flags); > +} > +EXPORT_SYMBOL(pin_longterm_pages_remote); > + > +/** > + * pin_user_pages() - pin user pages in memory for use by other devices > + * > + * Nearly the same as get_user_pages(), except that FOLL_TOUCH is not set, and > + * FOLL_PIN is set. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for details. > + * > + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It > + * is NOT intended for Case 2 (RDMA: long-term pins). > + */ > +long pin_user_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN; > + return __gup_longterm_locked(current, current->mm, start, nr_pages, > + pages, vmas, gup_flags); > +} > +EXPORT_SYMBOL(pin_user_pages); > + > +/** > + * pin_longterm_pages() - pin user pages in memory for long-term use (RDMA, > + * typically) > + * > + * Nearly the same as get_user_pages(), except that FOLL_PIN and FOLL_LONGTERM > + * are set. See get_user_pages_fast() for documentation on the function > + * arguments, because the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * FOLL_LONGTERM means that the pages are being pinned for "long term" use, > + * typically by a non-CPU device, and we cannot be sure that waiting for a > + * pinned page to become unpin will be effective. > + * > + * This is intended for Case 2 (RDMA: long-term pins) in > + * Documentation/vm/pin_user_pages.rst. > + */ > +long pin_longterm_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN | FOLL_LONGTERM; > + return __gup_longterm_locked(current, current->mm, start, nr_pages, > + pages, vmas, gup_flags); > +} > +EXPORT_SYMBOL(pin_longterm_pages); > -- > 2.23.0 > 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=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,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 6FC17CA9ECB for ; Thu, 31 Oct 2019 23:17:44 +0000 (UTC) Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (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 8A4132080F for ; Thu, 31 Oct 2019 23:17:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8A4132080F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=linuxppc-dev-bounces+linuxppc-dev=archiver.kernel.org@lists.ozlabs.org Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4741Sj008RzF5LZ for ; Fri, 1 Nov 2019 10:17:40 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=intel.com (client-ip=192.55.52.120; helo=mga04.intel.com; envelope-from=ira.weiny@intel.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=intel.com Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4741Py2TCGzF6Fr for ; Fri, 1 Nov 2019 10:15:12 +1100 (AEDT) X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Oct 2019 16:15:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,253,1569308400"; d="scan'208";a="225867978" Received: from iweiny-desk2.sc.intel.com ([10.3.52.157]) by fmsmga004.fm.intel.com with ESMTP; 31 Oct 2019 16:15:04 -0700 Date: Thu, 31 Oct 2019 16:15:04 -0700 From: Ira Weiny To: John Hubbard Subject: Re: [PATCH 05/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN Message-ID: <20191031231503.GF14771@iweiny-DESK2.sc.intel.com> References: <20191030224930.3990755-1-jhubbard@nvidia.com> <20191030224930.3990755-6-jhubbard@nvidia.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191030224930.3990755-6-jhubbard@nvidia.com> User-Agent: Mutt/1.11.1 (2018-12-01) X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michal Hocko , Jan Kara , kvm@vger.kernel.org, linux-doc@vger.kernel.org, David Airlie , Dave Chinner , dri-devel@lists.freedesktop.org, LKML , linux-mm@kvack.org, Paul Mackerras , linux-kselftest@vger.kernel.org, Shuah Khan , Jonathan Corbet , linux-rdma@vger.kernel.org, Christoph Hellwig , Jason Gunthorpe , Vlastimil Babka , =?iso-8859-1?Q?Bj=F6rn_T=F6pel?= , linux-media@vger.kernel.org, linux-block@vger.kernel.org, =?iso-8859-1?B?Suly9G1l?= Glisse , Al Viro , Dan Williams , Mauro Carvalho Chehab , bpf@vger.kernel.org, Magnus Karlsson , Jens Axboe , netdev@vger.kernel.org, Alex Williamson , Daniel Vetter , linux-fsdevel@vger.kernel.org, Andrew Morton , linuxppc-dev@lists.ozlabs.org, "David S . Miller" , Mike Kravetz Errors-To: linuxppc-dev-bounces+linuxppc-dev=archiver.kernel.org@lists.ozlabs.org Sender: "Linuxppc-dev" On Wed, Oct 30, 2019 at 03:49:16PM -0700, John Hubbard wrote: > Introduce pin_user_pages*() variations of get_user_pages*() calls, > and also pin_longterm_pages*() variations. > > These variants all set FOLL_PIN, which is also introduced, and > basically documented. (An upcoming patch provides more extensive > documentation.) The second set (pin_longterm*) also sets > FOLL_LONGTERM: > > pin_user_pages() > pin_user_pages_remote() > pin_user_pages_fast() > > pin_longterm_pages() > pin_longterm_pages_remote() > pin_longterm_pages_fast() > > All pages that are pinned via the above calls, must be unpinned via > put_user_page(). > > The underlying rules are: > > * These are gup-internal flags, so the call sites should not directly > set FOLL_PIN nor FOLL_LONGTERM. That behavior is enforced with > assertions, for the new FOLL_PIN flag. However, for the pre-existing > FOLL_LONGTERM flag, which has some call sites that still directly > set FOLL_LONGTERM, there is no assertion yet. > > * Call sites that want to indicate that they are going to do DirectIO > ("DIO") or something with similar characteristics, should call a > get_user_pages()-like wrapper call that sets FOLL_PIN. These wrappers > will: > * Start with "pin_user_pages" instead of "get_user_pages". That > makes it easy to find and audit the call sites. > * Set FOLL_PIN > > * For pages that are received via FOLL_PIN, those pages must be returned > via put_user_page(). > > Signed-off-by: John Hubbard > --- > include/linux/mm.h | 53 ++++++++- > mm/gup.c | 284 +++++++++++++++++++++++++++++++++++++++++---- > 2 files changed, 311 insertions(+), 26 deletions(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index cc292273e6ba..62c838a3e6c7 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -1526,9 +1526,23 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas, int *locked); > +long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked); > +long pin_longterm_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked); > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas); > +long pin_user_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas); > +long pin_longterm_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas); > long get_user_pages_locked(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, int *locked); > long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > @@ -1536,6 +1550,10 @@ long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, > > int get_user_pages_fast(unsigned long start, int nr_pages, > unsigned int gup_flags, struct page **pages); > +int pin_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages); > +int pin_longterm_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages); > > int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); > int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, > @@ -2594,13 +2612,15 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, > #define FOLL_ANON 0x8000 /* don't do file mappings */ > #define FOLL_LONGTERM 0x10000 /* mapping lifetime is indefinite: see below */ > #define FOLL_SPLIT_PMD 0x20000 /* split huge pmd before returning */ > +#define FOLL_PIN 0x40000 /* pages must be released via put_user_page() */ > > /* > - * NOTE on FOLL_LONGTERM: > + * FOLL_PIN and FOLL_LONGTERM may be used in various combinations with each > + * other. Here is what they mean, and how to use them: > * > * FOLL_LONGTERM indicates that the page will be held for an indefinite time > - * period _often_ under userspace control. This is contrasted with > - * iov_iter_get_pages() where usages which are transient. > + * period _often_ under userspace control. This is in contrast to > + * iov_iter_get_pages(), where usages which are transient. > * > * FIXME: For pages which are part of a filesystem, mappings are subject to the > * lifetime enforced by the filesystem and we need guarantees that longterm > @@ -2615,11 +2635,32 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, > * Currently only get_user_pages() and get_user_pages_fast() support this flag > * and calls to get_user_pages_[un]locked are specifically not allowed. This > * is due to an incompatibility with the FS DAX check and > - * FAULT_FLAG_ALLOW_RETRY > + * FAULT_FLAG_ALLOW_RETRY. > * > - * In the CMA case: longterm pins in a CMA region would unnecessarily fragment > - * that region. And so CMA attempts to migrate the page before pinning when > + * In the CMA case: long term pins in a CMA region would unnecessarily fragment > + * that region. And so, CMA attempts to migrate the page before pinning, when > * FOLL_LONGTERM is specified. > + * > + * FOLL_PIN indicates that a special kind of tracking (not just page->_refcount, > + * but an additional pin counting system) will be invoked. This is intended for > + * anything that gets a page reference and then touches page data (for example, > + * Direct IO). This lets the filesystem know that some non-file-system entity is > + * potentially changing the pages' data. In contrast to FOLL_GET (whose pages > + * are released via put_page()), FOLL_PIN pages must be released, ultimately, by > + * a call to put_user_page(). > + * > + * FOLL_PIN is similar to FOLL_GET: both of these pin pages. They use different > + * and separate refcounting mechanisms, however, and that means that each has > + * its own acquire and release mechanisms: > + * > + * FOLL_GET: get_user_pages*() to acquire, and put_page() to release. > + * > + * FOLL_PIN: pin_user_pages*() or pin_longterm_pages*() to acquire, and > + * put_user_pages to release. > + * > + * FOLL_PIN and FOLL_GET are mutually exclusive. You mean the flags are mutually exclusive for any single call, correct? Because my first thought was that you meant that a page which was pin'ed can't be "got". Which I don't think is true or necessary... > + * > + * Please see Documentation/vm/pin_user_pages.rst for more information. NIT: I think we should include this file as part of this patch... > */ > > static inline int vm_fault_to_errno(vm_fault_t vm_fault, int foll_flags) > diff --git a/mm/gup.c b/mm/gup.c > index 8fb0d9cdfaf5..8694bc7b3df3 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -179,6 +179,10 @@ static struct page *follow_page_pte(struct vm_area_struct *vma, > spinlock_t *ptl; > pte_t *ptep, pte; > > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) == > + (FOLL_PIN | FOLL_GET))) > + return ERR_PTR(-EINVAL); > retry: > if (unlikely(pmd_bad(*pmd))) > return no_page_table(vma, flags); > @@ -790,7 +794,7 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, > > start = untagged_addr(start); > > - VM_BUG_ON(!!pages != !!(gup_flags & FOLL_GET)); > + VM_BUG_ON(!!pages != !!(gup_flags & (FOLL_GET | FOLL_PIN))); > > /* > * If FOLL_FORCE is set then do not force a full fault as the hinting > @@ -1014,7 +1018,16 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, > BUG_ON(*locked != 1); > } > > - if (pages) > + /* > + * FOLL_PIN and FOLL_GET are mutually exclusive. Traditional behavior > + * is to set FOLL_GET if the caller wants pages[] filled in (but has > + * carelessly failed to specify FOLL_GET), so keep doing that, but only > + * for FOLL_GET, not for the newer FOLL_PIN. > + * > + * FOLL_PIN always expects pages to be non-null, but no need to assert > + * that here, as any failures will be obvious enough. > + */ > + if (pages && !(flags & FOLL_PIN)) > flags |= FOLL_GET; > > pages_done = 0; > @@ -1133,6 +1146,12 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk, > * is written to, set_page_dirty (or set_page_dirty_lock, as appropriate) must > * be called after the page is finished with, and before put_page is called. > * > + * A note on gup_flags: FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the caller. > + * That's in order to help avoid mismatches when releasing pages: > + * get_user_pages*() pages must be released via put_page(), while > + * pin_user_pages*() pages must be released via put_user_page(). > + * > * get_user_pages is typically used for fewer-copy IO operations, to get a > * handle on the memory by some means other than accesses via the user virtual > * addresses. The pages may be submitted for DMA to devices or accessed via > @@ -1151,6 +1170,14 @@ long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas, int *locked) > { > + /* > + * As detailed above, FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the > + * caller, so enforce that with an assertion: > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) > + return -EINVAL; > + > /* > * FIXME: Current FOLL_LONGTERM behavior is incompatible with > * FAULT_FLAG_ALLOW_RETRY because of the FS DAX check requirement on > @@ -1603,11 +1630,25 @@ static __always_inline long __gup_longterm_locked(struct task_struct *tsk, > * and mm being operated on are the current task's and don't allow > * passing of a locked parameter. We also obviously don't pass > * FOLL_REMOTE in here. > + * > + * A note on gup_flags: FOLL_PIN should only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the caller. > + * That's in order to help avoid mismatches when releasing pages: > + * get_user_pages*() pages must be released via put_page(), while > + * pin_user_pages*() pages must be released via put_user_page(). Rather than put this here should we put it next to the definition of FOLL_PIN? Because now we have this text 2x... :-/ > */ > long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas) > { > + /* > + * As detailed above, FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the > + * caller, so enforce that with an assertion: > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) > + return -EINVAL; > + > return __gup_longterm_locked(current, current->mm, start, nr_pages, > pages, vmas, gup_flags | FOLL_TOUCH); > } > @@ -2366,24 +2407,9 @@ static int __gup_longterm_unlocked(unsigned long start, int nr_pages, > return ret; > } > > -/** > - * get_user_pages_fast() - pin user pages in memory > - * @start: starting user address > - * @nr_pages: number of pages from start to pin > - * @gup_flags: flags modifying pin behaviour > - * @pages: array that receives pointers to the pages pinned. > - * Should be at least nr_pages long. > - * > - * Attempt to pin user pages in memory without taking mm->mmap_sem. > - * If not successful, it will fall back to taking the lock and > - * calling get_user_pages(). > - * > - * Returns number of pages pinned. This may be fewer than the number > - * requested. If nr_pages is 0 or negative, returns 0. If no pages > - * were pinned, returns -errno. > - */ > -int get_user_pages_fast(unsigned long start, int nr_pages, > - unsigned int gup_flags, struct page **pages) > +static int internal_get_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, > + struct page **pages) > { > unsigned long addr, len, end; > int nr = 0, ret = 0; > @@ -2428,4 +2454,222 @@ int get_user_pages_fast(unsigned long start, int nr_pages, > > return ret; > } > + > +/** > + * get_user_pages_fast() - pin user pages in memory > + * @start: starting user address > + * @nr_pages: number of pages from start to pin > + * @gup_flags: flags modifying pin behaviour > + * @pages: array that receives pointers to the pages pinned. > + * Should be at least nr_pages long. > + * > + * Attempt to pin user pages in memory without taking mm->mmap_sem. > + * If not successful, it will fall back to taking the lock and > + * calling get_user_pages(). > + * > + * A note on gup_flags: FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the caller. > + * That's in order to help avoid mismatches when releasing pages: > + * get_user_pages*() pages must be released via put_page(), while > + * pin_user_pages*() pages must be released via put_user_page(). > + * > + * Returns number of pages pinned. This may be fewer than the number requested. > + * If nr_pages is 0 or negative, returns 0. If no pages were pinned, returns > + * -errno. > + */ > +int get_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages) > +{ > + /* > + * As detailed above, FOLL_PIN must only be set internally by the > + * pin_user_page*() and pin_longterm_*() APIs, never directly by the > + * caller, so enforce that: > + */ > + if (WARN_ON_ONCE(gup_flags & FOLL_PIN)) > + return -EINVAL; > + > + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); > +} > EXPORT_SYMBOL_GPL(get_user_pages_fast); > + > +/** > + * pin_user_pages_fast() - pin user pages in memory without taking locks > + * > + * Nearly the same as get_user_pages_fast(), except that FOLL_PIN is set. See > + * get_user_pages_fast() for documentation on the function arguments, because > + * the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It > + * is NOT intended for Case 2 (RDMA: long-term pins). > + */ > +int pin_user_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN; > + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); > +} > +EXPORT_SYMBOL_GPL(pin_user_pages_fast); > + > +/** > + * pin_longterm_pages_fast() - pin user pages in memory without taking locks > + * > + * Nearly the same as get_user_pages_fast(), except that FOLL_PIN and > + * FOLL_LONGTERM are set. See get_user_pages_fast() for documentation on the > + * function arguments, because the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * FOLL_LONGTERM means that the pages are being pinned for "long term" use, > + * typically by a non-CPU device, and we cannot be sure that waiting for a > + * pinned page to become unpin will be effective. > + * > + * This is intended for Case 2 (RDMA: long-term pins) of the FOLL_PIN > + * documentation. > + */ > +int pin_longterm_pages_fast(unsigned long start, int nr_pages, > + unsigned int gup_flags, struct page **pages) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= (FOLL_PIN | FOLL_LONGTERM); > + return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages); > +} > +EXPORT_SYMBOL_GPL(pin_longterm_pages_fast); > + > +/** > + * pin_user_pages_remote() - pin pages for (typically) use by Direct IO, and > + * return the pages to the user. > + * > + * Nearly the same as get_user_pages_remote(), except that FOLL_PIN is set. See > + * get_user_pages_remote() for documentation on the function arguments, because > + * the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for details. > + * > + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It > + * is NOT intended for Case 2 (RDMA: long-term pins). > + */ > +long pin_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_TOUCH | FOLL_REMOTE | FOLL_PIN; > + > + return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, > + locked, gup_flags); > +} > +EXPORT_SYMBOL(pin_user_pages_remote); > + > +/** > + * pin_longterm_pages_remote() - pin pages for (typically) use by Direct IO, and > + * return the pages to the user. > + * > + * Nearly the same as get_user_pages_remote(), but note that FOLL_TOUCH is not > + * set, and FOLL_PIN and FOLL_LONGTERM are set. See get_user_pages_remote() for > + * documentation on the function arguments, because the arguments here are > + * identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * FOLL_LONGTERM means that the pages are being pinned for "long term" use, > + * typically by a non-CPU device, and we cannot be sure that waiting for a > + * pinned page to become unpin will be effective. > + * > + * This is intended for Case 2 (RDMA: long-term pins) in > + * Documentation/vm/pin_user_pages.rst. > + */ > +long pin_longterm_pages_remote(struct task_struct *tsk, struct mm_struct *mm, > + unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas, int *locked) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + /* > + * FIXME: as noted in the get_user_pages_remote() implementation, it > + * is not yet possible to safely set FOLL_LONGTERM here. FOLL_LONGTERM > + * needs to be set, but for now the best we can do is a "TODO" item. > + */ Wait? Why can't we set FOLL_LONGTERM here? pin_* are new calls which are not used yet right? You set it in the other new pin_* functions? Ira > + gup_flags |= FOLL_REMOTE | FOLL_PIN; > + > + return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas, > + locked, gup_flags); > +} > +EXPORT_SYMBOL(pin_longterm_pages_remote); > + > +/** > + * pin_user_pages() - pin user pages in memory for use by other devices > + * > + * Nearly the same as get_user_pages(), except that FOLL_TOUCH is not set, and > + * FOLL_PIN is set. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for details. > + * > + * This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It > + * is NOT intended for Case 2 (RDMA: long-term pins). > + */ > +long pin_user_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN; > + return __gup_longterm_locked(current, current->mm, start, nr_pages, > + pages, vmas, gup_flags); > +} > +EXPORT_SYMBOL(pin_user_pages); > + > +/** > + * pin_longterm_pages() - pin user pages in memory for long-term use (RDMA, > + * typically) > + * > + * Nearly the same as get_user_pages(), except that FOLL_PIN and FOLL_LONGTERM > + * are set. See get_user_pages_fast() for documentation on the function > + * arguments, because the arguments here are identical. > + * > + * FOLL_PIN means that the pages must be released via put_user_page(). Please > + * see Documentation/vm/pin_user_pages.rst for further details. > + * > + * FOLL_LONGTERM means that the pages are being pinned for "long term" use, > + * typically by a non-CPU device, and we cannot be sure that waiting for a > + * pinned page to become unpin will be effective. > + * > + * This is intended for Case 2 (RDMA: long-term pins) in > + * Documentation/vm/pin_user_pages.rst. > + */ > +long pin_longterm_pages(unsigned long start, unsigned long nr_pages, > + unsigned int gup_flags, struct page **pages, > + struct vm_area_struct **vmas) > +{ > + /* FOLL_GET and FOLL_PIN are mutually exclusive. */ > + if (WARN_ON_ONCE(gup_flags & FOLL_GET)) > + return -EINVAL; > + > + gup_flags |= FOLL_PIN | FOLL_LONGTERM; > + return __gup_longterm_locked(current, current->mm, start, nr_pages, > + pages, vmas, gup_flags); > +} > +EXPORT_SYMBOL(pin_longterm_pages); > -- > 2.23.0 > From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ira Weiny Subject: Re: [PATCH 05/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN Date: Thu, 31 Oct 2019 16:15:04 -0700 Message-ID: <20191031231503.GF14771@iweiny-DESK2.sc.intel.com> References: <20191030224930.3990755-1-jhubbard@nvidia.com> <20191030224930.3990755-6-jhubbard@nvidia.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 880D56F686 for ; Thu, 31 Oct 2019 23:15:11 +0000 (UTC) Content-Disposition: inline In-Reply-To: <20191030224930.3990755-6-jhubbard@nvidia.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: John Hubbard Cc: Michal Hocko , Jan Kara , kvm@vger.kernel.org, linux-doc@vger.kernel.org, David Airlie , Dave Chinner , dri-devel@lists.freedesktop.org, LKML , linux-mm@kvack.org, Paul Mackerras , linux-kselftest@vger.kernel.org, Shuah Khan , Jonathan Corbet , linux-rdma@vger.kernel.org, Michael Ellerman , Christoph Hellwig , Jason Gunthorpe , Vlastimil Babka , =?iso-8859-1?Q?Bj=F6rn_T=F6pel?= , linux-media@vger.kernel.org, linux-block@vger.kernel.org, =?iso-8859-1?B?Suly9G1l?= Glisse , Al Viro , Dan Williams , Mauro Carvalho Chehab , bpf@vger.kernel.orgM List-Id: dri-devel@lists.freedesktop.org T24gV2VkLCBPY3QgMzAsIDIwMTkgYXQgMDM6NDk6MTZQTSAtMDcwMCwgSm9obiBIdWJiYXJkIHdy b3RlOgo+IEludHJvZHVjZSBwaW5fdXNlcl9wYWdlcyooKSB2YXJpYXRpb25zIG9mIGdldF91c2Vy X3BhZ2VzKigpIGNhbGxzLAo+IGFuZCBhbHNvIHBpbl9sb25ndGVybV9wYWdlcyooKSB2YXJpYXRp b25zLgo+IAo+IFRoZXNlIHZhcmlhbnRzIGFsbCBzZXQgRk9MTF9QSU4sIHdoaWNoIGlzIGFsc28g aW50cm9kdWNlZCwgYW5kCj4gYmFzaWNhbGx5IGRvY3VtZW50ZWQuIChBbiB1cGNvbWluZyBwYXRj aCBwcm92aWRlcyBtb3JlIGV4dGVuc2l2ZQo+IGRvY3VtZW50YXRpb24uKSBUaGUgc2Vjb25kIHNl dCAocGluX2xvbmd0ZXJtKikgYWxzbyBzZXRzCj4gRk9MTF9MT05HVEVSTToKPiAKPiAgICAgcGlu X3VzZXJfcGFnZXMoKQo+ICAgICBwaW5fdXNlcl9wYWdlc19yZW1vdGUoKQo+ICAgICBwaW5fdXNl cl9wYWdlc19mYXN0KCkKPiAKPiAgICAgcGluX2xvbmd0ZXJtX3BhZ2VzKCkKPiAgICAgcGluX2xv bmd0ZXJtX3BhZ2VzX3JlbW90ZSgpCj4gICAgIHBpbl9sb25ndGVybV9wYWdlc19mYXN0KCkKPiAK PiBBbGwgcGFnZXMgdGhhdCBhcmUgcGlubmVkIHZpYSB0aGUgYWJvdmUgY2FsbHMsIG11c3QgYmUg dW5waW5uZWQgdmlhCj4gcHV0X3VzZXJfcGFnZSgpLgo+IAo+IFRoZSB1bmRlcmx5aW5nIHJ1bGVz IGFyZToKPiAKPiAqIFRoZXNlIGFyZSBndXAtaW50ZXJuYWwgZmxhZ3MsIHNvIHRoZSBjYWxsIHNp dGVzIHNob3VsZCBub3QgZGlyZWN0bHkKPiBzZXQgRk9MTF9QSU4gbm9yIEZPTExfTE9OR1RFUk0u IFRoYXQgYmVoYXZpb3IgaXMgZW5mb3JjZWQgd2l0aAo+IGFzc2VydGlvbnMsIGZvciB0aGUgbmV3 IEZPTExfUElOIGZsYWcuIEhvd2V2ZXIsIGZvciB0aGUgcHJlLWV4aXN0aW5nCj4gRk9MTF9MT05H VEVSTSBmbGFnLCB3aGljaCBoYXMgc29tZSBjYWxsIHNpdGVzIHRoYXQgc3RpbGwgZGlyZWN0bHkK PiBzZXQgRk9MTF9MT05HVEVSTSwgdGhlcmUgaXMgbm8gYXNzZXJ0aW9uIHlldC4KPiAKPiAqIENh bGwgc2l0ZXMgdGhhdCB3YW50IHRvIGluZGljYXRlIHRoYXQgdGhleSBhcmUgZ29pbmcgdG8gZG8g RGlyZWN0SU8KPiAgICgiRElPIikgb3Igc29tZXRoaW5nIHdpdGggc2ltaWxhciBjaGFyYWN0ZXJp c3RpY3MsIHNob3VsZCBjYWxsIGEKPiAgIGdldF91c2VyX3BhZ2VzKCktbGlrZSB3cmFwcGVyIGNh bGwgdGhhdCBzZXRzIEZPTExfUElOLiBUaGVzZSB3cmFwcGVycwo+ICAgd2lsbDoKPiAgICAgICAg ICogU3RhcnQgd2l0aCAicGluX3VzZXJfcGFnZXMiIGluc3RlYWQgb2YgImdldF91c2VyX3BhZ2Vz Ii4gVGhhdAo+ICAgICAgICAgICBtYWtlcyBpdCBlYXN5IHRvIGZpbmQgYW5kIGF1ZGl0IHRoZSBj YWxsIHNpdGVzLgo+ICAgICAgICAgKiBTZXQgRk9MTF9QSU4KPiAKPiAqIEZvciBwYWdlcyB0aGF0 IGFyZSByZWNlaXZlZCB2aWEgRk9MTF9QSU4sIHRob3NlIHBhZ2VzIG11c3QgYmUgcmV0dXJuZWQK PiAgIHZpYSBwdXRfdXNlcl9wYWdlKCkuCj4gCj4gU2lnbmVkLW9mZi1ieTogSm9obiBIdWJiYXJk IDxqaHViYmFyZEBudmlkaWEuY29tPgo+IC0tLQo+ICBpbmNsdWRlL2xpbnV4L21tLmggfCAgNTMg KysrKysrKystCj4gIG1tL2d1cC5jICAgICAgICAgICB8IDI4NCArKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKy0tLS0KPiAgMiBmaWxlcyBjaGFuZ2VkLCAzMTEgaW5zZXJ0 aW9ucygrKSwgMjYgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgv bW0uaCBiL2luY2x1ZGUvbGludXgvbW0uaAo+IGluZGV4IGNjMjkyMjczZTZiYS4uNjJjODM4YTNl NmM3IDEwMDY0NAo+IC0tLSBhL2luY2x1ZGUvbGludXgvbW0uaAo+ICsrKyBiL2luY2x1ZGUvbGlu dXgvbW0uaAo+IEBAIC0xNTI2LDkgKzE1MjYsMjMgQEAgbG9uZyBnZXRfdXNlcl9wYWdlc19yZW1v dGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICAJCQkg ICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiAgCQkJICAg IHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gIAkJCSAgICBz dHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzLCBpbnQgKmxvY2tlZCk7Cj4gK2xvbmcgcGluX3Vz ZXJfcGFnZXNfcmVtb3RlKHN0cnVjdCB0YXNrX3N0cnVjdCAqdHNrLCBzdHJ1Y3QgbW1fc3RydWN0 ICptbSwKPiArCQkJICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdl cywKPiArCQkJICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywK PiArCQkJICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcywgaW50ICpsb2NrZWQpOwo+ICts b25nIHBpbl9sb25ndGVybV9wYWdlc19yZW1vdGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0 cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICsJCQkgICAgICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5z aWduZWQgbG9uZyBucl9wYWdlcywKPiArCQkJICAgICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3Ms IHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gKwkJCSAgICAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3Qg Kip2bWFzLCBpbnQgKmxvY2tlZCk7Cj4gIGxvbmcgZ2V0X3VzZXJfcGFnZXModW5zaWduZWQgbG9u ZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiAgCQkJICAgIHVuc2lnbmVkIGludCBn dXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gIAkJCSAgICBzdHJ1Y3Qgdm1fYXJlYV9z dHJ1Y3QgKip2bWFzKTsKPiArbG9uZyBwaW5fdXNlcl9wYWdlcyh1bnNpZ25lZCBsb25nIHN0YXJ0 LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICsJCSAgICB1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdz LCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAo+ICsJCSAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2 bWFzKTsKPiArbG9uZyBwaW5fbG9uZ3Rlcm1fcGFnZXModW5zaWduZWQgbG9uZyBzdGFydCwgdW5z aWduZWQgbG9uZyBucl9wYWdlcywKPiArCQkJdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0 IHBhZ2UgKipwYWdlcywKPiArCQkJc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcyk7Cj4gIGxv bmcgZ2V0X3VzZXJfcGFnZXNfbG9ja2VkKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxv bmcgbnJfcGFnZXMsCj4gIAkJICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdl ICoqcGFnZXMsIGludCAqbG9ja2VkKTsKPiAgbG9uZyBnZXRfdXNlcl9wYWdlc191bmxvY2tlZCh1 bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+IEBAIC0xNTM2LDYg KzE1NTAsMTAgQEAgbG9uZyBnZXRfdXNlcl9wYWdlc191bmxvY2tlZCh1bnNpZ25lZCBsb25nIHN0 YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICAKPiAgaW50IGdldF91c2VyX3BhZ2VzX2Zh c3QodW5zaWduZWQgbG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICAJCQl1bnNpZ25lZCBpbnQg Z3VwX2ZsYWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKPiAraW50IHBpbl91c2VyX3BhZ2VzX2Zh c3QodW5zaWduZWQgbG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICsJCQl1bnNpZ25lZCBpbnQg Z3VwX2ZsYWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKPiAraW50IHBpbl9sb25ndGVybV9wYWdl c19mYXN0KHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBucl9wYWdlcywKPiArCQkJICAgIHVuc2ln bmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMpOwo+ICAKPiAgaW50IGFjY291 bnRfbG9ja2VkX3ZtKHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLCB1bnNpZ25lZCBsb25nIHBhZ2VzLCBi b29sIGluYyk7Cj4gIGludCBfX2FjY291bnRfbG9ja2VkX3ZtKHN0cnVjdCBtbV9zdHJ1Y3QgKm1t LCB1bnNpZ25lZCBsb25nIHBhZ2VzLCBib29sIGluYywKPiBAQCAtMjU5NCwxMyArMjYxMiwxNSBA QCBzdHJ1Y3QgcGFnZSAqZm9sbG93X3BhZ2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVu c2lnbmVkIGxvbmcgYWRkcmVzcywKPiAgI2RlZmluZSBGT0xMX0FOT04JMHg4MDAwCS8qIGRvbid0 IGRvIGZpbGUgbWFwcGluZ3MgKi8KPiAgI2RlZmluZSBGT0xMX0xPTkdURVJNCTB4MTAwMDAJLyog bWFwcGluZyBsaWZldGltZSBpcyBpbmRlZmluaXRlOiBzZWUgYmVsb3cgKi8KPiAgI2RlZmluZSBG T0xMX1NQTElUX1BNRAkweDIwMDAwCS8qIHNwbGl0IGh1Z2UgcG1kIGJlZm9yZSByZXR1cm5pbmcg Ki8KPiArI2RlZmluZSBGT0xMX1BJTgkweDQwMDAwCS8qIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQg dmlhIHB1dF91c2VyX3BhZ2UoKSAqLwo+ICAKPiAgLyoKPiAtICogTk9URSBvbiBGT0xMX0xPTkdU RVJNOgo+ICsgKiBGT0xMX1BJTiBhbmQgRk9MTF9MT05HVEVSTSBtYXkgYmUgdXNlZCBpbiB2YXJp b3VzIGNvbWJpbmF0aW9ucyB3aXRoIGVhY2gKPiArICogb3RoZXIuIEhlcmUgaXMgd2hhdCB0aGV5 IG1lYW4sIGFuZCBob3cgdG8gdXNlIHRoZW06Cj4gICAqCj4gICAqIEZPTExfTE9OR1RFUk0gaW5k aWNhdGVzIHRoYXQgdGhlIHBhZ2Ugd2lsbCBiZSBoZWxkIGZvciBhbiBpbmRlZmluaXRlIHRpbWUK PiAtICogcGVyaW9kIF9vZnRlbl8gdW5kZXIgdXNlcnNwYWNlIGNvbnRyb2wuICBUaGlzIGlzIGNv bnRyYXN0ZWQgd2l0aAo+IC0gKiBpb3ZfaXRlcl9nZXRfcGFnZXMoKSB3aGVyZSB1c2FnZXMgd2hp Y2ggYXJlIHRyYW5zaWVudC4KPiArICogcGVyaW9kIF9vZnRlbl8gdW5kZXIgdXNlcnNwYWNlIGNv bnRyb2wuICBUaGlzIGlzIGluIGNvbnRyYXN0IHRvCj4gKyAqIGlvdl9pdGVyX2dldF9wYWdlcygp LCB3aGVyZSB1c2FnZXMgd2hpY2ggYXJlIHRyYW5zaWVudC4KPiAgICoKPiAgICogRklYTUU6IEZv ciBwYWdlcyB3aGljaCBhcmUgcGFydCBvZiBhIGZpbGVzeXN0ZW0sIG1hcHBpbmdzIGFyZSBzdWJq ZWN0IHRvIHRoZQo+ICAgKiBsaWZldGltZSBlbmZvcmNlZCBieSB0aGUgZmlsZXN5c3RlbSBhbmQg d2UgbmVlZCBndWFyYW50ZWVzIHRoYXQgbG9uZ3Rlcm0KPiBAQCAtMjYxNSwxMSArMjYzNSwzMiBA QCBzdHJ1Y3QgcGFnZSAqZm9sbG93X3BhZ2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVu c2lnbmVkIGxvbmcgYWRkcmVzcywKPiAgICogQ3VycmVudGx5IG9ubHkgZ2V0X3VzZXJfcGFnZXMo KSBhbmQgZ2V0X3VzZXJfcGFnZXNfZmFzdCgpIHN1cHBvcnQgdGhpcyBmbGFnCj4gICAqIGFuZCBj YWxscyB0byBnZXRfdXNlcl9wYWdlc19bdW5dbG9ja2VkIGFyZSBzcGVjaWZpY2FsbHkgbm90IGFs bG93ZWQuICBUaGlzCj4gICAqIGlzIGR1ZSB0byBhbiBpbmNvbXBhdGliaWxpdHkgd2l0aCB0aGUg RlMgREFYIGNoZWNrIGFuZAo+IC0gKiBGQVVMVF9GTEFHX0FMTE9XX1JFVFJZCj4gKyAqIEZBVUxU X0ZMQUdfQUxMT1dfUkVUUlkuCj4gICAqCj4gLSAqIEluIHRoZSBDTUEgY2FzZTogbG9uZ3Rlcm0g cGlucyBpbiBhIENNQSByZWdpb24gd291bGQgdW5uZWNlc3NhcmlseSBmcmFnbWVudAo+IC0gKiB0 aGF0IHJlZ2lvbi4gIEFuZCBzbyBDTUEgYXR0ZW1wdHMgdG8gbWlncmF0ZSB0aGUgcGFnZSBiZWZv cmUgcGlubmluZyB3aGVuCj4gKyAqIEluIHRoZSBDTUEgY2FzZTogbG9uZyB0ZXJtIHBpbnMgaW4g YSBDTUEgcmVnaW9uIHdvdWxkIHVubmVjZXNzYXJpbHkgZnJhZ21lbnQKPiArICogdGhhdCByZWdp b24uICBBbmQgc28sIENNQSBhdHRlbXB0cyB0byBtaWdyYXRlIHRoZSBwYWdlIGJlZm9yZSBwaW5u aW5nLCB3aGVuCj4gICAqIEZPTExfTE9OR1RFUk0gaXMgc3BlY2lmaWVkLgo+ICsgKgo+ICsgKiBG T0xMX1BJTiBpbmRpY2F0ZXMgdGhhdCBhIHNwZWNpYWwga2luZCBvZiB0cmFja2luZyAobm90IGp1 c3QgcGFnZS0+X3JlZmNvdW50LAo+ICsgKiBidXQgYW4gYWRkaXRpb25hbCBwaW4gY291bnRpbmcg c3lzdGVtKSB3aWxsIGJlIGludm9rZWQuIFRoaXMgaXMgaW50ZW5kZWQgZm9yCj4gKyAqIGFueXRo aW5nIHRoYXQgZ2V0cyBhIHBhZ2UgcmVmZXJlbmNlIGFuZCB0aGVuIHRvdWNoZXMgcGFnZSBkYXRh IChmb3IgZXhhbXBsZSwKPiArICogRGlyZWN0IElPKS4gVGhpcyBsZXRzIHRoZSBmaWxlc3lzdGVt IGtub3cgdGhhdCBzb21lIG5vbi1maWxlLXN5c3RlbSBlbnRpdHkgaXMKPiArICogcG90ZW50aWFs bHkgY2hhbmdpbmcgdGhlIHBhZ2VzJyBkYXRhLiBJbiBjb250cmFzdCB0byBGT0xMX0dFVCAod2hv c2UgcGFnZXMKPiArICogYXJlIHJlbGVhc2VkIHZpYSBwdXRfcGFnZSgpKSwgRk9MTF9QSU4gcGFn ZXMgbXVzdCBiZSByZWxlYXNlZCwgdWx0aW1hdGVseSwgYnkKPiArICogYSBjYWxsIHRvIHB1dF91 c2VyX3BhZ2UoKS4KPiArICoKPiArICogRk9MTF9QSU4gaXMgc2ltaWxhciB0byBGT0xMX0dFVDog Ym90aCBvZiB0aGVzZSBwaW4gcGFnZXMuIFRoZXkgdXNlIGRpZmZlcmVudAo+ICsgKiBhbmQgc2Vw YXJhdGUgcmVmY291bnRpbmcgbWVjaGFuaXNtcywgaG93ZXZlciwgYW5kIHRoYXQgbWVhbnMgdGhh dCBlYWNoIGhhcwo+ICsgKiBpdHMgb3duIGFjcXVpcmUgYW5kIHJlbGVhc2UgbWVjaGFuaXNtczoK PiArICoKPiArICogICAgIEZPTExfR0VUOiBnZXRfdXNlcl9wYWdlcyooKSB0byBhY3F1aXJlLCBh bmQgcHV0X3BhZ2UoKSB0byByZWxlYXNlLgo+ICsgKgo+ICsgKiAgICAgRk9MTF9QSU46IHBpbl91 c2VyX3BhZ2VzKigpIG9yIHBpbl9sb25ndGVybV9wYWdlcyooKSB0byBhY3F1aXJlLCBhbmQKPiAr ICogICAgICAgICAgICAgICBwdXRfdXNlcl9wYWdlcyB0byByZWxlYXNlLgo+ICsgKgo+ICsgKiBG T0xMX1BJTiBhbmQgRk9MTF9HRVQgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4KCllvdSBtZWFuIHRo ZSBmbGFncyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGZvciBhbnkgc2luZ2xlIGNhbGwsIGNvcnJl Y3Q/CkJlY2F1c2UgbXkgZmlyc3QgdGhvdWdodCB3YXMgdGhhdCB5b3UgbWVhbnQgdGhhdCBhIHBh Z2Ugd2hpY2ggd2FzIHBpbidlZCBjYW4ndApiZSAiZ290Ii4gIFdoaWNoIEkgZG9uJ3QgdGhpbmsg aXMgdHJ1ZSBvciBuZWNlc3NhcnkuLi4KCj4gKyAqCj4gKyAqIFBsZWFzZSBzZWUgRG9jdW1lbnRh dGlvbi92bS9waW5fdXNlcl9wYWdlcy5yc3QgZm9yIG1vcmUgaW5mb3JtYXRpb24uCgpOSVQ6IEkg dGhpbmsgd2Ugc2hvdWxkIGluY2x1ZGUgdGhpcyBmaWxlIGFzIHBhcnQgb2YgdGhpcyBwYXRjaC4u LgoKPiAgICovCj4gIAo+ICBzdGF0aWMgaW5saW5lIGludCB2bV9mYXVsdF90b19lcnJubyh2bV9m YXVsdF90IHZtX2ZhdWx0LCBpbnQgZm9sbF9mbGFncykKPiBkaWZmIC0tZ2l0IGEvbW0vZ3VwLmMg Yi9tbS9ndXAuYwo+IGluZGV4IDhmYjBkOWNkZmFmNS4uODY5NGJjN2IzZGYzIDEwMDY0NAo+IC0t LSBhL21tL2d1cC5jCj4gKysrIGIvbW0vZ3VwLmMKPiBAQCAtMTc5LDYgKzE3OSwxMCBAQCBzdGF0 aWMgc3RydWN0IHBhZ2UgKmZvbGxvd19wYWdlX3B0ZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZt YSwKPiAgCXNwaW5sb2NrX3QgKnB0bDsKPiAgCXB0ZV90ICpwdGVwLCBwdGU7Cj4gIAo+ICsJLyog Rk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuICovCj4gKwlpZiAo V0FSTl9PTl9PTkNFKChmbGFncyAmIChGT0xMX1BJTiB8IEZPTExfR0VUKSkgPT0KPiArCQkJIChG T0xMX1BJTiB8IEZPTExfR0VUKSkpCj4gKwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gIHJl dHJ5Ogo+ICAJaWYgKHVubGlrZWx5KHBtZF9iYWQoKnBtZCkpKQo+ICAJCXJldHVybiBub19wYWdl X3RhYmxlKHZtYSwgZmxhZ3MpOwo+IEBAIC03OTAsNyArNzk0LDcgQEAgc3RhdGljIGxvbmcgX19n ZXRfdXNlcl9wYWdlcyhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywgc3RydWN0IG1tX3N0cnVjdCAq bW0sCj4gIAo+ICAJc3RhcnQgPSB1bnRhZ2dlZF9hZGRyKHN0YXJ0KTsKPiAgCj4gLQlWTV9CVUdf T04oISFwYWdlcyAhPSAhIShndXBfZmxhZ3MgJiBGT0xMX0dFVCkpOwo+ICsJVk1fQlVHX09OKCEh cGFnZXMgIT0gISEoZ3VwX2ZsYWdzICYgKEZPTExfR0VUIHwgRk9MTF9QSU4pKSk7Cj4gIAo+ICAJ LyoKPiAgCSAqIElmIEZPTExfRk9SQ0UgaXMgc2V0IHRoZW4gZG8gbm90IGZvcmNlIGEgZnVsbCBm YXVsdCBhcyB0aGUgaGludGluZwo+IEBAIC0xMDE0LDcgKzEwMTgsMTYgQEAgc3RhdGljIF9fYWx3 YXlzX2lubGluZSBsb25nIF9fZ2V0X3VzZXJfcGFnZXNfbG9ja2VkKHN0cnVjdCB0YXNrX3N0cnVj dCAqdHNrLAo+ICAJCUJVR19PTigqbG9ja2VkICE9IDEpOwo+ICAJfQo+ICAKPiAtCWlmIChwYWdl cykKPiArCS8qCj4gKwkgKiBGT0xMX1BJTiBhbmQgRk9MTF9HRVQgYXJlIG11dHVhbGx5IGV4Y2x1 c2l2ZS4gVHJhZGl0aW9uYWwgYmVoYXZpb3IKPiArCSAqIGlzIHRvIHNldCBGT0xMX0dFVCBpZiB0 aGUgY2FsbGVyIHdhbnRzIHBhZ2VzW10gZmlsbGVkIGluIChidXQgaGFzCj4gKwkgKiBjYXJlbGVz c2x5IGZhaWxlZCB0byBzcGVjaWZ5IEZPTExfR0VUKSwgc28ga2VlcCBkb2luZyB0aGF0LCBidXQg b25seQo+ICsJICogZm9yIEZPTExfR0VULCBub3QgZm9yIHRoZSBuZXdlciBGT0xMX1BJTi4KPiAr CSAqCj4gKwkgKiBGT0xMX1BJTiBhbHdheXMgZXhwZWN0cyBwYWdlcyB0byBiZSBub24tbnVsbCwg YnV0IG5vIG5lZWQgdG8gYXNzZXJ0Cj4gKwkgKiB0aGF0IGhlcmUsIGFzIGFueSBmYWlsdXJlcyB3 aWxsIGJlIG9idmlvdXMgZW5vdWdoLgo+ICsJICovCj4gKwlpZiAocGFnZXMgJiYgIShmbGFncyAm IEZPTExfUElOKSkKPiAgCQlmbGFncyB8PSBGT0xMX0dFVDsKPiAgCj4gIAlwYWdlc19kb25lID0g MDsKPiBAQCAtMTEzMyw2ICsxMTQ2LDEyIEBAIHN0YXRpYyBfX2Fsd2F5c19pbmxpbmUgbG9uZyBf X2dldF91c2VyX3BhZ2VzX2xvY2tlZChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywKPiAgICogaXMg d3JpdHRlbiB0bywgc2V0X3BhZ2VfZGlydHkgKG9yIHNldF9wYWdlX2RpcnR5X2xvY2ssIGFzIGFw cHJvcHJpYXRlKSBtdXN0Cj4gICAqIGJlIGNhbGxlZCBhZnRlciB0aGUgcGFnZSBpcyBmaW5pc2hl ZCB3aXRoLCBhbmQgYmVmb3JlIHB1dF9wYWdlIGlzIGNhbGxlZC4KPiAgICoKPiArICogQSBub3Rl IG9uIGd1cF9mbGFnczogRk9MTF9QSU4gbXVzdCBvbmx5IGJlIHNldCBpbnRlcm5hbGx5IGJ5IHRo ZQo+ICsgKiBwaW5fdXNlcl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVy IGRpcmVjdGx5IGJ5IHRoZSBjYWxsZXIuCj4gKyAqIFRoYXQncyBpbiBvcmRlciB0byBoZWxwIGF2 b2lkIG1pc21hdGNoZXMgd2hlbiByZWxlYXNpbmcgcGFnZXM6Cj4gKyAqIGdldF91c2VyX3BhZ2Vz KigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF9wYWdlKCksIHdoaWxlCj4gKyAqIHBp bl91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2Uo KS4KPiArICoKPiAgICogZ2V0X3VzZXJfcGFnZXMgaXMgdHlwaWNhbGx5IHVzZWQgZm9yIGZld2Vy LWNvcHkgSU8gb3BlcmF0aW9ucywgdG8gZ2V0IGEKPiAgICogaGFuZGxlIG9uIHRoZSBtZW1vcnkg Ynkgc29tZSBtZWFucyBvdGhlciB0aGFuIGFjY2Vzc2VzIHZpYSB0aGUgdXNlciB2aXJ0dWFsCj4g ICAqIGFkZHJlc3Nlcy4gVGhlIHBhZ2VzIG1heSBiZSBzdWJtaXR0ZWQgZm9yIERNQSB0byBkZXZp Y2VzIG9yIGFjY2Vzc2VkIHZpYQo+IEBAIC0xMTUxLDYgKzExNzAsMTQgQEAgbG9uZyBnZXRfdXNl cl9wYWdlc19yZW1vdGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3Qg Km1tLAo+ICAJCXVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4g IAkJc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcywgaW50ICpsb2NrZWQpCj4gIHsKPiArCS8q Cj4gKwkgKiBBcyBkZXRhaWxlZCBhYm92ZSwgRk9MTF9QSU4gbXVzdCBvbmx5IGJlIHNldCBpbnRl cm5hbGx5IGJ5IHRoZQo+ICsJICogcGluX3VzZXJfcGFnZSooKSBhbmQgcGluX2xvbmd0ZXJtXyoo KSBBUElzLCBuZXZlciBkaXJlY3RseSBieSB0aGUKPiArCSAqIGNhbGxlciwgc28gZW5mb3JjZSB0 aGF0IHdpdGggYW4gYXNzZXJ0aW9uOgo+ICsJICovCj4gKwlpZiAoV0FSTl9PTl9PTkNFKGd1cF9m bGFncyAmIEZPTExfUElOKSkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gIAkvKgo+ICAJICog RklYTUU6IEN1cnJlbnQgRk9MTF9MT05HVEVSTSBiZWhhdmlvciBpcyBpbmNvbXBhdGlibGUgd2l0 aAo+ICAJICogRkFVTFRfRkxBR19BTExPV19SRVRSWSBiZWNhdXNlIG9mIHRoZSBGUyBEQVggY2hl Y2sgcmVxdWlyZW1lbnQgb24KPiBAQCAtMTYwMywxMSArMTYzMCwyNSBAQCBzdGF0aWMgX19hbHdh eXNfaW5saW5lIGxvbmcgX19ndXBfbG9uZ3Rlcm1fbG9ja2VkKHN0cnVjdCB0YXNrX3N0cnVjdCAq dHNrLAo+ICAgKiBhbmQgbW0gYmVpbmcgb3BlcmF0ZWQgb24gYXJlIHRoZSBjdXJyZW50IHRhc2sn cyBhbmQgZG9uJ3QgYWxsb3cKPiAgICogcGFzc2luZyBvZiBhIGxvY2tlZCBwYXJhbWV0ZXIuICBX ZSBhbHNvIG9idmlvdXNseSBkb24ndCBwYXNzCj4gICAqIEZPTExfUkVNT1RFIGluIGhlcmUuCj4g KyAqCj4gKyAqIEEgbm90ZSBvbiBndXBfZmxhZ3M6IEZPTExfUElOIHNob3VsZCBvbmx5IGJlIHNl dCBpbnRlcm5hbGx5IGJ5IHRoZQo+ICsgKiBwaW5fdXNlcl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rl cm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRoZSBjYWxsZXIuCj4gKyAqIFRoYXQncyBp biBvcmRlciB0byBoZWxwIGF2b2lkIG1pc21hdGNoZXMgd2hlbiByZWxlYXNpbmcgcGFnZXM6Cj4g KyAqIGdldF91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF9wYWdl KCksIHdoaWxlCj4gKyAqIHBpbl91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQg dmlhIHB1dF91c2VyX3BhZ2UoKS4KClJhdGhlciB0aGFuIHB1dCB0aGlzIGhlcmUgc2hvdWxkIHdl IHB1dCBpdCBuZXh0IHRvIHRoZSBkZWZpbml0aW9uIG9mIEZPTExfUElOPwpCZWNhdXNlIG5vdyB3 ZSBoYXZlIHRoaXMgdGV4dCAyeC4uLiAgOi0vCgo+ICAgKi8KPiAgbG9uZyBnZXRfdXNlcl9wYWdl cyh1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICAJCXVuc2ln bmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gIAkJc3RydWN0IHZtX2Fy ZWFfc3RydWN0ICoqdm1hcykKPiAgewo+ICsJLyoKPiArCSAqIEFzIGRldGFpbGVkIGFib3ZlLCBG T0xMX1BJTiBtdXN0IG9ubHkgYmUgc2V0IGludGVybmFsbHkgYnkgdGhlCj4gKwkgKiBwaW5fdXNl cl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRo ZQo+ICsJICogY2FsbGVyLCBzbyBlbmZvcmNlIHRoYXQgd2l0aCBhbiBhc3NlcnRpb246Cj4gKwkg Ki8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9QSU4pKQo+ICsJCXJldHVy biAtRUlOVkFMOwo+ICsKPiAgCXJldHVybiBfX2d1cF9sb25ndGVybV9sb2NrZWQoY3VycmVudCwg Y3VycmVudC0+bW0sIHN0YXJ0LCBucl9wYWdlcywKPiAgCQkJCSAgICAgcGFnZXMsIHZtYXMsIGd1 cF9mbGFncyB8IEZPTExfVE9VQ0gpOwo+ICB9Cj4gQEAgLTIzNjYsMjQgKzI0MDcsOSBAQCBzdGF0 aWMgaW50IF9fZ3VwX2xvbmd0ZXJtX3VubG9ja2VkKHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBu cl9wYWdlcywKPiAgCXJldHVybiByZXQ7Cj4gIH0KPiAgCj4gLS8qKgo+IC0gKiBnZXRfdXNlcl9w YWdlc19mYXN0KCkgLSBwaW4gdXNlciBwYWdlcyBpbiBtZW1vcnkKPiAtICogQHN0YXJ0OglzdGFy dGluZyB1c2VyIGFkZHJlc3MKPiAtICogQG5yX3BhZ2VzOgludW1iZXIgb2YgcGFnZXMgZnJvbSBz dGFydCB0byBwaW4KPiAtICogQGd1cF9mbGFnczoJZmxhZ3MgbW9kaWZ5aW5nIHBpbiBiZWhhdmlv dXIKPiAtICogQHBhZ2VzOglhcnJheSB0aGF0IHJlY2VpdmVzIHBvaW50ZXJzIHRvIHRoZSBwYWdl cyBwaW5uZWQuCj4gLSAqCQlTaG91bGQgYmUgYXQgbGVhc3QgbnJfcGFnZXMgbG9uZy4KPiAtICoK PiAtICogQXR0ZW1wdCB0byBwaW4gdXNlciBwYWdlcyBpbiBtZW1vcnkgd2l0aG91dCB0YWtpbmcg bW0tPm1tYXBfc2VtLgo+IC0gKiBJZiBub3Qgc3VjY2Vzc2Z1bCwgaXQgd2lsbCBmYWxsIGJhY2sg dG8gdGFraW5nIHRoZSBsb2NrIGFuZAo+IC0gKiBjYWxsaW5nIGdldF91c2VyX3BhZ2VzKCkuCj4g LSAqCj4gLSAqIFJldHVybnMgbnVtYmVyIG9mIHBhZ2VzIHBpbm5lZC4gVGhpcyBtYXkgYmUgZmV3 ZXIgdGhhbiB0aGUgbnVtYmVyCj4gLSAqIHJlcXVlc3RlZC4gSWYgbnJfcGFnZXMgaXMgMCBvciBu ZWdhdGl2ZSwgcmV0dXJucyAwLiBJZiBubyBwYWdlcwo+IC0gKiB3ZXJlIHBpbm5lZCwgcmV0dXJu cyAtZXJybm8uCj4gLSAqLwo+IC1pbnQgZ2V0X3VzZXJfcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25n IHN0YXJ0LCBpbnQgbnJfcGFnZXMsCj4gLQkJCXVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVj dCBwYWdlICoqcGFnZXMpCj4gK3N0YXRpYyBpbnQgaW50ZXJuYWxfZ2V0X3VzZXJfcGFnZXNfZmFz dCh1bnNpZ25lZCBsb25nIHN0YXJ0LCBpbnQgbnJfcGFnZXMsCj4gKwkJCQkJdW5zaWduZWQgaW50 IGd1cF9mbGFncywKPiArCQkJCQlzdHJ1Y3QgcGFnZSAqKnBhZ2VzKQo+ICB7Cj4gIAl1bnNpZ25l ZCBsb25nIGFkZHIsIGxlbiwgZW5kOwo+ICAJaW50IG5yID0gMCwgcmV0ID0gMDsKPiBAQCAtMjQy OCw0ICsyNDU0LDIyMiBAQCBpbnQgZ2V0X3VzZXJfcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0 YXJ0LCBpbnQgbnJfcGFnZXMsCj4gIAo+ICAJcmV0dXJuIHJldDsKPiAgfQo+ICsKPiArLyoqCj4g KyAqIGdldF91c2VyX3BhZ2VzX2Zhc3QoKSAtIHBpbiB1c2VyIHBhZ2VzIGluIG1lbW9yeQo+ICsg KiBAc3RhcnQ6CXN0YXJ0aW5nIHVzZXIgYWRkcmVzcwo+ICsgKiBAbnJfcGFnZXM6CW51bWJlciBv ZiBwYWdlcyBmcm9tIHN0YXJ0IHRvIHBpbgo+ICsgKiBAZ3VwX2ZsYWdzOglmbGFncyBtb2RpZnlp bmcgcGluIGJlaGF2aW91cgo+ICsgKiBAcGFnZXM6CWFycmF5IHRoYXQgcmVjZWl2ZXMgcG9pbnRl cnMgdG8gdGhlIHBhZ2VzIHBpbm5lZC4KPiArICoJCVNob3VsZCBiZSBhdCBsZWFzdCBucl9wYWdl cyBsb25nLgo+ICsgKgo+ICsgKiBBdHRlbXB0IHRvIHBpbiB1c2VyIHBhZ2VzIGluIG1lbW9yeSB3 aXRob3V0IHRha2luZyBtbS0+bW1hcF9zZW0uCj4gKyAqIElmIG5vdCBzdWNjZXNzZnVsLCBpdCB3 aWxsIGZhbGwgYmFjayB0byB0YWtpbmcgdGhlIGxvY2sgYW5kCj4gKyAqIGNhbGxpbmcgZ2V0X3Vz ZXJfcGFnZXMoKS4KPiArICoKPiArICogQSBub3RlIG9uIGd1cF9mbGFnczogRk9MTF9QSU4gbXVz dCBvbmx5IGJlIHNldCBpbnRlcm5hbGx5IGJ5IHRoZQo+ICsgKiBwaW5fdXNlcl9wYWdlKigpIGFu ZCBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRoZSBjYWxsZXIuCj4g KyAqIFRoYXQncyBpbiBvcmRlciB0byBoZWxwIGF2b2lkIG1pc21hdGNoZXMgd2hlbiByZWxlYXNp bmcgcGFnZXM6Cj4gKyAqIGdldF91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQg dmlhIHB1dF9wYWdlKCksIHdoaWxlCj4gKyAqIHBpbl91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3Qg YmUgcmVsZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2UoKS4KPiArICoKPiArICogUmV0dXJucyBudW1i ZXIgb2YgcGFnZXMgcGlubmVkLiBUaGlzIG1heSBiZSBmZXdlciB0aGFuIHRoZSBudW1iZXIgcmVx dWVzdGVkLgo+ICsgKiBJZiBucl9wYWdlcyBpcyAwIG9yIG5lZ2F0aXZlLCByZXR1cm5zIDAuIElm IG5vIHBhZ2VzIHdlcmUgcGlubmVkLCByZXR1cm5zCj4gKyAqIC1lcnJuby4KPiArICovCj4gK2lu dCBnZXRfdXNlcl9wYWdlc19mYXN0KHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBucl9wYWdlcywK PiArCQkJdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcykKPiArewo+ ICsJLyoKPiArCSAqIEFzIGRldGFpbGVkIGFib3ZlLCBGT0xMX1BJTiBtdXN0IG9ubHkgYmUgc2V0 IGludGVybmFsbHkgYnkgdGhlCj4gKwkgKiBwaW5fdXNlcl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rl cm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRoZQo+ICsJICogY2FsbGVyLCBzbyBlbmZv cmNlIHRoYXQ6Cj4gKwkgKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9Q SU4pKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCXJldHVybiBpbnRlcm5hbF9nZXRfdXNl cl9wYWdlc19mYXN0KHN0YXJ0LCBucl9wYWdlcywgZ3VwX2ZsYWdzLCBwYWdlcyk7Cj4gK30KPiAg RVhQT1JUX1NZTUJPTF9HUEwoZ2V0X3VzZXJfcGFnZXNfZmFzdCk7Cj4gKwo+ICsvKioKPiArICog cGluX3VzZXJfcGFnZXNfZmFzdCgpIC0gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IHdpdGhvdXQg dGFraW5nIGxvY2tzCj4gKyAqCj4gKyAqIE5lYXJseSB0aGUgc2FtZSBhcyBnZXRfdXNlcl9wYWdl c19mYXN0KCksIGV4Y2VwdCB0aGF0IEZPTExfUElOIGlzIHNldC4gU2VlCj4gKyAqIGdldF91c2Vy X3BhZ2VzX2Zhc3QoKSBmb3IgZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYXJndW1lbnRz LCBiZWNhdXNlCj4gKyAqIHRoZSBhcmd1bWVudHMgaGVyZSBhcmUgaWRlbnRpY2FsLgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBw dXRfdXNlcl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNl cl9wYWdlcy5yc3QgZm9yIGZ1cnRoZXIgZGV0YWlscy4KPiArICoKPiArICogVGhpcyBpcyBpbnRl bmRlZCBmb3IgQ2FzZSAxIChESU8pIGluIERvY3VtZW50YXRpb24vdm0vcGluX3VzZXJfcGFnZXMu cnN0LiBJdAo+ICsgKiBpcyBOT1QgaW50ZW5kZWQgZm9yIENhc2UgMiAoUkRNQTogbG9uZy10ZXJt IHBpbnMpLgo+ICsgKi8KPiAraW50IHBpbl91c2VyX3BhZ2VzX2Zhc3QodW5zaWduZWQgbG9uZyBz dGFydCwgaW50IG5yX3BhZ2VzLAo+ICsJCQl1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1Y3Qg cGFnZSAqKnBhZ2VzKQo+ICt7Cj4gKwkvKiBGT0xMX0dFVCBhbmQgRk9MTF9QSU4gYXJlIG11dHVh bGx5IGV4Y2x1c2l2ZS4gKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9H RVQpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWd1cF9mbGFncyB8PSBGT0xMX1BJTjsK PiArCXJldHVybiBpbnRlcm5hbF9nZXRfdXNlcl9wYWdlc19mYXN0KHN0YXJ0LCBucl9wYWdlcywg Z3VwX2ZsYWdzLCBwYWdlcyk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTF9HUEwocGluX3VzZXJfcGFn ZXNfZmFzdCk7Cj4gKwo+ICsvKioKPiArICogcGluX2xvbmd0ZXJtX3BhZ2VzX2Zhc3QoKSAtIHBp biB1c2VyIHBhZ2VzIGluIG1lbW9yeSB3aXRob3V0IHRha2luZyBsb2Nrcwo+ICsgKgo+ICsgKiBO ZWFybHkgdGhlIHNhbWUgYXMgZ2V0X3VzZXJfcGFnZXNfZmFzdCgpLCBleGNlcHQgdGhhdCBGT0xM X1BJTiBhbmQKPiArICogRk9MTF9MT05HVEVSTSBhcmUgc2V0LiBTZWUgZ2V0X3VzZXJfcGFnZXNf ZmFzdCgpIGZvciBkb2N1bWVudGF0aW9uIG9uIHRoZQo+ICsgKiBmdW5jdGlvbiBhcmd1bWVudHMs IGJlY2F1c2UgdGhlIGFyZ3VtZW50cyBoZXJlIGFyZSBpZGVudGljYWwuCj4gKyAqCj4gKyAqIEZP TExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF91c2Vy X3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2Vz LnJzdCBmb3IgZnVydGhlciBkZXRhaWxzLgo+ICsgKgo+ICsgKiBGT0xMX0xPTkdURVJNIG1lYW5z IHRoYXQgdGhlIHBhZ2VzIGFyZSBiZWluZyBwaW5uZWQgZm9yICJsb25nIHRlcm0iIHVzZSwKPiAr ICogdHlwaWNhbGx5IGJ5IGEgbm9uLUNQVSBkZXZpY2UsIGFuZCB3ZSBjYW5ub3QgYmUgc3VyZSB0 aGF0IHdhaXRpbmcgZm9yIGEKPiArICogcGlubmVkIHBhZ2UgdG8gYmVjb21lIHVucGluIHdpbGwg YmUgZWZmZWN0aXZlLgo+ICsgKgo+ICsgKiBUaGlzIGlzIGludGVuZGVkIGZvciBDYXNlIDIgKFJE TUE6IGxvbmctdGVybSBwaW5zKSBvZiB0aGUgRk9MTF9QSU4KPiArICogZG9jdW1lbnRhdGlvbi4K PiArICovCj4gK2ludCBwaW5fbG9uZ3Rlcm1fcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0YXJ0 LCBpbnQgbnJfcGFnZXMsCj4gKwkJCSAgICB1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1Y3Qg cGFnZSAqKnBhZ2VzKQo+ICt7Cj4gKwkvKiBGT0xMX0dFVCBhbmQgRk9MTF9QSU4gYXJlIG11dHVh bGx5IGV4Y2x1c2l2ZS4gKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9H RVQpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWd1cF9mbGFncyB8PSAoRk9MTF9QSU4g fCBGT0xMX0xPTkdURVJNKTsKPiArCXJldHVybiBpbnRlcm5hbF9nZXRfdXNlcl9wYWdlc19mYXN0 KHN0YXJ0LCBucl9wYWdlcywgZ3VwX2ZsYWdzLCBwYWdlcyk7Cj4gK30KPiArRVhQT1JUX1NZTUJP TF9HUEwocGluX2xvbmd0ZXJtX3BhZ2VzX2Zhc3QpOwo+ICsKPiArLyoqCj4gKyAqIHBpbl91c2Vy X3BhZ2VzX3JlbW90ZSgpIC0gcGluIHBhZ2VzIGZvciAodHlwaWNhbGx5KSB1c2UgYnkgRGlyZWN0 IElPLCBhbmQKPiArICogcmV0dXJuIHRoZSBwYWdlcyB0byB0aGUgdXNlci4KPiArICoKPiArICog TmVhcmx5IHRoZSBzYW1lIGFzIGdldF91c2VyX3BhZ2VzX3JlbW90ZSgpLCBleGNlcHQgdGhhdCBG T0xMX1BJTiBpcyBzZXQuIFNlZQo+ICsgKiBnZXRfdXNlcl9wYWdlc19yZW1vdGUoKSBmb3IgZG9j dW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYXJndW1lbnRzLCBiZWNhdXNlCj4gKyAqIHRoZSBh cmd1bWVudHMgaGVyZSBhcmUgaWRlbnRpY2FsLgo+ICsgKgo+ICsgKiBGT0xMX1BJTiBtZWFucyB0 aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBwdXRfdXNlcl9wYWdlKCkuIFBsZWFz ZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNlcl9wYWdlcy5yc3QgZm9yIGRldGFp bHMuCj4gKyAqCj4gKyAqIFRoaXMgaXMgaW50ZW5kZWQgZm9yIENhc2UgMSAoRElPKSBpbiBEb2N1 bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4gSXQKPiArICogaXMgTk9UIGludGVuZGVk IGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKS4KPiArICovCj4gK2xvbmcgcGluX3Vz ZXJfcGFnZXNfcmVtb3RlKHN0cnVjdCB0YXNrX3N0cnVjdCAqdHNrLCBzdHJ1Y3QgbW1fc3RydWN0 ICptbSwKPiArCQkJICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdl cywKPiArCQkJICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywK PiArCQkJICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcywgaW50ICpsb2NrZWQpCj4gK3sK PiArCS8qIEZPTExfR0VUIGFuZCBGT0xMX1BJTiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ ICsJaWYgKFdBUk5fT05fT05DRShndXBfZmxhZ3MgJiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1F SU5WQUw7Cj4gKwo+ICsJZ3VwX2ZsYWdzIHw9IEZPTExfVE9VQ0ggfCBGT0xMX1JFTU9URSB8IEZP TExfUElOOwo+ICsKPiArCXJldHVybiBfX2dldF91c2VyX3BhZ2VzX2xvY2tlZCh0c2ssIG1tLCBz dGFydCwgbnJfcGFnZXMsIHBhZ2VzLCB2bWFzLAo+ICsJCQkJICAgICAgIGxvY2tlZCwgZ3VwX2Zs YWdzKTsKPiArfQo+ICtFWFBPUlRfU1lNQk9MKHBpbl91c2VyX3BhZ2VzX3JlbW90ZSk7Cj4gKwo+ ICsvKioKPiArICogcGluX2xvbmd0ZXJtX3BhZ2VzX3JlbW90ZSgpIC0gcGluIHBhZ2VzIGZvciAo dHlwaWNhbGx5KSB1c2UgYnkgRGlyZWN0IElPLCBhbmQKPiArICogcmV0dXJuIHRoZSBwYWdlcyB0 byB0aGUgdXNlci4KPiArICoKPiArICogTmVhcmx5IHRoZSBzYW1lIGFzIGdldF91c2VyX3BhZ2Vz X3JlbW90ZSgpLCBidXQgbm90ZSB0aGF0IEZPTExfVE9VQ0ggaXMgbm90Cj4gKyAqIHNldCwgYW5k IEZPTExfUElOIGFuZCBGT0xMX0xPTkdURVJNIGFyZSBzZXQuIFNlZSBnZXRfdXNlcl9wYWdlc19y ZW1vdGUoKSBmb3IKPiArICogZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYXJndW1lbnRz LCBiZWNhdXNlIHRoZSBhcmd1bWVudHMgaGVyZSBhcmUKPiArICogaWRlbnRpY2FsLgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBw dXRfdXNlcl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNl cl9wYWdlcy5yc3QgZm9yIGZ1cnRoZXIgZGV0YWlscy4KPiArICoKPiArICogRk9MTF9MT05HVEVS TSBtZWFucyB0aGF0IHRoZSBwYWdlcyBhcmUgYmVpbmcgcGlubmVkIGZvciAibG9uZyB0ZXJtIiB1 c2UsCj4gKyAqIHR5cGljYWxseSBieSBhIG5vbi1DUFUgZGV2aWNlLCBhbmQgd2UgY2Fubm90IGJl IHN1cmUgdGhhdCB3YWl0aW5nIGZvciBhCj4gKyAqIHBpbm5lZCBwYWdlIHRvIGJlY29tZSB1bnBp biB3aWxsIGJlIGVmZmVjdGl2ZS4KPiArICoKPiArICogVGhpcyBpcyBpbnRlbmRlZCBmb3IgQ2Fz ZSAyIChSRE1BOiBsb25nLXRlcm0gcGlucykgaW4KPiArICogRG9jdW1lbnRhdGlvbi92bS9waW5f dXNlcl9wYWdlcy5yc3QuCj4gKyAqLwo+ICtsb25nIHBpbl9sb25ndGVybV9wYWdlc19yZW1vdGUo c3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICsJCQkgICAg ICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiArCQkJICAg ICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gKwkJCSAg ICAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzLCBpbnQgKmxvY2tlZCkKPiArewo+ICsJ LyogRk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuICovCj4gKwlp ZiAoV0FSTl9PTl9PTkNFKGd1cF9mbGFncyAmIEZPTExfR0VUKSkKPiArCQlyZXR1cm4gLUVJTlZB TDsKPiArCj4gKwkvKgo+ICsJICogRklYTUU6IGFzIG5vdGVkIGluIHRoZSBnZXRfdXNlcl9wYWdl c19yZW1vdGUoKSBpbXBsZW1lbnRhdGlvbiwgaXQKPiArCSAqIGlzIG5vdCB5ZXQgcG9zc2libGUg dG8gc2FmZWx5IHNldCBGT0xMX0xPTkdURVJNIGhlcmUuIEZPTExfTE9OR1RFUk0KPiArCSAqIG5l ZWRzIHRvIGJlIHNldCwgYnV0IGZvciBub3cgdGhlIGJlc3Qgd2UgY2FuIGRvIGlzIGEgIlRPRE8i IGl0ZW0uCj4gKwkgKi8KCldhaXQ/ICBXaHkgY2FuJ3Qgd2Ugc2V0IEZPTExfTE9OR1RFUk0gaGVy ZT8gIHBpbl8qIGFyZSBuZXcgY2FsbHMgd2hpY2ggYXJlIG5vdAp1c2VkIHlldCByaWdodD8KCllv dSBzZXQgaXQgaW4gdGhlIG90aGVyIG5ldyBwaW5fKiBmdW5jdGlvbnM/CgpJcmEKCj4gKwlndXBf ZmxhZ3MgfD0gRk9MTF9SRU1PVEUgfCBGT0xMX1BJTjsKPiArCj4gKwlyZXR1cm4gX19nZXRfdXNl cl9wYWdlc19sb2NrZWQodHNrLCBtbSwgc3RhcnQsIG5yX3BhZ2VzLCBwYWdlcywgdm1hcywKPiAr CQkJCSAgICAgICBsb2NrZWQsIGd1cF9mbGFncyk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTChwaW5f bG9uZ3Rlcm1fcGFnZXNfcmVtb3RlKTsKPiArCj4gKy8qKgo+ICsgKiBwaW5fdXNlcl9wYWdlcygp IC0gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IGZvciB1c2UgYnkgb3RoZXIgZGV2aWNlcwo+ICsg Kgo+ICsgKiBOZWFybHkgdGhlIHNhbWUgYXMgZ2V0X3VzZXJfcGFnZXMoKSwgZXhjZXB0IHRoYXQg Rk9MTF9UT1VDSCBpcyBub3Qgc2V0LCBhbmQKPiArICogRk9MTF9QSU4gaXMgc2V0Lgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBw dXRfdXNlcl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNl cl9wYWdlcy5yc3QgZm9yIGRldGFpbHMuCj4gKyAqCj4gKyAqIFRoaXMgaXMgaW50ZW5kZWQgZm9y IENhc2UgMSAoRElPKSBpbiBEb2N1bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4gSXQK PiArICogaXMgTk9UIGludGVuZGVkIGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKS4K PiArICovCj4gK2xvbmcgcGluX3VzZXJfcGFnZXModW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWdu ZWQgbG9uZyBucl9wYWdlcywKPiArCQkgICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0 IHBhZ2UgKipwYWdlcywKPiArCQkgICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcykKPiAr ewo+ICsJLyogRk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuICov Cj4gKwlpZiAoV0FSTl9PTl9PTkNFKGd1cF9mbGFncyAmIEZPTExfR0VUKSkKPiArCQlyZXR1cm4g LUVJTlZBTDsKPiArCj4gKwlndXBfZmxhZ3MgfD0gRk9MTF9QSU47Cj4gKwlyZXR1cm4gX19ndXBf bG9uZ3Rlcm1fbG9ja2VkKGN1cnJlbnQsIGN1cnJlbnQtPm1tLCBzdGFydCwgbnJfcGFnZXMsCj4g KwkJCQkgICAgIHBhZ2VzLCB2bWFzLCBndXBfZmxhZ3MpOwo+ICt9Cj4gK0VYUE9SVF9TWU1CT0wo cGluX3VzZXJfcGFnZXMpOwo+ICsKPiArLyoqCj4gKyAqIHBpbl9sb25ndGVybV9wYWdlcygpIC0g cGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IGZvciBsb25nLXRlcm0gdXNlIChSRE1BLAo+ICsgKiB0 eXBpY2FsbHkpCj4gKyAqCj4gKyAqIE5lYXJseSB0aGUgc2FtZSBhcyBnZXRfdXNlcl9wYWdlcygp LCBleGNlcHQgdGhhdCBGT0xMX1BJTiBhbmQgRk9MTF9MT05HVEVSTQo+ICsgKiBhcmUgc2V0LiBT ZWUgZ2V0X3VzZXJfcGFnZXNfZmFzdCgpIGZvciBkb2N1bWVudGF0aW9uIG9uIHRoZSBmdW5jdGlv bgo+ICsgKiBhcmd1bWVudHMsIGJlY2F1c2UgdGhlIGFyZ3VtZW50cyBoZXJlIGFyZSBpZGVudGlj YWwuCj4gKyAqCj4gKyAqIEZPTExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3QgYmUgcmVs ZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVudGF0aW9u L3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdCBmb3IgZnVydGhlciBkZXRhaWxzLgo+ICsgKgo+ICsgKiBG T0xMX0xPTkdURVJNIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIGFyZSBiZWluZyBwaW5uZWQgZm9yICJs b25nIHRlcm0iIHVzZSwKPiArICogdHlwaWNhbGx5IGJ5IGEgbm9uLUNQVSBkZXZpY2UsIGFuZCB3 ZSBjYW5ub3QgYmUgc3VyZSB0aGF0IHdhaXRpbmcgZm9yIGEKPiArICogcGlubmVkIHBhZ2UgdG8g YmVjb21lIHVucGluIHdpbGwgYmUgZWZmZWN0aXZlLgo+ICsgKgo+ICsgKiBUaGlzIGlzIGludGVu ZGVkIGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKSBpbgo+ICsgKiBEb2N1bWVudGF0 aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4KPiArICovCj4gK2xvbmcgcGluX2xvbmd0ZXJtX3Bh Z2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMsCj4gKwkJCXVu c2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gKwkJCXN0cnVjdCB2 bV9hcmVhX3N0cnVjdCAqKnZtYXMpCj4gK3sKPiArCS8qIEZPTExfR0VUIGFuZCBGT0xMX1BJTiBh cmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ICsJaWYgKFdBUk5fT05fT05DRShndXBfZmxhZ3Mg JiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJZ3VwX2ZsYWdzIHw9IEZP TExfUElOIHwgRk9MTF9MT05HVEVSTTsKPiArCXJldHVybiBfX2d1cF9sb25ndGVybV9sb2NrZWQo Y3VycmVudCwgY3VycmVudC0+bW0sIHN0YXJ0LCBucl9wYWdlcywKPiArCQkJCSAgICAgcGFnZXMs IHZtYXMsIGd1cF9mbGFncyk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTChwaW5fbG9uZ3Rlcm1fcGFn ZXMpOwo+IC0tIAo+IDIuMjMuMAo+IApfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVl ZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5m by9kcmktZGV2ZWw= 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=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, 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 24BD7CA9ECB for ; Thu, 31 Oct 2019 23:15:13 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EFA2E2080F for ; Thu, 31 Oct 2019 23:15:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EFA2E2080F Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 79AB96F686; Thu, 31 Oct 2019 23:15:12 +0000 (UTC) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 880D56F686 for ; Thu, 31 Oct 2019 23:15:11 +0000 (UTC) X-Amp-Result: UNKNOWN X-Amp-Original-Verdict: FILE UNKNOWN X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Oct 2019 16:15:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,253,1569308400"; d="scan'208";a="225867978" Received: from iweiny-desk2.sc.intel.com ([10.3.52.157]) by fmsmga004.fm.intel.com with ESMTP; 31 Oct 2019 16:15:04 -0700 Date: Thu, 31 Oct 2019 16:15:04 -0700 From: Ira Weiny To: John Hubbard Subject: Re: [PATCH 05/19] mm/gup: introduce pin_user_pages*() and FOLL_PIN Message-ID: <20191031231503.GF14771@iweiny-DESK2.sc.intel.com> References: <20191030224930.3990755-1-jhubbard@nvidia.com> <20191030224930.3990755-6-jhubbard@nvidia.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191030224930.3990755-6-jhubbard@nvidia.com> User-Agent: Mutt/1.11.1 (2018-12-01) X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Michal Hocko , Jan Kara , kvm@vger.kernel.org, linux-doc@vger.kernel.org, David Airlie , Dave Chinner , dri-devel@lists.freedesktop.org, LKML , linux-mm@kvack.org, Paul Mackerras , linux-kselftest@vger.kernel.org, Shuah Khan , Jonathan Corbet , linux-rdma@vger.kernel.org, Michael Ellerman , Christoph Hellwig , Jason Gunthorpe , Vlastimil Babka , =?iso-8859-1?Q?Bj=F6rn_T=F6pel?= , linux-media@vger.kernel.org, linux-block@vger.kernel.org, =?iso-8859-1?B?Suly9G1l?= Glisse , Al Viro , Dan Williams , Mauro Carvalho Chehab , bpf@vger.kernel.org, Magnus Karlsson , Jens Axboe , netdev@vger.kernel.org, Alex Williamson , linux-fsdevel@vger.kernel.org, Andrew Morton , linuxppc-dev@lists.ozlabs.org, "David S . Miller" , Mike Kravetz Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Message-ID: <20191031231504.6Cek9bLHDf9Zcl1gxH9qcSMWEsAcBwb_p1pb1wNG6KA@z> T24gV2VkLCBPY3QgMzAsIDIwMTkgYXQgMDM6NDk6MTZQTSAtMDcwMCwgSm9obiBIdWJiYXJkIHdy b3RlOgo+IEludHJvZHVjZSBwaW5fdXNlcl9wYWdlcyooKSB2YXJpYXRpb25zIG9mIGdldF91c2Vy X3BhZ2VzKigpIGNhbGxzLAo+IGFuZCBhbHNvIHBpbl9sb25ndGVybV9wYWdlcyooKSB2YXJpYXRp b25zLgo+IAo+IFRoZXNlIHZhcmlhbnRzIGFsbCBzZXQgRk9MTF9QSU4sIHdoaWNoIGlzIGFsc28g aW50cm9kdWNlZCwgYW5kCj4gYmFzaWNhbGx5IGRvY3VtZW50ZWQuIChBbiB1cGNvbWluZyBwYXRj aCBwcm92aWRlcyBtb3JlIGV4dGVuc2l2ZQo+IGRvY3VtZW50YXRpb24uKSBUaGUgc2Vjb25kIHNl dCAocGluX2xvbmd0ZXJtKikgYWxzbyBzZXRzCj4gRk9MTF9MT05HVEVSTToKPiAKPiAgICAgcGlu X3VzZXJfcGFnZXMoKQo+ICAgICBwaW5fdXNlcl9wYWdlc19yZW1vdGUoKQo+ICAgICBwaW5fdXNl cl9wYWdlc19mYXN0KCkKPiAKPiAgICAgcGluX2xvbmd0ZXJtX3BhZ2VzKCkKPiAgICAgcGluX2xv bmd0ZXJtX3BhZ2VzX3JlbW90ZSgpCj4gICAgIHBpbl9sb25ndGVybV9wYWdlc19mYXN0KCkKPiAK PiBBbGwgcGFnZXMgdGhhdCBhcmUgcGlubmVkIHZpYSB0aGUgYWJvdmUgY2FsbHMsIG11c3QgYmUg dW5waW5uZWQgdmlhCj4gcHV0X3VzZXJfcGFnZSgpLgo+IAo+IFRoZSB1bmRlcmx5aW5nIHJ1bGVz IGFyZToKPiAKPiAqIFRoZXNlIGFyZSBndXAtaW50ZXJuYWwgZmxhZ3MsIHNvIHRoZSBjYWxsIHNp dGVzIHNob3VsZCBub3QgZGlyZWN0bHkKPiBzZXQgRk9MTF9QSU4gbm9yIEZPTExfTE9OR1RFUk0u IFRoYXQgYmVoYXZpb3IgaXMgZW5mb3JjZWQgd2l0aAo+IGFzc2VydGlvbnMsIGZvciB0aGUgbmV3 IEZPTExfUElOIGZsYWcuIEhvd2V2ZXIsIGZvciB0aGUgcHJlLWV4aXN0aW5nCj4gRk9MTF9MT05H VEVSTSBmbGFnLCB3aGljaCBoYXMgc29tZSBjYWxsIHNpdGVzIHRoYXQgc3RpbGwgZGlyZWN0bHkK PiBzZXQgRk9MTF9MT05HVEVSTSwgdGhlcmUgaXMgbm8gYXNzZXJ0aW9uIHlldC4KPiAKPiAqIENh bGwgc2l0ZXMgdGhhdCB3YW50IHRvIGluZGljYXRlIHRoYXQgdGhleSBhcmUgZ29pbmcgdG8gZG8g RGlyZWN0SU8KPiAgICgiRElPIikgb3Igc29tZXRoaW5nIHdpdGggc2ltaWxhciBjaGFyYWN0ZXJp c3RpY3MsIHNob3VsZCBjYWxsIGEKPiAgIGdldF91c2VyX3BhZ2VzKCktbGlrZSB3cmFwcGVyIGNh bGwgdGhhdCBzZXRzIEZPTExfUElOLiBUaGVzZSB3cmFwcGVycwo+ICAgd2lsbDoKPiAgICAgICAg ICogU3RhcnQgd2l0aCAicGluX3VzZXJfcGFnZXMiIGluc3RlYWQgb2YgImdldF91c2VyX3BhZ2Vz Ii4gVGhhdAo+ICAgICAgICAgICBtYWtlcyBpdCBlYXN5IHRvIGZpbmQgYW5kIGF1ZGl0IHRoZSBj YWxsIHNpdGVzLgo+ICAgICAgICAgKiBTZXQgRk9MTF9QSU4KPiAKPiAqIEZvciBwYWdlcyB0aGF0 IGFyZSByZWNlaXZlZCB2aWEgRk9MTF9QSU4sIHRob3NlIHBhZ2VzIG11c3QgYmUgcmV0dXJuZWQK PiAgIHZpYSBwdXRfdXNlcl9wYWdlKCkuCj4gCj4gU2lnbmVkLW9mZi1ieTogSm9obiBIdWJiYXJk IDxqaHViYmFyZEBudmlkaWEuY29tPgo+IC0tLQo+ICBpbmNsdWRlL2xpbnV4L21tLmggfCAgNTMg KysrKysrKystCj4gIG1tL2d1cC5jICAgICAgICAgICB8IDI4NCArKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKy0tLS0KPiAgMiBmaWxlcyBjaGFuZ2VkLCAzMTEgaW5zZXJ0 aW9ucygrKSwgMjYgZGVsZXRpb25zKC0pCj4gCj4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgv bW0uaCBiL2luY2x1ZGUvbGludXgvbW0uaAo+IGluZGV4IGNjMjkyMjczZTZiYS4uNjJjODM4YTNl NmM3IDEwMDY0NAo+IC0tLSBhL2luY2x1ZGUvbGludXgvbW0uaAo+ICsrKyBiL2luY2x1ZGUvbGlu dXgvbW0uaAo+IEBAIC0xNTI2LDkgKzE1MjYsMjMgQEAgbG9uZyBnZXRfdXNlcl9wYWdlc19yZW1v dGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICAJCQkg ICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiAgCQkJICAg IHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gIAkJCSAgICBz dHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzLCBpbnQgKmxvY2tlZCk7Cj4gK2xvbmcgcGluX3Vz ZXJfcGFnZXNfcmVtb3RlKHN0cnVjdCB0YXNrX3N0cnVjdCAqdHNrLCBzdHJ1Y3QgbW1fc3RydWN0 ICptbSwKPiArCQkJICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdl cywKPiArCQkJICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywK PiArCQkJICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcywgaW50ICpsb2NrZWQpOwo+ICts b25nIHBpbl9sb25ndGVybV9wYWdlc19yZW1vdGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0 cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICsJCQkgICAgICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5z aWduZWQgbG9uZyBucl9wYWdlcywKPiArCQkJICAgICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3Ms IHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gKwkJCSAgICAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3Qg Kip2bWFzLCBpbnQgKmxvY2tlZCk7Cj4gIGxvbmcgZ2V0X3VzZXJfcGFnZXModW5zaWduZWQgbG9u ZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiAgCQkJICAgIHVuc2lnbmVkIGludCBn dXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gIAkJCSAgICBzdHJ1Y3Qgdm1fYXJlYV9z dHJ1Y3QgKip2bWFzKTsKPiArbG9uZyBwaW5fdXNlcl9wYWdlcyh1bnNpZ25lZCBsb25nIHN0YXJ0 LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICsJCSAgICB1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdz LCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAo+ICsJCSAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2 bWFzKTsKPiArbG9uZyBwaW5fbG9uZ3Rlcm1fcGFnZXModW5zaWduZWQgbG9uZyBzdGFydCwgdW5z aWduZWQgbG9uZyBucl9wYWdlcywKPiArCQkJdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0 IHBhZ2UgKipwYWdlcywKPiArCQkJc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcyk7Cj4gIGxv bmcgZ2V0X3VzZXJfcGFnZXNfbG9ja2VkKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxv bmcgbnJfcGFnZXMsCj4gIAkJICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdl ICoqcGFnZXMsIGludCAqbG9ja2VkKTsKPiAgbG9uZyBnZXRfdXNlcl9wYWdlc191bmxvY2tlZCh1 bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+IEBAIC0xNTM2LDYg KzE1NTAsMTAgQEAgbG9uZyBnZXRfdXNlcl9wYWdlc191bmxvY2tlZCh1bnNpZ25lZCBsb25nIHN0 YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICAKPiAgaW50IGdldF91c2VyX3BhZ2VzX2Zh c3QodW5zaWduZWQgbG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICAJCQl1bnNpZ25lZCBpbnQg Z3VwX2ZsYWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKPiAraW50IHBpbl91c2VyX3BhZ2VzX2Zh c3QodW5zaWduZWQgbG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICsJCQl1bnNpZ25lZCBpbnQg Z3VwX2ZsYWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKPiAraW50IHBpbl9sb25ndGVybV9wYWdl c19mYXN0KHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBucl9wYWdlcywKPiArCQkJICAgIHVuc2ln bmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMpOwo+ICAKPiAgaW50IGFjY291 bnRfbG9ja2VkX3ZtKHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLCB1bnNpZ25lZCBsb25nIHBhZ2VzLCBi b29sIGluYyk7Cj4gIGludCBfX2FjY291bnRfbG9ja2VkX3ZtKHN0cnVjdCBtbV9zdHJ1Y3QgKm1t LCB1bnNpZ25lZCBsb25nIHBhZ2VzLCBib29sIGluYywKPiBAQCAtMjU5NCwxMyArMjYxMiwxNSBA QCBzdHJ1Y3QgcGFnZSAqZm9sbG93X3BhZ2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVu c2lnbmVkIGxvbmcgYWRkcmVzcywKPiAgI2RlZmluZSBGT0xMX0FOT04JMHg4MDAwCS8qIGRvbid0 IGRvIGZpbGUgbWFwcGluZ3MgKi8KPiAgI2RlZmluZSBGT0xMX0xPTkdURVJNCTB4MTAwMDAJLyog bWFwcGluZyBsaWZldGltZSBpcyBpbmRlZmluaXRlOiBzZWUgYmVsb3cgKi8KPiAgI2RlZmluZSBG T0xMX1NQTElUX1BNRAkweDIwMDAwCS8qIHNwbGl0IGh1Z2UgcG1kIGJlZm9yZSByZXR1cm5pbmcg Ki8KPiArI2RlZmluZSBGT0xMX1BJTgkweDQwMDAwCS8qIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQg dmlhIHB1dF91c2VyX3BhZ2UoKSAqLwo+ICAKPiAgLyoKPiAtICogTk9URSBvbiBGT0xMX0xPTkdU RVJNOgo+ICsgKiBGT0xMX1BJTiBhbmQgRk9MTF9MT05HVEVSTSBtYXkgYmUgdXNlZCBpbiB2YXJp b3VzIGNvbWJpbmF0aW9ucyB3aXRoIGVhY2gKPiArICogb3RoZXIuIEhlcmUgaXMgd2hhdCB0aGV5 IG1lYW4sIGFuZCBob3cgdG8gdXNlIHRoZW06Cj4gICAqCj4gICAqIEZPTExfTE9OR1RFUk0gaW5k aWNhdGVzIHRoYXQgdGhlIHBhZ2Ugd2lsbCBiZSBoZWxkIGZvciBhbiBpbmRlZmluaXRlIHRpbWUK PiAtICogcGVyaW9kIF9vZnRlbl8gdW5kZXIgdXNlcnNwYWNlIGNvbnRyb2wuICBUaGlzIGlzIGNv bnRyYXN0ZWQgd2l0aAo+IC0gKiBpb3ZfaXRlcl9nZXRfcGFnZXMoKSB3aGVyZSB1c2FnZXMgd2hp Y2ggYXJlIHRyYW5zaWVudC4KPiArICogcGVyaW9kIF9vZnRlbl8gdW5kZXIgdXNlcnNwYWNlIGNv bnRyb2wuICBUaGlzIGlzIGluIGNvbnRyYXN0IHRvCj4gKyAqIGlvdl9pdGVyX2dldF9wYWdlcygp LCB3aGVyZSB1c2FnZXMgd2hpY2ggYXJlIHRyYW5zaWVudC4KPiAgICoKPiAgICogRklYTUU6IEZv ciBwYWdlcyB3aGljaCBhcmUgcGFydCBvZiBhIGZpbGVzeXN0ZW0sIG1hcHBpbmdzIGFyZSBzdWJq ZWN0IHRvIHRoZQo+ICAgKiBsaWZldGltZSBlbmZvcmNlZCBieSB0aGUgZmlsZXN5c3RlbSBhbmQg d2UgbmVlZCBndWFyYW50ZWVzIHRoYXQgbG9uZ3Rlcm0KPiBAQCAtMjYxNSwxMSArMjYzNSwzMiBA QCBzdHJ1Y3QgcGFnZSAqZm9sbG93X3BhZ2Uoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVu c2lnbmVkIGxvbmcgYWRkcmVzcywKPiAgICogQ3VycmVudGx5IG9ubHkgZ2V0X3VzZXJfcGFnZXMo KSBhbmQgZ2V0X3VzZXJfcGFnZXNfZmFzdCgpIHN1cHBvcnQgdGhpcyBmbGFnCj4gICAqIGFuZCBj YWxscyB0byBnZXRfdXNlcl9wYWdlc19bdW5dbG9ja2VkIGFyZSBzcGVjaWZpY2FsbHkgbm90IGFs bG93ZWQuICBUaGlzCj4gICAqIGlzIGR1ZSB0byBhbiBpbmNvbXBhdGliaWxpdHkgd2l0aCB0aGUg RlMgREFYIGNoZWNrIGFuZAo+IC0gKiBGQVVMVF9GTEFHX0FMTE9XX1JFVFJZCj4gKyAqIEZBVUxU X0ZMQUdfQUxMT1dfUkVUUlkuCj4gICAqCj4gLSAqIEluIHRoZSBDTUEgY2FzZTogbG9uZ3Rlcm0g cGlucyBpbiBhIENNQSByZWdpb24gd291bGQgdW5uZWNlc3NhcmlseSBmcmFnbWVudAo+IC0gKiB0 aGF0IHJlZ2lvbi4gIEFuZCBzbyBDTUEgYXR0ZW1wdHMgdG8gbWlncmF0ZSB0aGUgcGFnZSBiZWZv cmUgcGlubmluZyB3aGVuCj4gKyAqIEluIHRoZSBDTUEgY2FzZTogbG9uZyB0ZXJtIHBpbnMgaW4g YSBDTUEgcmVnaW9uIHdvdWxkIHVubmVjZXNzYXJpbHkgZnJhZ21lbnQKPiArICogdGhhdCByZWdp b24uICBBbmQgc28sIENNQSBhdHRlbXB0cyB0byBtaWdyYXRlIHRoZSBwYWdlIGJlZm9yZSBwaW5u aW5nLCB3aGVuCj4gICAqIEZPTExfTE9OR1RFUk0gaXMgc3BlY2lmaWVkLgo+ICsgKgo+ICsgKiBG T0xMX1BJTiBpbmRpY2F0ZXMgdGhhdCBhIHNwZWNpYWwga2luZCBvZiB0cmFja2luZyAobm90IGp1 c3QgcGFnZS0+X3JlZmNvdW50LAo+ICsgKiBidXQgYW4gYWRkaXRpb25hbCBwaW4gY291bnRpbmcg c3lzdGVtKSB3aWxsIGJlIGludm9rZWQuIFRoaXMgaXMgaW50ZW5kZWQgZm9yCj4gKyAqIGFueXRo aW5nIHRoYXQgZ2V0cyBhIHBhZ2UgcmVmZXJlbmNlIGFuZCB0aGVuIHRvdWNoZXMgcGFnZSBkYXRh IChmb3IgZXhhbXBsZSwKPiArICogRGlyZWN0IElPKS4gVGhpcyBsZXRzIHRoZSBmaWxlc3lzdGVt IGtub3cgdGhhdCBzb21lIG5vbi1maWxlLXN5c3RlbSBlbnRpdHkgaXMKPiArICogcG90ZW50aWFs bHkgY2hhbmdpbmcgdGhlIHBhZ2VzJyBkYXRhLiBJbiBjb250cmFzdCB0byBGT0xMX0dFVCAod2hv c2UgcGFnZXMKPiArICogYXJlIHJlbGVhc2VkIHZpYSBwdXRfcGFnZSgpKSwgRk9MTF9QSU4gcGFn ZXMgbXVzdCBiZSByZWxlYXNlZCwgdWx0aW1hdGVseSwgYnkKPiArICogYSBjYWxsIHRvIHB1dF91 c2VyX3BhZ2UoKS4KPiArICoKPiArICogRk9MTF9QSU4gaXMgc2ltaWxhciB0byBGT0xMX0dFVDog Ym90aCBvZiB0aGVzZSBwaW4gcGFnZXMuIFRoZXkgdXNlIGRpZmZlcmVudAo+ICsgKiBhbmQgc2Vw YXJhdGUgcmVmY291bnRpbmcgbWVjaGFuaXNtcywgaG93ZXZlciwgYW5kIHRoYXQgbWVhbnMgdGhh dCBlYWNoIGhhcwo+ICsgKiBpdHMgb3duIGFjcXVpcmUgYW5kIHJlbGVhc2UgbWVjaGFuaXNtczoK PiArICoKPiArICogICAgIEZPTExfR0VUOiBnZXRfdXNlcl9wYWdlcyooKSB0byBhY3F1aXJlLCBh bmQgcHV0X3BhZ2UoKSB0byByZWxlYXNlLgo+ICsgKgo+ICsgKiAgICAgRk9MTF9QSU46IHBpbl91 c2VyX3BhZ2VzKigpIG9yIHBpbl9sb25ndGVybV9wYWdlcyooKSB0byBhY3F1aXJlLCBhbmQKPiAr ICogICAgICAgICAgICAgICBwdXRfdXNlcl9wYWdlcyB0byByZWxlYXNlLgo+ICsgKgo+ICsgKiBG T0xMX1BJTiBhbmQgRk9MTF9HRVQgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4KCllvdSBtZWFuIHRo ZSBmbGFncyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGZvciBhbnkgc2luZ2xlIGNhbGwsIGNvcnJl Y3Q/CkJlY2F1c2UgbXkgZmlyc3QgdGhvdWdodCB3YXMgdGhhdCB5b3UgbWVhbnQgdGhhdCBhIHBh Z2Ugd2hpY2ggd2FzIHBpbidlZCBjYW4ndApiZSAiZ290Ii4gIFdoaWNoIEkgZG9uJ3QgdGhpbmsg aXMgdHJ1ZSBvciBuZWNlc3NhcnkuLi4KCj4gKyAqCj4gKyAqIFBsZWFzZSBzZWUgRG9jdW1lbnRh dGlvbi92bS9waW5fdXNlcl9wYWdlcy5yc3QgZm9yIG1vcmUgaW5mb3JtYXRpb24uCgpOSVQ6IEkg dGhpbmsgd2Ugc2hvdWxkIGluY2x1ZGUgdGhpcyBmaWxlIGFzIHBhcnQgb2YgdGhpcyBwYXRjaC4u LgoKPiAgICovCj4gIAo+ICBzdGF0aWMgaW5saW5lIGludCB2bV9mYXVsdF90b19lcnJubyh2bV9m YXVsdF90IHZtX2ZhdWx0LCBpbnQgZm9sbF9mbGFncykKPiBkaWZmIC0tZ2l0IGEvbW0vZ3VwLmMg Yi9tbS9ndXAuYwo+IGluZGV4IDhmYjBkOWNkZmFmNS4uODY5NGJjN2IzZGYzIDEwMDY0NAo+IC0t LSBhL21tL2d1cC5jCj4gKysrIGIvbW0vZ3VwLmMKPiBAQCAtMTc5LDYgKzE3OSwxMCBAQCBzdGF0 aWMgc3RydWN0IHBhZ2UgKmZvbGxvd19wYWdlX3B0ZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZt YSwKPiAgCXNwaW5sb2NrX3QgKnB0bDsKPiAgCXB0ZV90ICpwdGVwLCBwdGU7Cj4gIAo+ICsJLyog Rk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuICovCj4gKwlpZiAo V0FSTl9PTl9PTkNFKChmbGFncyAmIChGT0xMX1BJTiB8IEZPTExfR0VUKSkgPT0KPiArCQkJIChG T0xMX1BJTiB8IEZPTExfR0VUKSkpCj4gKwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gIHJl dHJ5Ogo+ICAJaWYgKHVubGlrZWx5KHBtZF9iYWQoKnBtZCkpKQo+ICAJCXJldHVybiBub19wYWdl X3RhYmxlKHZtYSwgZmxhZ3MpOwo+IEBAIC03OTAsNyArNzk0LDcgQEAgc3RhdGljIGxvbmcgX19n ZXRfdXNlcl9wYWdlcyhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywgc3RydWN0IG1tX3N0cnVjdCAq bW0sCj4gIAo+ICAJc3RhcnQgPSB1bnRhZ2dlZF9hZGRyKHN0YXJ0KTsKPiAgCj4gLQlWTV9CVUdf T04oISFwYWdlcyAhPSAhIShndXBfZmxhZ3MgJiBGT0xMX0dFVCkpOwo+ICsJVk1fQlVHX09OKCEh cGFnZXMgIT0gISEoZ3VwX2ZsYWdzICYgKEZPTExfR0VUIHwgRk9MTF9QSU4pKSk7Cj4gIAo+ICAJ LyoKPiAgCSAqIElmIEZPTExfRk9SQ0UgaXMgc2V0IHRoZW4gZG8gbm90IGZvcmNlIGEgZnVsbCBm YXVsdCBhcyB0aGUgaGludGluZwo+IEBAIC0xMDE0LDcgKzEwMTgsMTYgQEAgc3RhdGljIF9fYWx3 YXlzX2lubGluZSBsb25nIF9fZ2V0X3VzZXJfcGFnZXNfbG9ja2VkKHN0cnVjdCB0YXNrX3N0cnVj dCAqdHNrLAo+ICAJCUJVR19PTigqbG9ja2VkICE9IDEpOwo+ICAJfQo+ICAKPiAtCWlmIChwYWdl cykKPiArCS8qCj4gKwkgKiBGT0xMX1BJTiBhbmQgRk9MTF9HRVQgYXJlIG11dHVhbGx5IGV4Y2x1 c2l2ZS4gVHJhZGl0aW9uYWwgYmVoYXZpb3IKPiArCSAqIGlzIHRvIHNldCBGT0xMX0dFVCBpZiB0 aGUgY2FsbGVyIHdhbnRzIHBhZ2VzW10gZmlsbGVkIGluIChidXQgaGFzCj4gKwkgKiBjYXJlbGVz c2x5IGZhaWxlZCB0byBzcGVjaWZ5IEZPTExfR0VUKSwgc28ga2VlcCBkb2luZyB0aGF0LCBidXQg b25seQo+ICsJICogZm9yIEZPTExfR0VULCBub3QgZm9yIHRoZSBuZXdlciBGT0xMX1BJTi4KPiAr CSAqCj4gKwkgKiBGT0xMX1BJTiBhbHdheXMgZXhwZWN0cyBwYWdlcyB0byBiZSBub24tbnVsbCwg YnV0IG5vIG5lZWQgdG8gYXNzZXJ0Cj4gKwkgKiB0aGF0IGhlcmUsIGFzIGFueSBmYWlsdXJlcyB3 aWxsIGJlIG9idmlvdXMgZW5vdWdoLgo+ICsJICovCj4gKwlpZiAocGFnZXMgJiYgIShmbGFncyAm IEZPTExfUElOKSkKPiAgCQlmbGFncyB8PSBGT0xMX0dFVDsKPiAgCj4gIAlwYWdlc19kb25lID0g MDsKPiBAQCAtMTEzMyw2ICsxMTQ2LDEyIEBAIHN0YXRpYyBfX2Fsd2F5c19pbmxpbmUgbG9uZyBf X2dldF91c2VyX3BhZ2VzX2xvY2tlZChzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywKPiAgICogaXMg d3JpdHRlbiB0bywgc2V0X3BhZ2VfZGlydHkgKG9yIHNldF9wYWdlX2RpcnR5X2xvY2ssIGFzIGFw cHJvcHJpYXRlKSBtdXN0Cj4gICAqIGJlIGNhbGxlZCBhZnRlciB0aGUgcGFnZSBpcyBmaW5pc2hl ZCB3aXRoLCBhbmQgYmVmb3JlIHB1dF9wYWdlIGlzIGNhbGxlZC4KPiAgICoKPiArICogQSBub3Rl IG9uIGd1cF9mbGFnczogRk9MTF9QSU4gbXVzdCBvbmx5IGJlIHNldCBpbnRlcm5hbGx5IGJ5IHRo ZQo+ICsgKiBwaW5fdXNlcl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVy IGRpcmVjdGx5IGJ5IHRoZSBjYWxsZXIuCj4gKyAqIFRoYXQncyBpbiBvcmRlciB0byBoZWxwIGF2 b2lkIG1pc21hdGNoZXMgd2hlbiByZWxlYXNpbmcgcGFnZXM6Cj4gKyAqIGdldF91c2VyX3BhZ2Vz KigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF9wYWdlKCksIHdoaWxlCj4gKyAqIHBp bl91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2Uo KS4KPiArICoKPiAgICogZ2V0X3VzZXJfcGFnZXMgaXMgdHlwaWNhbGx5IHVzZWQgZm9yIGZld2Vy LWNvcHkgSU8gb3BlcmF0aW9ucywgdG8gZ2V0IGEKPiAgICogaGFuZGxlIG9uIHRoZSBtZW1vcnkg Ynkgc29tZSBtZWFucyBvdGhlciB0aGFuIGFjY2Vzc2VzIHZpYSB0aGUgdXNlciB2aXJ0dWFsCj4g ICAqIGFkZHJlc3Nlcy4gVGhlIHBhZ2VzIG1heSBiZSBzdWJtaXR0ZWQgZm9yIERNQSB0byBkZXZp Y2VzIG9yIGFjY2Vzc2VkIHZpYQo+IEBAIC0xMTUxLDYgKzExNzAsMTQgQEAgbG9uZyBnZXRfdXNl cl9wYWdlc19yZW1vdGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3Qg Km1tLAo+ICAJCXVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4g IAkJc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcywgaW50ICpsb2NrZWQpCj4gIHsKPiArCS8q Cj4gKwkgKiBBcyBkZXRhaWxlZCBhYm92ZSwgRk9MTF9QSU4gbXVzdCBvbmx5IGJlIHNldCBpbnRl cm5hbGx5IGJ5IHRoZQo+ICsJICogcGluX3VzZXJfcGFnZSooKSBhbmQgcGluX2xvbmd0ZXJtXyoo KSBBUElzLCBuZXZlciBkaXJlY3RseSBieSB0aGUKPiArCSAqIGNhbGxlciwgc28gZW5mb3JjZSB0 aGF0IHdpdGggYW4gYXNzZXJ0aW9uOgo+ICsJICovCj4gKwlpZiAoV0FSTl9PTl9PTkNFKGd1cF9m bGFncyAmIEZPTExfUElOKSkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gIAkvKgo+ICAJICog RklYTUU6IEN1cnJlbnQgRk9MTF9MT05HVEVSTSBiZWhhdmlvciBpcyBpbmNvbXBhdGlibGUgd2l0 aAo+ICAJICogRkFVTFRfRkxBR19BTExPV19SRVRSWSBiZWNhdXNlIG9mIHRoZSBGUyBEQVggY2hl Y2sgcmVxdWlyZW1lbnQgb24KPiBAQCAtMTYwMywxMSArMTYzMCwyNSBAQCBzdGF0aWMgX19hbHdh eXNfaW5saW5lIGxvbmcgX19ndXBfbG9uZ3Rlcm1fbG9ja2VkKHN0cnVjdCB0YXNrX3N0cnVjdCAq dHNrLAo+ICAgKiBhbmQgbW0gYmVpbmcgb3BlcmF0ZWQgb24gYXJlIHRoZSBjdXJyZW50IHRhc2sn cyBhbmQgZG9uJ3QgYWxsb3cKPiAgICogcGFzc2luZyBvZiBhIGxvY2tlZCBwYXJhbWV0ZXIuICBX ZSBhbHNvIG9idmlvdXNseSBkb24ndCBwYXNzCj4gICAqIEZPTExfUkVNT1RFIGluIGhlcmUuCj4g KyAqCj4gKyAqIEEgbm90ZSBvbiBndXBfZmxhZ3M6IEZPTExfUElOIHNob3VsZCBvbmx5IGJlIHNl dCBpbnRlcm5hbGx5IGJ5IHRoZQo+ICsgKiBwaW5fdXNlcl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rl cm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRoZSBjYWxsZXIuCj4gKyAqIFRoYXQncyBp biBvcmRlciB0byBoZWxwIGF2b2lkIG1pc21hdGNoZXMgd2hlbiByZWxlYXNpbmcgcGFnZXM6Cj4g KyAqIGdldF91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF9wYWdl KCksIHdoaWxlCj4gKyAqIHBpbl91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQg dmlhIHB1dF91c2VyX3BhZ2UoKS4KClJhdGhlciB0aGFuIHB1dCB0aGlzIGhlcmUgc2hvdWxkIHdl IHB1dCBpdCBuZXh0IHRvIHRoZSBkZWZpbml0aW9uIG9mIEZPTExfUElOPwpCZWNhdXNlIG5vdyB3 ZSBoYXZlIHRoaXMgdGV4dCAyeC4uLiAgOi0vCgo+ICAgKi8KPiAgbG9uZyBnZXRfdXNlcl9wYWdl cyh1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICAJCXVuc2ln bmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gIAkJc3RydWN0IHZtX2Fy ZWFfc3RydWN0ICoqdm1hcykKPiAgewo+ICsJLyoKPiArCSAqIEFzIGRldGFpbGVkIGFib3ZlLCBG T0xMX1BJTiBtdXN0IG9ubHkgYmUgc2V0IGludGVybmFsbHkgYnkgdGhlCj4gKwkgKiBwaW5fdXNl cl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRo ZQo+ICsJICogY2FsbGVyLCBzbyBlbmZvcmNlIHRoYXQgd2l0aCBhbiBhc3NlcnRpb246Cj4gKwkg Ki8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9QSU4pKQo+ICsJCXJldHVy biAtRUlOVkFMOwo+ICsKPiAgCXJldHVybiBfX2d1cF9sb25ndGVybV9sb2NrZWQoY3VycmVudCwg Y3VycmVudC0+bW0sIHN0YXJ0LCBucl9wYWdlcywKPiAgCQkJCSAgICAgcGFnZXMsIHZtYXMsIGd1 cF9mbGFncyB8IEZPTExfVE9VQ0gpOwo+ICB9Cj4gQEAgLTIzNjYsMjQgKzI0MDcsOSBAQCBzdGF0 aWMgaW50IF9fZ3VwX2xvbmd0ZXJtX3VubG9ja2VkKHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBu cl9wYWdlcywKPiAgCXJldHVybiByZXQ7Cj4gIH0KPiAgCj4gLS8qKgo+IC0gKiBnZXRfdXNlcl9w YWdlc19mYXN0KCkgLSBwaW4gdXNlciBwYWdlcyBpbiBtZW1vcnkKPiAtICogQHN0YXJ0OglzdGFy dGluZyB1c2VyIGFkZHJlc3MKPiAtICogQG5yX3BhZ2VzOgludW1iZXIgb2YgcGFnZXMgZnJvbSBz dGFydCB0byBwaW4KPiAtICogQGd1cF9mbGFnczoJZmxhZ3MgbW9kaWZ5aW5nIHBpbiBiZWhhdmlv dXIKPiAtICogQHBhZ2VzOglhcnJheSB0aGF0IHJlY2VpdmVzIHBvaW50ZXJzIHRvIHRoZSBwYWdl cyBwaW5uZWQuCj4gLSAqCQlTaG91bGQgYmUgYXQgbGVhc3QgbnJfcGFnZXMgbG9uZy4KPiAtICoK PiAtICogQXR0ZW1wdCB0byBwaW4gdXNlciBwYWdlcyBpbiBtZW1vcnkgd2l0aG91dCB0YWtpbmcg bW0tPm1tYXBfc2VtLgo+IC0gKiBJZiBub3Qgc3VjY2Vzc2Z1bCwgaXQgd2lsbCBmYWxsIGJhY2sg dG8gdGFraW5nIHRoZSBsb2NrIGFuZAo+IC0gKiBjYWxsaW5nIGdldF91c2VyX3BhZ2VzKCkuCj4g LSAqCj4gLSAqIFJldHVybnMgbnVtYmVyIG9mIHBhZ2VzIHBpbm5lZC4gVGhpcyBtYXkgYmUgZmV3 ZXIgdGhhbiB0aGUgbnVtYmVyCj4gLSAqIHJlcXVlc3RlZC4gSWYgbnJfcGFnZXMgaXMgMCBvciBu ZWdhdGl2ZSwgcmV0dXJucyAwLiBJZiBubyBwYWdlcwo+IC0gKiB3ZXJlIHBpbm5lZCwgcmV0dXJu cyAtZXJybm8uCj4gLSAqLwo+IC1pbnQgZ2V0X3VzZXJfcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25n IHN0YXJ0LCBpbnQgbnJfcGFnZXMsCj4gLQkJCXVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVj dCBwYWdlICoqcGFnZXMpCj4gK3N0YXRpYyBpbnQgaW50ZXJuYWxfZ2V0X3VzZXJfcGFnZXNfZmFz dCh1bnNpZ25lZCBsb25nIHN0YXJ0LCBpbnQgbnJfcGFnZXMsCj4gKwkJCQkJdW5zaWduZWQgaW50 IGd1cF9mbGFncywKPiArCQkJCQlzdHJ1Y3QgcGFnZSAqKnBhZ2VzKQo+ICB7Cj4gIAl1bnNpZ25l ZCBsb25nIGFkZHIsIGxlbiwgZW5kOwo+ICAJaW50IG5yID0gMCwgcmV0ID0gMDsKPiBAQCAtMjQy OCw0ICsyNDU0LDIyMiBAQCBpbnQgZ2V0X3VzZXJfcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0 YXJ0LCBpbnQgbnJfcGFnZXMsCj4gIAo+ICAJcmV0dXJuIHJldDsKPiAgfQo+ICsKPiArLyoqCj4g KyAqIGdldF91c2VyX3BhZ2VzX2Zhc3QoKSAtIHBpbiB1c2VyIHBhZ2VzIGluIG1lbW9yeQo+ICsg KiBAc3RhcnQ6CXN0YXJ0aW5nIHVzZXIgYWRkcmVzcwo+ICsgKiBAbnJfcGFnZXM6CW51bWJlciBv ZiBwYWdlcyBmcm9tIHN0YXJ0IHRvIHBpbgo+ICsgKiBAZ3VwX2ZsYWdzOglmbGFncyBtb2RpZnlp bmcgcGluIGJlaGF2aW91cgo+ICsgKiBAcGFnZXM6CWFycmF5IHRoYXQgcmVjZWl2ZXMgcG9pbnRl cnMgdG8gdGhlIHBhZ2VzIHBpbm5lZC4KPiArICoJCVNob3VsZCBiZSBhdCBsZWFzdCBucl9wYWdl cyBsb25nLgo+ICsgKgo+ICsgKiBBdHRlbXB0IHRvIHBpbiB1c2VyIHBhZ2VzIGluIG1lbW9yeSB3 aXRob3V0IHRha2luZyBtbS0+bW1hcF9zZW0uCj4gKyAqIElmIG5vdCBzdWNjZXNzZnVsLCBpdCB3 aWxsIGZhbGwgYmFjayB0byB0YWtpbmcgdGhlIGxvY2sgYW5kCj4gKyAqIGNhbGxpbmcgZ2V0X3Vz ZXJfcGFnZXMoKS4KPiArICoKPiArICogQSBub3RlIG9uIGd1cF9mbGFnczogRk9MTF9QSU4gbXVz dCBvbmx5IGJlIHNldCBpbnRlcm5hbGx5IGJ5IHRoZQo+ICsgKiBwaW5fdXNlcl9wYWdlKigpIGFu ZCBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRoZSBjYWxsZXIuCj4g KyAqIFRoYXQncyBpbiBvcmRlciB0byBoZWxwIGF2b2lkIG1pc21hdGNoZXMgd2hlbiByZWxlYXNp bmcgcGFnZXM6Cj4gKyAqIGdldF91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQg dmlhIHB1dF9wYWdlKCksIHdoaWxlCj4gKyAqIHBpbl91c2VyX3BhZ2VzKigpIHBhZ2VzIG11c3Qg YmUgcmVsZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2UoKS4KPiArICoKPiArICogUmV0dXJucyBudW1i ZXIgb2YgcGFnZXMgcGlubmVkLiBUaGlzIG1heSBiZSBmZXdlciB0aGFuIHRoZSBudW1iZXIgcmVx dWVzdGVkLgo+ICsgKiBJZiBucl9wYWdlcyBpcyAwIG9yIG5lZ2F0aXZlLCByZXR1cm5zIDAuIElm IG5vIHBhZ2VzIHdlcmUgcGlubmVkLCByZXR1cm5zCj4gKyAqIC1lcnJuby4KPiArICovCj4gK2lu dCBnZXRfdXNlcl9wYWdlc19mYXN0KHVuc2lnbmVkIGxvbmcgc3RhcnQsIGludCBucl9wYWdlcywK PiArCQkJdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcykKPiArewo+ ICsJLyoKPiArCSAqIEFzIGRldGFpbGVkIGFib3ZlLCBGT0xMX1BJTiBtdXN0IG9ubHkgYmUgc2V0 IGludGVybmFsbHkgYnkgdGhlCj4gKwkgKiBwaW5fdXNlcl9wYWdlKigpIGFuZCBwaW5fbG9uZ3Rl cm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRoZQo+ICsJICogY2FsbGVyLCBzbyBlbmZv cmNlIHRoYXQ6Cj4gKwkgKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9Q SU4pKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCXJldHVybiBpbnRlcm5hbF9nZXRfdXNl cl9wYWdlc19mYXN0KHN0YXJ0LCBucl9wYWdlcywgZ3VwX2ZsYWdzLCBwYWdlcyk7Cj4gK30KPiAg RVhQT1JUX1NZTUJPTF9HUEwoZ2V0X3VzZXJfcGFnZXNfZmFzdCk7Cj4gKwo+ICsvKioKPiArICog cGluX3VzZXJfcGFnZXNfZmFzdCgpIC0gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IHdpdGhvdXQg dGFraW5nIGxvY2tzCj4gKyAqCj4gKyAqIE5lYXJseSB0aGUgc2FtZSBhcyBnZXRfdXNlcl9wYWdl c19mYXN0KCksIGV4Y2VwdCB0aGF0IEZPTExfUElOIGlzIHNldC4gU2VlCj4gKyAqIGdldF91c2Vy X3BhZ2VzX2Zhc3QoKSBmb3IgZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYXJndW1lbnRz LCBiZWNhdXNlCj4gKyAqIHRoZSBhcmd1bWVudHMgaGVyZSBhcmUgaWRlbnRpY2FsLgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBw dXRfdXNlcl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNl cl9wYWdlcy5yc3QgZm9yIGZ1cnRoZXIgZGV0YWlscy4KPiArICoKPiArICogVGhpcyBpcyBpbnRl bmRlZCBmb3IgQ2FzZSAxIChESU8pIGluIERvY3VtZW50YXRpb24vdm0vcGluX3VzZXJfcGFnZXMu cnN0LiBJdAo+ICsgKiBpcyBOT1QgaW50ZW5kZWQgZm9yIENhc2UgMiAoUkRNQTogbG9uZy10ZXJt IHBpbnMpLgo+ICsgKi8KPiAraW50IHBpbl91c2VyX3BhZ2VzX2Zhc3QodW5zaWduZWQgbG9uZyBz dGFydCwgaW50IG5yX3BhZ2VzLAo+ICsJCQl1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1Y3Qg cGFnZSAqKnBhZ2VzKQo+ICt7Cj4gKwkvKiBGT0xMX0dFVCBhbmQgRk9MTF9QSU4gYXJlIG11dHVh bGx5IGV4Y2x1c2l2ZS4gKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9H RVQpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWd1cF9mbGFncyB8PSBGT0xMX1BJTjsK PiArCXJldHVybiBpbnRlcm5hbF9nZXRfdXNlcl9wYWdlc19mYXN0KHN0YXJ0LCBucl9wYWdlcywg Z3VwX2ZsYWdzLCBwYWdlcyk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTF9HUEwocGluX3VzZXJfcGFn ZXNfZmFzdCk7Cj4gKwo+ICsvKioKPiArICogcGluX2xvbmd0ZXJtX3BhZ2VzX2Zhc3QoKSAtIHBp biB1c2VyIHBhZ2VzIGluIG1lbW9yeSB3aXRob3V0IHRha2luZyBsb2Nrcwo+ICsgKgo+ICsgKiBO ZWFybHkgdGhlIHNhbWUgYXMgZ2V0X3VzZXJfcGFnZXNfZmFzdCgpLCBleGNlcHQgdGhhdCBGT0xM X1BJTiBhbmQKPiArICogRk9MTF9MT05HVEVSTSBhcmUgc2V0LiBTZWUgZ2V0X3VzZXJfcGFnZXNf ZmFzdCgpIGZvciBkb2N1bWVudGF0aW9uIG9uIHRoZQo+ICsgKiBmdW5jdGlvbiBhcmd1bWVudHMs IGJlY2F1c2UgdGhlIGFyZ3VtZW50cyBoZXJlIGFyZSBpZGVudGljYWwuCj4gKyAqCj4gKyAqIEZP TExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF91c2Vy X3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2Vz LnJzdCBmb3IgZnVydGhlciBkZXRhaWxzLgo+ICsgKgo+ICsgKiBGT0xMX0xPTkdURVJNIG1lYW5z IHRoYXQgdGhlIHBhZ2VzIGFyZSBiZWluZyBwaW5uZWQgZm9yICJsb25nIHRlcm0iIHVzZSwKPiAr ICogdHlwaWNhbGx5IGJ5IGEgbm9uLUNQVSBkZXZpY2UsIGFuZCB3ZSBjYW5ub3QgYmUgc3VyZSB0 aGF0IHdhaXRpbmcgZm9yIGEKPiArICogcGlubmVkIHBhZ2UgdG8gYmVjb21lIHVucGluIHdpbGwg YmUgZWZmZWN0aXZlLgo+ICsgKgo+ICsgKiBUaGlzIGlzIGludGVuZGVkIGZvciBDYXNlIDIgKFJE TUE6IGxvbmctdGVybSBwaW5zKSBvZiB0aGUgRk9MTF9QSU4KPiArICogZG9jdW1lbnRhdGlvbi4K PiArICovCj4gK2ludCBwaW5fbG9uZ3Rlcm1fcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0YXJ0 LCBpbnQgbnJfcGFnZXMsCj4gKwkJCSAgICB1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1Y3Qg cGFnZSAqKnBhZ2VzKQo+ICt7Cj4gKwkvKiBGT0xMX0dFVCBhbmQgRk9MTF9QSU4gYXJlIG11dHVh bGx5IGV4Y2x1c2l2ZS4gKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9H RVQpKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWd1cF9mbGFncyB8PSAoRk9MTF9QSU4g fCBGT0xMX0xPTkdURVJNKTsKPiArCXJldHVybiBpbnRlcm5hbF9nZXRfdXNlcl9wYWdlc19mYXN0 KHN0YXJ0LCBucl9wYWdlcywgZ3VwX2ZsYWdzLCBwYWdlcyk7Cj4gK30KPiArRVhQT1JUX1NZTUJP TF9HUEwocGluX2xvbmd0ZXJtX3BhZ2VzX2Zhc3QpOwo+ICsKPiArLyoqCj4gKyAqIHBpbl91c2Vy X3BhZ2VzX3JlbW90ZSgpIC0gcGluIHBhZ2VzIGZvciAodHlwaWNhbGx5KSB1c2UgYnkgRGlyZWN0 IElPLCBhbmQKPiArICogcmV0dXJuIHRoZSBwYWdlcyB0byB0aGUgdXNlci4KPiArICoKPiArICog TmVhcmx5IHRoZSBzYW1lIGFzIGdldF91c2VyX3BhZ2VzX3JlbW90ZSgpLCBleGNlcHQgdGhhdCBG T0xMX1BJTiBpcyBzZXQuIFNlZQo+ICsgKiBnZXRfdXNlcl9wYWdlc19yZW1vdGUoKSBmb3IgZG9j dW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYXJndW1lbnRzLCBiZWNhdXNlCj4gKyAqIHRoZSBh cmd1bWVudHMgaGVyZSBhcmUgaWRlbnRpY2FsLgo+ICsgKgo+ICsgKiBGT0xMX1BJTiBtZWFucyB0 aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBwdXRfdXNlcl9wYWdlKCkuIFBsZWFz ZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNlcl9wYWdlcy5yc3QgZm9yIGRldGFp bHMuCj4gKyAqCj4gKyAqIFRoaXMgaXMgaW50ZW5kZWQgZm9yIENhc2UgMSAoRElPKSBpbiBEb2N1 bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4gSXQKPiArICogaXMgTk9UIGludGVuZGVk IGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKS4KPiArICovCj4gK2xvbmcgcGluX3Vz ZXJfcGFnZXNfcmVtb3RlKHN0cnVjdCB0YXNrX3N0cnVjdCAqdHNrLCBzdHJ1Y3QgbW1fc3RydWN0 ICptbSwKPiArCQkJICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdl cywKPiArCQkJICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywK PiArCQkJICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcywgaW50ICpsb2NrZWQpCj4gK3sK PiArCS8qIEZPTExfR0VUIGFuZCBGT0xMX1BJTiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ ICsJaWYgKFdBUk5fT05fT05DRShndXBfZmxhZ3MgJiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1F SU5WQUw7Cj4gKwo+ICsJZ3VwX2ZsYWdzIHw9IEZPTExfVE9VQ0ggfCBGT0xMX1JFTU9URSB8IEZP TExfUElOOwo+ICsKPiArCXJldHVybiBfX2dldF91c2VyX3BhZ2VzX2xvY2tlZCh0c2ssIG1tLCBz dGFydCwgbnJfcGFnZXMsIHBhZ2VzLCB2bWFzLAo+ICsJCQkJICAgICAgIGxvY2tlZCwgZ3VwX2Zs YWdzKTsKPiArfQo+ICtFWFBPUlRfU1lNQk9MKHBpbl91c2VyX3BhZ2VzX3JlbW90ZSk7Cj4gKwo+ ICsvKioKPiArICogcGluX2xvbmd0ZXJtX3BhZ2VzX3JlbW90ZSgpIC0gcGluIHBhZ2VzIGZvciAo dHlwaWNhbGx5KSB1c2UgYnkgRGlyZWN0IElPLCBhbmQKPiArICogcmV0dXJuIHRoZSBwYWdlcyB0 byB0aGUgdXNlci4KPiArICoKPiArICogTmVhcmx5IHRoZSBzYW1lIGFzIGdldF91c2VyX3BhZ2Vz X3JlbW90ZSgpLCBidXQgbm90ZSB0aGF0IEZPTExfVE9VQ0ggaXMgbm90Cj4gKyAqIHNldCwgYW5k IEZPTExfUElOIGFuZCBGT0xMX0xPTkdURVJNIGFyZSBzZXQuIFNlZSBnZXRfdXNlcl9wYWdlc19y ZW1vdGUoKSBmb3IKPiArICogZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24gYXJndW1lbnRz LCBiZWNhdXNlIHRoZSBhcmd1bWVudHMgaGVyZSBhcmUKPiArICogaWRlbnRpY2FsLgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBw dXRfdXNlcl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNl cl9wYWdlcy5yc3QgZm9yIGZ1cnRoZXIgZGV0YWlscy4KPiArICoKPiArICogRk9MTF9MT05HVEVS TSBtZWFucyB0aGF0IHRoZSBwYWdlcyBhcmUgYmVpbmcgcGlubmVkIGZvciAibG9uZyB0ZXJtIiB1 c2UsCj4gKyAqIHR5cGljYWxseSBieSBhIG5vbi1DUFUgZGV2aWNlLCBhbmQgd2UgY2Fubm90IGJl IHN1cmUgdGhhdCB3YWl0aW5nIGZvciBhCj4gKyAqIHBpbm5lZCBwYWdlIHRvIGJlY29tZSB1bnBp biB3aWxsIGJlIGVmZmVjdGl2ZS4KPiArICoKPiArICogVGhpcyBpcyBpbnRlbmRlZCBmb3IgQ2Fz ZSAyIChSRE1BOiBsb25nLXRlcm0gcGlucykgaW4KPiArICogRG9jdW1lbnRhdGlvbi92bS9waW5f dXNlcl9wYWdlcy5yc3QuCj4gKyAqLwo+ICtsb25nIHBpbl9sb25ndGVybV9wYWdlc19yZW1vdGUo c3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICsJCQkgICAg ICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiArCQkJICAg ICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gKwkJCSAg ICAgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzLCBpbnQgKmxvY2tlZCkKPiArewo+ICsJ LyogRk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuICovCj4gKwlp ZiAoV0FSTl9PTl9PTkNFKGd1cF9mbGFncyAmIEZPTExfR0VUKSkKPiArCQlyZXR1cm4gLUVJTlZB TDsKPiArCj4gKwkvKgo+ICsJICogRklYTUU6IGFzIG5vdGVkIGluIHRoZSBnZXRfdXNlcl9wYWdl c19yZW1vdGUoKSBpbXBsZW1lbnRhdGlvbiwgaXQKPiArCSAqIGlzIG5vdCB5ZXQgcG9zc2libGUg dG8gc2FmZWx5IHNldCBGT0xMX0xPTkdURVJNIGhlcmUuIEZPTExfTE9OR1RFUk0KPiArCSAqIG5l ZWRzIHRvIGJlIHNldCwgYnV0IGZvciBub3cgdGhlIGJlc3Qgd2UgY2FuIGRvIGlzIGEgIlRPRE8i IGl0ZW0uCj4gKwkgKi8KCldhaXQ/ICBXaHkgY2FuJ3Qgd2Ugc2V0IEZPTExfTE9OR1RFUk0gaGVy ZT8gIHBpbl8qIGFyZSBuZXcgY2FsbHMgd2hpY2ggYXJlIG5vdAp1c2VkIHlldCByaWdodD8KCllv dSBzZXQgaXQgaW4gdGhlIG90aGVyIG5ldyBwaW5fKiBmdW5jdGlvbnM/CgpJcmEKCj4gKwlndXBf ZmxhZ3MgfD0gRk9MTF9SRU1PVEUgfCBGT0xMX1BJTjsKPiArCj4gKwlyZXR1cm4gX19nZXRfdXNl cl9wYWdlc19sb2NrZWQodHNrLCBtbSwgc3RhcnQsIG5yX3BhZ2VzLCBwYWdlcywgdm1hcywKPiAr CQkJCSAgICAgICBsb2NrZWQsIGd1cF9mbGFncyk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTChwaW5f bG9uZ3Rlcm1fcGFnZXNfcmVtb3RlKTsKPiArCj4gKy8qKgo+ICsgKiBwaW5fdXNlcl9wYWdlcygp IC0gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IGZvciB1c2UgYnkgb3RoZXIgZGV2aWNlcwo+ICsg Kgo+ICsgKiBOZWFybHkgdGhlIHNhbWUgYXMgZ2V0X3VzZXJfcGFnZXMoKSwgZXhjZXB0IHRoYXQg Rk9MTF9UT1VDSCBpcyBub3Qgc2V0LCBhbmQKPiArICogRk9MTF9QSU4gaXMgc2V0Lgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBw dXRfdXNlcl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNl cl9wYWdlcy5yc3QgZm9yIGRldGFpbHMuCj4gKyAqCj4gKyAqIFRoaXMgaXMgaW50ZW5kZWQgZm9y IENhc2UgMSAoRElPKSBpbiBEb2N1bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4gSXQK PiArICogaXMgTk9UIGludGVuZGVkIGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKS4K PiArICovCj4gK2xvbmcgcGluX3VzZXJfcGFnZXModW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWdu ZWQgbG9uZyBucl9wYWdlcywKPiArCQkgICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0 IHBhZ2UgKipwYWdlcywKPiArCQkgICAgc3RydWN0IHZtX2FyZWFfc3RydWN0ICoqdm1hcykKPiAr ewo+ICsJLyogRk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuICov Cj4gKwlpZiAoV0FSTl9PTl9PTkNFKGd1cF9mbGFncyAmIEZPTExfR0VUKSkKPiArCQlyZXR1cm4g LUVJTlZBTDsKPiArCj4gKwlndXBfZmxhZ3MgfD0gRk9MTF9QSU47Cj4gKwlyZXR1cm4gX19ndXBf bG9uZ3Rlcm1fbG9ja2VkKGN1cnJlbnQsIGN1cnJlbnQtPm1tLCBzdGFydCwgbnJfcGFnZXMsCj4g KwkJCQkgICAgIHBhZ2VzLCB2bWFzLCBndXBfZmxhZ3MpOwo+ICt9Cj4gK0VYUE9SVF9TWU1CT0wo cGluX3VzZXJfcGFnZXMpOwo+ICsKPiArLyoqCj4gKyAqIHBpbl9sb25ndGVybV9wYWdlcygpIC0g cGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IGZvciBsb25nLXRlcm0gdXNlIChSRE1BLAo+ICsgKiB0 eXBpY2FsbHkpCj4gKyAqCj4gKyAqIE5lYXJseSB0aGUgc2FtZSBhcyBnZXRfdXNlcl9wYWdlcygp LCBleGNlcHQgdGhhdCBGT0xMX1BJTiBhbmQgRk9MTF9MT05HVEVSTQo+ICsgKiBhcmUgc2V0LiBT ZWUgZ2V0X3VzZXJfcGFnZXNfZmFzdCgpIGZvciBkb2N1bWVudGF0aW9uIG9uIHRoZSBmdW5jdGlv bgo+ICsgKiBhcmd1bWVudHMsIGJlY2F1c2UgdGhlIGFyZ3VtZW50cyBoZXJlIGFyZSBpZGVudGlj YWwuCj4gKyAqCj4gKyAqIEZPTExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3QgYmUgcmVs ZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVudGF0aW9u L3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdCBmb3IgZnVydGhlciBkZXRhaWxzLgo+ICsgKgo+ICsgKiBG T0xMX0xPTkdURVJNIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIGFyZSBiZWluZyBwaW5uZWQgZm9yICJs b25nIHRlcm0iIHVzZSwKPiArICogdHlwaWNhbGx5IGJ5IGEgbm9uLUNQVSBkZXZpY2UsIGFuZCB3 ZSBjYW5ub3QgYmUgc3VyZSB0aGF0IHdhaXRpbmcgZm9yIGEKPiArICogcGlubmVkIHBhZ2UgdG8g YmVjb21lIHVucGluIHdpbGwgYmUgZWZmZWN0aXZlLgo+ICsgKgo+ICsgKiBUaGlzIGlzIGludGVu ZGVkIGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKSBpbgo+ICsgKiBEb2N1bWVudGF0 aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4KPiArICovCj4gK2xvbmcgcGluX2xvbmd0ZXJtX3Bh Z2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMsCj4gKwkJCXVu c2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4gKwkJCXN0cnVjdCB2 bV9hcmVhX3N0cnVjdCAqKnZtYXMpCj4gK3sKPiArCS8qIEZPTExfR0VUIGFuZCBGT0xMX1BJTiBh cmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ICsJaWYgKFdBUk5fT05fT05DRShndXBfZmxhZ3Mg JiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJZ3VwX2ZsYWdzIHw9IEZP TExfUElOIHwgRk9MTF9MT05HVEVSTTsKPiArCXJldHVybiBfX2d1cF9sb25ndGVybV9sb2NrZWQo Y3VycmVudCwgY3VycmVudC0+bW0sIHN0YXJ0LCBucl9wYWdlcywKPiArCQkJCSAgICAgcGFnZXMs IHZtYXMsIGd1cF9mbGFncyk7Cj4gK30KPiArRVhQT1JUX1NZTUJPTChwaW5fbG9uZ3Rlcm1fcGFn ZXMpOwo+IC0tIAo+IDIuMjMuMAo+IApfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVl ZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5m by9kcmktZGV2ZWw=