From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71B79C433E0 for ; Wed, 27 Jan 2021 09:09:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 30F6820758 for ; Wed, 27 Jan 2021 09:09:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234946AbhA0JJS (ORCPT ); Wed, 27 Jan 2021 04:09:18 -0500 Received: from mx2.suse.de ([195.135.220.15]:47384 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234367AbhA0JGS (ORCPT ); Wed, 27 Jan 2021 04:06:18 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1611738329; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Frtjky50lhuCvhdjT76CPWeRZ4wg+efgdrWBbOOrsRo=; b=HEdTRyd7SvJg/XAQxhbRI7kwZArGDUP8Bfa5ruY6Zz9Lh5KvanjsFGFvcYG6e9Yk0sX6/n g42Pxw2b/GcalFfAglpeh+HvgT/22fH/pleNNTn0H5tDOKQNrO70p+2tBQ/+gqeupvnPut W9oZam+8xUskfiC8LH/7tPEML5Q4Acc= Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 0FEBFAD57; Wed, 27 Jan 2021 09:05:29 +0000 (UTC) Date: Wed, 27 Jan 2021 10:05:26 +0100 From: Michal Hocko To: Kalesh Singh Cc: surenb@google.com, minchan@kernel.org, gregkh@linuxfoundation.org, hridya@google.com, jannh@google.com, kernel-team@android.com, Alexey Dobriyan , Jonathan Corbet , Sumit Semwal , Christian =?iso-8859-1?Q?K=F6nig?= , Mauro Carvalho Chehab , Andrew Morton , Kees Cook , Alexey Gladkov , Szabolcs Nagy , "Eric W. Biederman" , Daniel Jordan , Michel Lespinasse , Bernd Edlinger , Andrei Vagin , Yafang Shao , Hui Su , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-doc@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-api@vger.kernel.org Subject: Re: [PATCH] procfs/dmabuf: Add /proc//task//dmabuf_fds Message-ID: <20210127090526.GB827@dhcp22.suse.cz> References: <20210126225138.1823266-1-kaleshsingh@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20210126225138.1823266-1-kaleshsingh@google.com> Precedence: bulk List-ID: X-Mailing-List: linux-api@vger.kernel.org [Cc linux-api as this is a new user interface] On Tue 26-01-21 22:51:28, Kalesh Singh wrote: > In order to measure how much memory a process actually consumes, it is > necessary to include the DMA buffer sizes for that process in the memory > accounting. Since the handle to DMA buffers are raw FDs, it is important > to be able to identify which processes have FD references to a DMA buffer. > > Currently, DMA buffer FDs can be accounted using /proc//fd/* and > /proc//fdinfo -- both of which are only root readable, as follows: > 1. Do a readlink on each FD. > 2. If the target path begins with "/dmabuf", then the FD is a dmabuf FD. > 3. stat the file to get the dmabuf inode number. > 4. Read/ proc//fdinfo/, to get the DMA buffer size. > > Android captures per-process system memory state when certain low memory > events (e.g a foreground app kill) occur, to identify potential memory > hoggers. To include a process’s dmabuf usage as part of its memory state, > the data collection needs to be fast enough to reflect the memory state at > the time of such events. > > Since reading /proc//fd/ and /proc//fdinfo/ requires root > privileges, this approach is not suitable for production builds. Granting > root privileges even to a system process increases the attack surface and > is highly undesirable. Additionally this is slow as it requires many > context switches for searching and getting the dma-buf info. > > With the addition of per-buffer dmabuf stats in sysfs [1], the DMA buffer > details can be queried using their unique inode numbers. > > This patch proposes adding a /proc//task//dmabuf_fds interface. > > /proc//task//dmabuf_fds contains a list of inode numbers for > every DMA buffer FD that the task has. Entries with the same inode > number can appear more than once, indicating the total FD references > for the associated DMA buffer. > > If a thread shares the same files as the group leader then its > dmabuf_fds file will be empty, as these dmabufs are reported by the > group leader. > > The interface requires PTRACE_MODE_READ_FSCRED (same as /proc//maps) > and allows the efficient accounting of per-process DMA buffer usage without > requiring root privileges. (See data below) > > Performance Comparison: > ----------------------- > > The following data compares the time to capture the sizes of all DMA > buffers referenced by FDs for all processes on an arm64 android device. > > ------------------------------------------------------- > | Core 0 (Little) | Core 7 (Big) | > ------------------------------------------------------- > >From /fdinfo | 318 ms | 145 ms | > ------------------------------------------------------- > Inodes from | 114 ms | 27 ms | > dmabuf_fds; | (2.8x ^) | (5.4x ^) | > data from sysfs | | | > ------------------------------------------------------- > > It can be inferred that in the worst case there is a 2.8x speedup for > determining per-process DMA buffer FD sizes, when using the proposed > interfaces. > > [1] https://lore.kernel.org/dri-devel/20210119225723.388883-1-hridya@google.com/ > > Signed-off-by: Kalesh Singh > --- > Documentation/filesystems/proc.rst | 30 ++++++ > drivers/dma-buf/dma-buf.c | 7 +- > fs/proc/Makefile | 1 + > fs/proc/base.c | 1 + > fs/proc/dma_bufs.c | 159 +++++++++++++++++++++++++++++ > fs/proc/internal.h | 1 + > include/linux/dma-buf.h | 5 + > 7 files changed, 198 insertions(+), 6 deletions(-) > create mode 100644 fs/proc/dma_bufs.c > > diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst > index 2fa69f710e2a..757dd47ab679 100644 > --- a/Documentation/filesystems/proc.rst > +++ b/Documentation/filesystems/proc.rst > @@ -47,6 +47,7 @@ fixes/update part 1.1 Stefani Seibold June 9 2009 > 3.10 /proc//timerslack_ns - Task timerslack value > 3.11 /proc//patch_state - Livepatch patch operation state > 3.12 /proc//arch_status - Task architecture specific information > + 3.13 /proc//task//dmabuf_fds - DMA buffers referenced by an FD > > 4 Configuring procfs > 4.1 Mount options > @@ -2131,6 +2132,35 @@ AVX512_elapsed_ms > the task is unlikely an AVX512 user, but depends on the workload and the > scheduling scenario, it also could be a false negative mentioned above. > > +3.13 /proc//task//dmabuf_fds - DMA buffers referenced by an FD > +------------------------------------------------------------------------- > +This file exposes a list of the inode numbers for every DMA buffer > +FD that the task has. > + > +The same inode number can appear more than once, indicating the total > +FD references for the associated DMA buffer. > + > +The inode number can be used to lookup the DMA buffer information in > +the sysfs interface /sys/kernel/dmabuf/buffers//. > + > +Example Output > +~~~~~~~~~~~~~~ > +$ cat /proc/612/task/612/dmabuf_fds > +30972 30973 45678 49326 > + > +Permission to access this file is governed by a ptrace access mode > +PTRACE_MODE_READ_FSCREDS. > + > +Threads can have different files when created without specifying > +the CLONE_FILES flag. For this reason the interface is presented as > +/proc//task//dmabuf_fds and not /proc//dmabuf_fds. > +This simplifies kernel code and aggregation can be handled in > +userspace. > + > +If a thread has the same files as its group leader, then its dmabuf_fds > +file will be empty as these dmabufs are already reported by the > +group leader. > + > Chapter 4: Configuring procfs > ============================= > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > index 9ad6397aaa97..0660c06be4c6 100644 > --- a/drivers/dma-buf/dma-buf.c > +++ b/drivers/dma-buf/dma-buf.c > @@ -29,8 +29,6 @@ > #include > #include > > -static inline int is_dma_buf_file(struct file *); > - > struct dma_buf_list { > struct list_head head; > struct mutex lock; > @@ -434,10 +432,7 @@ static const struct file_operations dma_buf_fops = { > .show_fdinfo = dma_buf_show_fdinfo, > }; > > -/* > - * is_dma_buf_file - Check if struct file* is associated with dma_buf > - */ > -static inline int is_dma_buf_file(struct file *file) > +int is_dma_buf_file(struct file *file) > { > return file->f_op == &dma_buf_fops; > } > diff --git a/fs/proc/Makefile b/fs/proc/Makefile > index bd08616ed8ba..91a67f43ddf4 100644 > --- a/fs/proc/Makefile > +++ b/fs/proc/Makefile > @@ -16,6 +16,7 @@ proc-y += cmdline.o > proc-y += consoles.o > proc-y += cpuinfo.o > proc-y += devices.o > +proc-y += dma_bufs.o > proc-y += interrupts.o > proc-y += loadavg.o > proc-y += meminfo.o > diff --git a/fs/proc/base.c b/fs/proc/base.c > index b3422cda2a91..af15a60b9831 100644 > --- a/fs/proc/base.c > +++ b/fs/proc/base.c > @@ -3598,6 +3598,7 @@ static const struct pid_entry tid_base_stuff[] = { > #ifdef CONFIG_SECCOMP_CACHE_DEBUG > ONE("seccomp_cache", S_IRUSR, proc_pid_seccomp_cache), > #endif > + REG("dmabuf_fds", 0444, proc_tid_dmabuf_fds_operations), > }; > > static int proc_tid_base_readdir(struct file *file, struct dir_context *ctx) > diff --git a/fs/proc/dma_bufs.c b/fs/proc/dma_bufs.c > new file mode 100644 > index 000000000000..46ea9cf968ed > --- /dev/null > +++ b/fs/proc/dma_bufs.c > @@ -0,0 +1,159 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Per-process DMA-BUF Stats > + * > + * Copyright (C) 2021 Google LLC. > + */ > + > +#include > +#include > +#include > +#include > + > +#include "internal.h" > + > +struct dmabuf_fds_private { > + struct inode *inode; > + struct task_struct *task; > + struct file *dmabuf_file; > +}; > + > +static loff_t *next_dmabuf(struct dmabuf_fds_private *priv, > + loff_t *pos) > +{ > + struct fdtable *fdt; > + struct file *file; > + > + rcu_read_lock(); > + fdt = files_fdtable(priv->task->files); > + for (; *pos < fdt->max_fds; ++*pos) { > + file = files_lookup_fd_rcu(priv->task->files, (unsigned int) *pos); > + if (file && is_dma_buf_file(file) && get_file_rcu(file)) { > + priv->dmabuf_file = file; > + break; > + } > + } > + if (*pos >= fdt->max_fds) > + pos = NULL; > + rcu_read_unlock(); > + > + return pos; > +} > + > +static void *dmabuf_fds_seq_start(struct seq_file *s, loff_t *pos) > +{ > + struct dmabuf_fds_private *priv = s->private; > + struct files_struct *group_leader_files; > + > + priv->task = get_proc_task(priv->inode); > + > + if (!priv->task) > + return ERR_PTR(-ESRCH); > + > + /* Hold task lock for duration that files need to be stable */ > + task_lock(priv->task); > + > + /* > + * If this task is not the group leader but shares the same files, leave file empty. > + * These dmabufs are already reported in the group leader's dmabuf_fds. > + */ > + group_leader_files = priv->task->group_leader->files; > + if (priv->task != priv->task->group_leader && priv->task->files == group_leader_files) { > + task_unlock(priv->task); > + put_task_struct(priv->task); > + priv->task = NULL; > + return NULL; > + } > + > + return next_dmabuf(priv, pos); > +} > + > +static void *dmabuf_fds_seq_next(struct seq_file *s, void *v, loff_t *pos) > +{ > + ++*pos; > + return next_dmabuf(s->private, pos); > +} > + > +static void dmabuf_fds_seq_stop(struct seq_file *s, void *v) > +{ > + struct dmabuf_fds_private *priv = s->private; > + > + if (priv->task) { > + task_unlock(priv->task); > + put_task_struct(priv->task); > + > + } > + if (priv->dmabuf_file) > + fput(priv->dmabuf_file); > +} > + > +static int dmabuf_fds_seq_show(struct seq_file *s, void *v) > +{ > + struct dmabuf_fds_private *priv = s->private; > + struct file *file = priv->dmabuf_file; > + struct dma_buf *dmabuf = file->private_data; > + > + if (!dmabuf) > + return -ESRCH; > + > + seq_printf(s, "%8lu ", file_inode(file)->i_ino); > + > + fput(priv->dmabuf_file); > + priv->dmabuf_file = NULL; > + > + return 0; > +} > + > +static const struct seq_operations proc_tid_dmabuf_fds_seq_ops = { > + .start = dmabuf_fds_seq_start, > + .next = dmabuf_fds_seq_next, > + .stop = dmabuf_fds_seq_stop, > + .show = dmabuf_fds_seq_show > +}; > + > +static int proc_dmabuf_fds_open(struct inode *inode, struct file *file, > + const struct seq_operations *ops) > +{ > + struct dmabuf_fds_private *priv; > + struct task_struct *task; > + bool allowed = false; > + > + task = get_proc_task(inode); > + if (!task) > + return -ESRCH; > + > + allowed = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS); > + put_task_struct(task); > + > + if (!allowed) > + return -EACCES; > + > + priv = __seq_open_private(file, ops, sizeof(*priv)); > + if (!priv) > + return -ENOMEM; > + > + priv->inode = inode; > + priv->task = NULL; > + priv->dmabuf_file = NULL; > + > + return 0; > +} > + > +static int proc_dmabuf_fds_release(struct inode *inode, struct file *file) > +{ > + return seq_release_private(inode, file); > +} > + > +static int tid_dmabuf_fds_open(struct inode *inode, struct file *file) > +{ > + return proc_dmabuf_fds_open(inode, file, > + &proc_tid_dmabuf_fds_seq_ops); > +} > + > +const struct file_operations proc_tid_dmabuf_fds_operations = { > + .open = tid_dmabuf_fds_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = proc_dmabuf_fds_release, > +}; > + > diff --git a/fs/proc/internal.h b/fs/proc/internal.h > index f60b379dcdc7..4ca74220db9c 100644 > --- a/fs/proc/internal.h > +++ b/fs/proc/internal.h > @@ -303,6 +303,7 @@ extern const struct file_operations proc_pid_smaps_operations; > extern const struct file_operations proc_pid_smaps_rollup_operations; > extern const struct file_operations proc_clear_refs_operations; > extern const struct file_operations proc_pagemap_operations; > +extern const struct file_operations proc_tid_dmabuf_fds_operations; > > extern unsigned long task_vsize(struct mm_struct *); > extern unsigned long task_statm(struct mm_struct *, > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > index cf72699cb2bc..087e11f7f193 100644 > --- a/include/linux/dma-buf.h > +++ b/include/linux/dma-buf.h > @@ -27,6 +27,11 @@ struct device; > struct dma_buf; > struct dma_buf_attachment; > > +/** > + * Check if struct file* is associated with dma_buf. > + */ > +int is_dma_buf_file(struct file *file); > + > /** > * struct dma_buf_ops - operations possible on struct dma_buf > * @vmap: [optional] creates a virtual mapping for the buffer into kernel > -- > 2.30.0.280.ga3ce27912f-goog -- Michal Hocko SUSE Labs 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=-13.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 27970C433E9 for ; Thu, 28 Jan 2021 08:18:01 +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 CCBC06146D for ; Thu, 28 Jan 2021 08:18:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CCBC06146D Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=suse.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 5F47E6E950; Thu, 28 Jan 2021 08:16:51 +0000 (UTC) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id A1F0B6E5A5 for ; Wed, 27 Jan 2021 09:05:30 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1611738329; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Frtjky50lhuCvhdjT76CPWeRZ4wg+efgdrWBbOOrsRo=; b=HEdTRyd7SvJg/XAQxhbRI7kwZArGDUP8Bfa5ruY6Zz9Lh5KvanjsFGFvcYG6e9Yk0sX6/n g42Pxw2b/GcalFfAglpeh+HvgT/22fH/pleNNTn0H5tDOKQNrO70p+2tBQ/+gqeupvnPut W9oZam+8xUskfiC8LH/7tPEML5Q4Acc= Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 0FEBFAD57; Wed, 27 Jan 2021 09:05:29 +0000 (UTC) Date: Wed, 27 Jan 2021 10:05:26 +0100 From: Michal Hocko To: Kalesh Singh Subject: Re: [PATCH] procfs/dmabuf: Add /proc//task//dmabuf_fds Message-ID: <20210127090526.GB827@dhcp22.suse.cz> References: <20210126225138.1823266-1-kaleshsingh@google.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20210126225138.1823266-1-kaleshsingh@google.com> X-Mailman-Approved-At: Thu, 28 Jan 2021 08:15:36 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-doc@vger.kernel.org, Szabolcs Nagy , dri-devel@lists.freedesktop.org, Andrei Vagin , Hui Su , Michel Lespinasse , Jonathan Corbet , Mauro Carvalho Chehab , Daniel Jordan , kernel-team@android.com, Alexey Dobriyan , linux-media@vger.kernel.org, Kees Cook , jannh@google.com, linaro-mm-sig@lists.linaro.org, linux-fsdevel@vger.kernel.org, Bernd Edlinger , surenb@google.com, Alexey Gladkov , linux-kernel@vger.kernel.org, minchan@kernel.org, Yafang Shao , "Eric W. Biederman" , gregkh@linuxfoundation.org, hridya@google.com, Andrew Morton , linux-api@vger.kernel.org, Christian =?iso-8859-1?Q?K=F6nig?= Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" W0NjIGxpbnV4LWFwaSBhcyB0aGlzIGlzIGEgbmV3IHVzZXIgaW50ZXJmYWNlXQoKT24gVHVlIDI2 LTAxLTIxIDIyOjUxOjI4LCBLYWxlc2ggU2luZ2ggd3JvdGU6Cj4gSW4gb3JkZXIgdG8gbWVhc3Vy ZSBob3cgbXVjaCBtZW1vcnkgYSBwcm9jZXNzIGFjdHVhbGx5IGNvbnN1bWVzLCBpdCBpcwo+IG5l Y2Vzc2FyeSB0byBpbmNsdWRlIHRoZSBETUEgYnVmZmVyIHNpemVzIGZvciB0aGF0IHByb2Nlc3Mg aW4gdGhlIG1lbW9yeQo+IGFjY291bnRpbmcuIFNpbmNlIHRoZSBoYW5kbGUgdG8gRE1BIGJ1ZmZl cnMgYXJlIHJhdyBGRHMsIGl0IGlzIGltcG9ydGFudAo+IHRvIGJlIGFibGUgdG8gaWRlbnRpZnkg d2hpY2ggcHJvY2Vzc2VzIGhhdmUgRkQgcmVmZXJlbmNlcyB0byBhIERNQSBidWZmZXIuCj4gCj4g Q3VycmVudGx5LCBETUEgYnVmZmVyIEZEcyBjYW4gYmUgYWNjb3VudGVkIHVzaW5nIC9wcm9jLzxw aWQ+L2ZkLyogYW5kCj4gL3Byb2MvPHBpZD4vZmRpbmZvIC0tIGJvdGggb2Ygd2hpY2ggYXJlIG9u bHkgcm9vdCByZWFkYWJsZSwgYXMgZm9sbG93czoKPiAgIDEuIERvIGEgcmVhZGxpbmsgb24gZWFj aCBGRC4KPiAgIDIuIElmIHRoZSB0YXJnZXQgcGF0aCBiZWdpbnMgd2l0aCAiL2RtYWJ1ZiIsIHRo ZW4gdGhlIEZEIGlzIGEgZG1hYnVmIEZELgo+ICAgMy4gc3RhdCB0aGUgZmlsZSB0byBnZXQgdGhl IGRtYWJ1ZiBpbm9kZSBudW1iZXIuCj4gICA0LiBSZWFkLyBwcm9jLzxwaWQ+L2ZkaW5mby88ZmQ+ LCB0byBnZXQgdGhlIERNQSBidWZmZXIgc2l6ZS4KPiAKPiBBbmRyb2lkIGNhcHR1cmVzIHBlci1w cm9jZXNzIHN5c3RlbSBtZW1vcnkgc3RhdGUgd2hlbiBjZXJ0YWluIGxvdyBtZW1vcnkKPiBldmVu dHMgKGUuZyBhIGZvcmVncm91bmQgYXBwIGtpbGwpIG9jY3VyLCB0byBpZGVudGlmeSBwb3RlbnRp YWwgbWVtb3J5Cj4gaG9nZ2Vycy4gVG8gaW5jbHVkZSBhIHByb2Nlc3PigJlzIGRtYWJ1ZiB1c2Fn ZSBhcyBwYXJ0IG9mIGl0cyBtZW1vcnkgc3RhdGUsCj4gdGhlIGRhdGEgY29sbGVjdGlvbiBuZWVk cyB0byBiZSBmYXN0IGVub3VnaCB0byByZWZsZWN0IHRoZSBtZW1vcnkgc3RhdGUgYXQKPiB0aGUg dGltZSBvZiBzdWNoIGV2ZW50cy4KPiAKPiBTaW5jZSByZWFkaW5nIC9wcm9jLzxwaWQ+L2ZkLyBh bmQgL3Byb2MvPHBpZD4vZmRpbmZvLyByZXF1aXJlcyByb290Cj4gcHJpdmlsZWdlcywgdGhpcyBh cHByb2FjaCBpcyBub3Qgc3VpdGFibGUgZm9yIHByb2R1Y3Rpb24gYnVpbGRzLiBHcmFudGluZwo+ IHJvb3QgcHJpdmlsZWdlcyBldmVuIHRvIGEgc3lzdGVtIHByb2Nlc3MgaW5jcmVhc2VzIHRoZSBh dHRhY2sgc3VyZmFjZSBhbmQKPiBpcyBoaWdobHkgdW5kZXNpcmFibGUuIEFkZGl0aW9uYWxseSB0 aGlzIGlzIHNsb3cgYXMgaXQgcmVxdWlyZXMgbWFueQo+IGNvbnRleHQgc3dpdGNoZXMgZm9yIHNl YXJjaGluZyBhbmQgZ2V0dGluZyB0aGUgZG1hLWJ1ZiBpbmZvLgo+IAo+IFdpdGggdGhlIGFkZGl0 aW9uIG9mIHBlci1idWZmZXIgZG1hYnVmIHN0YXRzIGluIHN5c2ZzIFsxXSwgdGhlIERNQSBidWZm ZXIKPiBkZXRhaWxzIGNhbiBiZSBxdWVyaWVkIHVzaW5nIHRoZWlyIHVuaXF1ZSBpbm9kZSBudW1i ZXJzLgo+IAo+IFRoaXMgcGF0Y2ggcHJvcG9zZXMgYWRkaW5nIGEgL3Byb2MvPHBpZD4vdGFzay88 dGlkPi9kbWFidWZfZmRzIGludGVyZmFjZS4KPiAKPiAvcHJvYy88cGlkPi90YXNrLzx0aWQ+L2Rt YWJ1Zl9mZHMgY29udGFpbnMgYSBsaXN0IG9mIGlub2RlIG51bWJlcnMgZm9yCj4gZXZlcnkgRE1B IGJ1ZmZlciBGRCB0aGF0IHRoZSB0YXNrIGhhcy4gRW50cmllcyB3aXRoIHRoZSBzYW1lIGlub2Rl Cj4gbnVtYmVyIGNhbiBhcHBlYXIgbW9yZSB0aGFuIG9uY2UsIGluZGljYXRpbmcgdGhlIHRvdGFs IEZEIHJlZmVyZW5jZXMKPiBmb3IgdGhlIGFzc29jaWF0ZWQgRE1BIGJ1ZmZlci4KPiAKPiBJZiBh IHRocmVhZCBzaGFyZXMgdGhlIHNhbWUgZmlsZXMgYXMgdGhlIGdyb3VwIGxlYWRlciB0aGVuIGl0 cwo+IGRtYWJ1Zl9mZHMgZmlsZSB3aWxsIGJlIGVtcHR5LCBhcyB0aGVzZSBkbWFidWZzIGFyZSBy ZXBvcnRlZCBieSB0aGUKPiBncm91cCBsZWFkZXIuCj4gCj4gVGhlIGludGVyZmFjZSByZXF1aXJl cyBQVFJBQ0VfTU9ERV9SRUFEX0ZTQ1JFRCAoc2FtZSBhcyAvcHJvYy88cGlkPi9tYXBzKQo+IGFu ZCBhbGxvd3MgdGhlIGVmZmljaWVudCBhY2NvdW50aW5nIG9mIHBlci1wcm9jZXNzIERNQSBidWZm ZXIgdXNhZ2Ugd2l0aG91dAo+IHJlcXVpcmluZyByb290IHByaXZpbGVnZXMuIChTZWUgZGF0YSBi ZWxvdykKPiAKPiBQZXJmb3JtYW5jZSBDb21wYXJpc29uOgo+IC0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tCj4gCj4gVGhlIGZvbGxvd2luZyBkYXRhIGNvbXBhcmVzIHRoZSB0aW1lIHRvIGNhcHR1cmUg dGhlIHNpemVzIG9mIGFsbCBETUEKPiBidWZmZXJzIHJlZmVyZW5jZWQgYnkgRkRzIGZvciBhbGwg cHJvY2Vzc2VzIG9uIGFuIGFybTY0IGFuZHJvaWQgZGV2aWNlLgo+IAo+IC0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiAgICAgICAgICAgICAg ICAgICAgfCAgQ29yZSAwIChMaXR0bGUpICB8ICBDb3JlIDcgKEJpZykgfAo+IC0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiA+RnJvbSA8cGlk Pi9mZGluZm8gIHwgICAgICAzMTggbXMgICAgICAgfCAgICAgMTQ1IG1zICAgIHwKPiAtLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4gSW5vZGVz IGZyb20gICAgICAgIHwgICAgICAxMTQgbXMgICAgICAgfCAgICAgIDI3IG1zICAgIHwKPiBkbWFi dWZfZmRzOyAgICAgICAgfCAgICAoMi44eCAgXikgICAgICB8ICAgKDUuNHggIF4pICAgfAo+IGRh dGEgZnJvbSBzeXNmcyAgICB8ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8Cj4g LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+ IAo+IEl0IGNhbiBiZSBpbmZlcnJlZCB0aGF0IGluIHRoZSB3b3JzdCBjYXNlIHRoZXJlIGlzIGEg Mi44eCBzcGVlZHVwIGZvcgo+IGRldGVybWluaW5nIHBlci1wcm9jZXNzIERNQSBidWZmZXIgRkQg c2l6ZXMsIHdoZW4gdXNpbmcgdGhlIHByb3Bvc2VkCj4gaW50ZXJmYWNlcy4KPiAKPiBbMV0gaHR0 cHM6Ly9sb3JlLmtlcm5lbC5vcmcvZHJpLWRldmVsLzIwMjEwMTE5MjI1NzIzLjM4ODg4My0xLWhy aWR5YUBnb29nbGUuY29tLwo+IAo+IFNpZ25lZC1vZmYtYnk6IEthbGVzaCBTaW5naCA8a2FsZXNo c2luZ2hAZ29vZ2xlLmNvbT4KPiAtLS0KPiAgRG9jdW1lbnRhdGlvbi9maWxlc3lzdGVtcy9wcm9j LnJzdCB8ICAzMCArKysrKysKPiAgZHJpdmVycy9kbWEtYnVmL2RtYS1idWYuYyAgICAgICAgICB8 ICAgNyArLQo+ICBmcy9wcm9jL01ha2VmaWxlICAgICAgICAgICAgICAgICAgIHwgICAxICsKPiAg ZnMvcHJvYy9iYXNlLmMgICAgICAgICAgICAgICAgICAgICB8ICAgMSArCj4gIGZzL3Byb2MvZG1h X2J1ZnMuYyAgICAgICAgICAgICAgICAgfCAxNTkgKysrKysrKysrKysrKysrKysrKysrKysrKysr KysKPiAgZnMvcHJvYy9pbnRlcm5hbC5oICAgICAgICAgICAgICAgICB8ICAgMSArCj4gIGluY2x1 ZGUvbGludXgvZG1hLWJ1Zi5oICAgICAgICAgICAgfCAgIDUgKwo+ICA3IGZpbGVzIGNoYW5nZWQs IDE5OCBpbnNlcnRpb25zKCspLCA2IGRlbGV0aW9ucygtKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQg ZnMvcHJvYy9kbWFfYnVmcy5jCj4gCj4gZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vZmlsZXN5 c3RlbXMvcHJvYy5yc3QgYi9Eb2N1bWVudGF0aW9uL2ZpbGVzeXN0ZW1zL3Byb2MucnN0Cj4gaW5k ZXggMmZhNjlmNzEwZTJhLi43NTdkZDQ3YWI2NzkgMTAwNjQ0Cj4gLS0tIGEvRG9jdW1lbnRhdGlv bi9maWxlc3lzdGVtcy9wcm9jLnJzdAo+ICsrKyBiL0RvY3VtZW50YXRpb24vZmlsZXN5c3RlbXMv cHJvYy5yc3QKPiBAQCAtNDcsNiArNDcsNyBAQCBmaXhlcy91cGRhdGUgcGFydCAxLjEgIFN0ZWZh bmkgU2VpYm9sZCA8c3RlZmFuaUBzZWlib2xkLm5ldD4gICAgSnVuZSA5IDIwMDkKPiAgICAzLjEw ICAvcHJvYy88cGlkPi90aW1lcnNsYWNrX25zIC0gVGFzayB0aW1lcnNsYWNrIHZhbHVlCj4gICAg My4xMQkvcHJvYy88cGlkPi9wYXRjaF9zdGF0ZSAtIExpdmVwYXRjaCBwYXRjaCBvcGVyYXRpb24g c3RhdGUKPiAgICAzLjEyCS9wcm9jLzxwaWQ+L2FyY2hfc3RhdHVzIC0gVGFzayBhcmNoaXRlY3R1 cmUgc3BlY2lmaWMgaW5mb3JtYXRpb24KPiArICAzLjEzCS9wcm9jLzxwaWQ+L3Rhc2svPHRpZD4v ZG1hYnVmX2ZkcyAtIERNQSBidWZmZXJzIHJlZmVyZW5jZWQgYnkgYW4gRkQKPiAgCj4gICAgNAlD b25maWd1cmluZyBwcm9jZnMKPiAgICA0LjEJTW91bnQgb3B0aW9ucwo+IEBAIC0yMTMxLDYgKzIx MzIsMzUgQEAgQVZYNTEyX2VsYXBzZWRfbXMKPiAgICB0aGUgdGFzayBpcyB1bmxpa2VseSBhbiBB Vlg1MTIgdXNlciwgYnV0IGRlcGVuZHMgb24gdGhlIHdvcmtsb2FkIGFuZCB0aGUKPiAgICBzY2hl ZHVsaW5nIHNjZW5hcmlvLCBpdCBhbHNvIGNvdWxkIGJlIGEgZmFsc2UgbmVnYXRpdmUgbWVudGlv bmVkIGFib3ZlLgo+ICAKPiArMy4xMyAvcHJvYy88cGlkPi90YXNrLzx0aWQ+L2RtYWJ1Zl9mZHMg LSBETUEgYnVmZmVycyByZWZlcmVuY2VkIGJ5IGFuIEZECj4gKy0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KPiAr VGhpcyBmaWxlICBleHBvc2VzIGEgbGlzdCBvZiB0aGUgaW5vZGUgbnVtYmVycyBmb3IgZXZlcnkg RE1BIGJ1ZmZlcgo+ICtGRCB0aGF0IHRoZSB0YXNrIGhhcy4KPiArCj4gK1RoZSBzYW1lIGlub2Rl IG51bWJlciBjYW4gYXBwZWFyIG1vcmUgdGhhbiBvbmNlLCBpbmRpY2F0aW5nIHRoZSB0b3RhbAo+ ICtGRCByZWZlcmVuY2VzIGZvciB0aGUgYXNzb2NpYXRlZCBETUEgYnVmZmVyLgo+ICsKPiArVGhl IGlub2RlIG51bWJlciBjYW4gYmUgdXNlZCB0byBsb29rdXAgdGhlIERNQSBidWZmZXIgaW5mb3Jt YXRpb24gaW4KPiArdGhlIHN5c2ZzIGludGVyZmFjZSAvc3lzL2tlcm5lbC9kbWFidWYvYnVmZmVy cy88aW5vZGUtbm8+Ly4KPiArCj4gK0V4YW1wbGUgT3V0cHV0Cj4gK35+fn5+fn5+fn5+fn5+Cj4g KyQgY2F0IC9wcm9jLzYxMi90YXNrLzYxMi9kbWFidWZfZmRzCj4gKzMwOTcyIDMwOTczIDQ1Njc4 IDQ5MzI2Cj4gKwo+ICtQZXJtaXNzaW9uIHRvIGFjY2VzcyB0aGlzIGZpbGUgaXMgZ292ZXJuZWQg YnkgYSBwdHJhY2UgYWNjZXNzIG1vZGUKPiArUFRSQUNFX01PREVfUkVBRF9GU0NSRURTLgo+ICsK PiArVGhyZWFkcyBjYW4gaGF2ZSBkaWZmZXJlbnQgZmlsZXMgd2hlbiBjcmVhdGVkIHdpdGhvdXQg c3BlY2lmeWluZwo+ICt0aGUgQ0xPTkVfRklMRVMgZmxhZy4gRm9yIHRoaXMgcmVhc29uIHRoZSBp bnRlcmZhY2UgaXMgcHJlc2VudGVkIGFzCj4gKy9wcm9jLzxwaWQ+L3Rhc2svPHRpZD4vZG1hYnVm X2ZkcyBhbmQgbm90IC9wcm9jLzxwaWQ+L2RtYWJ1Zl9mZHMuCj4gK1RoaXMgc2ltcGxpZmllcyBr ZXJuZWwgY29kZSBhbmQgYWdncmVnYXRpb24gY2FuIGJlIGhhbmRsZWQgaW4KPiArdXNlcnNwYWNl Lgo+ICsKPiArSWYgYSB0aHJlYWQgaGFzIHRoZSBzYW1lIGZpbGVzIGFzIGl0cyBncm91cCBsZWFk ZXIsIHRoZW4gaXRzIGRtYWJ1Zl9mZHMKPiArZmlsZSB3aWxsIGJlIGVtcHR5IGFzIHRoZXNlIGRt YWJ1ZnMgYXJlIGFscmVhZHkgcmVwb3J0ZWQgYnkgdGhlCj4gK2dyb3VwIGxlYWRlci4KPiArCj4g IENoYXB0ZXIgNDogQ29uZmlndXJpbmcgcHJvY2ZzCj4gID09PT09PT09PT09PT09PT09PT09PT09 PT09PT09Cj4gIAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS1idWYvZG1hLWJ1Zi5jIGIvZHJp dmVycy9kbWEtYnVmL2RtYS1idWYuYwo+IGluZGV4IDlhZDYzOTdhYWE5Ny4uMDY2MGMwNmJlNGM2 IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZG1hLWJ1Zi9kbWEtYnVmLmMKPiArKysgYi9kcml2ZXJz L2RtYS1idWYvZG1hLWJ1Zi5jCj4gQEAgLTI5LDggKzI5LDYgQEAKPiAgI2luY2x1ZGUgPHVhcGkv bGludXgvZG1hLWJ1Zi5oPgo+ICAjaW5jbHVkZSA8dWFwaS9saW51eC9tYWdpYy5oPgo+ICAKPiAt c3RhdGljIGlubGluZSBpbnQgaXNfZG1hX2J1Zl9maWxlKHN0cnVjdCBmaWxlICopOwo+IC0KPiAg c3RydWN0IGRtYV9idWZfbGlzdCB7Cj4gIAlzdHJ1Y3QgbGlzdF9oZWFkIGhlYWQ7Cj4gIAlzdHJ1 Y3QgbXV0ZXggbG9jazsKPiBAQCAtNDM0LDEwICs0MzIsNyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0 IGZpbGVfb3BlcmF0aW9ucyBkbWFfYnVmX2ZvcHMgPSB7Cj4gIAkuc2hvd19mZGluZm8JPSBkbWFf YnVmX3Nob3dfZmRpbmZvLAo+ICB9Owo+ICAKPiAtLyoKPiAtICogaXNfZG1hX2J1Zl9maWxlIC0g Q2hlY2sgaWYgc3RydWN0IGZpbGUqIGlzIGFzc29jaWF0ZWQgd2l0aCBkbWFfYnVmCj4gLSAqLwo+ IC1zdGF0aWMgaW5saW5lIGludCBpc19kbWFfYnVmX2ZpbGUoc3RydWN0IGZpbGUgKmZpbGUpCj4g K2ludCBpc19kbWFfYnVmX2ZpbGUoc3RydWN0IGZpbGUgKmZpbGUpCj4gIHsKPiAgCXJldHVybiBm aWxlLT5mX29wID09ICZkbWFfYnVmX2ZvcHM7Cj4gIH0KPiBkaWZmIC0tZ2l0IGEvZnMvcHJvYy9N YWtlZmlsZSBiL2ZzL3Byb2MvTWFrZWZpbGUKPiBpbmRleCBiZDA4NjE2ZWQ4YmEuLjkxYTY3ZjQz ZGRmNCAxMDA2NDQKPiAtLS0gYS9mcy9wcm9jL01ha2VmaWxlCj4gKysrIGIvZnMvcHJvYy9NYWtl ZmlsZQo+IEBAIC0xNiw2ICsxNiw3IEBAIHByb2MteQkrPSBjbWRsaW5lLm8KPiAgcHJvYy15CSs9 IGNvbnNvbGVzLm8KPiAgcHJvYy15CSs9IGNwdWluZm8ubwo+ICBwcm9jLXkJKz0gZGV2aWNlcy5v Cj4gK3Byb2MteQkrPSBkbWFfYnVmcy5vCj4gIHByb2MteQkrPSBpbnRlcnJ1cHRzLm8KPiAgcHJv Yy15CSs9IGxvYWRhdmcubwo+ICBwcm9jLXkJKz0gbWVtaW5mby5vCj4gZGlmZiAtLWdpdCBhL2Zz L3Byb2MvYmFzZS5jIGIvZnMvcHJvYy9iYXNlLmMKPiBpbmRleCBiMzQyMmNkYTJhOTEuLmFmMTVh NjBiOTgzMSAxMDA2NDQKPiAtLS0gYS9mcy9wcm9jL2Jhc2UuYwo+ICsrKyBiL2ZzL3Byb2MvYmFz ZS5jCj4gQEAgLTM1OTgsNiArMzU5OCw3IEBAIHN0YXRpYyBjb25zdCBzdHJ1Y3QgcGlkX2VudHJ5 IHRpZF9iYXNlX3N0dWZmW10gPSB7Cj4gICNpZmRlZiBDT05GSUdfU0VDQ09NUF9DQUNIRV9ERUJV Rwo+ICAJT05FKCJzZWNjb21wX2NhY2hlIiwgU19JUlVTUiwgcHJvY19waWRfc2VjY29tcF9jYWNo ZSksCj4gICNlbmRpZgo+ICsJUkVHKCJkbWFidWZfZmRzIiwgMDQ0NCwgcHJvY190aWRfZG1hYnVm X2Zkc19vcGVyYXRpb25zKSwKPiAgfTsKPiAgCj4gIHN0YXRpYyBpbnQgcHJvY190aWRfYmFzZV9y ZWFkZGlyKHN0cnVjdCBmaWxlICpmaWxlLCBzdHJ1Y3QgZGlyX2NvbnRleHQgKmN0eCkKPiBkaWZm IC0tZ2l0IGEvZnMvcHJvYy9kbWFfYnVmcy5jIGIvZnMvcHJvYy9kbWFfYnVmcy5jCj4gbmV3IGZp bGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLjQ2ZWE5Y2Y5NjhlZAo+IC0tLSAv ZGV2L251bGwKPiArKysgYi9mcy9wcm9jL2RtYV9idWZzLmMKPiBAQCAtMCwwICsxLDE1OSBAQAo+ ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ICsvKgo+ICsgKiBQZXItcHJv Y2VzcyBETUEtQlVGIFN0YXRzCj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykgMjAyMSBHb29nbGUg TExDLgo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxsaW51eC9kbWEtYnVmLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9mZHRhYmxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wdHJhY2UuaD4KPiArI2luY2x1 ZGUgPGxpbnV4L3NlcV9maWxlLmg+Cj4gKwo+ICsjaW5jbHVkZSAiaW50ZXJuYWwuaCIKPiArCj4g K3N0cnVjdCBkbWFidWZfZmRzX3ByaXZhdGUgewo+ICsJc3RydWN0IGlub2RlICppbm9kZTsKPiAr CXN0cnVjdCB0YXNrX3N0cnVjdCAqdGFzazsKPiArCXN0cnVjdCBmaWxlICpkbWFidWZfZmlsZTsK PiArfTsKPiArCj4gK3N0YXRpYyBsb2ZmX3QgKm5leHRfZG1hYnVmKHN0cnVjdCBkbWFidWZfZmRz X3ByaXZhdGUgKnByaXYsCj4gKwkJbG9mZl90ICpwb3MpCj4gK3sKPiArCXN0cnVjdCBmZHRhYmxl ICpmZHQ7Cj4gKwlzdHJ1Y3QgZmlsZSAqZmlsZTsKPiArCj4gKwlyY3VfcmVhZF9sb2NrKCk7Cj4g KwlmZHQgPSBmaWxlc19mZHRhYmxlKHByaXYtPnRhc2stPmZpbGVzKTsKPiArCWZvciAoOyAqcG9z IDwgZmR0LT5tYXhfZmRzOyArKypwb3MpIHsKPiArCQlmaWxlID0gZmlsZXNfbG9va3VwX2ZkX3Jj dShwcml2LT50YXNrLT5maWxlcywgKHVuc2lnbmVkIGludCkgKnBvcyk7Cj4gKwkJaWYgKGZpbGUg JiYgaXNfZG1hX2J1Zl9maWxlKGZpbGUpICYmIGdldF9maWxlX3JjdShmaWxlKSkgewo+ICsJCQlw cml2LT5kbWFidWZfZmlsZSA9IGZpbGU7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiArCX0KPiArCWlm ICgqcG9zID49IGZkdC0+bWF4X2ZkcykKPiArCQlwb3MgPSBOVUxMOwo+ICsJcmN1X3JlYWRfdW5s b2NrKCk7Cj4gKwo+ICsJcmV0dXJuIHBvczsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgKmRtYWJ1 Zl9mZHNfc2VxX3N0YXJ0KHN0cnVjdCBzZXFfZmlsZSAqcywgbG9mZl90ICpwb3MpCj4gK3sKPiAr CXN0cnVjdCBkbWFidWZfZmRzX3ByaXZhdGUgKnByaXYgPSBzLT5wcml2YXRlOwo+ICsJc3RydWN0 IGZpbGVzX3N0cnVjdCAqZ3JvdXBfbGVhZGVyX2ZpbGVzOwo+ICsKPiArCXByaXYtPnRhc2sgPSBn ZXRfcHJvY190YXNrKHByaXYtPmlub2RlKTsKPiArCj4gKwlpZiAoIXByaXYtPnRhc2spCj4gKwkJ cmV0dXJuIEVSUl9QVFIoLUVTUkNIKTsKPiArCj4gKwkvKiBIb2xkIHRhc2sgbG9jayBmb3IgZHVy YXRpb24gdGhhdCBmaWxlcyBuZWVkIHRvIGJlIHN0YWJsZSAqLwo+ICsJdGFza19sb2NrKHByaXYt PnRhc2spOwo+ICsKPiArCS8qCj4gKwkgKiBJZiB0aGlzIHRhc2sgaXMgbm90IHRoZSBncm91cCBs ZWFkZXIgYnV0IHNoYXJlcyB0aGUgc2FtZSBmaWxlcywgbGVhdmUgZmlsZSBlbXB0eS4KPiArCSAq IFRoZXNlIGRtYWJ1ZnMgYXJlIGFscmVhZHkgcmVwb3J0ZWQgaW4gdGhlIGdyb3VwIGxlYWRlcidz IGRtYWJ1Zl9mZHMuCj4gKwkgKi8KPiArCWdyb3VwX2xlYWRlcl9maWxlcyA9IHByaXYtPnRhc2st Pmdyb3VwX2xlYWRlci0+ZmlsZXM7Cj4gKwlpZiAocHJpdi0+dGFzayAhPSBwcml2LT50YXNrLT5n cm91cF9sZWFkZXIgJiYgcHJpdi0+dGFzay0+ZmlsZXMgPT0gZ3JvdXBfbGVhZGVyX2ZpbGVzKSB7 Cj4gKwkJdGFza191bmxvY2socHJpdi0+dGFzayk7Cj4gKwkJcHV0X3Rhc2tfc3RydWN0KHByaXYt PnRhc2spOwo+ICsJCXByaXYtPnRhc2sgPSBOVUxMOwo+ICsJCXJldHVybiBOVUxMOwo+ICsJfQo+ ICsKPiArCXJldHVybiBuZXh0X2RtYWJ1Zihwcml2LCBwb3MpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg dm9pZCAqZG1hYnVmX2Zkc19zZXFfbmV4dChzdHJ1Y3Qgc2VxX2ZpbGUgKnMsIHZvaWQgKnYsIGxv ZmZfdCAqcG9zKQo+ICt7Cj4gKwkrKypwb3M7Cj4gKwlyZXR1cm4gbmV4dF9kbWFidWYocy0+cHJp dmF0ZSwgcG9zKTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgZG1hYnVmX2Zkc19zZXFfc3RvcChz dHJ1Y3Qgc2VxX2ZpbGUgKnMsIHZvaWQgKnYpCj4gK3sKPiArCXN0cnVjdCBkbWFidWZfZmRzX3By aXZhdGUgKnByaXYgPSBzLT5wcml2YXRlOwo+ICsKPiArCWlmIChwcml2LT50YXNrKSB7Cj4gKwkJ dGFza191bmxvY2socHJpdi0+dGFzayk7Cj4gKwkJcHV0X3Rhc2tfc3RydWN0KHByaXYtPnRhc2sp Owo+ICsKPiArCX0KPiArCWlmIChwcml2LT5kbWFidWZfZmlsZSkKPiArCQlmcHV0KHByaXYtPmRt YWJ1Zl9maWxlKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBkbWFidWZfZmRzX3NlcV9zaG93KHN0 cnVjdCBzZXFfZmlsZSAqcywgdm9pZCAqdikKPiArewo+ICsJc3RydWN0IGRtYWJ1Zl9mZHNfcHJp dmF0ZSAqcHJpdiA9IHMtPnByaXZhdGU7Cj4gKwlzdHJ1Y3QgZmlsZSAqZmlsZSA9IHByaXYtPmRt YWJ1Zl9maWxlOwo+ICsJc3RydWN0IGRtYV9idWYgKmRtYWJ1ZiA9IGZpbGUtPnByaXZhdGVfZGF0 YTsKPiArCj4gKwlpZiAoIWRtYWJ1ZikKPiArCQlyZXR1cm4gLUVTUkNIOwo+ICsKPiArCXNlcV9w cmludGYocywgIiU4bHUgIiwgZmlsZV9pbm9kZShmaWxlKS0+aV9pbm8pOwo+ICsKPiArCWZwdXQo cHJpdi0+ZG1hYnVmX2ZpbGUpOwo+ICsJcHJpdi0+ZG1hYnVmX2ZpbGUgPSBOVUxMOwo+ICsKPiAr CXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHNlcV9vcGVyYXRpb25z IHByb2NfdGlkX2RtYWJ1Zl9mZHNfc2VxX29wcyA9IHsKPiArCS5zdGFydCA9IGRtYWJ1Zl9mZHNf c2VxX3N0YXJ0LAo+ICsJLm5leHQgID0gZG1hYnVmX2Zkc19zZXFfbmV4dCwKPiArCS5zdG9wICA9 IGRtYWJ1Zl9mZHNfc2VxX3N0b3AsCj4gKwkuc2hvdyAgPSBkbWFidWZfZmRzX3NlcV9zaG93Cj4g K307Cj4gKwo+ICtzdGF0aWMgaW50IHByb2NfZG1hYnVmX2Zkc19vcGVuKHN0cnVjdCBpbm9kZSAq aW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAo+ICsJCSAgICAgY29uc3Qgc3RydWN0IHNlcV9vcGVy YXRpb25zICpvcHMpCj4gK3sKPiArCXN0cnVjdCBkbWFidWZfZmRzX3ByaXZhdGUgKnByaXY7Cj4g KwlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRhc2s7Cj4gKwlib29sIGFsbG93ZWQgPSBmYWxzZTsKPiAr Cj4gKwl0YXNrID0gZ2V0X3Byb2NfdGFzayhpbm9kZSk7Cj4gKwlpZiAoIXRhc2spCj4gKwkJcmV0 dXJuIC1FU1JDSDsKPiArCj4gKwlhbGxvd2VkID0gcHRyYWNlX21heV9hY2Nlc3ModGFzaywgUFRS QUNFX01PREVfUkVBRF9GU0NSRURTKTsKPiArCXB1dF90YXNrX3N0cnVjdCh0YXNrKTsKPiArCj4g KwlpZiAoIWFsbG93ZWQpCj4gKwkJcmV0dXJuIC1FQUNDRVM7Cj4gKwo+ICsJcHJpdiA9IF9fc2Vx X29wZW5fcHJpdmF0ZShmaWxlLCBvcHMsIHNpemVvZigqcHJpdikpOwo+ICsJaWYgKCFwcml2KQo+ ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXByaXYtPmlub2RlID0gaW5vZGU7Cj4gKwlwcml2 LT50YXNrID0gTlVMTDsKPiArCXByaXYtPmRtYWJ1Zl9maWxlID0gTlVMTDsKPiArCj4gKwlyZXR1 cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBwcm9jX2RtYWJ1Zl9mZHNfcmVsZWFzZShzdHJ1 Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKPiArewo+ICsJcmV0dXJuIHNlcV9y ZWxlYXNlX3ByaXZhdGUoaW5vZGUsIGZpbGUpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHRpZF9k bWFidWZfZmRzX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCj4g K3sKPiArCXJldHVybiBwcm9jX2RtYWJ1Zl9mZHNfb3Blbihpbm9kZSwgZmlsZSwKPiArCQkJJnBy b2NfdGlkX2RtYWJ1Zl9mZHNfc2VxX29wcyk7Cj4gK30KPiArCj4gK2NvbnN0IHN0cnVjdCBmaWxl X29wZXJhdGlvbnMgcHJvY190aWRfZG1hYnVmX2Zkc19vcGVyYXRpb25zID0gewo+ICsJLm9wZW4J CT0gdGlkX2RtYWJ1Zl9mZHNfb3BlbiwKPiArCS5yZWFkCQk9IHNlcV9yZWFkLAo+ICsJLmxsc2Vl awkJPSBzZXFfbHNlZWssCj4gKwkucmVsZWFzZQk9IHByb2NfZG1hYnVmX2Zkc19yZWxlYXNlLAo+ ICt9Owo+ICsKPiBkaWZmIC0tZ2l0IGEvZnMvcHJvYy9pbnRlcm5hbC5oIGIvZnMvcHJvYy9pbnRl cm5hbC5oCj4gaW5kZXggZjYwYjM3OWRjZGM3Li40Y2E3NDIyMGRiOWMgMTAwNjQ0Cj4gLS0tIGEv ZnMvcHJvYy9pbnRlcm5hbC5oCj4gKysrIGIvZnMvcHJvYy9pbnRlcm5hbC5oCj4gQEAgLTMwMyw2 ICszMDMsNyBAQCBleHRlcm4gY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwcm9jX3BpZF9z bWFwc19vcGVyYXRpb25zOwo+ICBleHRlcm4gY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBw cm9jX3BpZF9zbWFwc19yb2xsdXBfb3BlcmF0aW9uczsKPiAgZXh0ZXJuIGNvbnN0IHN0cnVjdCBm aWxlX29wZXJhdGlvbnMgcHJvY19jbGVhcl9yZWZzX29wZXJhdGlvbnM7Cj4gIGV4dGVybiBjb25z dCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIHByb2NfcGFnZW1hcF9vcGVyYXRpb25zOwo+ICtleHRl cm4gY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBwcm9jX3RpZF9kbWFidWZfZmRzX29wZXJh dGlvbnM7Cj4gIAo+ICBleHRlcm4gdW5zaWduZWQgbG9uZyB0YXNrX3ZzaXplKHN0cnVjdCBtbV9z dHJ1Y3QgKik7Cj4gIGV4dGVybiB1bnNpZ25lZCBsb25nIHRhc2tfc3RhdG0oc3RydWN0IG1tX3N0 cnVjdCAqLAo+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L2RtYS1idWYuaCBiL2luY2x1ZGUv bGludXgvZG1hLWJ1Zi5oCj4gaW5kZXggY2Y3MjY5OWNiMmJjLi4wODdlMTFmN2YxOTMgMTAwNjQ0 Cj4gLS0tIGEvaW5jbHVkZS9saW51eC9kbWEtYnVmLmgKPiArKysgYi9pbmNsdWRlL2xpbnV4L2Rt YS1idWYuaAo+IEBAIC0yNyw2ICsyNywxMSBAQCBzdHJ1Y3QgZGV2aWNlOwo+ICBzdHJ1Y3QgZG1h X2J1ZjsKPiAgc3RydWN0IGRtYV9idWZfYXR0YWNobWVudDsKPiAgCj4gKy8qKgo+ICsgKiBDaGVj ayBpZiBzdHJ1Y3QgZmlsZSogaXMgYXNzb2NpYXRlZCB3aXRoIGRtYV9idWYuCj4gKyAqLwo+ICtp bnQgaXNfZG1hX2J1Zl9maWxlKHN0cnVjdCBmaWxlICpmaWxlKTsKPiArCj4gIC8qKgo+ICAgKiBz dHJ1Y3QgZG1hX2J1Zl9vcHMgLSBvcGVyYXRpb25zIHBvc3NpYmxlIG9uIHN0cnVjdCBkbWFfYnVm Cj4gICAqIEB2bWFwOiBbb3B0aW9uYWxdIGNyZWF0ZXMgYSB2aXJ0dWFsIG1hcHBpbmcgZm9yIHRo ZSBidWZmZXIgaW50byBrZXJuZWwKPiAtLSAKPiAyLjMwLjAuMjgwLmdhM2NlMjc5MTJmLWdvb2cK Ci0tIApNaWNoYWwgSG9ja28KU1VTRSBMYWJzCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3Rz LmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xp c3RpbmZvL2RyaS1kZXZlbAo=