From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mike Rapoport Subject: Re: [PATCH v2 05/18] mm/gup: introduce pin_user_pages*() and FOLL_PIN Date: Tue, 5 Nov 2019 15:10:34 +0200 Message-ID: <20191105131032.GG25005@rapoport-lnx> References: <20191103211813.213227-1-jhubbard@nvidia.com> <20191103211813.213227-6-jhubbard@nvidia.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Content-Disposition: inline In-Reply-To: <20191103211813.213227-6-jhubbard@nvidia.com> Sender: netdev-owner@vger.kernel.org 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" , Ira Weiny , Jan Kara , Jason Gunthorpe , Jens Axboe , Jonathan Corbet , =?iso-8859-1?B?Suly9G1l?= Glisse , Magnus Karlsson , Mauro Carvalho Chehab , Micha List-Id: dri-devel@lists.freedesktop.org On Sun, Nov 03, 2019 at 01:18:00PM -0800, 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 > thoroughly documented. > > The pin_longterm*() variants also set FOLL_LONGTERM, in addition > to FOLL_PIN: > > 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(). > > Thanks to Jan Kara and Vlastimil Babka for explaining the 4 cases > in this documentation. (I've reworded it and expanded on it slightly.) > > Cc: Jonathan Corbet > Cc: Ira Weiny > Signed-off-by: John Hubbard > --- > Documentation/vm/index.rst | 1 + > Documentation/vm/pin_user_pages.rst | 212 ++++++++++++++++++++++ I think it belongs to Documentation/core-api. > include/linux/mm.h | 62 ++++++- > mm/gup.c | 265 +++++++++++++++++++++++++--- > 4 files changed, 514 insertions(+), 26 deletions(-) > create mode 100644 Documentation/vm/pin_user_pages.rst > > diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst > index e8d943b21cf9..7194efa3554a 100644 > --- a/Documentation/vm/index.rst > +++ b/Documentation/vm/index.rst > @@ -44,6 +44,7 @@ descriptions of data structures and algorithms. > page_migration > page_frags > page_owner > + pin_user_pages > remap_file_pages > slub > split_page_table_lock > diff --git a/Documentation/vm/pin_user_pages.rst b/Documentation/vm/pin_user_pages.rst > new file mode 100644 > index 000000000000..3910f49ca98c > --- /dev/null > +++ b/Documentation/vm/pin_user_pages.rst > @@ -0,0 +1,212 @@ > +.. SPDX-License-Identifier: GPL-2.0 > + > +==================================================== > +pin_user_pages() and related calls > +==================================================== I know this is too much to ask, but having pin_user_pages() a part of more general GUP description would be really great :) > + > +.. contents:: :local: > + > +Overview > +======== > + > +This document describes the following functions: :: > + > + pin_user_pages > + pin_user_pages_fast > + pin_user_pages_remote > + > + pin_longterm_pages > + pin_longterm_pages_fast > + pin_longterm_pages_remote > + > +Basic description of FOLL_PIN > +============================= > + > +A new flag for get_user_pages ("gup") has been added: FOLL_PIN. FOLL_PIN has Consider reading this after, say, half a year ;-) > +significant interactions and interdependencies with FOLL_LONGTERM, so both are > +covered here. > + > +Both FOLL_PIN and FOLL_LONGTERM are "internal" to gup, meaning that neither > +FOLL_PIN nor FOLL_LONGTERM should not appear at the gup call sites. This allows > +the associated wrapper functions (pin_user_pages and others) to set the correct > +combination of these flags, and to check for problems as well. > + > +FOLL_PIN and FOLL_GET are mutually exclusive for a given gup call. However, > +multiple threads and call sites are free to pin the same struct pages, via both > +FOLL_PIN and FOLL_GET. It's just the call site that needs to choose one or the > +other, not the struct page(s). > + > +The FOLL_PIN implementation is nearly the same as FOLL_GET, except that FOLL_PIN > +uses a different reference counting technique. > + > +FOLL_PIN is a prerequisite to FOLL_LONGTGERM. Another way of saying that is, > +FOLL_LONGTERM is a specific case, more restrictive case of FOLL_PIN. > + > +Which flags are set by each wrapper > +=================================== > + > +Only FOLL_PIN and FOLL_LONGTERM are covered here. These flags are added to > +whatever flags the caller provides:: > + > + Function gup flags (FOLL_PIN or FOLL_LONGTERM only) > + -------- ------------------------------------------ > + pin_user_pages FOLL_PIN > + pin_user_pages_fast FOLL_PIN > + pin_user_pages_remote FOLL_PIN > + > + pin_longterm_pages FOLL_PIN | FOLL_LONGTERM > + pin_longterm_pages_fast FOLL_PIN | FOLL_LONGTERM > + pin_longterm_pages_remote FOLL_PIN | FOLL_LONGTERM > + > +Tracking dma-pinned pages > +========================= > + > +Some of the key design constraints, and solutions, for tracking dma-pinned > +pages: > + > +* An actual reference count, per struct page, is required. This is because > + multiple processes may pin and unpin a page. > + > +* False positives (reporting that a page is dma-pinned, when in fact it is not) > + are acceptable, but false negatives are not. > + > +* struct page may not be increased in size for this, and all fields are already > + used. > + > +* Given the above, we can overload the page->_refcount field by using, sort of, > + the upper bits in that field for a dma-pinned count. "Sort of", means that, > + rather than dividing page->_refcount into bit fields, we simple add a medium- > + large value (GUP_PIN_COUNTING_BIAS, initially chosen to be 1024: 10 bits) to > + page->_refcount. This provides fuzzy behavior: if a page has get_page() called > + on it 1024 times, then it will appear to have a single dma-pinned count. > + And again, that's acceptable. > + > +This also leads to limitations: there are only 31-10==21 bits available for a > +counter that increments 10 bits at a time. > + > +TODO: for 1GB and larger huge pages, this is cutting it close. That's because > +when pin_user_pages() follows such pages, it increments the head page by "1" > +(where "1" used to mean "+1" for get_user_pages(), but now means "+1024" for > +pin_user_pages()) for each tail page. So if you have a 1GB huge page: > + > +* There are 256K (18 bits) worth of 4 KB tail pages. > +* There are 21 bits available to count up via GUP_PIN_COUNTING_BIAS (that is, > + 10 bits at a time) > +* There are 21 - 18 == 3 bits available to count. Except that there aren't, > + because you need to allow for a few normal get_page() calls on the head page, > + as well. Fortunately, the approach of using addition, rather than "hard" > + bitfields, within page->_refcount, allows for sharing these bits gracefully. > + But we're still looking at about 8 references. > + > +This, however, is a missing feature more than anything else, because it's easily > +solved by addressing an obvious inefficiency in the original get_user_pages() > +approach of retrieving pages: stop treating all the pages as if they were > +PAGE_SIZE. Retrieve huge pages as huge pages. The callers need to be aware of > +this, so some work is required. Once that's in place, this limitation mostly > +disappears from view, because there will be ample refcounting range available. > + > +* Callers must specifically request "dma-pinned tracking of pages". In other > + words, just calling get_user_pages() will not suffice; a new set of functions, > + pin_user_page() and related, must be used. > + > +FOLL_PIN, FOLL_GET, FOLL_LONGTERM: when to use which flags > +========================================================== > + > +Thanks to Jan Kara, Vlastimil Babka and several other -mm people, for describing > +these categories: > + > +CASE 1: Direct IO (DIO) > +----------------------- > +There are GUP references to pages that are serving > +as DIO buffers. These buffers are needed for a relatively short time (so they > +are not "long term"). No special synchronization with page_mkclean() or > +munmap() is provided. Therefore, flags to set at the call site are: :: > + > + FOLL_PIN > + > +...but rather than setting FOLL_PIN directly, call sites should use one of > +the pin_user_pages*() routines that set FOLL_PIN. > + > +CASE 2: RDMA > +------------ > +There are GUP references to pages that are serving as DMA > +buffers. These buffers are needed for a long time ("long term"). No special > +synchronization with page_mkclean() or munmap() is provided. Therefore, flags > +to set at the call site are: :: > + > + FOLL_PIN | FOLL_LONGTERM > + > +NOTE: Some pages, such as DAX pages, cannot be pinned with longterm pins. That's > +because DAX pages do not have a separate page cache, and so "pinning" implies > +locking down file system blocks, which is not (yet) supported in that way. > + > +CASE 3: ODP > +----------- > +(Mellanox/Infiniband On Demand Paging: the hardware supports > +replayable page faulting). There are GUP references to pages serving as DMA > +buffers. For ODP, MMU notifiers are used to synchronize with page_mkclean() > +and munmap(). Therefore, normal GUP calls are sufficient, so neither flag > +needs to be set. > + > +CASE 4: Pinning for struct page manipulation only > +------------------------------------------------- > +Here, normal GUP calls are sufficient, so neither flag needs to be set. > + > +page_dma_pinned(): the whole point of pinning > +============================================= > + > +The whole point of marking pages as "DMA-pinned" or "gup-pinned" is to be able > +to query, "is this page DMA-pinned?" That allows code such as page_mkclean() > +(and file system writeback code in general) to make informed decisions about > +what to do when a page cannot be unmapped due to such pins. > + > +What to do in those cases is the subject of a years-long series of discussions > +and debates (see the References at the end of this document). It's a TODO item > +here: fill in the details once that's worked out. Meanwhile, it's safe to say > +that having this available: :: > + > + static inline bool page_dma_pinned(struct page *page) > + > +...is a prerequisite to solving the long-running gup+DMA problem. > + > +Another way of thinking about FOLL_GET, FOLL_PIN, and FOLL_LONGTERM > +=================================================================== > + > +Another way of thinking about these flags is as a progression of restrictions: > +FOLL_GET is for struct page manipulation, without affecting the data that the > +struct page refers to. FOLL_PIN is a *replacement* for FOLL_GET, and is for > +short term pins on pages whose data *will* get accessed. As such, FOLL_PIN is > +a "more severe" form of pinning. And finally, FOLL_LONGTERM is an even more > +restrictive case that has FOLL_PIN as a prerequisite: this is for pages that > +will be pinned longterm, and whose data will be accessed. > + > +Unit testing > +============ > +This file:: > + > + tools/testing/selftests/vm/gup_benchmark.c > + > +has the following new calls to exercise the new pin*() wrapper functions: > + > +* PIN_FAST_BENCHMARK (./gup_benchmark -a) > +* PIN_LONGTERM_BENCHMARK (./gup_benchmark -a) > +* PIN_BENCHMARK (./gup_benchmark -a) > + > +You can monitor how many total dma-pinned pages have been acquired and released > +since the system was booted, via two new /proc/vmstat entries: :: > + > + /proc/vmstat/nr_foll_pin_requested > + /proc/vmstat/nr_foll_pin_requested > + > +Those are both going to show zero, unless CONFIG_DEBUG_VM is set. This is > +because there is a noticeable performance drop in put_user_page(), when they > +are activated. > + > +References > +========== > + > +* `Some slow progress on get_user_pages() (Apr 2, 2019) `_ > +* `DMA and get_user_pages() (LPC: Dec 12, 2018) `_ > +* `The trouble with get_user_pages() (Apr 30, 2018) `_ > + > +John Hubbard, October, 2019 > diff --git a/include/linux/mm.h b/include/linux/mm.h > index cc292273e6ba..cdfb6fedb271 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,41 @@ 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 for a given function call. > + * (The underlying pages may experience both FOLL_GET-based and FOLL_PIN-based > + * calls applied to them, and that's perfectly OK. This is a constraint on the > + * callers, not on the pages.) > + * > + * FOLL_PIN and FOLL_LONGTERM should 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(). > + * > + * Please see Documentation/vm/pin_user_pages.rst for more information. > */ > > 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 199da99e8ffc..1aea48427879 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; > @@ -1151,6 +1164,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) > { > + /* > + * 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 > @@ -1608,6 +1629,14 @@ long get_user_pages(unsigned long start, unsigned long nr_pages, > unsigned int gup_flags, struct page **pages, > struct vm_area_struct **vmas) > { > + /* > + * 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); > } > @@ -2373,24 +2402,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; > @@ -2435,4 +2449,215 @@ 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(). > + * > + * 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) > +{ > + /* > + * 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. > + */ > + 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 > > -- Sincerely yours, Mike. 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.5 required=3.0 tests=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 7C12DC17460 for ; Tue, 5 Nov 2019 13:10:50 +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 5910A21D7C for ; Tue, 5 Nov 2019 13:10:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5910A21D7C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org 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 B2F0B6EA46; Tue, 5 Nov 2019 13:10:49 +0000 (UTC) Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4B6AD6EA46 for ; Tue, 5 Nov 2019 13:10:48 +0000 (UTC) Received: from rapoport-lnx (nesher1.haifa.il.ibm.com [195.110.40.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 3BAFB21882; Tue, 5 Nov 2019 13:10:38 +0000 (UTC) Date: Tue, 5 Nov 2019 15:10:34 +0200 From: Mike Rapoport To: John Hubbard Subject: Re: [PATCH v2 05/18] mm/gup: introduce pin_user_pages*() and FOLL_PIN Message-ID: <20191105131032.GG25005@rapoport-lnx> References: <20191103211813.213227-1-jhubbard@nvidia.com> <20191103211813.213227-6-jhubbard@nvidia.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20191103211813.213227-6-jhubbard@nvidia.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1572959448; bh=vQ3G3gXntK/LDngknBhGWjzSEECHf91Tn3dUHddTs1g=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=uJHNiBXfr/6eTLhAJBmPj0BBfms5QJb6XhqslfHojJdfV1LBbB43tiEggrKjZmSPM rCpK6sWp0KoQMwWCivODtZauvu3MOL9N2dVzjgWjQLLpc9Jub5dpx2Y6+rqI8O5RhV TJMV4GpKU+emJfOk+0crj53gORAiMuFkUj9rXoqI= 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, Ira Weiny , 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, Shuah Khan , 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: <20191105131034.r7UPRpb0WtKxMoXpDTZ1bdFJFY_jFKpJiKiX-11JXLk@z> T24gU3VuLCBOb3YgMDMsIDIwMTkgYXQgMDE6MTg6MDBQTSAtMDgwMCwgSm9obiBIdWJiYXJkIHdy b3RlOgo+IEludHJvZHVjZSBwaW5fdXNlcl9wYWdlcyooKSB2YXJpYXRpb25zIG9mIGdldF91c2Vy X3BhZ2VzKigpIGNhbGxzLAo+IGFuZCBhbHNvIHBpbl9sb25ndGVybV9wYWdlcyooKSB2YXJpYXRp b25zLgo+IAo+IFRoZXNlIHZhcmlhbnRzIGFsbCBzZXQgRk9MTF9QSU4sIHdoaWNoIGlzIGFsc28g aW50cm9kdWNlZCwgYW5kCj4gdGhvcm91Z2hseSBkb2N1bWVudGVkLgo+IAo+IFRoZSBwaW5fbG9u Z3Rlcm0qKCkgdmFyaWFudHMgYWxzbyBzZXQgRk9MTF9MT05HVEVSTSwgaW4gYWRkaXRpb24KPiB0 byBGT0xMX1BJTjoKPiAKPiAgICAgcGluX3VzZXJfcGFnZXMoKQo+ICAgICBwaW5fdXNlcl9wYWdl c19yZW1vdGUoKQo+ICAgICBwaW5fdXNlcl9wYWdlc19mYXN0KCkKPiAKPiAgICAgcGluX2xvbmd0 ZXJtX3BhZ2VzKCkKPiAgICAgcGluX2xvbmd0ZXJtX3BhZ2VzX3JlbW90ZSgpCj4gICAgIHBpbl9s b25ndGVybV9wYWdlc19mYXN0KCkKPiAKPiBBbGwgcGFnZXMgdGhhdCBhcmUgcGlubmVkIHZpYSB0 aGUgYWJvdmUgY2FsbHMsIG11c3QgYmUgdW5waW5uZWQgdmlhCj4gcHV0X3VzZXJfcGFnZSgpLgo+ IAo+IFRoZSB1bmRlcmx5aW5nIHJ1bGVzIGFyZToKPiAKPiAqIFRoZXNlIGFyZSBndXAtaW50ZXJu YWwgZmxhZ3MsIHNvIHRoZSBjYWxsIHNpdGVzIHNob3VsZCBub3QgZGlyZWN0bHkKPiBzZXQgRk9M TF9QSU4gbm9yIEZPTExfTE9OR1RFUk0uIFRoYXQgYmVoYXZpb3IgaXMgZW5mb3JjZWQgd2l0aAo+ IGFzc2VydGlvbnMsIGZvciB0aGUgbmV3IEZPTExfUElOIGZsYWcuIEhvd2V2ZXIsIGZvciB0aGUg cHJlLWV4aXN0aW5nCj4gRk9MTF9MT05HVEVSTSBmbGFnLCB3aGljaCBoYXMgc29tZSBjYWxsIHNp dGVzIHRoYXQgc3RpbGwgZGlyZWN0bHkKPiBzZXQgRk9MTF9MT05HVEVSTSwgdGhlcmUgaXMgbm8g YXNzZXJ0aW9uIHlldC4KPiAKPiAqIENhbGwgc2l0ZXMgdGhhdCB3YW50IHRvIGluZGljYXRlIHRo YXQgdGhleSBhcmUgZ29pbmcgdG8gZG8gRGlyZWN0SU8KPiAgICgiRElPIikgb3Igc29tZXRoaW5n IHdpdGggc2ltaWxhciBjaGFyYWN0ZXJpc3RpY3MsIHNob3VsZCBjYWxsIGEKPiAgIGdldF91c2Vy X3BhZ2VzKCktbGlrZSB3cmFwcGVyIGNhbGwgdGhhdCBzZXRzIEZPTExfUElOLiBUaGVzZSB3cmFw cGVycwo+ICAgd2lsbDoKPiAgICAgICAgICogU3RhcnQgd2l0aCAicGluX3VzZXJfcGFnZXMiIGlu c3RlYWQgb2YgImdldF91c2VyX3BhZ2VzIi4gVGhhdAo+ICAgICAgICAgICBtYWtlcyBpdCBlYXN5 IHRvIGZpbmQgYW5kIGF1ZGl0IHRoZSBjYWxsIHNpdGVzLgo+ICAgICAgICAgKiBTZXQgRk9MTF9Q SU4KPiAKPiAqIEZvciBwYWdlcyB0aGF0IGFyZSByZWNlaXZlZCB2aWEgRk9MTF9QSU4sIHRob3Nl IHBhZ2VzIG11c3QgYmUgcmV0dXJuZWQKPiAgIHZpYSBwdXRfdXNlcl9wYWdlKCkuCj4gCj4gVGhh bmtzIHRvIEphbiBLYXJhIGFuZCBWbGFzdGltaWwgQmFia2EgZm9yIGV4cGxhaW5pbmcgdGhlIDQg Y2FzZXMKPiBpbiB0aGlzIGRvY3VtZW50YXRpb24uIChJJ3ZlIHJld29yZGVkIGl0IGFuZCBleHBh bmRlZCBvbiBpdCBzbGlnaHRseS4pCj4gCj4gQ2M6IEpvbmF0aGFuIENvcmJldCA8Y29yYmV0QGx3 bi5uZXQ+Cj4gQ2M6IElyYSBXZWlueSA8aXJhLndlaW55QGludGVsLmNvbT4KPiBTaWduZWQtb2Zm LWJ5OiBKb2huIEh1YmJhcmQgPGpodWJiYXJkQG52aWRpYS5jb20+Cj4gLS0tCj4gIERvY3VtZW50 YXRpb24vdm0vaW5kZXgucnN0ICAgICAgICAgIHwgICAxICsKPiAgRG9jdW1lbnRhdGlvbi92bS9w aW5fdXNlcl9wYWdlcy5yc3QgfCAyMTIgKysrKysrKysrKysrKysrKysrKysrKwoKSSB0aGluayBp dCBiZWxvbmdzIHRvIERvY3VtZW50YXRpb24vY29yZS1hcGkuCgo+ICBpbmNsdWRlL2xpbnV4L21t LmggICAgICAgICAgICAgICAgICB8ICA2MiArKysrKystCj4gIG1tL2d1cC5jICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgMjY1ICsrKysrKysrKysrKysrKysrKysrKysrKystLS0KPiAgNCBm aWxlcyBjaGFuZ2VkLCA1MTQgaW5zZXJ0aW9ucygrKSwgMjYgZGVsZXRpb25zKC0pCj4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBEb2N1bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdAo+IAo+IGRp ZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL3ZtL2luZGV4LnJzdCBiL0RvY3VtZW50YXRpb24vdm0v aW5kZXgucnN0Cj4gaW5kZXggZThkOTQzYjIxY2Y5Li43MTk0ZWZhMzU1NGEgMTAwNjQ0Cj4gLS0t IGEvRG9jdW1lbnRhdGlvbi92bS9pbmRleC5yc3QKPiArKysgYi9Eb2N1bWVudGF0aW9uL3ZtL2lu ZGV4LnJzdAo+IEBAIC00NCw2ICs0NCw3IEBAIGRlc2NyaXB0aW9ucyBvZiBkYXRhIHN0cnVjdHVy ZXMgYW5kIGFsZ29yaXRobXMuCj4gICAgIHBhZ2VfbWlncmF0aW9uCj4gICAgIHBhZ2VfZnJhZ3MK PiAgICAgcGFnZV9vd25lcgo+ICsgICBwaW5fdXNlcl9wYWdlcwo+ICAgICByZW1hcF9maWxlX3Bh Z2VzCj4gICAgIHNsdWIKPiAgICAgc3BsaXRfcGFnZV90YWJsZV9sb2NrCj4gZGlmZiAtLWdpdCBh L0RvY3VtZW50YXRpb24vdm0vcGluX3VzZXJfcGFnZXMucnN0IGIvRG9jdW1lbnRhdGlvbi92bS9w aW5fdXNlcl9wYWdlcy5yc3QKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAwMDAwMDAw MDAwMC4uMzkxMGY0OWNhOThjCj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL0RvY3VtZW50YXRpb24v dm0vcGluX3VzZXJfcGFnZXMucnN0Cj4gQEAgLTAsMCArMSwyMTIgQEAKPiArLi4gU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPiArCj4gKz09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT0KPiArcGluX3VzZXJfcGFnZXMoKSBhbmQgcmVsYXRl ZCBjYWxscwo+ICs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09CgpJIGtub3cgdGhpcyBpcyB0b28gbXVjaCB0byBhc2ssIGJ1dCBoYXZpbmcgcGluX3Vz ZXJfcGFnZXMoKSBhIHBhcnQgb2YgbW9yZQpnZW5lcmFsIEdVUCBkZXNjcmlwdGlvbiB3b3VsZCBi ZSByZWFsbHkgZ3JlYXQgOikKCj4gKwo+ICsuLiBjb250ZW50czo6IDpsb2NhbDoKPiArCj4gK092 ZXJ2aWV3Cj4gKz09PT09PT09Cj4gKwo+ICtUaGlzIGRvY3VtZW50IGRlc2NyaWJlcyB0aGUgZm9s bG93aW5nIGZ1bmN0aW9uczogOjoKPiArCj4gKyBwaW5fdXNlcl9wYWdlcwo+ICsgcGluX3VzZXJf cGFnZXNfZmFzdAo+ICsgcGluX3VzZXJfcGFnZXNfcmVtb3RlCj4gKwo+ICsgcGluX2xvbmd0ZXJt X3BhZ2VzCj4gKyBwaW5fbG9uZ3Rlcm1fcGFnZXNfZmFzdAo+ICsgcGluX2xvbmd0ZXJtX3BhZ2Vz X3JlbW90ZQo+ICsKPiArQmFzaWMgZGVzY3JpcHRpb24gb2YgRk9MTF9QSU4KPiArPT09PT09PT09 PT09PT09PT09PT09PT09PT09PT0KPiArCj4gK0EgbmV3IGZsYWcgZm9yIGdldF91c2VyX3BhZ2Vz ICgiZ3VwIikgaGFzIGJlZW4gYWRkZWQ6IEZPTExfUElOLiBGT0xMX1BJTiBoYXMKCkNvbnNpZGVy IHJlYWRpbmcgdGhpcyBhZnRlciwgc2F5LCBoYWxmIGEgeWVhciA7LSkKCj4gK3NpZ25pZmljYW50 IGludGVyYWN0aW9ucyBhbmQgaW50ZXJkZXBlbmRlbmNpZXMgd2l0aCBGT0xMX0xPTkdURVJNLCBz byBib3RoIGFyZQo+ICtjb3ZlcmVkIGhlcmUuCj4gKwo+ICtCb3RoIEZPTExfUElOIGFuZCBGT0xM X0xPTkdURVJNIGFyZSAiaW50ZXJuYWwiIHRvIGd1cCwgbWVhbmluZyB0aGF0IG5laXRoZXIKPiAr Rk9MTF9QSU4gbm9yIEZPTExfTE9OR1RFUk0gc2hvdWxkIG5vdCBhcHBlYXIgYXQgdGhlIGd1cCBj YWxsIHNpdGVzLiBUaGlzIGFsbG93cwo+ICt0aGUgYXNzb2NpYXRlZCB3cmFwcGVyIGZ1bmN0aW9u cyAgKHBpbl91c2VyX3BhZ2VzIGFuZCBvdGhlcnMpIHRvIHNldCB0aGUgY29ycmVjdAo+ICtjb21i aW5hdGlvbiBvZiB0aGVzZSBmbGFncywgYW5kIHRvIGNoZWNrIGZvciBwcm9ibGVtcyBhcyB3ZWxs Lgo+ICsKPiArRk9MTF9QSU4gYW5kIEZPTExfR0VUIGFyZSBtdXR1YWxseSBleGNsdXNpdmUgZm9y IGEgZ2l2ZW4gZ3VwIGNhbGwuIEhvd2V2ZXIsCj4gK211bHRpcGxlIHRocmVhZHMgYW5kIGNhbGwg c2l0ZXMgYXJlIGZyZWUgdG8gcGluIHRoZSBzYW1lIHN0cnVjdCBwYWdlcywgdmlhIGJvdGgKPiAr Rk9MTF9QSU4gYW5kIEZPTExfR0VULiBJdCdzIGp1c3QgdGhlIGNhbGwgc2l0ZSB0aGF0IG5lZWRz IHRvIGNob29zZSBvbmUgb3IgdGhlCj4gK290aGVyLCBub3QgdGhlIHN0cnVjdCBwYWdlKHMpLgo+ ICsKPiArVGhlIEZPTExfUElOIGltcGxlbWVudGF0aW9uIGlzIG5lYXJseSB0aGUgc2FtZSBhcyBG T0xMX0dFVCwgZXhjZXB0IHRoYXQgRk9MTF9QSU4KPiArdXNlcyBhIGRpZmZlcmVudCByZWZlcmVu Y2UgY291bnRpbmcgdGVjaG5pcXVlLgo+ICsKPiArRk9MTF9QSU4gaXMgYSBwcmVyZXF1aXNpdGUg dG8gRk9MTF9MT05HVEdFUk0uIEFub3RoZXIgd2F5IG9mIHNheWluZyB0aGF0IGlzLAo+ICtGT0xM X0xPTkdURVJNIGlzIGEgc3BlY2lmaWMgY2FzZSwgbW9yZSByZXN0cmljdGl2ZSBjYXNlIG9mIEZP TExfUElOLgo+ICsKPiArV2hpY2ggZmxhZ3MgYXJlIHNldCBieSBlYWNoIHdyYXBwZXIKPiArPT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KPiArCj4gK09ubHkgRk9MTF9QSU4gYW5k IEZPTExfTE9OR1RFUk0gYXJlIGNvdmVyZWQgaGVyZS4gVGhlc2UgZmxhZ3MgYXJlIGFkZGVkIHRv Cj4gK3doYXRldmVyIGZsYWdzIHRoZSBjYWxsZXIgcHJvdmlkZXM6Ogo+ICsKPiArIEZ1bmN0aW9u ICAgICAgICAgICAgICAgICAgICBndXAgZmxhZ3MgKEZPTExfUElOIG9yIEZPTExfTE9OR1RFUk0g b25seSkKPiArIC0tLS0tLS0tICAgICAgICAgICAgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiArIHBpbl91c2VyX3BhZ2VzICAgICAgICAgICAgICBG T0xMX1BJTgo+ICsgcGluX3VzZXJfcGFnZXNfZmFzdCAgICAgICAgIEZPTExfUElOCj4gKyBwaW5f dXNlcl9wYWdlc19yZW1vdGUgICAgICAgRk9MTF9QSU4KPiArCj4gKyBwaW5fbG9uZ3Rlcm1fcGFn ZXMgICAgICAgICAgRk9MTF9QSU4gfCBGT0xMX0xPTkdURVJNCj4gKyBwaW5fbG9uZ3Rlcm1fcGFn ZXNfZmFzdCAgICAgRk9MTF9QSU4gfCBGT0xMX0xPTkdURVJNCj4gKyBwaW5fbG9uZ3Rlcm1fcGFn ZXNfcmVtb3RlICAgRk9MTF9QSU4gfCBGT0xMX0xPTkdURVJNCj4gKwo+ICtUcmFja2luZyBkbWEt cGlubmVkIHBhZ2VzCj4gKz09PT09PT09PT09PT09PT09PT09PT09PT0KPiArCj4gK1NvbWUgb2Yg dGhlIGtleSBkZXNpZ24gY29uc3RyYWludHMsIGFuZCBzb2x1dGlvbnMsIGZvciB0cmFja2luZyBk bWEtcGlubmVkCj4gK3BhZ2VzOgo+ICsKPiArKiBBbiBhY3R1YWwgcmVmZXJlbmNlIGNvdW50LCBw ZXIgc3RydWN0IHBhZ2UsIGlzIHJlcXVpcmVkLiBUaGlzIGlzIGJlY2F1c2UKPiArICBtdWx0aXBs ZSBwcm9jZXNzZXMgbWF5IHBpbiBhbmQgdW5waW4gYSBwYWdlLgo+ICsKPiArKiBGYWxzZSBwb3Np dGl2ZXMgKHJlcG9ydGluZyB0aGF0IGEgcGFnZSBpcyBkbWEtcGlubmVkLCB3aGVuIGluIGZhY3Qg aXQgaXMgbm90KQo+ICsgIGFyZSBhY2NlcHRhYmxlLCBidXQgZmFsc2UgbmVnYXRpdmVzIGFyZSBu b3QuCj4gKwo+ICsqIHN0cnVjdCBwYWdlIG1heSBub3QgYmUgaW5jcmVhc2VkIGluIHNpemUgZm9y IHRoaXMsIGFuZCBhbGwgZmllbGRzIGFyZSBhbHJlYWR5Cj4gKyAgdXNlZC4KPiArCj4gKyogR2l2 ZW4gdGhlIGFib3ZlLCB3ZSBjYW4gb3ZlcmxvYWQgdGhlIHBhZ2UtPl9yZWZjb3VudCBmaWVsZCBi eSB1c2luZywgc29ydCBvZiwKPiArICB0aGUgdXBwZXIgYml0cyBpbiB0aGF0IGZpZWxkIGZvciBh IGRtYS1waW5uZWQgY291bnQuICJTb3J0IG9mIiwgbWVhbnMgdGhhdCwKPiArICByYXRoZXIgdGhh biBkaXZpZGluZyBwYWdlLT5fcmVmY291bnQgaW50byBiaXQgZmllbGRzLCB3ZSBzaW1wbGUgYWRk IGEgbWVkaXVtLQo+ICsgIGxhcmdlIHZhbHVlIChHVVBfUElOX0NPVU5USU5HX0JJQVMsIGluaXRp YWxseSBjaG9zZW4gdG8gYmUgMTAyNDogMTAgYml0cykgdG8KPiArICBwYWdlLT5fcmVmY291bnQu IFRoaXMgcHJvdmlkZXMgZnV6enkgYmVoYXZpb3I6IGlmIGEgcGFnZSBoYXMgZ2V0X3BhZ2UoKSBj YWxsZWQKPiArICBvbiBpdCAxMDI0IHRpbWVzLCB0aGVuIGl0IHdpbGwgYXBwZWFyIHRvIGhhdmUg YSBzaW5nbGUgZG1hLXBpbm5lZCBjb3VudC4KPiArICBBbmQgYWdhaW4sIHRoYXQncyBhY2NlcHRh YmxlLgo+ICsKPiArVGhpcyBhbHNvIGxlYWRzIHRvIGxpbWl0YXRpb25zOiB0aGVyZSBhcmUgb25s eSAzMS0xMD09MjEgYml0cyBhdmFpbGFibGUgZm9yIGEKPiArY291bnRlciB0aGF0IGluY3JlbWVu dHMgMTAgYml0cyBhdCBhIHRpbWUuCj4gKwo+ICtUT0RPOiBmb3IgMUdCIGFuZCBsYXJnZXIgaHVn ZSBwYWdlcywgdGhpcyBpcyBjdXR0aW5nIGl0IGNsb3NlLiBUaGF0J3MgYmVjYXVzZQo+ICt3aGVu IHBpbl91c2VyX3BhZ2VzKCkgZm9sbG93cyBzdWNoIHBhZ2VzLCBpdCBpbmNyZW1lbnRzIHRoZSBo ZWFkIHBhZ2UgYnkgIjEiCj4gKyh3aGVyZSAiMSIgdXNlZCB0byBtZWFuICIrMSIgZm9yIGdldF91 c2VyX3BhZ2VzKCksIGJ1dCBub3cgbWVhbnMgIisxMDI0IiBmb3IKPiArcGluX3VzZXJfcGFnZXMo KSkgZm9yIGVhY2ggdGFpbCBwYWdlLiBTbyBpZiB5b3UgaGF2ZSBhIDFHQiBodWdlIHBhZ2U6Cj4g Kwo+ICsqIFRoZXJlIGFyZSAyNTZLICgxOCBiaXRzKSB3b3J0aCBvZiA0IEtCIHRhaWwgcGFnZXMu Cj4gKyogVGhlcmUgYXJlIDIxIGJpdHMgYXZhaWxhYmxlIHRvIGNvdW50IHVwIHZpYSBHVVBfUElO X0NPVU5USU5HX0JJQVMgKHRoYXQgaXMsCj4gKyAgMTAgYml0cyBhdCBhIHRpbWUpCj4gKyogVGhl cmUgYXJlIDIxIC0gMTggPT0gMyBiaXRzIGF2YWlsYWJsZSB0byBjb3VudC4gRXhjZXB0IHRoYXQg dGhlcmUgYXJlbid0LAo+ICsgIGJlY2F1c2UgeW91IG5lZWQgdG8gYWxsb3cgZm9yIGEgZmV3IG5v cm1hbCBnZXRfcGFnZSgpIGNhbGxzIG9uIHRoZSBoZWFkIHBhZ2UsCj4gKyAgYXMgd2VsbC4gRm9y dHVuYXRlbHksIHRoZSBhcHByb2FjaCBvZiB1c2luZyBhZGRpdGlvbiwgcmF0aGVyIHRoYW4gImhh cmQiCj4gKyAgYml0ZmllbGRzLCB3aXRoaW4gcGFnZS0+X3JlZmNvdW50LCBhbGxvd3MgZm9yIHNo YXJpbmcgdGhlc2UgYml0cyBncmFjZWZ1bGx5Lgo+ICsgIEJ1dCB3ZSdyZSBzdGlsbCBsb29raW5n IGF0IGFib3V0IDggcmVmZXJlbmNlcy4KPiArCj4gK1RoaXMsIGhvd2V2ZXIsIGlzIGEgbWlzc2lu ZyBmZWF0dXJlIG1vcmUgdGhhbiBhbnl0aGluZyBlbHNlLCBiZWNhdXNlIGl0J3MgZWFzaWx5Cj4g K3NvbHZlZCBieSBhZGRyZXNzaW5nIGFuIG9idmlvdXMgaW5lZmZpY2llbmN5IGluIHRoZSBvcmln aW5hbCBnZXRfdXNlcl9wYWdlcygpCj4gK2FwcHJvYWNoIG9mIHJldHJpZXZpbmcgcGFnZXM6IHN0 b3AgdHJlYXRpbmcgYWxsIHRoZSBwYWdlcyBhcyBpZiB0aGV5IHdlcmUKPiArUEFHRV9TSVpFLiBS ZXRyaWV2ZSBodWdlIHBhZ2VzIGFzIGh1Z2UgcGFnZXMuIFRoZSBjYWxsZXJzIG5lZWQgdG8gYmUg YXdhcmUgb2YKPiArdGhpcywgc28gc29tZSB3b3JrIGlzIHJlcXVpcmVkLiBPbmNlIHRoYXQncyBp biBwbGFjZSwgdGhpcyBsaW1pdGF0aW9uIG1vc3RseQo+ICtkaXNhcHBlYXJzIGZyb20gdmlldywg YmVjYXVzZSB0aGVyZSB3aWxsIGJlIGFtcGxlIHJlZmNvdW50aW5nIHJhbmdlIGF2YWlsYWJsZS4K PiArCj4gKyogQ2FsbGVycyBtdXN0IHNwZWNpZmljYWxseSByZXF1ZXN0ICJkbWEtcGlubmVkIHRy YWNraW5nIG9mIHBhZ2VzIi4gSW4gb3RoZXIKPiArICB3b3JkcywganVzdCBjYWxsaW5nIGdldF91 c2VyX3BhZ2VzKCkgd2lsbCBub3Qgc3VmZmljZTsgYSBuZXcgc2V0IG9mIGZ1bmN0aW9ucywKPiAr ICBwaW5fdXNlcl9wYWdlKCkgYW5kIHJlbGF0ZWQsIG11c3QgYmUgdXNlZC4KPiArCj4gK0ZPTExf UElOLCBGT0xMX0dFVCwgRk9MTF9MT05HVEVSTTogd2hlbiB0byB1c2Ugd2hpY2ggZmxhZ3MKPiAr PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PQo+ICsKPiArVGhhbmtzIHRvIEphbiBLYXJhLCBWbGFzdGltaWwgQmFia2EgYW5kIHNldmVyYWwg b3RoZXIgLW1tIHBlb3BsZSwgZm9yIGRlc2NyaWJpbmcKPiArdGhlc2UgY2F0ZWdvcmllczoKPiAr Cj4gK0NBU0UgMTogRGlyZWN0IElPIChESU8pCj4gKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4g K1RoZXJlIGFyZSBHVVAgcmVmZXJlbmNlcyB0byBwYWdlcyB0aGF0IGFyZSBzZXJ2aW5nCj4gK2Fz IERJTyBidWZmZXJzLiBUaGVzZSBidWZmZXJzIGFyZSBuZWVkZWQgZm9yIGEgcmVsYXRpdmVseSBz aG9ydCB0aW1lIChzbyB0aGV5Cj4gK2FyZSBub3QgImxvbmcgdGVybSIpLiBObyBzcGVjaWFsIHN5 bmNocm9uaXphdGlvbiB3aXRoIHBhZ2VfbWtjbGVhbigpIG9yCj4gK211bm1hcCgpIGlzIHByb3Zp ZGVkLiBUaGVyZWZvcmUsIGZsYWdzIHRvIHNldCBhdCB0aGUgY2FsbCBzaXRlIGFyZTogOjoKPiAr Cj4gKyAgICBGT0xMX1BJTgo+ICsKPiArLi4uYnV0IHJhdGhlciB0aGFuIHNldHRpbmcgRk9MTF9Q SU4gZGlyZWN0bHksIGNhbGwgc2l0ZXMgc2hvdWxkIHVzZSBvbmUgb2YKPiArdGhlIHBpbl91c2Vy X3BhZ2VzKigpIHJvdXRpbmVzIHRoYXQgc2V0IEZPTExfUElOLgo+ICsKPiArQ0FTRSAyOiBSRE1B Cj4gKy0tLS0tLS0tLS0tLQo+ICtUaGVyZSBhcmUgR1VQIHJlZmVyZW5jZXMgdG8gcGFnZXMgdGhh dCBhcmUgc2VydmluZyBhcyBETUEKPiArYnVmZmVycy4gVGhlc2UgYnVmZmVycyBhcmUgbmVlZGVk IGZvciBhIGxvbmcgdGltZSAoImxvbmcgdGVybSIpLiBObyBzcGVjaWFsCj4gK3N5bmNocm9uaXph dGlvbiB3aXRoIHBhZ2VfbWtjbGVhbigpIG9yIG11bm1hcCgpIGlzIHByb3ZpZGVkLiBUaGVyZWZv cmUsIGZsYWdzCj4gK3RvIHNldCBhdCB0aGUgY2FsbCBzaXRlIGFyZTogOjoKPiArCj4gKyAgICBG T0xMX1BJTiB8IEZPTExfTE9OR1RFUk0KPiArCj4gK05PVEU6IFNvbWUgcGFnZXMsIHN1Y2ggYXMg REFYIHBhZ2VzLCBjYW5ub3QgYmUgcGlubmVkIHdpdGggbG9uZ3Rlcm0gcGlucy4gVGhhdCdzCj4g K2JlY2F1c2UgREFYIHBhZ2VzIGRvIG5vdCBoYXZlIGEgc2VwYXJhdGUgcGFnZSBjYWNoZSwgYW5k IHNvICJwaW5uaW5nIiBpbXBsaWVzCj4gK2xvY2tpbmcgZG93biBmaWxlIHN5c3RlbSBibG9ja3Ms IHdoaWNoIGlzIG5vdCAoeWV0KSBzdXBwb3J0ZWQgaW4gdGhhdCB3YXkuCj4gKwo+ICtDQVNFIDM6 IE9EUAo+ICstLS0tLS0tLS0tLQo+ICsoTWVsbGFub3gvSW5maW5pYmFuZCBPbiBEZW1hbmQgUGFn aW5nOiB0aGUgaGFyZHdhcmUgc3VwcG9ydHMKPiArcmVwbGF5YWJsZSBwYWdlIGZhdWx0aW5nKS4g VGhlcmUgYXJlIEdVUCByZWZlcmVuY2VzIHRvIHBhZ2VzIHNlcnZpbmcgYXMgRE1BCj4gK2J1ZmZl cnMuIEZvciBPRFAsIE1NVSBub3RpZmllcnMgYXJlIHVzZWQgdG8gc3luY2hyb25pemUgd2l0aCBw YWdlX21rY2xlYW4oKQo+ICthbmQgbXVubWFwKCkuIFRoZXJlZm9yZSwgbm9ybWFsIEdVUCBjYWxs cyBhcmUgc3VmZmljaWVudCwgc28gbmVpdGhlciBmbGFnCj4gK25lZWRzIHRvIGJlIHNldC4KPiAr Cj4gK0NBU0UgNDogUGlubmluZyBmb3Igc3RydWN0IHBhZ2UgbWFuaXB1bGF0aW9uIG9ubHkKPiAr LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+ICtIZXJl LCBub3JtYWwgR1VQIGNhbGxzIGFyZSBzdWZmaWNpZW50LCBzbyBuZWl0aGVyIGZsYWcgbmVlZHMg dG8gYmUgc2V0Lgo+ICsKPiArcGFnZV9kbWFfcGlubmVkKCk6IHRoZSB3aG9sZSBwb2ludCBvZiBw aW5uaW5nCj4gKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQo+ ICsKPiArVGhlIHdob2xlIHBvaW50IG9mIG1hcmtpbmcgcGFnZXMgYXMgIkRNQS1waW5uZWQiIG9y ICJndXAtcGlubmVkIiBpcyB0byBiZSBhYmxlCj4gK3RvIHF1ZXJ5LCAiaXMgdGhpcyBwYWdlIERN QS1waW5uZWQ/IiBUaGF0IGFsbG93cyBjb2RlIHN1Y2ggYXMgcGFnZV9ta2NsZWFuKCkKPiArKGFu ZCBmaWxlIHN5c3RlbSB3cml0ZWJhY2sgY29kZSBpbiBnZW5lcmFsKSB0byBtYWtlIGluZm9ybWVk IGRlY2lzaW9ucyBhYm91dAo+ICt3aGF0IHRvIGRvIHdoZW4gYSBwYWdlIGNhbm5vdCBiZSB1bm1h cHBlZCBkdWUgdG8gc3VjaCBwaW5zLgo+ICsKPiArV2hhdCB0byBkbyBpbiB0aG9zZSBjYXNlcyBp cyB0aGUgc3ViamVjdCBvZiBhIHllYXJzLWxvbmcgc2VyaWVzIG9mIGRpc2N1c3Npb25zCj4gK2Fu ZCBkZWJhdGVzIChzZWUgdGhlIFJlZmVyZW5jZXMgYXQgdGhlIGVuZCBvZiB0aGlzIGRvY3VtZW50 KS4gSXQncyBhIFRPRE8gaXRlbQo+ICtoZXJlOiBmaWxsIGluIHRoZSBkZXRhaWxzIG9uY2UgdGhh dCdzIHdvcmtlZCBvdXQuIE1lYW53aGlsZSwgaXQncyBzYWZlIHRvIHNheQo+ICt0aGF0IGhhdmlu ZyB0aGlzIGF2YWlsYWJsZTogOjoKPiArCj4gKyAgICAgICAgc3RhdGljIGlubGluZSBib29sIHBh Z2VfZG1hX3Bpbm5lZChzdHJ1Y3QgcGFnZSAqcGFnZSkKPiArCj4gKy4uLmlzIGEgcHJlcmVxdWlz aXRlIHRvIHNvbHZpbmcgdGhlIGxvbmctcnVubmluZyBndXArRE1BIHByb2JsZW0uCj4gKwo+ICtB bm90aGVyIHdheSBvZiB0aGlua2luZyBhYm91dCBGT0xMX0dFVCwgRk9MTF9QSU4sIGFuZCBGT0xM X0xPTkdURVJNCj4gKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT0KPiArCj4gK0Fub3RoZXIgd2F5IG9mIHRoaW5raW5nIGFi b3V0IHRoZXNlIGZsYWdzIGlzIGFzIGEgcHJvZ3Jlc3Npb24gb2YgcmVzdHJpY3Rpb25zOgo+ICtG T0xMX0dFVCBpcyBmb3Igc3RydWN0IHBhZ2UgbWFuaXB1bGF0aW9uLCB3aXRob3V0IGFmZmVjdGlu ZyB0aGUgZGF0YSB0aGF0IHRoZQo+ICtzdHJ1Y3QgcGFnZSByZWZlcnMgdG8uIEZPTExfUElOIGlz IGEgKnJlcGxhY2VtZW50KiBmb3IgRk9MTF9HRVQsIGFuZCBpcyBmb3IKPiArc2hvcnQgdGVybSBw aW5zIG9uIHBhZ2VzIHdob3NlIGRhdGEgKndpbGwqIGdldCBhY2Nlc3NlZC4gQXMgc3VjaCwgRk9M TF9QSU4gaXMKPiArYSAibW9yZSBzZXZlcmUiIGZvcm0gb2YgcGlubmluZy4gQW5kIGZpbmFsbHks IEZPTExfTE9OR1RFUk0gaXMgYW4gZXZlbiBtb3JlCj4gK3Jlc3RyaWN0aXZlIGNhc2UgdGhhdCBo YXMgRk9MTF9QSU4gYXMgYSBwcmVyZXF1aXNpdGU6IHRoaXMgaXMgZm9yIHBhZ2VzIHRoYXQKPiAr d2lsbCBiZSBwaW5uZWQgbG9uZ3Rlcm0sIGFuZCB3aG9zZSBkYXRhIHdpbGwgYmUgYWNjZXNzZWQu Cj4gKwo+ICtVbml0IHRlc3RpbmcKPiArPT09PT09PT09PT09Cj4gK1RoaXMgZmlsZTo6Cj4gKwo+ ICsgdG9vbHMvdGVzdGluZy9zZWxmdGVzdHMvdm0vZ3VwX2JlbmNobWFyay5jCj4gKwo+ICtoYXMg dGhlIGZvbGxvd2luZyBuZXcgY2FsbHMgdG8gZXhlcmNpc2UgdGhlIG5ldyBwaW4qKCkgd3JhcHBl ciBmdW5jdGlvbnM6Cj4gKwo+ICsqIFBJTl9GQVNUX0JFTkNITUFSSyAoLi9ndXBfYmVuY2htYXJr IC1hKQo+ICsqIFBJTl9MT05HVEVSTV9CRU5DSE1BUksgKC4vZ3VwX2JlbmNobWFyayAtYSkKPiAr KiBQSU5fQkVOQ0hNQVJLICguL2d1cF9iZW5jaG1hcmsgLWEpCj4gKwo+ICtZb3UgY2FuIG1vbml0 b3IgaG93IG1hbnkgdG90YWwgZG1hLXBpbm5lZCBwYWdlcyBoYXZlIGJlZW4gYWNxdWlyZWQgYW5k IHJlbGVhc2VkCj4gK3NpbmNlIHRoZSBzeXN0ZW0gd2FzIGJvb3RlZCwgdmlhIHR3byBuZXcgL3By b2Mvdm1zdGF0IGVudHJpZXM6IDo6Cj4gKwo+ICsgICAgL3Byb2Mvdm1zdGF0L25yX2ZvbGxfcGlu X3JlcXVlc3RlZAo+ICsgICAgL3Byb2Mvdm1zdGF0L25yX2ZvbGxfcGluX3JlcXVlc3RlZAo+ICsK PiArVGhvc2UgYXJlIGJvdGggZ29pbmcgdG8gc2hvdyB6ZXJvLCB1bmxlc3MgQ09ORklHX0RFQlVH X1ZNIGlzIHNldC4gVGhpcyBpcwo+ICtiZWNhdXNlIHRoZXJlIGlzIGEgbm90aWNlYWJsZSBwZXJm b3JtYW5jZSBkcm9wIGluIHB1dF91c2VyX3BhZ2UoKSwgd2hlbiB0aGV5Cj4gK2FyZSBhY3RpdmF0 ZWQuCj4gKwo+ICtSZWZlcmVuY2VzCj4gKz09PT09PT09PT0KPiArCj4gKyogYFNvbWUgc2xvdyBw cm9ncmVzcyBvbiBnZXRfdXNlcl9wYWdlcygpIChBcHIgMiwgMjAxOSkgPGh0dHBzOi8vbHduLm5l dC9BcnRpY2xlcy83ODQ1NzQvPmBfCj4gKyogYERNQSBhbmQgZ2V0X3VzZXJfcGFnZXMoKSAoTFBD OiBEZWMgMTIsIDIwMTgpIDxodHRwczovL2x3bi5uZXQvQXJ0aWNsZXMvNzc0NDExLz5gXwo+ICsq IGBUaGUgdHJvdWJsZSB3aXRoIGdldF91c2VyX3BhZ2VzKCkgKEFwciAzMCwgMjAxOCkgPGh0dHBz Oi8vbHduLm5ldC9BcnRpY2xlcy83NTMwMjcvPmBfCj4gKwo+ICtKb2huIEh1YmJhcmQsIE9jdG9i ZXIsIDIwMTkKPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9tbS5oIGIvaW5jbHVkZS9saW51 eC9tbS5oCj4gaW5kZXggY2MyOTIyNzNlNmJhLi5jZGZiNmZlZGIyNzEgMTAwNjQ0Cj4gLS0tIGEv aW5jbHVkZS9saW51eC9tbS5oCj4gKysrIGIvaW5jbHVkZS9saW51eC9tbS5oCj4gQEAgLTE1MjYs OSArMTUyNiwyMyBAQCBsb25nIGdldF91c2VyX3BhZ2VzX3JlbW90ZShzdHJ1Y3QgdGFza19zdHJ1 Y3QgKnRzaywgc3RydWN0IG1tX3N0cnVjdCAqbW0sCj4gIAkJCSAgICB1bnNpZ25lZCBsb25nIHN0 YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICAJCQkgICAgdW5zaWduZWQgaW50IGd1cF9m bGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywKPiAgCQkJICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVj dCAqKnZtYXMsIGludCAqbG9ja2VkKTsKPiArbG9uZyBwaW5fdXNlcl9wYWdlc19yZW1vdGUoc3Ry dWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICsJCQkgICB1bnNp Z25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICsJCQkgICB1bnNpZ25l ZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAo+ICsJCQkgICBzdHJ1Y3Qgdm1f YXJlYV9zdHJ1Y3QgKip2bWFzLCBpbnQgKmxvY2tlZCk7Cj4gK2xvbmcgcGluX2xvbmd0ZXJtX3Bh Z2VzX3JlbW90ZShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywgc3RydWN0IG1tX3N0cnVjdCAqbW0s Cj4gKwkJCSAgICAgICB1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2Vz LAo+ICsJCQkgICAgICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdl cywKPiArCQkJICAgICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqKnZtYXMsIGludCAqbG9ja2Vk KTsKPiAgbG9uZyBnZXRfdXNlcl9wYWdlcyh1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBs b25nIG5yX3BhZ2VzLAo+ICAJCQkgICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBh Z2UgKipwYWdlcywKPiAgCQkJICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqKnZtYXMpOwo+ICts b25nIHBpbl91c2VyX3BhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcgbnJf cGFnZXMsCj4gKwkJICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFn ZXMsCj4gKwkJICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqKnZtYXMpOwo+ICtsb25nIHBpbl9s b25ndGVybV9wYWdlcyh1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2Vz LAo+ICsJCQl1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAo+ICsJ CQlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzKTsKPiAgbG9uZyBnZXRfdXNlcl9wYWdlc19s b2NrZWQodW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBucl9wYWdlcywKPiAgCQkg ICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywgaW50ICpsb2Nr ZWQpOwo+ICBsb25nIGdldF91c2VyX3BhZ2VzX3VubG9ja2VkKHVuc2lnbmVkIGxvbmcgc3RhcnQs IHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMsCj4gQEAgLTE1MzYsNiArMTU1MCwxMCBAQCBsb25nIGdl dF91c2VyX3BhZ2VzX3VubG9ja2VkKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcg bnJfcGFnZXMsCj4gIAo+ICBpbnQgZ2V0X3VzZXJfcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0 YXJ0LCBpbnQgbnJfcGFnZXMsCj4gIAkJCXVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBw YWdlICoqcGFnZXMpOwo+ICtpbnQgcGluX3VzZXJfcGFnZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0 YXJ0LCBpbnQgbnJfcGFnZXMsCj4gKwkJCXVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBw YWdlICoqcGFnZXMpOwo+ICtpbnQgcGluX2xvbmd0ZXJtX3BhZ2VzX2Zhc3QodW5zaWduZWQgbG9u ZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICsJCQkgICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywg c3RydWN0IHBhZ2UgKipwYWdlcyk7Cj4gIAo+ICBpbnQgYWNjb3VudF9sb2NrZWRfdm0oc3RydWN0 IG1tX3N0cnVjdCAqbW0sIHVuc2lnbmVkIGxvbmcgcGFnZXMsIGJvb2wgaW5jKTsKPiAgaW50IF9f YWNjb3VudF9sb2NrZWRfdm0oc3RydWN0IG1tX3N0cnVjdCAqbW0sIHVuc2lnbmVkIGxvbmcgcGFn ZXMsIGJvb2wgaW5jLAo+IEBAIC0yNTk0LDEzICsyNjEyLDE1IEBAIHN0cnVjdCBwYWdlICpmb2xs b3dfcGFnZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgdW5zaWduZWQgbG9uZyBhZGRyZXNz LAo+ICAjZGVmaW5lIEZPTExfQU5PTgkweDgwMDAJLyogZG9uJ3QgZG8gZmlsZSBtYXBwaW5ncyAq Lwo+ICAjZGVmaW5lIEZPTExfTE9OR1RFUk0JMHgxMDAwMAkvKiBtYXBwaW5nIGxpZmV0aW1lIGlz IGluZGVmaW5pdGU6IHNlZSBiZWxvdyAqLwo+ICAjZGVmaW5lIEZPTExfU1BMSVRfUE1ECTB4MjAw MDAJLyogc3BsaXQgaHVnZSBwbWQgYmVmb3JlIHJldHVybmluZyAqLwo+ICsjZGVmaW5lIEZPTExf UElOCTB4NDAwMDAJLyogcGFnZXMgbXVzdCBiZSByZWxlYXNlZCB2aWEgcHV0X3VzZXJfcGFnZSgp ICovCj4gIAo+ICAvKgo+IC0gKiBOT1RFIG9uIEZPTExfTE9OR1RFUk06Cj4gKyAqIEZPTExfUElO IGFuZCBGT0xMX0xPTkdURVJNIG1heSBiZSB1c2VkIGluIHZhcmlvdXMgY29tYmluYXRpb25zIHdp dGggZWFjaAo+ICsgKiBvdGhlci4gSGVyZSBpcyB3aGF0IHRoZXkgbWVhbiwgYW5kIGhvdyB0byB1 c2UgdGhlbToKPiAgICoKPiAgICogRk9MTF9MT05HVEVSTSBpbmRpY2F0ZXMgdGhhdCB0aGUgcGFn ZSB3aWxsIGJlIGhlbGQgZm9yIGFuIGluZGVmaW5pdGUgdGltZQo+IC0gKiBwZXJpb2QgX29mdGVu XyB1bmRlciB1c2Vyc3BhY2UgY29udHJvbC4gIFRoaXMgaXMgY29udHJhc3RlZCB3aXRoCj4gLSAq IGlvdl9pdGVyX2dldF9wYWdlcygpIHdoZXJlIHVzYWdlcyB3aGljaCBhcmUgdHJhbnNpZW50Lgo+ ICsgKiBwZXJpb2QgX29mdGVuXyB1bmRlciB1c2Vyc3BhY2UgY29udHJvbC4gIFRoaXMgaXMgaW4g Y29udHJhc3QgdG8KPiArICogaW92X2l0ZXJfZ2V0X3BhZ2VzKCksIHdoZXJlIHVzYWdlcyB3aGlj aCBhcmUgdHJhbnNpZW50Lgo+ICAgKgo+ICAgKiBGSVhNRTogRm9yIHBhZ2VzIHdoaWNoIGFyZSBw YXJ0IG9mIGEgZmlsZXN5c3RlbSwgbWFwcGluZ3MgYXJlIHN1YmplY3QgdG8gdGhlCj4gICAqIGxp ZmV0aW1lIGVuZm9yY2VkIGJ5IHRoZSBmaWxlc3lzdGVtIGFuZCB3ZSBuZWVkIGd1YXJhbnRlZXMg dGhhdCBsb25ndGVybQo+IEBAIC0yNjE1LDExICsyNjM1LDQxIEBAIHN0cnVjdCBwYWdlICpmb2xs b3dfcGFnZShzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSwgdW5zaWduZWQgbG9uZyBhZGRyZXNz LAo+ICAgKiBDdXJyZW50bHkgb25seSBnZXRfdXNlcl9wYWdlcygpIGFuZCBnZXRfdXNlcl9wYWdl c19mYXN0KCkgc3VwcG9ydCB0aGlzIGZsYWcKPiAgICogYW5kIGNhbGxzIHRvIGdldF91c2VyX3Bh Z2VzX1t1bl1sb2NrZWQgYXJlIHNwZWNpZmljYWxseSBub3QgYWxsb3dlZC4gIFRoaXMKPiAgICog aXMgZHVlIHRvIGFuIGluY29tcGF0aWJpbGl0eSB3aXRoIHRoZSBGUyBEQVggY2hlY2sgYW5kCj4g LSAqIEZBVUxUX0ZMQUdfQUxMT1dfUkVUUlkKPiArICogRkFVTFRfRkxBR19BTExPV19SRVRSWS4K PiAgICoKPiAtICogSW4gdGhlIENNQSBjYXNlOiBsb25ndGVybSBwaW5zIGluIGEgQ01BIHJlZ2lv biB3b3VsZCB1bm5lY2Vzc2FyaWx5IGZyYWdtZW50Cj4gLSAqIHRoYXQgcmVnaW9uLiAgQW5kIHNv IENNQSBhdHRlbXB0cyB0byBtaWdyYXRlIHRoZSBwYWdlIGJlZm9yZSBwaW5uaW5nIHdoZW4KPiAr ICogSW4gdGhlIENNQSBjYXNlOiBsb25nIHRlcm0gcGlucyBpbiBhIENNQSByZWdpb24gd291bGQg dW5uZWNlc3NhcmlseSBmcmFnbWVudAo+ICsgKiB0aGF0IHJlZ2lvbi4gIEFuZCBzbywgQ01BIGF0 dGVtcHRzIHRvIG1pZ3JhdGUgdGhlIHBhZ2UgYmVmb3JlIHBpbm5pbmcsIHdoZW4KPiAgICogRk9M TF9MT05HVEVSTSBpcyBzcGVjaWZpZWQuCj4gKyAqCj4gKyAqIEZPTExfUElOIGluZGljYXRlcyB0 aGF0IGEgc3BlY2lhbCBraW5kIG9mIHRyYWNraW5nIChub3QganVzdCBwYWdlLT5fcmVmY291bnQs Cj4gKyAqIGJ1dCBhbiBhZGRpdGlvbmFsIHBpbiBjb3VudGluZyBzeXN0ZW0pIHdpbGwgYmUgaW52 b2tlZC4gVGhpcyBpcyBpbnRlbmRlZCBmb3IKPiArICogYW55dGhpbmcgdGhhdCBnZXRzIGEgcGFn ZSByZWZlcmVuY2UgYW5kIHRoZW4gdG91Y2hlcyBwYWdlIGRhdGEgKGZvciBleGFtcGxlLAo+ICsg KiBEaXJlY3QgSU8pLiBUaGlzIGxldHMgdGhlIGZpbGVzeXN0ZW0ga25vdyB0aGF0IHNvbWUgbm9u LWZpbGUtc3lzdGVtIGVudGl0eSBpcwo+ICsgKiBwb3RlbnRpYWxseSBjaGFuZ2luZyB0aGUgcGFn ZXMnIGRhdGEuIEluIGNvbnRyYXN0IHRvIEZPTExfR0VUICh3aG9zZSBwYWdlcwo+ICsgKiBhcmUg cmVsZWFzZWQgdmlhIHB1dF9wYWdlKCkpLCBGT0xMX1BJTiBwYWdlcyBtdXN0IGJlIHJlbGVhc2Vk LCB1bHRpbWF0ZWx5LCBieQo+ICsgKiBhIGNhbGwgdG8gcHV0X3VzZXJfcGFnZSgpLgo+ICsgKgo+ ICsgKiBGT0xMX1BJTiBpcyBzaW1pbGFyIHRvIEZPTExfR0VUOiBib3RoIG9mIHRoZXNlIHBpbiBw YWdlcy4gVGhleSB1c2UgZGlmZmVyZW50Cj4gKyAqIGFuZCBzZXBhcmF0ZSByZWZjb3VudGluZyBt ZWNoYW5pc21zLCBob3dldmVyLCBhbmQgdGhhdCBtZWFucyB0aGF0IGVhY2ggaGFzCj4gKyAqIGl0 cyBvd24gYWNxdWlyZSBhbmQgcmVsZWFzZSBtZWNoYW5pc21zOgo+ICsgKgo+ICsgKiAgICAgRk9M TF9HRVQ6IGdldF91c2VyX3BhZ2VzKigpIHRvIGFjcXVpcmUsIGFuZCBwdXRfcGFnZSgpIHRvIHJl bGVhc2UuCj4gKyAqCj4gKyAqICAgICBGT0xMX1BJTjogcGluX3VzZXJfcGFnZXMqKCkgb3IgcGlu X2xvbmd0ZXJtX3BhZ2VzKigpIHRvIGFjcXVpcmUsIGFuZAo+ICsgKiAgICAgICAgICAgICAgIHB1 dF91c2VyX3BhZ2VzIHRvIHJlbGVhc2UuCj4gKyAqCj4gKyAqIEZPTExfUElOIGFuZCBGT0xMX0dF VCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGZvciBhIGdpdmVuIGZ1bmN0aW9uIGNhbGwuCj4gKyAq IChUaGUgdW5kZXJseWluZyBwYWdlcyBtYXkgZXhwZXJpZW5jZSBib3RoIEZPTExfR0VULWJhc2Vk IGFuZCBGT0xMX1BJTi1iYXNlZAo+ICsgKiBjYWxscyBhcHBsaWVkIHRvIHRoZW0sIGFuZCB0aGF0 J3MgcGVyZmVjdGx5IE9LLiBUaGlzIGlzIGEgY29uc3RyYWludCBvbiB0aGUKPiArICogY2FsbGVy cywgbm90IG9uIHRoZSBwYWdlcy4pCj4gKyAqCj4gKyAqIEZPTExfUElOIGFuZCBGT0xMX0xPTkdU RVJNIHNob3VsZCBiZSBzZXQgaW50ZXJuYWxseSBieSB0aGUgcGluX3VzZXJfcGFnZSooKQo+ICsg KiBhbmQgcGluX2xvbmd0ZXJtXyooKSBBUElzLCBuZXZlciBkaXJlY3RseSBieSB0aGUgY2FsbGVy LiBUaGF0J3MgaW4gb3JkZXIgdG8KPiArICogaGVscCBhdm9pZCBtaXNtYXRjaGVzIHdoZW4gcmVs ZWFzaW5nIHBhZ2VzOiBnZXRfdXNlcl9wYWdlcyooKSBwYWdlcyBtdXN0IGJlCj4gKyAqIHJlbGVh c2VkIHZpYSBwdXRfcGFnZSgpLCB3aGlsZSBwaW5fdXNlcl9wYWdlcyooKSBwYWdlcyBtdXN0IGJl IHJlbGVhc2VkIHZpYQo+ICsgKiBwdXRfdXNlcl9wYWdlKCkuCj4gKyAqCj4gKyAqIFBsZWFzZSBz ZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNlcl9wYWdlcy5yc3QgZm9yIG1vcmUgaW5mb3JtYXRp b24uCj4gICAqLwo+ICAKPiAgc3RhdGljIGlubGluZSBpbnQgdm1fZmF1bHRfdG9fZXJybm8odm1f ZmF1bHRfdCB2bV9mYXVsdCwgaW50IGZvbGxfZmxhZ3MpCj4gZGlmZiAtLWdpdCBhL21tL2d1cC5j IGIvbW0vZ3VwLmMKPiBpbmRleCAxOTlkYTk5ZThmZmMuLjFhZWE0ODQyNzg3OSAxMDA2NDQKPiAt LS0gYS9tbS9ndXAuYwo+ICsrKyBiL21tL2d1cC5jCj4gQEAgLTE3OSw2ICsxNzksMTAgQEAgc3Rh dGljIHN0cnVjdCBwYWdlICpmb2xsb3dfcGFnZV9wdGUoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2 bWEsCj4gIAlzcGlubG9ja190ICpwdGw7Cj4gIAlwdGVfdCAqcHRlcCwgcHRlOwo+ICAKPiArCS8q IEZPTExfR0VUIGFuZCBGT0xMX1BJTiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ICsJaWYg KFdBUk5fT05fT05DRSgoZmxhZ3MgJiAoRk9MTF9QSU4gfCBGT0xMX0dFVCkpID09Cj4gKwkJCSAo Rk9MTF9QSU4gfCBGT0xMX0dFVCkpKQo+ICsJCXJldHVybiBFUlJfUFRSKC1FSU5WQUwpOwo+ICBy ZXRyeToKPiAgCWlmICh1bmxpa2VseShwbWRfYmFkKCpwbWQpKSkKPiAgCQlyZXR1cm4gbm9fcGFn ZV90YWJsZSh2bWEsIGZsYWdzKTsKPiBAQCAtNzkwLDcgKzc5NCw3IEBAIHN0YXRpYyBsb25nIF9f Z2V0X3VzZXJfcGFnZXMoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ssIHN0cnVjdCBtbV9zdHJ1Y3Qg Km1tLAo+ICAKPiAgCXN0YXJ0ID0gdW50YWdnZWRfYWRkcihzdGFydCk7Cj4gIAo+IC0JVk1fQlVH X09OKCEhcGFnZXMgIT0gISEoZ3VwX2ZsYWdzICYgRk9MTF9HRVQpKTsKPiArCVZNX0JVR19PTigh IXBhZ2VzICE9ICEhKGd1cF9mbGFncyAmIChGT0xMX0dFVCB8IEZPTExfUElOKSkpOwo+ICAKPiAg CS8qCj4gIAkgKiBJZiBGT0xMX0ZPUkNFIGlzIHNldCB0aGVuIGRvIG5vdCBmb3JjZSBhIGZ1bGwg ZmF1bHQgYXMgdGhlIGhpbnRpbmcKPiBAQCAtMTAxNCw3ICsxMDE4LDE2IEBAIHN0YXRpYyBfX2Fs d2F5c19pbmxpbmUgbG9uZyBfX2dldF91c2VyX3BhZ2VzX2xvY2tlZChzdHJ1Y3QgdGFza19zdHJ1 Y3QgKnRzaywKPiAgCQlCVUdfT04oKmxvY2tlZCAhPSAxKTsKPiAgCX0KPiAgCj4gLQlpZiAocGFn ZXMpCj4gKwkvKgo+ICsJICogRk9MTF9QSU4gYW5kIEZPTExfR0VUIGFyZSBtdXR1YWxseSBleGNs dXNpdmUuIFRyYWRpdGlvbmFsIGJlaGF2aW9yCj4gKwkgKiBpcyB0byBzZXQgRk9MTF9HRVQgaWYg dGhlIGNhbGxlciB3YW50cyBwYWdlc1tdIGZpbGxlZCBpbiAoYnV0IGhhcwo+ICsJICogY2FyZWxl c3NseSBmYWlsZWQgdG8gc3BlY2lmeSBGT0xMX0dFVCksIHNvIGtlZXAgZG9pbmcgdGhhdCwgYnV0 IG9ubHkKPiArCSAqIGZvciBGT0xMX0dFVCwgbm90IGZvciB0aGUgbmV3ZXIgRk9MTF9QSU4uCj4g KwkgKgo+ICsJICogRk9MTF9QSU4gYWx3YXlzIGV4cGVjdHMgcGFnZXMgdG8gYmUgbm9uLW51bGws IGJ1dCBubyBuZWVkIHRvIGFzc2VydAo+ICsJICogdGhhdCBoZXJlLCBhcyBhbnkgZmFpbHVyZXMg d2lsbCBiZSBvYnZpb3VzIGVub3VnaC4KPiArCSAqLwo+ICsJaWYgKHBhZ2VzICYmICEoZmxhZ3Mg JiBGT0xMX1BJTikpCj4gIAkJZmxhZ3MgfD0gRk9MTF9HRVQ7Cj4gIAo+ICAJcGFnZXNfZG9uZSA9 IDA7Cj4gQEAgLTExNTEsNiArMTE2NCwxNCBAQCBsb25nIGdldF91c2VyX3BhZ2VzX3JlbW90ZShz dHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywgc3RydWN0IG1tX3N0cnVjdCAqbW0sCj4gIAkJdW5zaWdu ZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2UgKipwYWdlcywKPiAgCQlzdHJ1Y3Qgdm1fYXJl YV9zdHJ1Y3QgKip2bWFzLCBpbnQgKmxvY2tlZCkKPiAgewo+ICsJLyoKPiArCSAqIEZPTExfUElO IG11c3Qgb25seSBiZSBzZXQgaW50ZXJuYWxseSBieSB0aGUgcGluX3VzZXJfcGFnZSooKSBhbmQK PiArCSAqIHBpbl9sb25ndGVybV8qKCkgQVBJcywgbmV2ZXIgZGlyZWN0bHkgYnkgdGhlIGNhbGxl ciwgc28gZW5mb3JjZSB0aGF0Cj4gKwkgKiB3aXRoIGFuIGFzc2VydGlvbjoKPiArCSAqLwo+ICsJ aWYgKFdBUk5fT05fT05DRShndXBfZmxhZ3MgJiBGT0xMX1BJTikpCj4gKwkJcmV0dXJuIC1FSU5W QUw7Cj4gKwo+ICAJLyoKPiAgCSAqIEZJWE1FOiBDdXJyZW50IEZPTExfTE9OR1RFUk0gYmVoYXZp b3IgaXMgaW5jb21wYXRpYmxlIHdpdGgKPiAgCSAqIEZBVUxUX0ZMQUdfQUxMT1dfUkVUUlkgYmVj YXVzZSBvZiB0aGUgRlMgREFYIGNoZWNrIHJlcXVpcmVtZW50IG9uCj4gQEAgLTE2MDgsNiArMTYy OSwxNCBAQCBsb25nIGdldF91c2VyX3BhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVk IGxvbmcgbnJfcGFnZXMsCj4gIAkJdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2Ug KipwYWdlcywKPiAgCQlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzKQo+ICB7Cj4gKwkvKgo+ ICsJICogRk9MTF9QSU4gbXVzdCBvbmx5IGJlIHNldCBpbnRlcm5hbGx5IGJ5IHRoZSBwaW5fdXNl cl9wYWdlKigpIGFuZAo+ICsJICogcGluX2xvbmd0ZXJtXyooKSBBUElzLCBuZXZlciBkaXJlY3Rs eSBieSB0aGUgY2FsbGVyLCBzbyBlbmZvcmNlIHRoYXQKPiArCSAqIHdpdGggYW4gYXNzZXJ0aW9u Ogo+ICsJICovCj4gKwlpZiAoV0FSTl9PTl9PTkNFKGd1cF9mbGFncyAmIEZPTExfUElOKSkKPiAr CQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gIAlyZXR1cm4gX19ndXBfbG9uZ3Rlcm1fbG9ja2VkKGN1 cnJlbnQsIGN1cnJlbnQtPm1tLCBzdGFydCwgbnJfcGFnZXMsCj4gIAkJCQkgICAgIHBhZ2VzLCB2 bWFzLCBndXBfZmxhZ3MgfCBGT0xMX1RPVUNIKTsKPiAgfQo+IEBAIC0yMzczLDI0ICsyNDAyLDkg QEAgc3RhdGljIGludCBfX2d1cF9sb25ndGVybV91bmxvY2tlZCh1bnNpZ25lZCBsb25nIHN0YXJ0 LCBpbnQgbnJfcGFnZXMsCj4gIAlyZXR1cm4gcmV0Owo+ICB9Cj4gIAo+IC0vKioKPiAtICogZ2V0 X3VzZXJfcGFnZXNfZmFzdCgpIC0gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5Cj4gLSAqIEBzdGFy dDoJc3RhcnRpbmcgdXNlciBhZGRyZXNzCj4gLSAqIEBucl9wYWdlczoJbnVtYmVyIG9mIHBhZ2Vz IGZyb20gc3RhcnQgdG8gcGluCj4gLSAqIEBndXBfZmxhZ3M6CWZsYWdzIG1vZGlmeWluZyBwaW4g YmVoYXZpb3VyCj4gLSAqIEBwYWdlczoJYXJyYXkgdGhhdCByZWNlaXZlcyBwb2ludGVycyB0byB0 aGUgcGFnZXMgcGlubmVkLgo+IC0gKgkJU2hvdWxkIGJlIGF0IGxlYXN0IG5yX3BhZ2VzIGxvbmcu Cj4gLSAqCj4gLSAqIEF0dGVtcHQgdG8gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IHdpdGhvdXQg dGFraW5nIG1tLT5tbWFwX3NlbS4KPiAtICogSWYgbm90IHN1Y2Nlc3NmdWwsIGl0IHdpbGwgZmFs bCBiYWNrIHRvIHRha2luZyB0aGUgbG9jayBhbmQKPiAtICogY2FsbGluZyBnZXRfdXNlcl9wYWdl cygpLgo+IC0gKgo+IC0gKiBSZXR1cm5zIG51bWJlciBvZiBwYWdlcyBwaW5uZWQuIFRoaXMgbWF5 IGJlIGZld2VyIHRoYW4gdGhlIG51bWJlcgo+IC0gKiByZXF1ZXN0ZWQuIElmIG5yX3BhZ2VzIGlz IDAgb3IgbmVnYXRpdmUsIHJldHVybnMgMC4gSWYgbm8gcGFnZXMKPiAtICogd2VyZSBwaW5uZWQs IHJldHVybnMgLWVycm5vLgo+IC0gKi8KPiAtaW50IGdldF91c2VyX3BhZ2VzX2Zhc3QodW5zaWdu ZWQgbG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+IC0JCQl1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdz LCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKQo+ICtzdGF0aWMgaW50IGludGVybmFsX2dldF91c2VyX3Bh Z2VzX2Zhc3QodW5zaWduZWQgbG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICsJCQkJCXVuc2ln bmVkIGludCBndXBfZmxhZ3MsCj4gKwkJCQkJc3RydWN0IHBhZ2UgKipwYWdlcykKPiAgewo+ICAJ dW5zaWduZWQgbG9uZyBhZGRyLCBsZW4sIGVuZDsKPiAgCWludCBuciA9IDAsIHJldCA9IDA7Cj4g QEAgLTI0MzUsNCArMjQ0OSwyMTUgQEAgaW50IGdldF91c2VyX3BhZ2VzX2Zhc3QodW5zaWduZWQg bG9uZyBzdGFydCwgaW50IG5yX3BhZ2VzLAo+ICAKPiAgCXJldHVybiByZXQ7Cj4gIH0KPiArCj4g Ky8qKgo+ICsgKiBnZXRfdXNlcl9wYWdlc19mYXN0KCkgLSBwaW4gdXNlciBwYWdlcyBpbiBtZW1v cnkKPiArICogQHN0YXJ0OglzdGFydGluZyB1c2VyIGFkZHJlc3MKPiArICogQG5yX3BhZ2VzOglu dW1iZXIgb2YgcGFnZXMgZnJvbSBzdGFydCB0byBwaW4KPiArICogQGd1cF9mbGFnczoJZmxhZ3Mg bW9kaWZ5aW5nIHBpbiBiZWhhdmlvdXIKPiArICogQHBhZ2VzOglhcnJheSB0aGF0IHJlY2VpdmVz IHBvaW50ZXJzIHRvIHRoZSBwYWdlcyBwaW5uZWQuCj4gKyAqCQlTaG91bGQgYmUgYXQgbGVhc3Qg bnJfcGFnZXMgbG9uZy4KPiArICoKPiArICogQXR0ZW1wdCB0byBwaW4gdXNlciBwYWdlcyBpbiBt ZW1vcnkgd2l0aG91dCB0YWtpbmcgbW0tPm1tYXBfc2VtLgo+ICsgKiBJZiBub3Qgc3VjY2Vzc2Z1 bCwgaXQgd2lsbCBmYWxsIGJhY2sgdG8gdGFraW5nIHRoZSBsb2NrIGFuZAo+ICsgKiBjYWxsaW5n IGdldF91c2VyX3BhZ2VzKCkuCj4gKyAqCj4gKyAqIFJldHVybnMgbnVtYmVyIG9mIHBhZ2VzIHBp bm5lZC4gVGhpcyBtYXkgYmUgZmV3ZXIgdGhhbiB0aGUgbnVtYmVyIHJlcXVlc3RlZC4KPiArICog SWYgbnJfcGFnZXMgaXMgMCBvciBuZWdhdGl2ZSwgcmV0dXJucyAwLiBJZiBubyBwYWdlcyB3ZXJl IHBpbm5lZCwgcmV0dXJucwo+ICsgKiAtZXJybm8uCj4gKyAqLwo+ICtpbnQgZ2V0X3VzZXJfcGFn ZXNfZmFzdCh1bnNpZ25lZCBsb25nIHN0YXJ0LCBpbnQgbnJfcGFnZXMsCj4gKwkJCXVuc2lnbmVk IGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMpCj4gK3sKPiArCS8qCj4gKwkgKiBG T0xMX1BJTiBtdXN0IG9ubHkgYmUgc2V0IGludGVybmFsbHkgYnkgdGhlIHBpbl91c2VyX3BhZ2Uq KCkgYW5kCj4gKwkgKiBwaW5fbG9uZ3Rlcm1fKigpIEFQSXMsIG5ldmVyIGRpcmVjdGx5IGJ5IHRo ZSBjYWxsZXIsIHNvIGVuZm9yY2UgdGhhdDoKPiArCSAqLwo+ICsJaWYgKFdBUk5fT05fT05DRShn dXBfZmxhZ3MgJiBGT0xMX1BJTikpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJcmV0dXJu IGludGVybmFsX2dldF91c2VyX3BhZ2VzX2Zhc3Qoc3RhcnQsIG5yX3BhZ2VzLCBndXBfZmxhZ3Ms IHBhZ2VzKTsKPiArfQo+ICBFWFBPUlRfU1lNQk9MX0dQTChnZXRfdXNlcl9wYWdlc19mYXN0KTsK PiArCj4gKy8qKgo+ICsgKiBwaW5fdXNlcl9wYWdlc19mYXN0KCkgLSBwaW4gdXNlciBwYWdlcyBp biBtZW1vcnkgd2l0aG91dCB0YWtpbmcgbG9ja3MKPiArICoKPiArICogTmVhcmx5IHRoZSBzYW1l IGFzIGdldF91c2VyX3BhZ2VzX2Zhc3QoKSwgZXhjZXB0IHRoYXQgRk9MTF9QSU4gaXMgc2V0LiBT ZWUKPiArICogZ2V0X3VzZXJfcGFnZXNfZmFzdCgpIGZvciBkb2N1bWVudGF0aW9uIG9uIHRoZSBm dW5jdGlvbiBhcmd1bWVudHMsIGJlY2F1c2UKPiArICogdGhlIGFyZ3VtZW50cyBoZXJlIGFyZSBp ZGVudGljYWwuCj4gKyAqCj4gKyAqIEZPTExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3Qg YmUgcmVsZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVu dGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdCBmb3IgZnVydGhlciBkZXRhaWxzLgo+ICsgKgo+ ICsgKiBUaGlzIGlzIGludGVuZGVkIGZvciBDYXNlIDEgKERJTykgaW4gRG9jdW1lbnRhdGlvbi92 bS9waW5fdXNlcl9wYWdlcy5yc3QuIEl0Cj4gKyAqIGlzIE5PVCBpbnRlbmRlZCBmb3IgQ2FzZSAy IChSRE1BOiBsb25nLXRlcm0gcGlucykuCj4gKyAqLwo+ICtpbnQgcGluX3VzZXJfcGFnZXNfZmFz dCh1bnNpZ25lZCBsb25nIHN0YXJ0LCBpbnQgbnJfcGFnZXMsCj4gKwkJCXVuc2lnbmVkIGludCBn dXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMpCj4gK3sKPiArCS8qIEZPTExfR0VUIGFuZCBG T0xMX1BJTiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ICsJaWYgKFdBUk5fT05fT05DRShn dXBfZmxhZ3MgJiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJZ3VwX2Zs YWdzIHw9IEZPTExfUElOOwo+ICsJcmV0dXJuIGludGVybmFsX2dldF91c2VyX3BhZ2VzX2Zhc3Qo c3RhcnQsIG5yX3BhZ2VzLCBndXBfZmxhZ3MsIHBhZ2VzKTsKPiArfQo+ICtFWFBPUlRfU1lNQk9M X0dQTChwaW5fdXNlcl9wYWdlc19mYXN0KTsKPiArCj4gKy8qKgo+ICsgKiBwaW5fbG9uZ3Rlcm1f cGFnZXNfZmFzdCgpIC0gcGluIHVzZXIgcGFnZXMgaW4gbWVtb3J5IHdpdGhvdXQgdGFraW5nIGxv Y2tzCj4gKyAqCj4gKyAqIE5lYXJseSB0aGUgc2FtZSBhcyBnZXRfdXNlcl9wYWdlc19mYXN0KCks IGV4Y2VwdCB0aGF0IEZPTExfUElOIGFuZAo+ICsgKiBGT0xMX0xPTkdURVJNIGFyZSBzZXQuIFNl ZSBnZXRfdXNlcl9wYWdlc19mYXN0KCkgZm9yIGRvY3VtZW50YXRpb24gb24gdGhlCj4gKyAqIGZ1 bmN0aW9uIGFyZ3VtZW50cywgYmVjYXVzZSB0aGUgYXJndW1lbnRzIGhlcmUgYXJlIGlkZW50aWNh bC4KPiArICoKPiArICogRk9MTF9QSU4gbWVhbnMgdGhhdCB0aGUgcGFnZXMgbXVzdCBiZSByZWxl YXNlZCB2aWEgcHV0X3VzZXJfcGFnZSgpLiBQbGVhc2UKPiArICogc2VlIERvY3VtZW50YXRpb24v dm0vcGluX3VzZXJfcGFnZXMucnN0IGZvciBmdXJ0aGVyIGRldGFpbHMuCj4gKyAqCj4gKyAqIEZP TExfTE9OR1RFUk0gbWVhbnMgdGhhdCB0aGUgcGFnZXMgYXJlIGJlaW5nIHBpbm5lZCBmb3IgImxv bmcgdGVybSIgdXNlLAo+ICsgKiB0eXBpY2FsbHkgYnkgYSBub24tQ1BVIGRldmljZSwgYW5kIHdl IGNhbm5vdCBiZSBzdXJlIHRoYXQgd2FpdGluZyBmb3IgYQo+ICsgKiBwaW5uZWQgcGFnZSB0byBi ZWNvbWUgdW5waW4gd2lsbCBiZSBlZmZlY3RpdmUuCj4gKyAqCj4gKyAqIFRoaXMgaXMgaW50ZW5k ZWQgZm9yIENhc2UgMiAoUkRNQTogbG9uZy10ZXJtIHBpbnMpIG9mIHRoZSBGT0xMX1BJTgo+ICsg KiBkb2N1bWVudGF0aW9uLgo+ICsgKi8KPiAraW50IHBpbl9sb25ndGVybV9wYWdlc19mYXN0KHVu c2lnbmVkIGxvbmcgc3RhcnQsIGludCBucl9wYWdlcywKPiArCQkJICAgIHVuc2lnbmVkIGludCBn dXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMpCj4gK3sKPiArCS8qIEZPTExfR0VUIGFuZCBG T0xMX1BJTiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ICsJaWYgKFdBUk5fT05fT05DRShn dXBfZmxhZ3MgJiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJZ3VwX2Zs YWdzIHw9IChGT0xMX1BJTiB8IEZPTExfTE9OR1RFUk0pOwo+ICsJcmV0dXJuIGludGVybmFsX2dl dF91c2VyX3BhZ2VzX2Zhc3Qoc3RhcnQsIG5yX3BhZ2VzLCBndXBfZmxhZ3MsIHBhZ2VzKTsKPiAr fQo+ICtFWFBPUlRfU1lNQk9MX0dQTChwaW5fbG9uZ3Rlcm1fcGFnZXNfZmFzdCk7Cj4gKwo+ICsv KioKPiArICogcGluX3VzZXJfcGFnZXNfcmVtb3RlKCkgLSBwaW4gcGFnZXMgZm9yICh0eXBpY2Fs bHkpIHVzZSBieSBEaXJlY3QgSU8sIGFuZAo+ICsgKiByZXR1cm4gdGhlIHBhZ2VzIHRvIHRoZSB1 c2VyLgo+ICsgKgo+ICsgKiBOZWFybHkgdGhlIHNhbWUgYXMgZ2V0X3VzZXJfcGFnZXNfcmVtb3Rl KCksIGV4Y2VwdCB0aGF0IEZPTExfUElOIGlzIHNldC4gU2VlCj4gKyAqIGdldF91c2VyX3BhZ2Vz X3JlbW90ZSgpIGZvciBkb2N1bWVudGF0aW9uIG9uIHRoZSBmdW5jdGlvbiBhcmd1bWVudHMsIGJl Y2F1c2UKPiArICogdGhlIGFyZ3VtZW50cyBoZXJlIGFyZSBpZGVudGljYWwuCj4gKyAqCj4gKyAq IEZPTExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3QgYmUgcmVsZWFzZWQgdmlhIHB1dF91 c2VyX3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3Bh Z2VzLnJzdCBmb3IgZGV0YWlscy4KPiArICoKPiArICogVGhpcyBpcyBpbnRlbmRlZCBmb3IgQ2Fz ZSAxIChESU8pIGluIERvY3VtZW50YXRpb24vdm0vcGluX3VzZXJfcGFnZXMucnN0LiBJdAo+ICsg KiBpcyBOT1QgaW50ZW5kZWQgZm9yIENhc2UgMiAoUkRNQTogbG9uZy10ZXJtIHBpbnMpLgo+ICsg Ki8KPiArbG9uZyBwaW5fdXNlcl9wYWdlc19yZW1vdGUoc3RydWN0IHRhc2tfc3RydWN0ICp0c2ss IHN0cnVjdCBtbV9zdHJ1Y3QgKm1tLAo+ICsJCQkgICB1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNp Z25lZCBsb25nIG5yX3BhZ2VzLAo+ICsJCQkgICB1bnNpZ25lZCBpbnQgZ3VwX2ZsYWdzLCBzdHJ1 Y3QgcGFnZSAqKnBhZ2VzLAo+ICsJCQkgICBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2bWFzLCBp bnQgKmxvY2tlZCkKPiArewo+ICsJLyogRk9MTF9HRVQgYW5kIEZPTExfUElOIGFyZSBtdXR1YWxs eSBleGNsdXNpdmUuICovCj4gKwlpZiAoV0FSTl9PTl9PTkNFKGd1cF9mbGFncyAmIEZPTExfR0VU KSkKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCj4gKwlndXBfZmxhZ3MgfD0gRk9MTF9UT1VDSCB8 IEZPTExfUkVNT1RFIHwgRk9MTF9QSU47Cj4gKwo+ICsJcmV0dXJuIF9fZ2V0X3VzZXJfcGFnZXNf bG9ja2VkKHRzaywgbW0sIHN0YXJ0LCBucl9wYWdlcywgcGFnZXMsIHZtYXMsCj4gKwkJCQkgICAg ICAgbG9ja2VkLCBndXBfZmxhZ3MpOwo+ICt9Cj4gK0VYUE9SVF9TWU1CT0wocGluX3VzZXJfcGFn ZXNfcmVtb3RlKTsKPiArCj4gKy8qKgo+ICsgKiBwaW5fbG9uZ3Rlcm1fcGFnZXNfcmVtb3RlKCkg LSBwaW4gcGFnZXMgZm9yICh0eXBpY2FsbHkpIHVzZSBieSBEaXJlY3QgSU8sIGFuZAo+ICsgKiBy ZXR1cm4gdGhlIHBhZ2VzIHRvIHRoZSB1c2VyLgo+ICsgKgo+ICsgKiBOZWFybHkgdGhlIHNhbWUg YXMgZ2V0X3VzZXJfcGFnZXNfcmVtb3RlKCksIGJ1dCBub3RlIHRoYXQgRk9MTF9UT1VDSCBpcyBu b3QKPiArICogc2V0LCBhbmQgRk9MTF9QSU4gYW5kIEZPTExfTE9OR1RFUk0gYXJlIHNldC4gU2Vl IGdldF91c2VyX3BhZ2VzX3JlbW90ZSgpIGZvcgo+ICsgKiBkb2N1bWVudGF0aW9uIG9uIHRoZSBm dW5jdGlvbiBhcmd1bWVudHMsIGJlY2F1c2UgdGhlIGFyZ3VtZW50cyBoZXJlIGFyZQo+ICsgKiBp ZGVudGljYWwuCj4gKyAqCj4gKyAqIEZPTExfUElOIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIG11c3Qg YmUgcmVsZWFzZWQgdmlhIHB1dF91c2VyX3BhZ2UoKS4gUGxlYXNlCj4gKyAqIHNlZSBEb2N1bWVu dGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdCBmb3IgZnVydGhlciBkZXRhaWxzLgo+ICsgKgo+ ICsgKiBGT0xMX0xPTkdURVJNIG1lYW5zIHRoYXQgdGhlIHBhZ2VzIGFyZSBiZWluZyBwaW5uZWQg Zm9yICJsb25nIHRlcm0iIHVzZSwKPiArICogdHlwaWNhbGx5IGJ5IGEgbm9uLUNQVSBkZXZpY2Us IGFuZCB3ZSBjYW5ub3QgYmUgc3VyZSB0aGF0IHdhaXRpbmcgZm9yIGEKPiArICogcGlubmVkIHBh Z2UgdG8gYmVjb21lIHVucGluIHdpbGwgYmUgZWZmZWN0aXZlLgo+ICsgKgo+ICsgKiBUaGlzIGlz IGludGVuZGVkIGZvciBDYXNlIDIgKFJETUE6IGxvbmctdGVybSBwaW5zKSBpbgo+ICsgKiBEb2N1 bWVudGF0aW9uL3ZtL3Bpbl91c2VyX3BhZ2VzLnJzdC4KPiArICovCj4gK2xvbmcgcGluX2xvbmd0 ZXJtX3BhZ2VzX3JlbW90ZShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzaywgc3RydWN0IG1tX3N0cnVj dCAqbW0sCj4gKwkJCSAgICAgICB1bnNpZ25lZCBsb25nIHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5y X3BhZ2VzLAo+ICsJCQkgICAgICAgdW5zaWduZWQgaW50IGd1cF9mbGFncywgc3RydWN0IHBhZ2Ug KipwYWdlcywKPiArCQkJICAgICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqKnZtYXMsIGludCAq bG9ja2VkKQo+ICt7Cj4gKwkvKiBGT0xMX0dFVCBhbmQgRk9MTF9QSU4gYXJlIG11dHVhbGx5IGV4 Y2x1c2l2ZS4gKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9HRVQpKQo+ ICsJCXJldHVybiAtRUlOVkFMOwo+ICsKPiArCS8qCj4gKwkgKiBGSVhNRTogYXMgbm90ZWQgaW4g dGhlIGdldF91c2VyX3BhZ2VzX3JlbW90ZSgpIGltcGxlbWVudGF0aW9uLCBpdAo+ICsJICogaXMg bm90IHlldCBwb3NzaWJsZSB0byBzYWZlbHkgc2V0IEZPTExfTE9OR1RFUk0gaGVyZS4gRk9MTF9M T05HVEVSTQo+ICsJICogbmVlZHMgdG8gYmUgc2V0LCBidXQgZm9yIG5vdyB0aGUgYmVzdCB3ZSBj YW4gZG8gaXMgYSAiVE9ETyIgaXRlbS4KPiArCSAqLwo+ICsJZ3VwX2ZsYWdzIHw9IEZPTExfUkVN T1RFIHwgRk9MTF9QSU47Cj4gKwo+ICsJcmV0dXJuIF9fZ2V0X3VzZXJfcGFnZXNfbG9ja2VkKHRz aywgbW0sIHN0YXJ0LCBucl9wYWdlcywgcGFnZXMsIHZtYXMsCj4gKwkJCQkgICAgICAgbG9ja2Vk LCBndXBfZmxhZ3MpOwo+ICt9Cj4gK0VYUE9SVF9TWU1CT0wocGluX2xvbmd0ZXJtX3BhZ2VzX3Jl bW90ZSk7Cj4gKwo+ICsvKioKPiArICogcGluX3VzZXJfcGFnZXMoKSAtIHBpbiB1c2VyIHBhZ2Vz IGluIG1lbW9yeSBmb3IgdXNlIGJ5IG90aGVyIGRldmljZXMKPiArICoKPiArICogTmVhcmx5IHRo ZSBzYW1lIGFzIGdldF91c2VyX3BhZ2VzKCksIGV4Y2VwdCB0aGF0IEZPTExfVE9VQ0ggaXMgbm90 IHNldCwgYW5kCj4gKyAqIEZPTExfUElOIGlzIHNldC4KPiArICoKPiArICogRk9MTF9QSU4gbWVh bnMgdGhhdCB0aGUgcGFnZXMgbXVzdCBiZSByZWxlYXNlZCB2aWEgcHV0X3VzZXJfcGFnZSgpLiBQ bGVhc2UKPiArICogc2VlIERvY3VtZW50YXRpb24vdm0vcGluX3VzZXJfcGFnZXMucnN0IGZvciBk ZXRhaWxzLgo+ICsgKgo+ICsgKiBUaGlzIGlzIGludGVuZGVkIGZvciBDYXNlIDEgKERJTykgaW4g RG9jdW1lbnRhdGlvbi92bS9waW5fdXNlcl9wYWdlcy5yc3QuIEl0Cj4gKyAqIGlzIE5PVCBpbnRl bmRlZCBmb3IgQ2FzZSAyIChSRE1BOiBsb25nLXRlcm0gcGlucykuCj4gKyAqLwo+ICtsb25nIHBp bl91c2VyX3BhZ2VzKHVuc2lnbmVkIGxvbmcgc3RhcnQsIHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMs Cj4gKwkJICAgIHVuc2lnbmVkIGludCBndXBfZmxhZ3MsIHN0cnVjdCBwYWdlICoqcGFnZXMsCj4g KwkJICAgIHN0cnVjdCB2bV9hcmVhX3N0cnVjdCAqKnZtYXMpCj4gK3sKPiArCS8qIEZPTExfR0VU IGFuZCBGT0xMX1BJTiBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLiAqLwo+ICsJaWYgKFdBUk5fT05f T05DRShndXBfZmxhZ3MgJiBGT0xMX0dFVCkpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ICsJ Z3VwX2ZsYWdzIHw9IEZPTExfUElOOwo+ICsJcmV0dXJuIF9fZ3VwX2xvbmd0ZXJtX2xvY2tlZChj dXJyZW50LCBjdXJyZW50LT5tbSwgc3RhcnQsIG5yX3BhZ2VzLAo+ICsJCQkJICAgICBwYWdlcywg dm1hcywgZ3VwX2ZsYWdzKTsKPiArfQo+ICtFWFBPUlRfU1lNQk9MKHBpbl91c2VyX3BhZ2VzKTsK PiArCj4gKy8qKgo+ICsgKiBwaW5fbG9uZ3Rlcm1fcGFnZXMoKSAtIHBpbiB1c2VyIHBhZ2VzIGlu IG1lbW9yeSBmb3IgbG9uZy10ZXJtIHVzZSAoUkRNQSwKPiArICogdHlwaWNhbGx5KQo+ICsgKgo+ ICsgKiBOZWFybHkgdGhlIHNhbWUgYXMgZ2V0X3VzZXJfcGFnZXMoKSwgZXhjZXB0IHRoYXQgRk9M TF9QSU4gYW5kIEZPTExfTE9OR1RFUk0KPiArICogYXJlIHNldC4gU2VlIGdldF91c2VyX3BhZ2Vz X2Zhc3QoKSBmb3IgZG9jdW1lbnRhdGlvbiBvbiB0aGUgZnVuY3Rpb24KPiArICogYXJndW1lbnRz LCBiZWNhdXNlIHRoZSBhcmd1bWVudHMgaGVyZSBhcmUgaWRlbnRpY2FsLgo+ICsgKgo+ICsgKiBG T0xMX1BJTiBtZWFucyB0aGF0IHRoZSBwYWdlcyBtdXN0IGJlIHJlbGVhc2VkIHZpYSBwdXRfdXNl cl9wYWdlKCkuIFBsZWFzZQo+ICsgKiBzZWUgRG9jdW1lbnRhdGlvbi92bS9waW5fdXNlcl9wYWdl cy5yc3QgZm9yIGZ1cnRoZXIgZGV0YWlscy4KPiArICoKPiArICogRk9MTF9MT05HVEVSTSBtZWFu cyB0aGF0IHRoZSBwYWdlcyBhcmUgYmVpbmcgcGlubmVkIGZvciAibG9uZyB0ZXJtIiB1c2UsCj4g KyAqIHR5cGljYWxseSBieSBhIG5vbi1DUFUgZGV2aWNlLCBhbmQgd2UgY2Fubm90IGJlIHN1cmUg dGhhdCB3YWl0aW5nIGZvciBhCj4gKyAqIHBpbm5lZCBwYWdlIHRvIGJlY29tZSB1bnBpbiB3aWxs IGJlIGVmZmVjdGl2ZS4KPiArICoKPiArICogVGhpcyBpcyBpbnRlbmRlZCBmb3IgQ2FzZSAyIChS RE1BOiBsb25nLXRlcm0gcGlucykgaW4KPiArICogRG9jdW1lbnRhdGlvbi92bS9waW5fdXNlcl9w YWdlcy5yc3QuCj4gKyAqLwo+ICtsb25nIHBpbl9sb25ndGVybV9wYWdlcyh1bnNpZ25lZCBsb25n IHN0YXJ0LCB1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLAo+ICsJCQl1bnNpZ25lZCBpbnQgZ3VwX2Zs YWdzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAo+ICsJCQlzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKip2 bWFzKQo+ICt7Cj4gKwkvKiBGT0xMX0dFVCBhbmQgRk9MTF9QSU4gYXJlIG11dHVhbGx5IGV4Y2x1 c2l2ZS4gKi8KPiArCWlmIChXQVJOX09OX09OQ0UoZ3VwX2ZsYWdzICYgRk9MTF9HRVQpKQo+ICsJ CXJldHVybiAtRUlOVkFMOwo+ICsKPiArCWd1cF9mbGFncyB8PSBGT0xMX1BJTiB8IEZPTExfTE9O R1RFUk07Cj4gKwlyZXR1cm4gX19ndXBfbG9uZ3Rlcm1fbG9ja2VkKGN1cnJlbnQsIGN1cnJlbnQt Pm1tLCBzdGFydCwgbnJfcGFnZXMsCj4gKwkJCQkgICAgIHBhZ2VzLCB2bWFzLCBndXBfZmxhZ3Mp Owo+ICt9Cj4gK0VYUE9SVF9TWU1CT0wocGluX2xvbmd0ZXJtX3BhZ2VzKTsKPiAtLSAKPiAyLjIz LjAKPiAKPiAKCi0tIApTaW5jZXJlbHkgeW91cnMsCk1pa2UuCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRl dmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9t YWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbA==