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=-23.3 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, 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,USER_IN_DEF_DKIM_WL 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 CE9E2C433DB for ; Wed, 20 Jan 2021 20:42:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 82F1A235F7 for ; Wed, 20 Jan 2021 20:42:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388216AbhATUju (ORCPT ); Wed, 20 Jan 2021 15:39:50 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392813AbhATUg0 (ORCPT ); Wed, 20 Jan 2021 15:36:26 -0500 Received: from mail-qv1-xf29.google.com (mail-qv1-xf29.google.com [IPv6:2607:f8b0:4864:20::f29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7BB32C0613CF for ; Wed, 20 Jan 2021 12:35:38 -0800 (PST) Received: by mail-qv1-xf29.google.com with SMTP id a1so11549302qvd.13 for ; Wed, 20 Jan 2021 12:35:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=Z0QoUnMigHZv62iqBIHVw3IzALde+Sr2xiVtJxAC/JA=; b=hRm+u1Ec/AFUit6iuIVxpXiDikz7HhehQDfrW0OBud7m3m2qxq7sRTjVn0SWV9wfw+ zgcxp2Vb246+0c0qfFipKHsI+d1nB/7/Xv5ubRaNZUt5/4uSFw0hwaBMnL/KJXoIdBhQ Y+NeUr9aZZwhS87eFR18MW7ACq9xcJxCsg8uB6JwDbzNDRgQNx0QGp4bUCvxkVTwgGNu j9wZkbHpATMBZBmgab1GWsmeYaUGyuI3W15JeNgGprusnojdV4s5HIVUwylhBSKGf2b2 qgTtFO74fzr/y5vsOaElQcinrWxEobz58GGB/UesnN2IhMUU3gKwLJ5+AbXbMkUIi6Bw J71A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=Z0QoUnMigHZv62iqBIHVw3IzALde+Sr2xiVtJxAC/JA=; b=UI1pUP8/h/beJc+IONVfRHJQaInGLdRuNTaa5on6eap3y6NroFewTsMxj55Tw46etf xh0AqZeHMlsB0bMQyus3YXB8coAOtwDnH0D/lgnl3A7qkRU+y6NbNUKczNbaenvZyQmG mV74qjRFVVX3uZdIM4JkO8plQO5YChhfDRgcgOkUNLOb5lQpwUYbmCXCl5r0bRAgf2ZJ oAXNMLipF0O8avp4RKrkOyNMilnE6AJLRJZdeD2ZSsczq9gIrq1HjxdL6W//toRXxxbg 98bWsRvBlWE3QchO7951dFO8G6KfPy3WIkAkzjugR4z4dFxI3g7n8/OIcBKR4e9pUKTb IuCQ== X-Gm-Message-State: AOAM532l8qir3edxyrhp1u69obsG3n+hwaVW9e0vljTHMubVGc3on18o d/RLZMrUBQzGJp37zR6zEFqnbIxeZPNZnCw9mfo01Q== X-Google-Smtp-Source: ABdhPJxFSrvkUPhzivgN09xn5QczRNY8sy5obem5udP1jEXDUeCqoC6zTMeC4yFMw/DzDQhTFoBNajuC3vbG7HcpCpY= X-Received: by 2002:a0c:8203:: with SMTP id h3mr11117071qva.0.1611174937158; Wed, 20 Jan 2021 12:35:37 -0800 (PST) MIME-Version: 1.0 References: <20210119225723.388883-1-hridya@google.com> In-Reply-To: From: Hridya Valsaraju Date: Wed, 20 Jan 2021 12:34:59 -0800 Message-ID: Subject: Re: [Linaro-mm-sig] [PATCH v2] dmabuf: Add the capability to expose DMA-BUF stats in sysfs To: Daniel Vetter Cc: =?UTF-8?Q?Christian_K=C3=B6nig?= , Yiwei Zhang , Sumit Semwal , Linux Kernel Mailing List , "open list:DMA BUFFER SHARING FRAMEWORK" , dri-devel , "moderated list:DMA BUFFER SHARING FRAMEWORK" , Suren Baghdasaryan , Greg KH , Android Kernel Team , Hyesoo Yu Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jan 20, 2021 at 4:42 AM Daniel Vetter wrote: > > On Wed, Jan 20, 2021 at 1:22 PM Christian K=C3=B6nig > wrote: > > > > Am 19.01.21 um 23:57 schrieb Hridya Valsaraju: > > > This patch allows statistics to be enabled for each DMA-BUF in > > > sysfs by enabling the config CONFIG_DMABUF_SYSFS_STATS. > > > > > > The following stats will be exposed by the interface: > > > > > > /sys/kernel/dmabuf/buffers//exporter_name > > > /sys/kernel/dmabuf/buffers//size > > > /sys/kernel/dmabuf/buffers//attachments//de= vice > > > /sys/kernel/dmabuf/buffers//attachments//ma= p_counter > > > > > > The inode_number is unique for each DMA-BUF and was added earlier [1] > > > in order to allow userspace to track DMA-BUF usage across different > > > processes. > > > > > > Currently, this information is exposed in > > > /sys/kernel/debug/dma_buf/bufinfo. > > > However, since debugfs is considered unsafe to be mounted in producti= on, > > > it is being duplicated in sysfs. > > > > > > This information will be used to derive DMA-BUF > > > per-exporter stats and per-device usage stats for Android Bug reports= . > > > The corresponding userspace changes can be found at [2]. > > > Telemetry tools will also capture this information(along with other > > > memory metrics) periodically as well as on important events like a > > > foreground app kill (which might have been triggered by Low Memory > > > Killer). It will also contribute to provide a snapshot of the system > > > memory usage on other events such as OOM kills and Application Not > > > Responding events. > > > > > > A shell script that can be run on a classic Linux environment to read > > > out the DMA-BUF statistics can be found at [3](suggested by John > > > Stultz). > > > > > > The patch contains the following improvements over the previous versi= on: > > > 1) Each attachment is represented by its own directory to allow creat= ing > > > a symlink to the importing device and to also provide room for future > > > expansion. > > > 2) The number of distinct mappings of each attachment is exposed in a > > > separate file. > > > 3) The per-buffer statistics are now in /sys/kernel/dmabuf/buffers > > > inorder to make the interface expandable in future. > > > > > > All of the improvements above are based on suggestions/feedback from > > > Daniel Vetter and Christian K=C3=B6nig. > > > > > > [1]: https://lore.kernel.org/patchwork/patch/1088791/ > > > [2]: https://android-review.googlesource.com/q/topic:%22dmabuf-sysfs%= 22+(status:open%20OR%20status:merged) > > > [3]: https://android-review.googlesource.com/c/platform/system/memory= /libmeminfo/+/1549734 > > > > > > Signed-off-by: Hridya Valsaraju > > > --- > > > Changes in v2: > > > -Move statistics to /sys/kernel/dmabuf/buffers in oder to allow addit= ion > > > of other DMA-BUF-related sysfs stats in future. Based on feedback fro= m > > > Daniel Vetter. > > > -Each attachment has its own directory to represent attaching devices= as > > > symlinks and to introduce map_count as a separate file. Based on > > > feedback from Daniel Vetter and Christian K=C3=B6nig. Thank you both! > > > -Commit messages updated to point to userspace code in AOSP that will > > > read the DMA-BUF sysfs stats. > > > > > > .../ABI/testing/sysfs-kernel-dmabuf-buffers | 52 ++++ > > > drivers/dma-buf/Kconfig | 11 + > > > drivers/dma-buf/Makefile | 1 + > > > drivers/dma-buf/dma-buf-sysfs-stats.c | 283 +++++++++++++++= +++ > > > drivers/dma-buf/dma-buf-sysfs-stats.h | 62 ++++ > > > drivers/dma-buf/dma-buf.c | 37 +++ > > > include/linux/dma-buf.h | 20 ++ > > > 7 files changed, 466 insertions(+) > > > create mode 100644 Documentation/ABI/testing/sysfs-kernel-dmabuf-bu= ffers > > > create mode 100644 drivers/dma-buf/dma-buf-sysfs-stats.c > > > create mode 100644 drivers/dma-buf/dma-buf-sysfs-stats.h > > > > > > diff --git a/Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers b/= Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers > > > new file mode 100644 > > > index 000000000000..6f7c65209f07 > > > --- /dev/null > > > +++ b/Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers > > > @@ -0,0 +1,52 @@ > > > +What: /sys/kernel/dmabuf/buffers > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: The /sys/kernel/dmabuf/buffers directory contains a > > > + snapshot of the internal state of every DMA-BUF. > > > + /sys/kernel/dmabuf/buffers/ will contain = the > > > + statistics for the DMA-BUF with the unique inode number > > > + > > > +Users: kernel memory tuning/debugging tools > > > + > > > +What: /sys/kernel/dmabuf/buffers//expor= ter_name > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: This file is read-only and contains the name of the exp= orter of > > > + the DMA-BUF. > > > + > > > +What: /sys/kernel/dmabuf/buffers//size > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: This file is read-only and specifies the size of the DM= A-BUF in > > > + bytes. > > > + > > > +What: /sys/kernel/dmabuf/buffers//attac= hments > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: This directory will contain subdirectories representing= every > > > + attachment of the DMA-BUF. > > > + > > > +What: /sys/kernel/dmabuf/buffers//attac= hments/ > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: This directory will contain information on the attachin= g device > > > + and the number of current distinct device mappings. > > > + > > > +What: /sys/kernel/dmabuf/buffers//attac= hments//device > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: This file is read-only and is a symlink to the attachin= g devices's > > > + sysfs entry. > > > + > > > +What: /sys/kernel/dmabuf/buffers//attac= hments//map_counter > > > +Date: January 2021 > > > +KernelVersion: v5.12 > > > +Contact: Hridya Valsaraju > > > +Description: This file is read-only and contains a map_counter indic= ating the > > > + number of distinct device mappings of the attachment. > > > diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig > > > index 4f8224a6ac95..27e6a2dafeaa 100644 > > > --- a/drivers/dma-buf/Kconfig > > > +++ b/drivers/dma-buf/Kconfig > > > @@ -64,6 +64,17 @@ menuconfig DMABUF_HEAPS > > > allows userspace to allocate dma-bufs that can be shared > > > between drivers. > > > > > > +menuconfig DMABUF_SYSFS_STATS > > > + bool "DMA-BUF sysfs statistics" > > > + select DMA_SHARED_BUFFER > > > + help > > > + Choose this option to enable DMA-BUF sysfs statistics > > > + in location /sys/kernel/dmabuf/buffers. > > > + > > > + /sys/kernel/dmabuf/buffers/ will contain > > > + statistics for the DMA-BUF with the unique inode number > > > + . > > > + > > > source "drivers/dma-buf/heaps/Kconfig" > > > > > > endmenu > > > diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile > > > index 995e05f609ff..40d81f23cacf 100644 > > > --- a/drivers/dma-buf/Makefile > > > +++ b/drivers/dma-buf/Makefile > > > @@ -6,6 +6,7 @@ obj-$(CONFIG_DMABUF_HEAPS) +=3D heaps/ > > > obj-$(CONFIG_SYNC_FILE) +=3D sync_file.o > > > obj-$(CONFIG_SW_SYNC) +=3D sw_sync.o sync_debug.o > > > obj-$(CONFIG_UDMABUF) +=3D udmabuf.o > > > +obj-$(CONFIG_DMABUF_SYSFS_STATS) +=3D dma-buf-sysfs-stats.o > > > > > > dmabuf_selftests-y :=3D \ > > > selftest.o \ > > > diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.c b/drivers/dma-buf/= dma-buf-sysfs-stats.c > > > new file mode 100644 > > > index 000000000000..61f85c3d16a5 > > > --- /dev/null > > > +++ b/drivers/dma-buf/dma-buf-sysfs-stats.c > > > @@ -0,0 +1,283 @@ > > > +// SPDX-License-Identifier: GPL-2.0-only > > > +/* > > > + * DMA-BUF sysfs statistics. > > > + * > > > + * Copyright (C) 2021 Google LLC. > > > + */ > > > + > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > +#include > > > + > > > +#define to_dma_buf_entry_from_kobj(x) container_of(x, struct dma_buf= _sysfs_entry, kobj) > > > + > > > +struct dma_buf_stats_attribute { > > > + struct attribute attr; > > > + ssize_t (*show)(struct dma_buf *dmabuf, > > > + struct dma_buf_stats_attribute *attr, char *buf= ); > > > +}; > > > +#define to_dma_buf_stats_attr(x) container_of(x, struct dma_buf_stat= s_attribute, attr) > > > + > > > +static ssize_t dma_buf_stats_attribute_show(struct kobject *kobj, > > > + struct attribute *attr, > > > + char *buf) > > > +{ > > > + struct dma_buf_stats_attribute *attribute; > > > + struct dma_buf_sysfs_entry *sysfs_entry; > > > + struct dma_buf *dmabuf; > > > + > > > + attribute =3D to_dma_buf_stats_attr(attr); > > > + sysfs_entry =3D to_dma_buf_entry_from_kobj(kobj); > > > + dmabuf =3D sysfs_entry->dmabuf; > > > + > > > + if (!dmabuf || !attribute->show) > > > + return -EIO; > > > + > > > + return attribute->show(dmabuf, attribute, buf); > > > +} > > > + > > > +static const struct sysfs_ops dma_buf_stats_sysfs_ops =3D { > > > + .show =3D dma_buf_stats_attribute_show, > > > +}; > > > + > > > +static ssize_t exporter_name_show(struct dma_buf *dmabuf, > > > + struct dma_buf_stats_attribute *attr, > > > + char *buf) > > > +{ > > > + return sysfs_emit(buf, "%s\n", dmabuf->exp_name); > > > +} > > > + > > > +static ssize_t size_show(struct dma_buf *dmabuf, > > > + struct dma_buf_stats_attribute *attr, > > > + char *buf) > > > +{ > > > + return sysfs_emit(buf, "%zu\n", dmabuf->size); > > > +} > > > + > > > +static struct dma_buf_stats_attribute exporter_name_attribute =3D > > > + __ATTR_RO(exporter_name); > > > +static struct dma_buf_stats_attribute size_attribute =3D __ATTR_RO(s= ize); > > > + > > > +static struct attribute *dma_buf_stats_default_attrs[] =3D { > > > + &exporter_name_attribute.attr, > > > + &size_attribute.attr, > > > + NULL, > > > +}; > > > +ATTRIBUTE_GROUPS(dma_buf_stats_default); > > > + > > > +static void dma_buf_sysfs_release(struct kobject *kobj) > > > +{ > > > + struct dma_buf_sysfs_entry *sysfs_entry; > > > + > > > + sysfs_entry =3D to_dma_buf_entry_from_kobj(kobj); > > > + kfree(sysfs_entry); > > > +} > > > + > > > +static struct kobj_type dma_buf_ktype =3D { > > > + .sysfs_ops =3D &dma_buf_stats_sysfs_ops, > > > + .release =3D dma_buf_sysfs_release, > > > + .default_groups =3D dma_buf_stats_default_groups, > > > +}; > > > + > > > +#define to_dma_buf_attach_entry_from_kobj(x) container_of(x, struct = dma_buf_attach_sysfs_entry, kobj) > > > + > > > +struct dma_buf_attach_stats_attribute { > > > + struct attribute attr; > > > + ssize_t (*show)(struct dma_buf_attach_sysfs_entry *sysfs_entry, > > > + struct dma_buf_attach_stats_attribute *attr, ch= ar *buf); > > > +}; > > > +#define to_dma_buf_attach_stats_attr(x) container_of(x, struct dma_b= uf_attach_stats_attribute, attr) > > > + > > > +static ssize_t dma_buf_attach_stats_attribute_show(struct kobject *k= obj, > > > + struct attribute *at= tr, > > > + char *buf) > > > +{ > > > + struct dma_buf_attach_stats_attribute *attribute; > > > + struct dma_buf_attach_sysfs_entry *sysfs_entry; > > > + > > > + attribute =3D to_dma_buf_attach_stats_attr(attr); > > > + sysfs_entry =3D to_dma_buf_attach_entry_from_kobj(kobj); > > > + > > > + if (!attribute->show) > > > + return -EIO; > > > + > > > + return attribute->show(sysfs_entry, attribute, buf); > > > +} > > > + > > > +static const struct sysfs_ops dma_buf_attach_stats_sysfs_ops =3D { > > > + .show =3D dma_buf_attach_stats_attribute_show, > > > +}; > > > + > > > +static ssize_t map_counter_show(struct dma_buf_attach_sysfs_entry *s= ysfs_entry, > > > + struct dma_buf_attach_stats_attribute *= attr, > > > + char *buf) > > > +{ > > > + return sysfs_emit(buf, "%u\n", sysfs_entry->map_counter); > > > +} > > > + > > > +static struct dma_buf_attach_stats_attribute map_counter_attribute = =3D > > > + __ATTR_RO(map_counter); > > > + > > > +static struct attribute *dma_buf_attach_stats_default_attrs[] =3D { > > > + &map_counter_attribute.attr, > > > + NULL, > > > +}; > > > +ATTRIBUTE_GROUPS(dma_buf_attach_stats_default); > > > + > > > +static void dma_buf_attach_sysfs_release(struct kobject *kobj) > > > +{ > > > + struct dma_buf_attach_sysfs_entry *sysfs_entry; > > > + > > > + sysfs_entry =3D to_dma_buf_attach_entry_from_kobj(kobj); > > > + kfree(sysfs_entry); > > > +} > > > + > > > +static struct kobj_type dma_buf_attach_ktype =3D { > > > + .sysfs_ops =3D &dma_buf_attach_stats_sysfs_ops, > > > + .release =3D dma_buf_attach_sysfs_release, > > > + .default_groups =3D dma_buf_attach_stats_default_groups, > > > +}; > > > + > > > +void dma_buf_attach_stats_teardown(struct dma_buf_attachment *attach= ) > > > +{ > > > + struct dma_buf_attach_sysfs_entry *sysfs_entry; > > > + > > > + sysfs_entry =3D attach->sysfs_entry; > > > + if (!sysfs_entry) > > > + return; > > > + > > > + sysfs_delete_link(&sysfs_entry->kobj, &attach->dev->kobj, "devi= ce"); > > > + > > > + kobject_del(&sysfs_entry->kobj); > > > + kobject_put(&sysfs_entry->kobj); > > > +} > > > + > > > +int dma_buf_attach_stats_setup(struct dma_buf_attachment *attach, > > > + unsigned int uid) > > > +{ > > > + struct dma_buf_attach_sysfs_entry *sysfs_entry; > > > + int ret; > > > + struct dma_buf *dmabuf; > > > + > > > + if (!attach) > > > + return -EINVAL; > > > + > > > + dmabuf =3D attach->dmabuf; > > > + > > > + sysfs_entry =3D kzalloc(sizeof(struct dma_buf_attach_sysfs_entr= y), > > > + GFP_KERNEL); > > > + if (!sysfs_entry) > > > + return -ENOMEM; > > > + > > > + sysfs_entry->kobj.kset =3D dmabuf->sysfs_entry->attach_stats_ks= et; > > > + > > > + attach->sysfs_entry =3D sysfs_entry; > > > + > > > + ret =3D kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_attac= h_ktype, > > > + NULL, "%u", uid); > > > + if (ret) > > > + goto kobj_err; > > > + > > > + ret =3D sysfs_create_link(&sysfs_entry->kobj, &attach->dev->kob= j, > > > + "device"); > > > + if (ret) > > > + goto link_err; > > > + > > > + return 0; > > > + > > > +link_err: > > > + kobject_del(&sysfs_entry->kobj); > > > +kobj_err: > > > + kobject_put(&sysfs_entry->kobj); > > > + attach->sysfs_entry =3D NULL; > > > + > > > + return ret; > > > +} > > > +void dma_buf_stats_teardown(struct dma_buf *dmabuf) > > > +{ > > > + struct dma_buf_sysfs_entry *sysfs_entry; > > > + > > > + sysfs_entry =3D dmabuf->sysfs_entry; > > > + if (!sysfs_entry) > > > + return; > > > + > > > + kset_unregister(sysfs_entry->attach_stats_kset); > > > + kobject_del(&sysfs_entry->kobj); > > > + kobject_put(&sysfs_entry->kobj); > > > +} > > > + > > > +static struct kset *dma_buf_stats_kset; > > > +static struct kset *dma_buf_per_buffer_stats_kset; > > > +int dma_buf_init_sysfs_statistics(void) > > > +{ > > > + dma_buf_stats_kset =3D kset_create_and_add("dmabuf", NULL, kern= el_kobj); > > > + if (!dma_buf_stats_kset) > > > + return -ENOMEM; > > > + > > > + dma_buf_per_buffer_stats_kset =3D kset_create_and_add("buffers"= , NULL, > > > + &dma_buf_st= ats_kset->kobj); > > > + if (!dma_buf_per_buffer_stats_kset) { > > > + kset_unregister(dma_buf_stats_kset); > > > + return -ENOMEM; > > > + } > > > + > > > + return 0; > > > +} > > > + > > > +void dma_buf_uninit_sysfs_statistics(void) > > > +{ > > > + kset_unregister(dma_buf_per_buffer_stats_kset); > > > + kset_unregister(dma_buf_stats_kset); > > > +} > > > + > > > +int dma_buf_stats_setup(struct dma_buf *dmabuf) > > > +{ > > > + struct dma_buf_sysfs_entry *sysfs_entry; > > > + int ret; > > > + struct kset *attach_stats_kset; > > > + > > > + if (!dmabuf || !dmabuf->file) > > > + return -EINVAL; > > > + > > > + if (!dmabuf->exp_name) { > > > + pr_err("exporter name must not be empty if stats needed= \n"); > > > + return -EINVAL; > > > + } > > > + > > > + sysfs_entry =3D kzalloc(sizeof(struct dma_buf_sysfs_entry), GFP= _KERNEL); > > > + if (!sysfs_entry) > > > + return -ENOMEM; > > > + > > > + sysfs_entry->kobj.kset =3D dma_buf_per_buffer_stats_kset; > > > + sysfs_entry->dmabuf =3D dmabuf; > > > + > > > + dmabuf->sysfs_entry =3D sysfs_entry; > > > + > > > + /* create the directory for buffer stats */ > > > + ret =3D kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_ktype= , NULL, > > > + "%lu", file_inode(dmabuf->file)->i_i= no); > > > + if (ret) > > > + goto err_sysfs_dmabuf; > > > + > > > + /* create the directory for attachment stats */ > > > + attach_stats_kset =3D kset_create_and_add("attachments", NULL, > > > + &sysfs_entry->kobj); > > > + if (!attach_stats_kset) { > > > + ret =3D -ENOMEM; > > > + goto err_sysfs_attach; > > > + } > > > + > > > + sysfs_entry->attach_stats_kset =3D attach_stats_kset; > > > + > > > + return 0; > > > + > > > +err_sysfs_attach: > > > + kobject_del(&sysfs_entry->kobj); > > > +err_sysfs_dmabuf: > > > + kobject_put(&sysfs_entry->kobj); > > > + dmabuf->sysfs_entry =3D NULL; > > > + return ret; > > > +} > > > diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.h b/drivers/dma-buf/= dma-buf-sysfs-stats.h > > > new file mode 100644 > > > index 000000000000..5f4703249117 > > > --- /dev/null > > > +++ b/drivers/dma-buf/dma-buf-sysfs-stats.h > > > @@ -0,0 +1,62 @@ > > > +/* SPDX-License-Identifier: GPL-2.0-only */ > > > +/* > > > + * DMA-BUF sysfs statistics. > > > + * > > > + * Copyright (C) 2021 Google LLC. > > > + */ > > > + > > > +#ifndef _DMA_BUF_SYSFS_STATS_H > > > +#define _DMA_BUF_SYSFS_STATS_H > > > + > > > +#ifdef CONFIG_DMABUF_SYSFS_STATS > > > + > > > +int dma_buf_init_sysfs_statistics(void); > > > +void dma_buf_uninit_sysfs_statistics(void); > > > + > > > +int dma_buf_stats_setup(struct dma_buf *dmabuf); > > > +int dma_buf_attach_stats_setup(struct dma_buf_attachment *attach, > > > + unsigned int uid); > > > +static inline void dma_buf_update_attachment_map_count(struct dma_bu= f_attachment *attach, > > > + int delta) > > > +{ > > > + struct dma_buf_attach_sysfs_entry *entry =3D attach->sysfs_entr= y; > > > + > > > + entry->map_counter +=3D delta; > > > +} > > > +void dma_buf_stats_teardown(struct dma_buf *dmabuf); > > > +void dma_buf_attach_stats_teardown(struct dma_buf_attachment *attach= ); > > > +static inline unsigned int dma_buf_update_attach_uid(struct dma_buf = *dmabuf) > > > +{ > > > + struct dma_buf_sysfs_entry *entry =3D dmabuf->sysfs_entry; > > > + > > > + return entry->attachment_uid++; > > > +} > > > +#else > > > + > > > +static inline int dma_buf_init_sysfs_statistics(void) > > > +{ > > > + return 0; > > > +} > > > + > > > +static inline void dma_buf_uninit_sysfs_statistics(void) {} > > > + > > > +static inline int dma_buf_stats_setup(struct dma_buf *dmabuf) > > > +{ > > > + return 0; > > > +} > > > +static inline int dma_buf_attach_stats_setup(struct dma_buf_attachme= nt *attach, > > > + unsigned int uid) > > > +{ > > > + return 0; > > > +} > > > + > > > +static inline void dma_buf_stats_teardown(struct dma_buf *dmabuf) {} > > > +static inline void dma_buf_attach_stats_teardown(struct dma_buf_atta= chment *attach) {} > > > +static inline void dma_buf_update_attachment_map_count(struct dma_bu= f_attachment *attach, > > > + int delta) {} > > > +static inline unsigned int dma_buf_update_attach_uid(struct dma_buf = *dmabuf) > > > +{ > > > + return 0; > > > +} > > > +#endif > > > +#endif // _DMA_BUF_SYSFS_STATS_H > > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c > > > index 9ad6397aaa97..29f9ea18eb47 100644 > > > --- a/drivers/dma-buf/dma-buf.c > > > +++ b/drivers/dma-buf/dma-buf.c > > > @@ -29,6 +29,8 @@ > > > #include > > > #include > > > > > > +#include "dma-buf-sysfs-stats.h" > > > + > > > static inline int is_dma_buf_file(struct file *); > > > > > > struct dma_buf_list { > > > @@ -79,6 +81,7 @@ static void dma_buf_release(struct dentry *dentry) > > > if (dmabuf->resv =3D=3D (struct dma_resv *)&dmabuf[1]) > > > dma_resv_fini(dmabuf->resv); > > > > > > + dma_buf_stats_teardown(dmabuf); > > > module_put(dmabuf->owner); > > > kfree(dmabuf->name); > > > kfree(dmabuf); > > > @@ -579,6 +582,10 @@ struct dma_buf *dma_buf_export(const struct dma_= buf_export_info *exp_info) > > > file->f_mode |=3D FMODE_LSEEK; > > > dmabuf->file =3D file; > > > > > > + ret =3D dma_buf_stats_setup(dmabuf); > > > + if (ret) > > > + goto err_sysfs; > > > + > > > mutex_init(&dmabuf->lock); > > > INIT_LIST_HEAD(&dmabuf->attachments); > > > > > > @@ -588,6 +595,14 @@ struct dma_buf *dma_buf_export(const struct dma_= buf_export_info *exp_info) > > > > > > return dmabuf; > > > > > > +err_sysfs: > > > + /* > > > + * Set file->f_path.dentry->d_fsdata to NULL so that when > > > + * dma_buf_release() gets invoked by dentry_ops, it exits > > > + * early before calling the release() dma_buf op. > > > + */ > > > + file->f_path.dentry->d_fsdata =3D NULL; > > > + fput(file); > > > err_dmabuf: > > > kfree(dmabuf); > > > err_module: > > > @@ -692,6 +707,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, st= ruct device *dev, > > > { > > > struct dma_buf_attachment *attach; > > > int ret; > > > + unsigned int attach_uid; > > > > > > if (WARN_ON(!dmabuf || !dev)) > > > return ERR_PTR(-EINVAL); > > > @@ -717,8 +733,13 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, s= truct device *dev, > > > } > > > dma_resv_lock(dmabuf->resv, NULL); > > > list_add(&attach->node, &dmabuf->attachments); > > > + attach_uid =3D dma_buf_update_attach_uid(dmabuf); > > > dma_resv_unlock(dmabuf->resv); > > > > > > + ret =3D dma_buf_attach_stats_setup(attach, attach_uid); > > > + if (ret) > > > + goto err_sysfs; > > > + > > > /* When either the importer or the exporter can't handle dynami= c > > > * mappings we cache the mapping here to avoid issues with the > > > * reservation object lock. > > > @@ -745,6 +766,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, st= ruct device *dev, > > > dma_resv_unlock(attach->dmabuf->resv); > > > attach->sgt =3D sgt; > > > attach->dir =3D DMA_BIDIRECTIONAL; > > > + dma_buf_update_attachment_map_count(attach, 1 /* delta = */); > > > } > > > > > > return attach; > > > @@ -761,6 +783,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, st= ruct device *dev, > > > if (dma_buf_is_dynamic(attach->dmabuf)) > > > dma_resv_unlock(attach->dmabuf->resv); > > > > > > +err_sysfs: > > > dma_buf_detach(dmabuf, attach); > > > return ERR_PTR(ret); > > > } > > > @@ -799,6 +822,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struc= t dma_buf_attachment *attach) > > > dma_resv_lock(attach->dmabuf->resv, NULL); > > > > > > dmabuf->ops->unmap_dma_buf(attach, attach->sgt, attach-= >dir); > > > + dma_buf_update_attachment_map_count(attach, -1 /* delta= */); > > > > > > if (dma_buf_is_dynamic(attach->dmabuf)) { > > > dma_buf_unpin(attach); > > > @@ -812,6 +836,7 @@ void dma_buf_detach(struct dma_buf *dmabuf, struc= t dma_buf_attachment *attach) > > > if (dmabuf->ops->detach) > > > dmabuf->ops->detach(dmabuf, attach); > > > > > > + dma_buf_attach_stats_teardown(attach); > > > kfree(attach); > > > } > > > EXPORT_SYMBOL_GPL(dma_buf_detach); > > > @@ -938,6 +963,9 @@ struct sg_table *dma_buf_map_attachment(struct dm= a_buf_attachment *attach, > > > } > > > #endif /* CONFIG_DMA_API_DEBUG */ > > > > > > + if (!IS_ERR(sg_table)) > > > + dma_buf_update_attachment_map_count(attach, 1 /* delta = */); > > > + > > > return sg_table; > > > } > > > EXPORT_SYMBOL_GPL(dma_buf_map_attachment); > > > @@ -975,6 +1003,8 @@ void dma_buf_unmap_attachment(struct dma_buf_att= achment *attach, > > > if (dma_buf_is_dynamic(attach->dmabuf) && > > > !IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) > > > dma_buf_unpin(attach); > > > + > > > + dma_buf_update_attachment_map_count(attach, -1 /* delta */); > > > } > > > EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); > > > > > > @@ -1412,6 +1442,12 @@ static inline void dma_buf_uninit_debugfs(void= ) > > > > > > static int __init dma_buf_init(void) > > > { > > > + int ret; > > > + > > > + ret =3D dma_buf_init_sysfs_statistics(); > > > + if (ret) > > > + return ret; > > > + > > > dma_buf_mnt =3D kern_mount(&dma_buf_fs_type); > > > if (IS_ERR(dma_buf_mnt)) > > > return PTR_ERR(dma_buf_mnt); > > > @@ -1427,5 +1463,6 @@ static void __exit dma_buf_deinit(void) > > > { > > > dma_buf_uninit_debugfs(); > > > kern_unmount(dma_buf_mnt); > > > + dma_buf_uninit_sysfs_statistics(); > > > } > > > __exitcall(dma_buf_deinit); > > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h > > > index cf72699cb2bc..4ae5cc38a4a7 100644 > > > --- a/include/linux/dma-buf.h > > > +++ b/include/linux/dma-buf.h > > > @@ -294,6 +294,9 @@ struct dma_buf_ops { > > > * @poll: for userspace poll support > > > * @cb_excl: for userspace poll support > > > * @cb_shared: for userspace poll support > > > + * @sysfs_entry: for exposing information about this buffer in sysfs= . > > > + * The attachment_uid member of @sysfs_entry is protected by dma_res= v lock > > > + * and is incremented on each attach. > > > * > > > * This represents a shared buffer, created by calling dma_buf_expo= rt(). The > > > * userspace representation is a normal file descriptor, which can = be created by > > > @@ -329,6 +332,15 @@ struct dma_buf { > > > > > > __poll_t active; > > > } cb_excl, cb_shared; > > > +#ifdef CONFIG_DMABUF_SYSFS_STATS > > > + /* for sysfs stats */ > > > + struct dma_buf_sysfs_entry { > > > + struct kobject kobj; > > > + struct dma_buf *dmabuf; > > > + unsigned int attachment_uid; > > > + struct kset *attach_stats_kset; > > > + } *sysfs_entry; > > > +#endif > > > > Why not directly embed that? > > > > > }; > > > > > > /** > > > @@ -378,6 +390,7 @@ struct dma_buf_attach_ops { > > > * @importer_ops: importer operations for this attachment, if provi= ded > > > * dma_buf_map/unmap_attachment() must be called with the dma_resv = lock held. > > > * @importer_priv: importer specific attachment data. > > > + * @sysfs_entry: For exposing information about this attachment in s= ysfs. > > > * > > > * This structure holds the attachment information between the dma_= buf buffer > > > * and its user device(s). The list contains one attachment struct = per device > > > @@ -398,6 +411,13 @@ struct dma_buf_attachment { > > > const struct dma_buf_attach_ops *importer_ops; > > > void *importer_priv; > > > void *priv; > > > +#ifdef CONFIG_DMABUF_SYSFS_STATS > > > + /* for sysfs stats */ > > > + struct dma_buf_attach_sysfs_entry { > > > + struct kobject kobj; > > > + unsigned int map_counter; > > > + } *sysfs_entry; > > > +#endif > > > > Same question here. > > > > Apart from that the general approach looks solid to me now. > > > > But somebody with more sysfs background should check if everything ther= e > > is the right thing to do. > > So apparently Android is completely revamping all of this, but feeding > it to upstream in pieces, and that doesn't work. Here's another part: > > https://lore.kernel.org/dri-devel/CAKMK7uE3xF80AsJ1zGfSM-KTry=3DikJ-S-Dn6= nK8ZAvCSWw2FHQ@mail.gmail.com/ Thank you for taking a look and the guidance so far Daniel! The above patch (which adds tracepoints to track total GPU memory allocations) is independent of the DMA-BUF sysfs stats effort. I agree that the value from the tracepoint will include memory that is shared as DMA-BUFs. However, there is no interdependency between the two efforts. I have linked to the AOSP code that will parse the DMA-BUF sysfs statistics in the commit message. We do have plans to expand the sysfs interface itself in future(thank you for suggesting to make it expandable in v1!) but when we do, we will make sure to send the userspace code that uses it as well so that you can get the full picture. Regards, Hridya > > I think we need an overall integrated solution here, or we're just > building uapi that won't last (but we still have to support it > forever). > > I think aside from having the full android side covered (but on > upstream drivers, and including dma-buf sharing, not just only > virtio-gpu) we also need to figure out how this will fit into other > tracking efforts like cgroups. Otherwise we end up with one way of > tracking gpu memory usage for android, implemented by out-of-tree > drivers mostly. Another one for servers in cgroups, implemented by amd > and intel, and then probably a third one for cros > virtualization/containers, just because. That doesn't work too well. > -Daniel > -- > Daniel Vetter > Software Engineer, Intel Corporation > http://blog.ffwll.ch 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_ADSP_CUSTOM_MED,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 57528C433E6 for ; Thu, 21 Jan 2021 08:53:42 +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 13E6E239D3 for ; Thu, 21 Jan 2021 08:53:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 13E6E239D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.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 8CE016E901; Thu, 21 Jan 2021 08:53:18 +0000 (UTC) Received: from mail-qv1-xf30.google.com (mail-qv1-xf30.google.com [IPv6:2607:f8b0:4864:20::f30]) by gabe.freedesktop.org (Postfix) with ESMTPS id 938736E45D for ; Wed, 20 Jan 2021 20:35:38 +0000 (UTC) Received: by mail-qv1-xf30.google.com with SMTP id s6so11559268qvn.6 for ; Wed, 20 Jan 2021 12:35:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=Z0QoUnMigHZv62iqBIHVw3IzALde+Sr2xiVtJxAC/JA=; b=hRm+u1Ec/AFUit6iuIVxpXiDikz7HhehQDfrW0OBud7m3m2qxq7sRTjVn0SWV9wfw+ zgcxp2Vb246+0c0qfFipKHsI+d1nB/7/Xv5ubRaNZUt5/4uSFw0hwaBMnL/KJXoIdBhQ Y+NeUr9aZZwhS87eFR18MW7ACq9xcJxCsg8uB6JwDbzNDRgQNx0QGp4bUCvxkVTwgGNu j9wZkbHpATMBZBmgab1GWsmeYaUGyuI3W15JeNgGprusnojdV4s5HIVUwylhBSKGf2b2 qgTtFO74fzr/y5vsOaElQcinrWxEobz58GGB/UesnN2IhMUU3gKwLJ5+AbXbMkUIi6Bw J71A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=Z0QoUnMigHZv62iqBIHVw3IzALde+Sr2xiVtJxAC/JA=; b=hAauY6kwWUMar9Yhn2qAMz7y/evjiNceyRM0F9GYCd+eLm8znQKWVKv1G4lnc/yCjF t+KvptEkZ6IWN5zKMnt3cNXoaJZeYnQo7khopHhBto6KZJYZHSQfAyzXX3x0NNvR0kQu byN0wJBkOy8GxR6FhLsYXQ7cx+DrBUOmhAQShmb78HVTauBRYvLBgdnvLg6T9Tnx+yfm fN4ySOSqZ6t5HpWOM9nfb+QH2CymXI8myvijj19feowNSNuQ3l+wMCx26hvQFIbx9b63 DQ2NcNI1gGixVDuTAAESXASAPg/TavqWuKFjWZJUX4bHLkMIUA/GIpRhM0Q7Wb7iGCbU NaVQ== X-Gm-Message-State: AOAM533DBA6yc3gs6E0+/gxqQ7L1eyXhV9RYFA95MsLd1El6u+nZpDyD XoT2RHLUOTKTCS0eQJxFmbsHa5quiS4T2b8cRQro6Q== X-Google-Smtp-Source: ABdhPJxFSrvkUPhzivgN09xn5QczRNY8sy5obem5udP1jEXDUeCqoC6zTMeC4yFMw/DzDQhTFoBNajuC3vbG7HcpCpY= X-Received: by 2002:a0c:8203:: with SMTP id h3mr11117071qva.0.1611174937158; Wed, 20 Jan 2021 12:35:37 -0800 (PST) MIME-Version: 1.0 References: <20210119225723.388883-1-hridya@google.com> In-Reply-To: From: Hridya Valsaraju Date: Wed, 20 Jan 2021 12:34:59 -0800 Message-ID: Subject: Re: [Linaro-mm-sig] [PATCH v2] dmabuf: Add the capability to expose DMA-BUF stats in sysfs To: Daniel Vetter X-Mailman-Approved-At: Thu, 21 Jan 2021 08:52:32 +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: Android Kernel Team , Suren Baghdasaryan , Linux Kernel Mailing List , dri-devel , "moderated list:DMA BUFFER SHARING FRAMEWORK" , Hyesoo Yu , Greg KH , Yiwei Zhang , =?UTF-8?Q?Christian_K=C3=B6nig?= , "open list:DMA BUFFER SHARING FRAMEWORK" Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" T24gV2VkLCBKYW4gMjAsIDIwMjEgYXQgNDo0MiBBTSBEYW5pZWwgVmV0dGVyIDxkYW5pZWxAZmZ3 bGwuY2g+IHdyb3RlOgo+Cj4gT24gV2VkLCBKYW4gMjAsIDIwMjEgYXQgMToyMiBQTSBDaHJpc3Rp YW4gS8O2bmlnCj4gPGNrb2VuaWcubGVpY2h0enVtZXJrZW5AZ21haWwuY29tPiB3cm90ZToKPiA+ Cj4gPiBBbSAxOS4wMS4yMSB1bSAyMzo1NyBzY2hyaWViIEhyaWR5YSBWYWxzYXJhanU6Cj4gPiA+ IFRoaXMgcGF0Y2ggYWxsb3dzIHN0YXRpc3RpY3MgdG8gYmUgZW5hYmxlZCBmb3IgZWFjaCBETUEt QlVGIGluCj4gPiA+IHN5c2ZzIGJ5IGVuYWJsaW5nIHRoZSBjb25maWcgQ09ORklHX0RNQUJVRl9T WVNGU19TVEFUUy4KPiA+ID4KPiA+ID4gVGhlIGZvbGxvd2luZyBzdGF0cyB3aWxsIGJlIGV4cG9z ZWQgYnkgdGhlIGludGVyZmFjZToKPiA+ID4KPiA+ID4gL3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZl cnMvPGlub2RlX251bWJlcj4vZXhwb3J0ZXJfbmFtZQo+ID4gPiAvc3lzL2tlcm5lbC9kbWFidWYv YnVmZmVycy88aW5vZGVfbnVtYmVyPi9zaXplCj4gPiA+IC9zeXMva2VybmVsL2RtYWJ1Zi9idWZm ZXJzLzxpbm9kZV9udW1iZXI+L2F0dGFjaG1lbnRzLzxhdHRhY2hfdWlkPi9kZXZpY2UKPiA+ID4g L3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZlcnMvPGlub2RlX251bWJlcj4vYXR0YWNobWVudHMvPGF0 dGFjaF91aWQ+L21hcF9jb3VudGVyCj4gPiA+Cj4gPiA+IFRoZSBpbm9kZV9udW1iZXIgaXMgdW5p cXVlIGZvciBlYWNoIERNQS1CVUYgYW5kIHdhcyBhZGRlZCBlYXJsaWVyIFsxXQo+ID4gPiBpbiBv cmRlciB0byBhbGxvdyB1c2Vyc3BhY2UgdG8gdHJhY2sgRE1BLUJVRiB1c2FnZSBhY3Jvc3MgZGlm ZmVyZW50Cj4gPiA+IHByb2Nlc3Nlcy4KPiA+ID4KPiA+ID4gQ3VycmVudGx5LCB0aGlzIGluZm9y bWF0aW9uIGlzIGV4cG9zZWQgaW4KPiA+ID4gL3N5cy9rZXJuZWwvZGVidWcvZG1hX2J1Zi9idWZp bmZvLgo+ID4gPiBIb3dldmVyLCBzaW5jZSBkZWJ1Z2ZzIGlzIGNvbnNpZGVyZWQgdW5zYWZlIHRv IGJlIG1vdW50ZWQgaW4gcHJvZHVjdGlvbiwKPiA+ID4gaXQgaXMgYmVpbmcgZHVwbGljYXRlZCBp biBzeXNmcy4KPiA+ID4KPiA+ID4gVGhpcyBpbmZvcm1hdGlvbiB3aWxsIGJlIHVzZWQgdG8gZGVy aXZlIERNQS1CVUYKPiA+ID4gcGVyLWV4cG9ydGVyIHN0YXRzIGFuZCBwZXItZGV2aWNlIHVzYWdl IHN0YXRzIGZvciBBbmRyb2lkIEJ1ZyByZXBvcnRzLgo+ID4gPiBUaGUgY29ycmVzcG9uZGluZyB1 c2Vyc3BhY2UgY2hhbmdlcyBjYW4gYmUgZm91bmQgYXQgWzJdLgo+ID4gPiBUZWxlbWV0cnkgdG9v bHMgd2lsbCBhbHNvIGNhcHR1cmUgdGhpcyBpbmZvcm1hdGlvbihhbG9uZyB3aXRoIG90aGVyCj4g PiA+IG1lbW9yeSBtZXRyaWNzKSBwZXJpb2RpY2FsbHkgYXMgd2VsbCBhcyBvbiBpbXBvcnRhbnQg ZXZlbnRzIGxpa2UgYQo+ID4gPiBmb3JlZ3JvdW5kIGFwcCBraWxsICh3aGljaCBtaWdodCBoYXZl IGJlZW4gdHJpZ2dlcmVkIGJ5IExvdyBNZW1vcnkKPiA+ID4gS2lsbGVyKS4gSXQgd2lsbCBhbHNv IGNvbnRyaWJ1dGUgdG8gcHJvdmlkZSBhIHNuYXBzaG90IG9mIHRoZSBzeXN0ZW0KPiA+ID4gbWVt b3J5IHVzYWdlIG9uIG90aGVyIGV2ZW50cyBzdWNoIGFzIE9PTSBraWxscyBhbmQgQXBwbGljYXRp b24gTm90Cj4gPiA+IFJlc3BvbmRpbmcgZXZlbnRzLgo+ID4gPgo+ID4gPiBBIHNoZWxsIHNjcmlw dCB0aGF0IGNhbiBiZSBydW4gb24gYSBjbGFzc2ljIExpbnV4IGVudmlyb25tZW50IHRvIHJlYWQK PiA+ID4gb3V0IHRoZSBETUEtQlVGIHN0YXRpc3RpY3MgY2FuIGJlIGZvdW5kIGF0IFszXShzdWdn ZXN0ZWQgYnkgSm9obgo+ID4gPiBTdHVsdHopLgo+ID4gPgo+ID4gPiBUaGUgcGF0Y2ggY29udGFp bnMgdGhlIGZvbGxvd2luZyBpbXByb3ZlbWVudHMgb3ZlciB0aGUgcHJldmlvdXMgdmVyc2lvbjoK PiA+ID4gMSkgRWFjaCBhdHRhY2htZW50IGlzIHJlcHJlc2VudGVkIGJ5IGl0cyBvd24gZGlyZWN0 b3J5IHRvIGFsbG93IGNyZWF0aW5nCj4gPiA+IGEgc3ltbGluayB0byB0aGUgaW1wb3J0aW5nIGRl dmljZSBhbmQgdG8gYWxzbyBwcm92aWRlIHJvb20gZm9yIGZ1dHVyZQo+ID4gPiBleHBhbnNpb24u Cj4gPiA+IDIpIFRoZSBudW1iZXIgb2YgZGlzdGluY3QgbWFwcGluZ3Mgb2YgZWFjaCBhdHRhY2ht ZW50IGlzIGV4cG9zZWQgaW4gYQo+ID4gPiBzZXBhcmF0ZSBmaWxlLgo+ID4gPiAzKSBUaGUgcGVy LWJ1ZmZlciBzdGF0aXN0aWNzIGFyZSBub3cgaW4gL3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZlcnMK PiA+ID4gaW5vcmRlciB0byBtYWtlIHRoZSBpbnRlcmZhY2UgZXhwYW5kYWJsZSBpbiBmdXR1cmUu Cj4gPiA+Cj4gPiA+IEFsbCBvZiB0aGUgaW1wcm92ZW1lbnRzIGFib3ZlIGFyZSBiYXNlZCBvbiBz dWdnZXN0aW9ucy9mZWVkYmFjayBmcm9tCj4gPiA+IERhbmllbCBWZXR0ZXIgYW5kIENocmlzdGlh biBLw7ZuaWcuCj4gPiA+Cj4gPiA+IFsxXTogaHR0cHM6Ly9sb3JlLmtlcm5lbC5vcmcvcGF0Y2h3 b3JrL3BhdGNoLzEwODg3OTEvCj4gPiA+IFsyXTogaHR0cHM6Ly9hbmRyb2lkLXJldmlldy5nb29n bGVzb3VyY2UuY29tL3EvdG9waWM6JTIyZG1hYnVmLXN5c2ZzJTIyKyhzdGF0dXM6b3BlbiUyME9S JTIwc3RhdHVzOm1lcmdlZCkKPiA+ID4gWzNdOiBodHRwczovL2FuZHJvaWQtcmV2aWV3Lmdvb2ds ZXNvdXJjZS5jb20vYy9wbGF0Zm9ybS9zeXN0ZW0vbWVtb3J5L2xpYm1lbWluZm8vKy8xNTQ5NzM0 Cj4gPiA+Cj4gPiA+IFNpZ25lZC1vZmYtYnk6IEhyaWR5YSBWYWxzYXJhanUgPGhyaWR5YUBnb29n bGUuY29tPgo+ID4gPiAtLS0KPiA+ID4gQ2hhbmdlcyBpbiB2MjoKPiA+ID4gLU1vdmUgc3RhdGlz dGljcyB0byAvc3lzL2tlcm5lbC9kbWFidWYvYnVmZmVycyBpbiBvZGVyIHRvIGFsbG93IGFkZGl0 aW9uCj4gPiA+IG9mIG90aGVyIERNQS1CVUYtcmVsYXRlZCBzeXNmcyBzdGF0cyBpbiBmdXR1cmUu IEJhc2VkIG9uIGZlZWRiYWNrIGZyb20KPiA+ID4gRGFuaWVsIFZldHRlci4KPiA+ID4gLUVhY2gg YXR0YWNobWVudCBoYXMgaXRzIG93biBkaXJlY3RvcnkgdG8gcmVwcmVzZW50IGF0dGFjaGluZyBk ZXZpY2VzIGFzCj4gPiA+IHN5bWxpbmtzIGFuZCB0byBpbnRyb2R1Y2UgbWFwX2NvdW50IGFzIGEg c2VwYXJhdGUgZmlsZS4gQmFzZWQgb24KPiA+ID4gZmVlZGJhY2sgZnJvbSBEYW5pZWwgVmV0dGVy IGFuZCBDaHJpc3RpYW4gS8O2bmlnLiBUaGFuayB5b3UgYm90aCEKPiA+ID4gLUNvbW1pdCBtZXNz YWdlcyB1cGRhdGVkIHRvIHBvaW50IHRvIHVzZXJzcGFjZSBjb2RlIGluIEFPU1AgdGhhdCB3aWxs Cj4gPiA+IHJlYWQgdGhlIERNQS1CVUYgc3lzZnMgc3RhdHMuCj4gPiA+Cj4gPiA+ICAgLi4uL0FC SS90ZXN0aW5nL3N5c2ZzLWtlcm5lbC1kbWFidWYtYnVmZmVycyAgIHwgIDUyICsrKysKPiA+ID4g ICBkcml2ZXJzL2RtYS1idWYvS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgfCAgMTEgKwo+ ID4gPiAgIGRyaXZlcnMvZG1hLWJ1Zi9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAgICB8ICAg MSArCj4gPiA+ICAgZHJpdmVycy9kbWEtYnVmL2RtYS1idWYtc3lzZnMtc3RhdHMuYyAgICAgICAg IHwgMjgzICsrKysrKysrKysrKysrKysrKwo+ID4gPiAgIGRyaXZlcnMvZG1hLWJ1Zi9kbWEtYnVm LXN5c2ZzLXN0YXRzLmggICAgICAgICB8ICA2MiArKysrCj4gPiA+ICAgZHJpdmVycy9kbWEtYnVm L2RtYS1idWYuYyAgICAgICAgICAgICAgICAgICAgIHwgIDM3ICsrKwo+ID4gPiAgIGluY2x1ZGUv bGludXgvZG1hLWJ1Zi5oICAgICAgICAgICAgICAgICAgICAgICB8ICAyMCArKwo+ID4gPiAgIDcg ZmlsZXMgY2hhbmdlZCwgNDY2IGluc2VydGlvbnMoKykKPiA+ID4gICBjcmVhdGUgbW9kZSAxMDA2 NDQgRG9jdW1lbnRhdGlvbi9BQkkvdGVzdGluZy9zeXNmcy1rZXJuZWwtZG1hYnVmLWJ1ZmZlcnMK PiA+ID4gICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9kbWEtYnVmL2RtYS1idWYtc3lzZnMt c3RhdHMuYwo+ID4gPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2RtYS1idWYvZG1hLWJ1 Zi1zeXNmcy1zdGF0cy5oCj4gPiA+Cj4gPiA+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL0FC SS90ZXN0aW5nL3N5c2ZzLWtlcm5lbC1kbWFidWYtYnVmZmVycyBiL0RvY3VtZW50YXRpb24vQUJJ L3Rlc3Rpbmcvc3lzZnMta2VybmVsLWRtYWJ1Zi1idWZmZXJzCj4gPiA+IG5ldyBmaWxlIG1vZGUg MTAwNjQ0Cj4gPiA+IGluZGV4IDAwMDAwMDAwMDAwMC4uNmY3YzY1MjA5ZjA3Cj4gPiA+IC0tLSAv ZGV2L251bGwKPiA+ID4gKysrIGIvRG9jdW1lbnRhdGlvbi9BQkkvdGVzdGluZy9zeXNmcy1rZXJu ZWwtZG1hYnVmLWJ1ZmZlcnMKPiA+ID4gQEAgLTAsMCArMSw1MiBAQAo+ID4gPiArV2hhdDogICAg ICAgICAgICAgICAgL3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZlcnMKPiA+ID4gK0RhdGU6ICAgICAg ICAgICAgICAgIEphbnVhcnkgMjAyMQo+ID4gPiArS2VybmVsVmVyc2lvbjogICAgICAgdjUuMTIK PiA+ID4gK0NvbnRhY3Q6ICAgICBIcmlkeWEgVmFsc2FyYWp1IDxocmlkeWFAZ29vZ2xlLmNvbT4K PiA+ID4gK0Rlc2NyaXB0aW9uOiBUaGUgL3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZlcnMgZGlyZWN0 b3J5IGNvbnRhaW5zIGEKPiA+ID4gKyAgICAgICAgICAgICBzbmFwc2hvdCBvZiB0aGUgaW50ZXJu YWwgc3RhdGUgb2YgZXZlcnkgRE1BLUJVRi4KPiA+ID4gKyAgICAgICAgICAgICAvc3lzL2tlcm5l bC9kbWFidWYvYnVmZmVycy88aW5vZGVfbnVtYmVyPiB3aWxsIGNvbnRhaW4gdGhlCj4gPiA+ICsg ICAgICAgICAgICAgc3RhdGlzdGljcyBmb3IgdGhlIERNQS1CVUYgd2l0aCB0aGUgdW5pcXVlIGlu b2RlIG51bWJlcgo+ID4gPiArICAgICAgICAgICAgIDxpbm9kZV9udW1iZXI+Cj4gPiA+ICtVc2Vy czogICAgICAgICAgICAgICBrZXJuZWwgbWVtb3J5IHR1bmluZy9kZWJ1Z2dpbmcgdG9vbHMKPiA+ ID4gKwo+ID4gPiArV2hhdDogICAgICAgICAgICAgICAgL3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZl cnMvPGlub2RlX251bWJlcj4vZXhwb3J0ZXJfbmFtZQo+ID4gPiArRGF0ZTogICAgICAgICAgICAg ICAgSmFudWFyeSAyMDIxCj4gPiA+ICtLZXJuZWxWZXJzaW9uOiAgICAgICB2NS4xMgo+ID4gPiAr Q29udGFjdDogICAgIEhyaWR5YSBWYWxzYXJhanUgPGhyaWR5YUBnb29nbGUuY29tPgo+ID4gPiAr RGVzY3JpcHRpb246IFRoaXMgZmlsZSBpcyByZWFkLW9ubHkgYW5kIGNvbnRhaW5zIHRoZSBuYW1l IG9mIHRoZSBleHBvcnRlciBvZgo+ID4gPiArICAgICAgICAgICAgIHRoZSBETUEtQlVGLgo+ID4g PiArCj4gPiA+ICtXaGF0OiAgICAgICAgICAgICAgICAvc3lzL2tlcm5lbC9kbWFidWYvYnVmZmVy cy88aW5vZGVfbnVtYmVyPi9zaXplCj4gPiA+ICtEYXRlOiAgICAgICAgICAgICAgICBKYW51YXJ5 IDIwMjEKPiA+ID4gK0tlcm5lbFZlcnNpb246ICAgICAgIHY1LjEyCj4gPiA+ICtDb250YWN0OiAg ICAgSHJpZHlhIFZhbHNhcmFqdSA8aHJpZHlhQGdvb2dsZS5jb20+Cj4gPiA+ICtEZXNjcmlwdGlv bjogVGhpcyBmaWxlIGlzIHJlYWQtb25seSBhbmQgc3BlY2lmaWVzIHRoZSBzaXplIG9mIHRoZSBE TUEtQlVGIGluCj4gPiA+ICsgICAgICAgICAgICAgYnl0ZXMuCj4gPiA+ICsKPiA+ID4gK1doYXQ6 ICAgICAgICAgICAgICAgIC9zeXMva2VybmVsL2RtYWJ1Zi9idWZmZXJzLzxpbm9kZV9udW1iZXI+ L2F0dGFjaG1lbnRzCj4gPiA+ICtEYXRlOiAgICAgICAgICAgICAgICBKYW51YXJ5IDIwMjEKPiA+ ID4gK0tlcm5lbFZlcnNpb246ICAgICAgIHY1LjEyCj4gPiA+ICtDb250YWN0OiAgICAgSHJpZHlh IFZhbHNhcmFqdSA8aHJpZHlhQGdvb2dsZS5jb20+Cj4gPiA+ICtEZXNjcmlwdGlvbjogVGhpcyBk aXJlY3Rvcnkgd2lsbCBjb250YWluIHN1YmRpcmVjdG9yaWVzIHJlcHJlc2VudGluZyBldmVyeQo+ ID4gPiArICAgICAgICAgICAgIGF0dGFjaG1lbnQgb2YgdGhlIERNQS1CVUYuCj4gPiA+ICsKPiA+ ID4gK1doYXQ6ICAgICAgICAgICAgICAgIC9zeXMva2VybmVsL2RtYWJ1Zi9idWZmZXJzLzxpbm9k ZV9udW1iZXI+L2F0dGFjaG1lbnRzLzxhdHRhY2htZW50X3VpZD4KPiA+ID4gK0RhdGU6ICAgICAg ICAgICAgICAgIEphbnVhcnkgMjAyMQo+ID4gPiArS2VybmVsVmVyc2lvbjogICAgICAgdjUuMTIK PiA+ID4gK0NvbnRhY3Q6ICAgICBIcmlkeWEgVmFsc2FyYWp1IDxocmlkeWFAZ29vZ2xlLmNvbT4K PiA+ID4gK0Rlc2NyaXB0aW9uOiBUaGlzIGRpcmVjdG9yeSB3aWxsIGNvbnRhaW4gaW5mb3JtYXRp b24gb24gdGhlIGF0dGFjaGluZyBkZXZpY2UKPiA+ID4gKyAgICAgICAgICAgICBhbmQgdGhlIG51 bWJlciBvZiBjdXJyZW50IGRpc3RpbmN0IGRldmljZSBtYXBwaW5ncy4KPiA+ID4gKwo+ID4gPiAr V2hhdDogICAgICAgICAgICAgICAgL3N5cy9rZXJuZWwvZG1hYnVmL2J1ZmZlcnMvPGlub2RlX251 bWJlcj4vYXR0YWNobWVudHMvPGF0dGFjaG1lbnRfdWlkPi9kZXZpY2UKPiA+ID4gK0RhdGU6ICAg ICAgICAgICAgICAgIEphbnVhcnkgMjAyMQo+ID4gPiArS2VybmVsVmVyc2lvbjogICAgICAgdjUu MTIKPiA+ID4gK0NvbnRhY3Q6ICAgICBIcmlkeWEgVmFsc2FyYWp1IDxocmlkeWFAZ29vZ2xlLmNv bT4KPiA+ID4gK0Rlc2NyaXB0aW9uOiBUaGlzIGZpbGUgaXMgcmVhZC1vbmx5IGFuZCBpcyBhIHN5 bWxpbmsgdG8gdGhlIGF0dGFjaGluZyBkZXZpY2VzJ3MKPiA+ID4gKyAgICAgICAgICAgICBzeXNm cyBlbnRyeS4KPiA+ID4gKwo+ID4gPiArV2hhdDogICAgICAgICAgICAgICAgL3N5cy9rZXJuZWwv ZG1hYnVmL2J1ZmZlcnMvPGlub2RlX251bWJlcj4vYXR0YWNobWVudHMvPGF0dGFjaG1lbnRfdWlk Pi9tYXBfY291bnRlcgo+ID4gPiArRGF0ZTogICAgICAgICAgICAgICAgSmFudWFyeSAyMDIxCj4g PiA+ICtLZXJuZWxWZXJzaW9uOiAgICAgICB2NS4xMgo+ID4gPiArQ29udGFjdDogICAgIEhyaWR5 YSBWYWxzYXJhanUgPGhyaWR5YUBnb29nbGUuY29tPgo+ID4gPiArRGVzY3JpcHRpb246IFRoaXMg ZmlsZSBpcyByZWFkLW9ubHkgYW5kIGNvbnRhaW5zIGEgbWFwX2NvdW50ZXIgaW5kaWNhdGluZyB0 aGUKPiA+ID4gKyAgICAgICAgICAgICBudW1iZXIgb2YgZGlzdGluY3QgZGV2aWNlIG1hcHBpbmdz IG9mIHRoZSBhdHRhY2htZW50Lgo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9kbWEtYnVmL0tj b25maWcgYi9kcml2ZXJzL2RtYS1idWYvS2NvbmZpZwo+ID4gPiBpbmRleCA0ZjgyMjRhNmFjOTUu LjI3ZTZhMmRhZmVhYSAxMDA2NDQKPiA+ID4gLS0tIGEvZHJpdmVycy9kbWEtYnVmL0tjb25maWcK PiA+ID4gKysrIGIvZHJpdmVycy9kbWEtYnVmL0tjb25maWcKPiA+ID4gQEAgLTY0LDYgKzY0LDE3 IEBAIG1lbnVjb25maWcgRE1BQlVGX0hFQVBTCj4gPiA+ICAgICAgICAgYWxsb3dzIHVzZXJzcGFj ZSB0byBhbGxvY2F0ZSBkbWEtYnVmcyB0aGF0IGNhbiBiZSBzaGFyZWQKPiA+ID4gICAgICAgICBi ZXR3ZWVuIGRyaXZlcnMuCj4gPiA+Cj4gPiA+ICttZW51Y29uZmlnIERNQUJVRl9TWVNGU19TVEFU Uwo+ID4gPiArICAgICBib29sICJETUEtQlVGIHN5c2ZzIHN0YXRpc3RpY3MiCj4gPiA+ICsgICAg IHNlbGVjdCBETUFfU0hBUkVEX0JVRkZFUgo+ID4gPiArICAgICBoZWxwCj4gPiA+ICsgICAgICAg IENob29zZSB0aGlzIG9wdGlvbiB0byBlbmFibGUgRE1BLUJVRiBzeXNmcyBzdGF0aXN0aWNzCj4g PiA+ICsgICAgICAgIGluIGxvY2F0aW9uIC9zeXMva2VybmVsL2RtYWJ1Zi9idWZmZXJzLgo+ID4g PiArCj4gPiA+ICsgICAgICAgIC9zeXMva2VybmVsL2RtYWJ1Zi9idWZmZXJzLzxpbm9kZV9udW1i ZXI+IHdpbGwgY29udGFpbgo+ID4gPiArICAgICAgICBzdGF0aXN0aWNzIGZvciB0aGUgRE1BLUJV RiB3aXRoIHRoZSB1bmlxdWUgaW5vZGUgbnVtYmVyCj4gPiA+ICsgICAgICAgIDxpbm9kZV9udW1i ZXI+Lgo+ID4gPiArCj4gPiA+ICAgc291cmNlICJkcml2ZXJzL2RtYS1idWYvaGVhcHMvS2NvbmZp ZyIKPiA+ID4KPiA+ID4gICBlbmRtZW51Cj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS1i dWYvTWFrZWZpbGUgYi9kcml2ZXJzL2RtYS1idWYvTWFrZWZpbGUKPiA+ID4gaW5kZXggOTk1ZTA1 ZjYwOWZmLi40MGQ4MWYyM2NhY2YgMTAwNjQ0Cj4gPiA+IC0tLSBhL2RyaXZlcnMvZG1hLWJ1Zi9N YWtlZmlsZQo+ID4gPiArKysgYi9kcml2ZXJzL2RtYS1idWYvTWFrZWZpbGUKPiA+ID4gQEAgLTYs NiArNiw3IEBAIG9iai0kKENPTkZJR19ETUFCVUZfSEVBUFMpICAgICs9IGhlYXBzLwo+ID4gPiAg IG9iai0kKENPTkZJR19TWU5DX0ZJTEUpICAgICAgICAgICAgICs9IHN5bmNfZmlsZS5vCj4gPiA+ ICAgb2JqLSQoQ09ORklHX1NXX1NZTkMpICAgICAgICAgICAgICAgKz0gc3dfc3luYy5vIHN5bmNf ZGVidWcubwo+ID4gPiAgIG9iai0kKENPTkZJR19VRE1BQlVGKSAgICAgICAgICAgICAgICs9IHVk bWFidWYubwo+ID4gPiArb2JqLSQoQ09ORklHX0RNQUJVRl9TWVNGU19TVEFUUykgKz0gZG1hLWJ1 Zi1zeXNmcy1zdGF0cy5vCj4gPiA+Cj4gPiA+ICAgZG1hYnVmX3NlbGZ0ZXN0cy15IDo9IFwKPiA+ ID4gICAgICAgc2VsZnRlc3QubyBcCj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS1idWYv ZG1hLWJ1Zi1zeXNmcy1zdGF0cy5jIGIvZHJpdmVycy9kbWEtYnVmL2RtYS1idWYtc3lzZnMtc3Rh dHMuYwo+ID4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+ID4gPiBpbmRleCAwMDAwMDAwMDAwMDAu LjYxZjg1YzNkMTZhNQo+ID4gPiAtLS0gL2Rldi9udWxsCj4gPiA+ICsrKyBiL2RyaXZlcnMvZG1h LWJ1Zi9kbWEtYnVmLXN5c2ZzLXN0YXRzLmMKPiA+ID4gQEAgLTAsMCArMSwyODMgQEAKPiA+ID4g Ky8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkKPiA+ID4gKy8qCj4gPiA+ ICsgKiBETUEtQlVGIHN5c2ZzIHN0YXRpc3RpY3MuCj4gPiA+ICsgKgo+ID4gPiArICogQ29weXJp Z2h0IChDKSAyMDIxIEdvb2dsZSBMTEMuCj4gPiA+ICsgKi8KPiA+ID4gKwo+ID4gPiArI2luY2x1 ZGUgPGxpbnV4L2RtYS1idWYuaD4KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9kbWEtcmVzdi5oPgo+ ID4gPiArI2luY2x1ZGUgPGxpbnV4L2tvYmplY3QuaD4KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9w cmludGsuaD4KPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gPiA+ICsjaW5jbHVkZSA8 bGludXgvc3lzZnMuaD4KPiA+ID4gKwo+ID4gPiArI2RlZmluZSB0b19kbWFfYnVmX2VudHJ5X2Zy b21fa29iaih4KSBjb250YWluZXJfb2YoeCwgc3RydWN0IGRtYV9idWZfc3lzZnNfZW50cnksIGtv YmopCj4gPiA+ICsKPiA+ID4gK3N0cnVjdCBkbWFfYnVmX3N0YXRzX2F0dHJpYnV0ZSB7Cj4gPiA+ ICsgICAgIHN0cnVjdCBhdHRyaWJ1dGUgYXR0cjsKPiA+ID4gKyAgICAgc3NpemVfdCAoKnNob3cp KHN0cnVjdCBkbWFfYnVmICpkbWFidWYsCj4gPiA+ICsgICAgICAgICAgICAgICAgICAgICBzdHJ1 Y3QgZG1hX2J1Zl9zdGF0c19hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1Zik7Cj4gPiA+ICt9Owo+ ID4gPiArI2RlZmluZSB0b19kbWFfYnVmX3N0YXRzX2F0dHIoeCkgY29udGFpbmVyX29mKHgsIHN0 cnVjdCBkbWFfYnVmX3N0YXRzX2F0dHJpYnV0ZSwgYXR0cikKPiA+ID4gKwo+ID4gPiArc3RhdGlj IHNzaXplX3QgZG1hX2J1Zl9zdGF0c19hdHRyaWJ1dGVfc2hvdyhzdHJ1Y3Qga29iamVjdCAqa29i aiwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0 IGF0dHJpYnV0ZSAqYXR0ciwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgY2hhciAqYnVmKQo+ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3QgZG1hX2J1Zl9z dGF0c19hdHRyaWJ1dGUgKmF0dHJpYnV0ZTsKPiA+ID4gKyAgICAgc3RydWN0IGRtYV9idWZfc3lz ZnNfZW50cnkgKnN5c2ZzX2VudHJ5Owo+ID4gPiArICAgICBzdHJ1Y3QgZG1hX2J1ZiAqZG1hYnVm Owo+ID4gPiArCj4gPiA+ICsgICAgIGF0dHJpYnV0ZSA9IHRvX2RtYV9idWZfc3RhdHNfYXR0cihh dHRyKTsKPiA+ID4gKyAgICAgc3lzZnNfZW50cnkgPSB0b19kbWFfYnVmX2VudHJ5X2Zyb21fa29i aihrb2JqKTsKPiA+ID4gKyAgICAgZG1hYnVmID0gc3lzZnNfZW50cnktPmRtYWJ1ZjsKPiA+ID4g Kwo+ID4gPiArICAgICBpZiAoIWRtYWJ1ZiB8fCAhYXR0cmlidXRlLT5zaG93KQo+ID4gPiArICAg ICAgICAgICAgIHJldHVybiAtRUlPOwo+ID4gPiArCj4gPiA+ICsgICAgIHJldHVybiBhdHRyaWJ1 dGUtPnNob3coZG1hYnVmLCBhdHRyaWJ1dGUsIGJ1Zik7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4g K3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc3lzZnNfb3BzIGRtYV9idWZfc3RhdHNfc3lzZnNfb3BzID0g ewo+ID4gPiArICAgICAuc2hvdyA9IGRtYV9idWZfc3RhdHNfYXR0cmlidXRlX3Nob3csCj4gPiA+ ICt9Owo+ID4gPiArCj4gPiA+ICtzdGF0aWMgc3NpemVfdCBleHBvcnRlcl9uYW1lX3Nob3coc3Ry dWN0IGRtYV9idWYgKmRtYWJ1ZiwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBzdHJ1Y3QgZG1hX2J1Zl9zdGF0c19hdHRyaWJ1dGUgKmF0dHIsCj4gPiA+ICsgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgY2hhciAqYnVmKQo+ID4gPiArewo+ID4gPiArICAgICByZXR1 cm4gc3lzZnNfZW1pdChidWYsICIlc1xuIiwgZG1hYnVmLT5leHBfbmFtZSk7Cj4gPiA+ICt9Cj4g PiA+ICsKPiA+ID4gK3N0YXRpYyBzc2l6ZV90IHNpemVfc2hvdyhzdHJ1Y3QgZG1hX2J1ZiAqZG1h YnVmLAo+ID4gPiArICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBkbWFfYnVmX3N0YXRzX2F0 dHJpYnV0ZSAqYXR0ciwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICBjaGFyICpidWYpCj4g PiA+ICt7Cj4gPiA+ICsgICAgIHJldHVybiBzeXNmc19lbWl0KGJ1ZiwgIiV6dVxuIiwgZG1hYnVm LT5zaXplKTsKPiA+ID4gK30KPiA+ID4gKwo+ID4gPiArc3RhdGljIHN0cnVjdCBkbWFfYnVmX3N0 YXRzX2F0dHJpYnV0ZSBleHBvcnRlcl9uYW1lX2F0dHJpYnV0ZSA9Cj4gPiA+ICsgICAgIF9fQVRU Ul9STyhleHBvcnRlcl9uYW1lKTsKPiA+ID4gK3N0YXRpYyBzdHJ1Y3QgZG1hX2J1Zl9zdGF0c19h dHRyaWJ1dGUgc2l6ZV9hdHRyaWJ1dGUgPSBfX0FUVFJfUk8oc2l6ZSk7Cj4gPiA+ICsKPiA+ID4g K3N0YXRpYyBzdHJ1Y3QgYXR0cmlidXRlICpkbWFfYnVmX3N0YXRzX2RlZmF1bHRfYXR0cnNbXSA9 IHsKPiA+ID4gKyAgICAgJmV4cG9ydGVyX25hbWVfYXR0cmlidXRlLmF0dHIsCj4gPiA+ICsgICAg ICZzaXplX2F0dHJpYnV0ZS5hdHRyLAo+ID4gPiArICAgICBOVUxMLAo+ID4gPiArfTsKPiA+ID4g K0FUVFJJQlVURV9HUk9VUFMoZG1hX2J1Zl9zdGF0c19kZWZhdWx0KTsKPiA+ID4gKwo+ID4gPiAr c3RhdGljIHZvaWQgZG1hX2J1Zl9zeXNmc19yZWxlYXNlKHN0cnVjdCBrb2JqZWN0ICprb2JqKQo+ ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3QgZG1hX2J1Zl9zeXNmc19lbnRyeSAqc3lzZnNfZW50 cnk7Cj4gPiA+ICsKPiA+ID4gKyAgICAgc3lzZnNfZW50cnkgPSB0b19kbWFfYnVmX2VudHJ5X2Zy b21fa29iaihrb2JqKTsKPiA+ID4gKyAgICAga2ZyZWUoc3lzZnNfZW50cnkpOwo+ID4gPiArfQo+ ID4gPiArCj4gPiA+ICtzdGF0aWMgc3RydWN0IGtvYmpfdHlwZSBkbWFfYnVmX2t0eXBlID0gewo+ ID4gPiArICAgICAuc3lzZnNfb3BzID0gJmRtYV9idWZfc3RhdHNfc3lzZnNfb3BzLAo+ID4gPiAr ICAgICAucmVsZWFzZSA9IGRtYV9idWZfc3lzZnNfcmVsZWFzZSwKPiA+ID4gKyAgICAgLmRlZmF1 bHRfZ3JvdXBzID0gZG1hX2J1Zl9zdGF0c19kZWZhdWx0X2dyb3VwcywKPiA+ID4gK307Cj4gPiA+ ICsKPiA+ID4gKyNkZWZpbmUgdG9fZG1hX2J1Zl9hdHRhY2hfZW50cnlfZnJvbV9rb2JqKHgpIGNv bnRhaW5lcl9vZih4LCBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2hfc3lzZnNfZW50cnksIGtvYmopCj4g PiA+ICsKPiA+ID4gK3N0cnVjdCBkbWFfYnVmX2F0dGFjaF9zdGF0c19hdHRyaWJ1dGUgewo+ID4g PiArICAgICBzdHJ1Y3QgYXR0cmlidXRlIGF0dHI7Cj4gPiA+ICsgICAgIHNzaXplX3QgKCpzaG93 KShzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2hfc3lzZnNfZW50cnkgKnN5c2ZzX2VudHJ5LAo+ID4gPiAr ICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRtYV9idWZfYXR0YWNoX3N0YXRzX2F0dHJpYnV0 ZSAqYXR0ciwgY2hhciAqYnVmKTsKPiA+ID4gK307Cj4gPiA+ICsjZGVmaW5lIHRvX2RtYV9idWZf YXR0YWNoX3N0YXRzX2F0dHIoeCkgY29udGFpbmVyX29mKHgsIHN0cnVjdCBkbWFfYnVmX2F0dGFj aF9zdGF0c19hdHRyaWJ1dGUsIGF0dHIpCj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBzc2l6ZV90IGRt YV9idWZfYXR0YWNoX3N0YXRzX2F0dHJpYnV0ZV9zaG93KHN0cnVjdCBrb2JqZWN0ICprb2JqLAo+ ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ry dWN0IGF0dHJpYnV0ZSAqYXR0ciwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIGNoYXIgKmJ1ZikKPiA+ID4gK3sKPiA+ID4gKyAgICAgc3RydWN0 IGRtYV9idWZfYXR0YWNoX3N0YXRzX2F0dHJpYnV0ZSAqYXR0cmlidXRlOwo+ID4gPiArICAgICBz dHJ1Y3QgZG1hX2J1Zl9hdHRhY2hfc3lzZnNfZW50cnkgKnN5c2ZzX2VudHJ5Owo+ID4gPiArCj4g PiA+ICsgICAgIGF0dHJpYnV0ZSA9IHRvX2RtYV9idWZfYXR0YWNoX3N0YXRzX2F0dHIoYXR0cik7 Cj4gPiA+ICsgICAgIHN5c2ZzX2VudHJ5ID0gdG9fZG1hX2J1Zl9hdHRhY2hfZW50cnlfZnJvbV9r b2JqKGtvYmopOwo+ID4gPiArCj4gPiA+ICsgICAgIGlmICghYXR0cmlidXRlLT5zaG93KQo+ID4g PiArICAgICAgICAgICAgIHJldHVybiAtRUlPOwo+ID4gPiArCj4gPiA+ICsgICAgIHJldHVybiBh dHRyaWJ1dGUtPnNob3coc3lzZnNfZW50cnksIGF0dHJpYnV0ZSwgYnVmKTsKPiA+ID4gK30KPiA+ ID4gKwo+ID4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBzeXNmc19vcHMgZG1hX2J1Zl9hdHRhY2hf c3RhdHNfc3lzZnNfb3BzID0gewo+ID4gPiArICAgICAuc2hvdyA9IGRtYV9idWZfYXR0YWNoX3N0 YXRzX2F0dHJpYnV0ZV9zaG93LAo+ID4gPiArfTsKPiA+ID4gKwo+ID4gPiArc3RhdGljIHNzaXpl X3QgbWFwX2NvdW50ZXJfc2hvdyhzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2hfc3lzZnNfZW50cnkgKnN5 c2ZzX2VudHJ5LAo+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZG1h X2J1Zl9hdHRhY2hfc3RhdHNfYXR0cmlidXRlICphdHRyLAo+ID4gPiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBjaGFyICpidWYpCj4gPiA+ICt7Cj4gPiA+ICsgICAgIHJldHVybiBzeXNm c19lbWl0KGJ1ZiwgIiV1XG4iLCBzeXNmc19lbnRyeS0+bWFwX2NvdW50ZXIpOwo+ID4gPiArfQo+ ID4gPiArCj4gPiA+ICtzdGF0aWMgc3RydWN0IGRtYV9idWZfYXR0YWNoX3N0YXRzX2F0dHJpYnV0 ZSBtYXBfY291bnRlcl9hdHRyaWJ1dGUgPQo+ID4gPiArICAgICBfX0FUVFJfUk8obWFwX2NvdW50 ZXIpOwo+ID4gPiArCj4gPiA+ICtzdGF0aWMgc3RydWN0IGF0dHJpYnV0ZSAqZG1hX2J1Zl9hdHRh Y2hfc3RhdHNfZGVmYXVsdF9hdHRyc1tdID0gewo+ID4gPiArICAgICAmbWFwX2NvdW50ZXJfYXR0 cmlidXRlLmF0dHIsCj4gPiA+ICsgICAgIE5VTEwsCj4gPiA+ICt9Owo+ID4gPiArQVRUUklCVVRF X0dST1VQUyhkbWFfYnVmX2F0dGFjaF9zdGF0c19kZWZhdWx0KTsKPiA+ID4gKwo+ID4gPiArc3Rh dGljIHZvaWQgZG1hX2J1Zl9hdHRhY2hfc3lzZnNfcmVsZWFzZShzdHJ1Y3Qga29iamVjdCAqa29i aikKPiA+ID4gK3sKPiA+ID4gKyAgICAgc3RydWN0IGRtYV9idWZfYXR0YWNoX3N5c2ZzX2VudHJ5 ICpzeXNmc19lbnRyeTsKPiA+ID4gKwo+ID4gPiArICAgICBzeXNmc19lbnRyeSA9IHRvX2RtYV9i dWZfYXR0YWNoX2VudHJ5X2Zyb21fa29iaihrb2JqKTsKPiA+ID4gKyAgICAga2ZyZWUoc3lzZnNf ZW50cnkpOwo+ID4gPiArfQo+ID4gPiArCj4gPiA+ICtzdGF0aWMgc3RydWN0IGtvYmpfdHlwZSBk bWFfYnVmX2F0dGFjaF9rdHlwZSA9IHsKPiA+ID4gKyAgICAgLnN5c2ZzX29wcyA9ICZkbWFfYnVm X2F0dGFjaF9zdGF0c19zeXNmc19vcHMsCj4gPiA+ICsgICAgIC5yZWxlYXNlID0gZG1hX2J1Zl9h dHRhY2hfc3lzZnNfcmVsZWFzZSwKPiA+ID4gKyAgICAgLmRlZmF1bHRfZ3JvdXBzID0gZG1hX2J1 Zl9hdHRhY2hfc3RhdHNfZGVmYXVsdF9ncm91cHMsCj4gPiA+ICt9Owo+ID4gPiArCj4gPiA+ICt2 b2lkIGRtYV9idWZfYXR0YWNoX3N0YXRzX3RlYXJkb3duKHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1l bnQgKmF0dGFjaCkKPiA+ID4gK3sKPiA+ID4gKyAgICAgc3RydWN0IGRtYV9idWZfYXR0YWNoX3N5 c2ZzX2VudHJ5ICpzeXNmc19lbnRyeTsKPiA+ID4gKwo+ID4gPiArICAgICBzeXNmc19lbnRyeSA9 IGF0dGFjaC0+c3lzZnNfZW50cnk7Cj4gPiA+ICsgICAgIGlmICghc3lzZnNfZW50cnkpCj4gPiA+ ICsgICAgICAgICAgICAgcmV0dXJuOwo+ID4gPiArCj4gPiA+ICsgICAgIHN5c2ZzX2RlbGV0ZV9s aW5rKCZzeXNmc19lbnRyeS0+a29iaiwgJmF0dGFjaC0+ZGV2LT5rb2JqLCAiZGV2aWNlIik7Cj4g PiA+ICsKPiA+ID4gKyAgICAga29iamVjdF9kZWwoJnN5c2ZzX2VudHJ5LT5rb2JqKTsKPiA+ID4g KyAgICAga29iamVjdF9wdXQoJnN5c2ZzX2VudHJ5LT5rb2JqKTsKPiA+ID4gK30KPiA+ID4gKwo+ ID4gPiAraW50IGRtYV9idWZfYXR0YWNoX3N0YXRzX3NldHVwKHN0cnVjdCBkbWFfYnVmX2F0dGFj aG1lbnQgKmF0dGFjaCwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25l ZCBpbnQgdWlkKQo+ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2hfc3lz ZnNfZW50cnkgKnN5c2ZzX2VudHJ5Owo+ID4gPiArICAgICBpbnQgcmV0Owo+ID4gPiArICAgICBz dHJ1Y3QgZG1hX2J1ZiAqZG1hYnVmOwo+ID4gPiArCj4gPiA+ICsgICAgIGlmICghYXR0YWNoKQo+ ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+ID4gPiArCj4gPiA+ICsgICAgIGRt YWJ1ZiA9IGF0dGFjaC0+ZG1hYnVmOwo+ID4gPiArCj4gPiA+ICsgICAgIHN5c2ZzX2VudHJ5ID0g a3phbGxvYyhzaXplb2Yoc3RydWN0IGRtYV9idWZfYXR0YWNoX3N5c2ZzX2VudHJ5KSwKPiA+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgIEdGUF9LRVJORUwpOwo+ID4gPiArICAgICBpZiAo IXN5c2ZzX2VudHJ5KQo+ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRU5PTUVNOwo+ID4gPiAr Cj4gPiA+ICsgICAgIHN5c2ZzX2VudHJ5LT5rb2JqLmtzZXQgPSBkbWFidWYtPnN5c2ZzX2VudHJ5 LT5hdHRhY2hfc3RhdHNfa3NldDsKPiA+ID4gKwo+ID4gPiArICAgICBhdHRhY2gtPnN5c2ZzX2Vu dHJ5ID0gc3lzZnNfZW50cnk7Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0ID0ga29iamVjdF9pbml0 X2FuZF9hZGQoJnN5c2ZzX2VudHJ5LT5rb2JqLCAmZG1hX2J1Zl9hdHRhY2hfa3R5cGUsCj4gPiA+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICIldSIsIHVpZCk7Cj4gPiA+ ICsgICAgIGlmIChyZXQpCj4gPiA+ICsgICAgICAgICAgICAgZ290byBrb2JqX2VycjsKPiA+ID4g Kwo+ID4gPiArICAgICByZXQgPSBzeXNmc19jcmVhdGVfbGluaygmc3lzZnNfZW50cnktPmtvYmos ICZhdHRhY2gtPmRldi0+a29iaiwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ImRldmljZSIpOwo+ID4gPiArICAgICBpZiAocmV0KQo+ID4gPiArICAgICAgICAgICAgIGdvdG8g bGlua19lcnI7Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICsKPiA+ID4gK2xp bmtfZXJyOgo+ID4gPiArICAgICBrb2JqZWN0X2RlbCgmc3lzZnNfZW50cnktPmtvYmopOwo+ID4g PiAra29ial9lcnI6Cj4gPiA+ICsgICAgIGtvYmplY3RfcHV0KCZzeXNmc19lbnRyeS0+a29iaik7 Cj4gPiA+ICsgICAgIGF0dGFjaC0+c3lzZnNfZW50cnkgPSBOVUxMOwo+ID4gPiArCj4gPiA+ICsg ICAgIHJldHVybiByZXQ7Cj4gPiA+ICt9Cj4gPiA+ICt2b2lkIGRtYV9idWZfc3RhdHNfdGVhcmRv d24oc3RydWN0IGRtYV9idWYgKmRtYWJ1ZikKPiA+ID4gK3sKPiA+ID4gKyAgICAgc3RydWN0IGRt YV9idWZfc3lzZnNfZW50cnkgKnN5c2ZzX2VudHJ5Owo+ID4gPiArCj4gPiA+ICsgICAgIHN5c2Zz X2VudHJ5ID0gZG1hYnVmLT5zeXNmc19lbnRyeTsKPiA+ID4gKyAgICAgaWYgKCFzeXNmc19lbnRy eSkKPiA+ID4gKyAgICAgICAgICAgICByZXR1cm47Cj4gPiA+ICsKPiA+ID4gKyAgICAga3NldF91 bnJlZ2lzdGVyKHN5c2ZzX2VudHJ5LT5hdHRhY2hfc3RhdHNfa3NldCk7Cj4gPiA+ICsgICAgIGtv YmplY3RfZGVsKCZzeXNmc19lbnRyeS0+a29iaik7Cj4gPiA+ICsgICAgIGtvYmplY3RfcHV0KCZz eXNmc19lbnRyeS0+a29iaik7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBzdHJ1Y3Qg a3NldCAqZG1hX2J1Zl9zdGF0c19rc2V0Owo+ID4gPiArc3RhdGljIHN0cnVjdCBrc2V0ICpkbWFf YnVmX3Blcl9idWZmZXJfc3RhdHNfa3NldDsKPiA+ID4gK2ludCBkbWFfYnVmX2luaXRfc3lzZnNf c3RhdGlzdGljcyh2b2lkKQo+ID4gPiArewo+ID4gPiArICAgICBkbWFfYnVmX3N0YXRzX2tzZXQg PSBrc2V0X2NyZWF0ZV9hbmRfYWRkKCJkbWFidWYiLCBOVUxMLCBrZXJuZWxfa29iaik7Cj4gPiA+ ICsgICAgIGlmICghZG1hX2J1Zl9zdGF0c19rc2V0KQo+ID4gPiArICAgICAgICAgICAgIHJldHVy biAtRU5PTUVNOwo+ID4gPiArCj4gPiA+ICsgICAgIGRtYV9idWZfcGVyX2J1ZmZlcl9zdGF0c19r c2V0ID0ga3NldF9jcmVhdGVfYW5kX2FkZCgiYnVmZmVycyIsIE5VTEwsCj4gPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZG1hX2J1 Zl9zdGF0c19rc2V0LT5rb2JqKTsKPiA+ID4gKyAgICAgaWYgKCFkbWFfYnVmX3Blcl9idWZmZXJf c3RhdHNfa3NldCkgewo+ID4gPiArICAgICAgICAgICAgIGtzZXRfdW5yZWdpc3RlcihkbWFfYnVm X3N0YXRzX2tzZXQpOwo+ID4gPiArICAgICAgICAgICAgIHJldHVybiAtRU5PTUVNOwo+ID4gPiAr ICAgICB9Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ ID4gK3ZvaWQgZG1hX2J1Zl91bmluaXRfc3lzZnNfc3RhdGlzdGljcyh2b2lkKQo+ID4gPiArewo+ ID4gPiArICAgICBrc2V0X3VucmVnaXN0ZXIoZG1hX2J1Zl9wZXJfYnVmZmVyX3N0YXRzX2tzZXQp Owo+ID4gPiArICAgICBrc2V0X3VucmVnaXN0ZXIoZG1hX2J1Zl9zdGF0c19rc2V0KTsKPiA+ID4g K30KPiA+ID4gKwo+ID4gPiAraW50IGRtYV9idWZfc3RhdHNfc2V0dXAoc3RydWN0IGRtYV9idWYg KmRtYWJ1ZikKPiA+ID4gK3sKPiA+ID4gKyAgICAgc3RydWN0IGRtYV9idWZfc3lzZnNfZW50cnkg KnN5c2ZzX2VudHJ5Owo+ID4gPiArICAgICBpbnQgcmV0Owo+ID4gPiArICAgICBzdHJ1Y3Qga3Nl dCAqYXR0YWNoX3N0YXRzX2tzZXQ7Cj4gPiA+ICsKPiA+ID4gKyAgICAgaWYgKCFkbWFidWYgfHwg IWRtYWJ1Zi0+ZmlsZSkKPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiA+ID4g Kwo+ID4gPiArICAgICBpZiAoIWRtYWJ1Zi0+ZXhwX25hbWUpIHsKPiA+ID4gKyAgICAgICAgICAg ICBwcl9lcnIoImV4cG9ydGVyIG5hbWUgbXVzdCBub3QgYmUgZW1wdHkgaWYgc3RhdHMgbmVlZGVk XG4iKTsKPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsKPiA+ID4gKyAgICAgfQo+ ID4gPiArCj4gPiA+ICsgICAgIHN5c2ZzX2VudHJ5ID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IGRt YV9idWZfc3lzZnNfZW50cnkpLCBHRlBfS0VSTkVMKTsKPiA+ID4gKyAgICAgaWYgKCFzeXNmc19l bnRyeSkKPiA+ID4gKyAgICAgICAgICAgICByZXR1cm4gLUVOT01FTTsKPiA+ID4gKwo+ID4gPiAr ICAgICBzeXNmc19lbnRyeS0+a29iai5rc2V0ID0gZG1hX2J1Zl9wZXJfYnVmZmVyX3N0YXRzX2tz ZXQ7Cj4gPiA+ICsgICAgIHN5c2ZzX2VudHJ5LT5kbWFidWYgPSBkbWFidWY7Cj4gPiA+ICsKPiA+ ID4gKyAgICAgZG1hYnVmLT5zeXNmc19lbnRyeSA9IHN5c2ZzX2VudHJ5Owo+ID4gPiArCj4gPiA+ ICsgICAgIC8qIGNyZWF0ZSB0aGUgZGlyZWN0b3J5IGZvciBidWZmZXIgc3RhdHMgKi8KPiA+ID4g KyAgICAgcmV0ID0ga29iamVjdF9pbml0X2FuZF9hZGQoJnN5c2ZzX2VudHJ5LT5rb2JqLCAmZG1h X2J1Zl9rdHlwZSwgTlVMTCwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IiVsdSIsIGZpbGVfaW5vZGUoZG1hYnVmLT5maWxlKS0+aV9pbm8pOwo+ID4gPiArICAgICBpZiAo cmV0KQo+ID4gPiArICAgICAgICAgICAgIGdvdG8gZXJyX3N5c2ZzX2RtYWJ1ZjsKPiA+ID4gKwo+ ID4gPiArICAgICAvKiBjcmVhdGUgdGhlIGRpcmVjdG9yeSBmb3IgYXR0YWNobWVudCBzdGF0cyAq Lwo+ID4gPiArICAgICBhdHRhY2hfc3RhdHNfa3NldCA9IGtzZXRfY3JlYXRlX2FuZF9hZGQoImF0 dGFjaG1lbnRzIiwgTlVMTCwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICZzeXNmc19lbnRyeS0+a29iaik7Cj4gPiA+ICsgICAgIGlmICghYXR0YWNo X3N0YXRzX2tzZXQpIHsKPiA+ID4gKyAgICAgICAgICAgICByZXQgPSAtRU5PTUVNOwo+ID4gPiAr ICAgICAgICAgICAgIGdvdG8gZXJyX3N5c2ZzX2F0dGFjaDsKPiA+ID4gKyAgICAgfQo+ID4gPiAr Cj4gPiA+ICsgICAgIHN5c2ZzX2VudHJ5LT5hdHRhY2hfc3RhdHNfa3NldCA9IGF0dGFjaF9zdGF0 c19rc2V0Owo+ID4gPiArCj4gPiA+ICsgICAgIHJldHVybiAwOwo+ID4gPiArCj4gPiA+ICtlcnJf c3lzZnNfYXR0YWNoOgo+ID4gPiArICAgICBrb2JqZWN0X2RlbCgmc3lzZnNfZW50cnktPmtvYmop Owo+ID4gPiArZXJyX3N5c2ZzX2RtYWJ1ZjoKPiA+ID4gKyAgICAga29iamVjdF9wdXQoJnN5c2Zz X2VudHJ5LT5rb2JqKTsKPiA+ID4gKyAgICAgZG1hYnVmLT5zeXNmc19lbnRyeSA9IE5VTEw7Cj4g PiA+ICsgICAgIHJldHVybiByZXQ7Cj4gPiA+ICt9Cj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2RtYS1idWYvZG1hLWJ1Zi1zeXNmcy1zdGF0cy5oIGIvZHJpdmVycy9kbWEtYnVmL2RtYS1idWYt c3lzZnMtc3RhdHMuaAo+ID4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+ID4gPiBpbmRleCAwMDAw MDAwMDAwMDAuLjVmNDcwMzI0OTExNwo+ID4gPiAtLS0gL2Rldi9udWxsCj4gPiA+ICsrKyBiL2Ry aXZlcnMvZG1hLWJ1Zi9kbWEtYnVmLXN5c2ZzLXN0YXRzLmgKPiA+ID4gQEAgLTAsMCArMSw2MiBA QAo+ID4gPiArLyogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb25seSAqLwo+ID4g PiArLyoKPiA+ID4gKyAqIERNQS1CVUYgc3lzZnMgc3RhdGlzdGljcy4KPiA+ID4gKyAqCj4gPiA+ ICsgKiBDb3B5cmlnaHQgKEMpIDIwMjEgR29vZ2xlIExMQy4KPiA+ID4gKyAqLwo+ID4gPiArCj4g PiA+ICsjaWZuZGVmIF9ETUFfQlVGX1NZU0ZTX1NUQVRTX0gKPiA+ID4gKyNkZWZpbmUgX0RNQV9C VUZfU1lTRlNfU1RBVFNfSAo+ID4gPiArCj4gPiA+ICsjaWZkZWYgQ09ORklHX0RNQUJVRl9TWVNG U19TVEFUUwo+ID4gPiArCj4gPiA+ICtpbnQgZG1hX2J1Zl9pbml0X3N5c2ZzX3N0YXRpc3RpY3Mo dm9pZCk7Cj4gPiA+ICt2b2lkIGRtYV9idWZfdW5pbml0X3N5c2ZzX3N0YXRpc3RpY3Modm9pZCk7 Cj4gPiA+ICsKPiA+ID4gK2ludCBkbWFfYnVmX3N0YXRzX3NldHVwKHN0cnVjdCBkbWFfYnVmICpk bWFidWYpOwo+ID4gPiAraW50IGRtYV9idWZfYXR0YWNoX3N0YXRzX3NldHVwKHN0cnVjdCBkbWFf YnVmX2F0dGFjaG1lbnQgKmF0dGFjaCwKPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICB1bnNpZ25lZCBpbnQgdWlkKTsKPiA+ID4gK3N0YXRpYyBpbmxpbmUgdm9pZCBkbWFfYnVmX3Vw ZGF0ZV9hdHRhY2htZW50X21hcF9jb3VudChzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICphdHRh Y2gsCj4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgaW50IGRlbHRhKQo+ID4gPiArewo+ID4gPiArICAgICBzdHJ1Y3QgZG1hX2J1Zl9hdHRh Y2hfc3lzZnNfZW50cnkgKmVudHJ5ID0gYXR0YWNoLT5zeXNmc19lbnRyeTsKPiA+ID4gKwo+ID4g PiArICAgICBlbnRyeS0+bWFwX2NvdW50ZXIgKz0gZGVsdGE7Cj4gPiA+ICt9Cj4gPiA+ICt2b2lk IGRtYV9idWZfc3RhdHNfdGVhcmRvd24oc3RydWN0IGRtYV9idWYgKmRtYWJ1Zik7Cj4gPiA+ICt2 b2lkIGRtYV9idWZfYXR0YWNoX3N0YXRzX3RlYXJkb3duKHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1l bnQgKmF0dGFjaCk7Cj4gPiA+ICtzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludCBkbWFfYnVmX3Vw ZGF0ZV9hdHRhY2hfdWlkKHN0cnVjdCBkbWFfYnVmICpkbWFidWYpCj4gPiA+ICt7Cj4gPiA+ICsg ICAgIHN0cnVjdCBkbWFfYnVmX3N5c2ZzX2VudHJ5ICplbnRyeSA9IGRtYWJ1Zi0+c3lzZnNfZW50 cnk7Cj4gPiA+ICsKPiA+ID4gKyAgICAgcmV0dXJuIGVudHJ5LT5hdHRhY2htZW50X3VpZCsrOwo+ ID4gPiArfQo+ID4gPiArI2Vsc2UKPiA+ID4gKwo+ID4gPiArc3RhdGljIGlubGluZSBpbnQgZG1h X2J1Zl9pbml0X3N5c2ZzX3N0YXRpc3RpY3Modm9pZCkKPiA+ID4gK3sKPiA+ID4gKyAgICAgcmV0 dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBpbmxpbmUgdm9pZCBkbWFfYnVm X3VuaW5pdF9zeXNmc19zdGF0aXN0aWNzKHZvaWQpIHt9Cj4gPiA+ICsKPiA+ID4gK3N0YXRpYyBp bmxpbmUgaW50IGRtYV9idWZfc3RhdHNfc2V0dXAoc3RydWN0IGRtYV9idWYgKmRtYWJ1ZikKPiA+ ID4gK3sKPiA+ID4gKyAgICAgcmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICtzdGF0aWMgaW5saW5l IGludCBkbWFfYnVmX2F0dGFjaF9zdGF0c19zZXR1cChzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50 ICphdHRhY2gsCj4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICB1bnNpZ25lZCBpbnQgdWlkKQo+ID4gPiArewo+ID4gPiArICAgICByZXR1cm4gMDsKPiA+ID4g K30KPiA+ID4gKwo+ID4gPiArc3RhdGljIGlubGluZSB2b2lkIGRtYV9idWZfc3RhdHNfdGVhcmRv d24oc3RydWN0IGRtYV9idWYgKmRtYWJ1Zikge30KPiA+ID4gK3N0YXRpYyBpbmxpbmUgdm9pZCBk bWFfYnVmX2F0dGFjaF9zdGF0c190ZWFyZG93bihzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICph dHRhY2gpIHt9Cj4gPiA+ICtzdGF0aWMgaW5saW5lIHZvaWQgZG1hX2J1Zl91cGRhdGVfYXR0YWNo bWVudF9tYXBfY291bnQoc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNoLAo+ID4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBk ZWx0YSkge30KPiA+ID4gK3N0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IGRtYV9idWZfdXBkYXRl X2F0dGFjaF91aWQoc3RydWN0IGRtYV9idWYgKmRtYWJ1ZikKPiA+ID4gK3sKPiA+ID4gKyAgICAg cmV0dXJuIDA7Cj4gPiA+ICt9Cj4gPiA+ICsjZW5kaWYKPiA+ID4gKyNlbmRpZiAvLyBfRE1BX0JV Rl9TWVNGU19TVEFUU19ICj4gPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS1idWYvZG1hLWJ1 Zi5jIGIvZHJpdmVycy9kbWEtYnVmL2RtYS1idWYuYwo+ID4gPiBpbmRleCA5YWQ2Mzk3YWFhOTcu LjI5ZjllYTE4ZWI0NyAxMDA2NDQKPiA+ID4gLS0tIGEvZHJpdmVycy9kbWEtYnVmL2RtYS1idWYu Ywo+ID4gPiArKysgYi9kcml2ZXJzL2RtYS1idWYvZG1hLWJ1Zi5jCj4gPiA+IEBAIC0yOSw2ICsy OSw4IEBACj4gPiA+ICAgI2luY2x1ZGUgPHVhcGkvbGludXgvZG1hLWJ1Zi5oPgo+ID4gPiAgICNp bmNsdWRlIDx1YXBpL2xpbnV4L21hZ2ljLmg+Cj4gPiA+Cj4gPiA+ICsjaW5jbHVkZSAiZG1hLWJ1 Zi1zeXNmcy1zdGF0cy5oIgo+ID4gPiArCj4gPiA+ICAgc3RhdGljIGlubGluZSBpbnQgaXNfZG1h X2J1Zl9maWxlKHN0cnVjdCBmaWxlICopOwo+ID4gPgo+ID4gPiAgIHN0cnVjdCBkbWFfYnVmX2xp c3Qgewo+ID4gPiBAQCAtNzksNiArODEsNyBAQCBzdGF0aWMgdm9pZCBkbWFfYnVmX3JlbGVhc2Uo c3RydWN0IGRlbnRyeSAqZGVudHJ5KQo+ID4gPiAgICAgICBpZiAoZG1hYnVmLT5yZXN2ID09IChz dHJ1Y3QgZG1hX3Jlc3YgKikmZG1hYnVmWzFdKQo+ID4gPiAgICAgICAgICAgICAgIGRtYV9yZXN2 X2ZpbmkoZG1hYnVmLT5yZXN2KTsKPiA+ID4KPiA+ID4gKyAgICAgZG1hX2J1Zl9zdGF0c190ZWFy ZG93bihkbWFidWYpOwo+ID4gPiAgICAgICBtb2R1bGVfcHV0KGRtYWJ1Zi0+b3duZXIpOwo+ID4g PiAgICAgICBrZnJlZShkbWFidWYtPm5hbWUpOwo+ID4gPiAgICAgICBrZnJlZShkbWFidWYpOwo+ ID4gPiBAQCAtNTc5LDYgKzU4MiwxMCBAQCBzdHJ1Y3QgZG1hX2J1ZiAqZG1hX2J1Zl9leHBvcnQo Y29uc3Qgc3RydWN0IGRtYV9idWZfZXhwb3J0X2luZm8gKmV4cF9pbmZvKQo+ID4gPiAgICAgICBm aWxlLT5mX21vZGUgfD0gRk1PREVfTFNFRUs7Cj4gPiA+ICAgICAgIGRtYWJ1Zi0+ZmlsZSA9IGZp bGU7Cj4gPiA+Cj4gPiA+ICsgICAgIHJldCA9IGRtYV9idWZfc3RhdHNfc2V0dXAoZG1hYnVmKTsK PiA+ID4gKyAgICAgaWYgKHJldCkKPiA+ID4gKyAgICAgICAgICAgICBnb3RvIGVycl9zeXNmczsK PiA+ID4gKwo+ID4gPiAgICAgICBtdXRleF9pbml0KCZkbWFidWYtPmxvY2spOwo+ID4gPiAgICAg ICBJTklUX0xJU1RfSEVBRCgmZG1hYnVmLT5hdHRhY2htZW50cyk7Cj4gPiA+Cj4gPiA+IEBAIC01 ODgsNiArNTk1LDE0IEBAIHN0cnVjdCBkbWFfYnVmICpkbWFfYnVmX2V4cG9ydChjb25zdCBzdHJ1 Y3QgZG1hX2J1Zl9leHBvcnRfaW5mbyAqZXhwX2luZm8pCj4gPiA+Cj4gPiA+ICAgICAgIHJldHVy biBkbWFidWY7Cj4gPiA+Cj4gPiA+ICtlcnJfc3lzZnM6Cj4gPiA+ICsgICAgIC8qCj4gPiA+ICsg ICAgICAqIFNldCBmaWxlLT5mX3BhdGguZGVudHJ5LT5kX2ZzZGF0YSB0byBOVUxMIHNvIHRoYXQg d2hlbgo+ID4gPiArICAgICAgKiBkbWFfYnVmX3JlbGVhc2UoKSBnZXRzIGludm9rZWQgYnkgZGVu dHJ5X29wcywgaXQgZXhpdHMKPiA+ID4gKyAgICAgICogZWFybHkgYmVmb3JlIGNhbGxpbmcgdGhl IHJlbGVhc2UoKSBkbWFfYnVmIG9wLgo+ID4gPiArICAgICAgKi8KPiA+ID4gKyAgICAgZmlsZS0+ Zl9wYXRoLmRlbnRyeS0+ZF9mc2RhdGEgPSBOVUxMOwo+ID4gPiArICAgICBmcHV0KGZpbGUpOwo+ ID4gPiAgIGVycl9kbWFidWY6Cj4gPiA+ICAgICAgIGtmcmVlKGRtYWJ1Zik7Cj4gPiA+ICAgZXJy X21vZHVsZToKPiA+ID4gQEAgLTY5Miw2ICs3MDcsNyBAQCBkbWFfYnVmX2R5bmFtaWNfYXR0YWNo KHN0cnVjdCBkbWFfYnVmICpkbWFidWYsIHN0cnVjdCBkZXZpY2UgKmRldiwKPiA+ID4gICB7Cj4g PiA+ICAgICAgIHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQgKmF0dGFjaDsKPiA+ID4gICAgICAg aW50IHJldDsKPiA+ID4gKyAgICAgdW5zaWduZWQgaW50IGF0dGFjaF91aWQ7Cj4gPiA+Cj4gPiA+ ICAgICAgIGlmIChXQVJOX09OKCFkbWFidWYgfHwgIWRldikpCj4gPiA+ICAgICAgICAgICAgICAg cmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gPiA+IEBAIC03MTcsOCArNzMzLDEzIEBAIGRtYV9i dWZfZHluYW1pY19hdHRhY2goc3RydWN0IGRtYV9idWYgKmRtYWJ1Ziwgc3RydWN0IGRldmljZSAq ZGV2LAo+ID4gPiAgICAgICB9Cj4gPiA+ICAgICAgIGRtYV9yZXN2X2xvY2soZG1hYnVmLT5yZXN2 LCBOVUxMKTsKPiA+ID4gICAgICAgbGlzdF9hZGQoJmF0dGFjaC0+bm9kZSwgJmRtYWJ1Zi0+YXR0 YWNobWVudHMpOwo+ID4gPiArICAgICBhdHRhY2hfdWlkID0gZG1hX2J1Zl91cGRhdGVfYXR0YWNo X3VpZChkbWFidWYpOwo+ID4gPiAgICAgICBkbWFfcmVzdl91bmxvY2soZG1hYnVmLT5yZXN2KTsK PiA+ID4KPiA+ID4gKyAgICAgcmV0ID0gZG1hX2J1Zl9hdHRhY2hfc3RhdHNfc2V0dXAoYXR0YWNo LCBhdHRhY2hfdWlkKTsKPiA+ID4gKyAgICAgaWYgKHJldCkKPiA+ID4gKyAgICAgICAgICAgICBn b3RvIGVycl9zeXNmczsKPiA+ID4gKwo+ID4gPiAgICAgICAvKiBXaGVuIGVpdGhlciB0aGUgaW1w b3J0ZXIgb3IgdGhlIGV4cG9ydGVyIGNhbid0IGhhbmRsZSBkeW5hbWljCj4gPiA+ICAgICAgICAq IG1hcHBpbmdzIHdlIGNhY2hlIHRoZSBtYXBwaW5nIGhlcmUgdG8gYXZvaWQgaXNzdWVzIHdpdGgg dGhlCj4gPiA+ICAgICAgICAqIHJlc2VydmF0aW9uIG9iamVjdCBsb2NrLgo+ID4gPiBAQCAtNzQ1 LDYgKzc2Niw3IEBAIGRtYV9idWZfZHluYW1pY19hdHRhY2goc3RydWN0IGRtYV9idWYgKmRtYWJ1 Ziwgc3RydWN0IGRldmljZSAqZGV2LAo+ID4gPiAgICAgICAgICAgICAgICAgICAgICAgZG1hX3Jl c3ZfdW5sb2NrKGF0dGFjaC0+ZG1hYnVmLT5yZXN2KTsKPiA+ID4gICAgICAgICAgICAgICBhdHRh Y2gtPnNndCA9IHNndDsKPiA+ID4gICAgICAgICAgICAgICBhdHRhY2gtPmRpciA9IERNQV9CSURJ UkVDVElPTkFMOwo+ID4gPiArICAgICAgICAgICAgIGRtYV9idWZfdXBkYXRlX2F0dGFjaG1lbnRf bWFwX2NvdW50KGF0dGFjaCwgMSAvKiBkZWx0YSAqLyk7Cj4gPiA+ICAgICAgIH0KPiA+ID4KPiA+ ID4gICAgICAgcmV0dXJuIGF0dGFjaDsKPiA+ID4gQEAgLTc2MSw2ICs3ODMsNyBAQCBkbWFfYnVm X2R5bmFtaWNfYXR0YWNoKHN0cnVjdCBkbWFfYnVmICpkbWFidWYsIHN0cnVjdCBkZXZpY2UgKmRl diwKPiA+ID4gICAgICAgaWYgKGRtYV9idWZfaXNfZHluYW1pYyhhdHRhY2gtPmRtYWJ1ZikpCj4g PiA+ICAgICAgICAgICAgICAgZG1hX3Jlc3ZfdW5sb2NrKGF0dGFjaC0+ZG1hYnVmLT5yZXN2KTsK PiA+ID4KPiA+ID4gK2Vycl9zeXNmczoKPiA+ID4gICAgICAgZG1hX2J1Zl9kZXRhY2goZG1hYnVm LCBhdHRhY2gpOwo+ID4gPiAgICAgICByZXR1cm4gRVJSX1BUUihyZXQpOwo+ID4gPiAgIH0KPiA+ ID4gQEAgLTc5OSw2ICs4MjIsNyBAQCB2b2lkIGRtYV9idWZfZGV0YWNoKHN0cnVjdCBkbWFfYnVm ICpkbWFidWYsIHN0cnVjdCBkbWFfYnVmX2F0dGFjaG1lbnQgKmF0dGFjaCkKPiA+ID4gICAgICAg ICAgICAgICAgICAgICAgIGRtYV9yZXN2X2xvY2soYXR0YWNoLT5kbWFidWYtPnJlc3YsIE5VTEwp Owo+ID4gPgo+ID4gPiAgICAgICAgICAgICAgIGRtYWJ1Zi0+b3BzLT51bm1hcF9kbWFfYnVmKGF0 dGFjaCwgYXR0YWNoLT5zZ3QsIGF0dGFjaC0+ZGlyKTsKPiA+ID4gKyAgICAgICAgICAgICBkbWFf YnVmX3VwZGF0ZV9hdHRhY2htZW50X21hcF9jb3VudChhdHRhY2gsIC0xIC8qIGRlbHRhICovKTsK PiA+ID4KPiA+ID4gICAgICAgICAgICAgICBpZiAoZG1hX2J1Zl9pc19keW5hbWljKGF0dGFjaC0+ ZG1hYnVmKSkgewo+ID4gPiAgICAgICAgICAgICAgICAgICAgICAgZG1hX2J1Zl91bnBpbihhdHRh Y2gpOwo+ID4gPiBAQCAtODEyLDYgKzgzNiw3IEBAIHZvaWQgZG1hX2J1Zl9kZXRhY2goc3RydWN0 IGRtYV9idWYgKmRtYWJ1Ziwgc3RydWN0IGRtYV9idWZfYXR0YWNobWVudCAqYXR0YWNoKQo+ID4g PiAgICAgICBpZiAoZG1hYnVmLT5vcHMtPmRldGFjaCkKPiA+ID4gICAgICAgICAgICAgICBkbWFi dWYtPm9wcy0+ZGV0YWNoKGRtYWJ1ZiwgYXR0YWNoKTsKPiA+ID4KPiA+ID4gKyAgICAgZG1hX2J1 Zl9hdHRhY2hfc3RhdHNfdGVhcmRvd24oYXR0YWNoKTsKPiA+ID4gICAgICAga2ZyZWUoYXR0YWNo KTsKPiA+ID4gICB9Cj4gPiA+ICAgRVhQT1JUX1NZTUJPTF9HUEwoZG1hX2J1Zl9kZXRhY2gpOwo+ ID4gPiBAQCAtOTM4LDYgKzk2Myw5IEBAIHN0cnVjdCBzZ190YWJsZSAqZG1hX2J1Zl9tYXBfYXR0 YWNobWVudChzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50ICphdHRhY2gsCj4gPiA+ICAgICAgIH0K PiA+ID4gICAjZW5kaWYgLyogQ09ORklHX0RNQV9BUElfREVCVUcgKi8KPiA+ID4KPiA+ID4gKyAg ICAgaWYgKCFJU19FUlIoc2dfdGFibGUpKQo+ID4gPiArICAgICAgICAgICAgIGRtYV9idWZfdXBk YXRlX2F0dGFjaG1lbnRfbWFwX2NvdW50KGF0dGFjaCwgMSAvKiBkZWx0YSAqLyk7Cj4gPiA+ICsK PiA+ID4gICAgICAgcmV0dXJuIHNnX3RhYmxlOwo+ID4gPiAgIH0KPiA+ID4gICBFWFBPUlRfU1lN Qk9MX0dQTChkbWFfYnVmX21hcF9hdHRhY2htZW50KTsKPiA+ID4gQEAgLTk3NSw2ICsxMDAzLDgg QEAgdm9pZCBkbWFfYnVmX3VubWFwX2F0dGFjaG1lbnQoc3RydWN0IGRtYV9idWZfYXR0YWNobWVu dCAqYXR0YWNoLAo+ID4gPiAgICAgICBpZiAoZG1hX2J1Zl9pc19keW5hbWljKGF0dGFjaC0+ZG1h YnVmKSAmJgo+ID4gPiAgICAgICAgICAgIUlTX0VOQUJMRUQoQ09ORklHX0RNQUJVRl9NT1ZFX05P VElGWSkpCj4gPiA+ICAgICAgICAgICAgICAgZG1hX2J1Zl91bnBpbihhdHRhY2gpOwo+ID4gPiAr Cj4gPiA+ICsgICAgIGRtYV9idWZfdXBkYXRlX2F0dGFjaG1lbnRfbWFwX2NvdW50KGF0dGFjaCwg LTEgLyogZGVsdGEgKi8pOwo+ID4gPiAgIH0KPiA+ID4gICBFWFBPUlRfU1lNQk9MX0dQTChkbWFf YnVmX3VubWFwX2F0dGFjaG1lbnQpOwo+ID4gPgo+ID4gPiBAQCAtMTQxMiw2ICsxNDQyLDEyIEBA IHN0YXRpYyBpbmxpbmUgdm9pZCBkbWFfYnVmX3VuaW5pdF9kZWJ1Z2ZzKHZvaWQpCj4gPiA+Cj4g PiA+ICAgc3RhdGljIGludCBfX2luaXQgZG1hX2J1Zl9pbml0KHZvaWQpCj4gPiA+ICAgewo+ID4g PiArICAgICBpbnQgcmV0Owo+ID4gPiArCj4gPiA+ICsgICAgIHJldCA9IGRtYV9idWZfaW5pdF9z eXNmc19zdGF0aXN0aWNzKCk7Cj4gPiA+ICsgICAgIGlmIChyZXQpCj4gPiA+ICsgICAgICAgICAg ICAgcmV0dXJuIHJldDsKPiA+ID4gKwo+ID4gPiAgICAgICBkbWFfYnVmX21udCA9IGtlcm5fbW91 bnQoJmRtYV9idWZfZnNfdHlwZSk7Cj4gPiA+ICAgICAgIGlmIChJU19FUlIoZG1hX2J1Zl9tbnQp KQo+ID4gPiAgICAgICAgICAgICAgIHJldHVybiBQVFJfRVJSKGRtYV9idWZfbW50KTsKPiA+ID4g QEAgLTE0MjcsNSArMTQ2Myw2IEBAIHN0YXRpYyB2b2lkIF9fZXhpdCBkbWFfYnVmX2RlaW5pdCh2 b2lkKQo+ID4gPiAgIHsKPiA+ID4gICAgICAgZG1hX2J1Zl91bmluaXRfZGVidWdmcygpOwo+ID4g PiAgICAgICBrZXJuX3VubW91bnQoZG1hX2J1Zl9tbnQpOwo+ID4gPiArICAgICBkbWFfYnVmX3Vu aW5pdF9zeXNmc19zdGF0aXN0aWNzKCk7Cj4gPiA+ICAgfQo+ID4gPiAgIF9fZXhpdGNhbGwoZG1h X2J1Zl9kZWluaXQpOwo+ID4gPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9kbWEtYnVmLmgg Yi9pbmNsdWRlL2xpbnV4L2RtYS1idWYuaAo+ID4gPiBpbmRleCBjZjcyNjk5Y2IyYmMuLjRhZTVj YzM4YTRhNyAxMDA2NDQKPiA+ID4gLS0tIGEvaW5jbHVkZS9saW51eC9kbWEtYnVmLmgKPiA+ID4g KysrIGIvaW5jbHVkZS9saW51eC9kbWEtYnVmLmgKPiA+ID4gQEAgLTI5NCw2ICsyOTQsOSBAQCBz dHJ1Y3QgZG1hX2J1Zl9vcHMgewo+ID4gPiAgICAqIEBwb2xsOiBmb3IgdXNlcnNwYWNlIHBvbGwg c3VwcG9ydAo+ID4gPiAgICAqIEBjYl9leGNsOiBmb3IgdXNlcnNwYWNlIHBvbGwgc3VwcG9ydAo+ ID4gPiAgICAqIEBjYl9zaGFyZWQ6IGZvciB1c2Vyc3BhY2UgcG9sbCBzdXBwb3J0Cj4gPiA+ICsg KiBAc3lzZnNfZW50cnk6IGZvciBleHBvc2luZyBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIGJ1ZmZl ciBpbiBzeXNmcy4KPiA+ID4gKyAqIFRoZSBhdHRhY2htZW50X3VpZCBtZW1iZXIgb2YgQHN5c2Zz X2VudHJ5IGlzIHByb3RlY3RlZCBieSBkbWFfcmVzdiBsb2NrCj4gPiA+ICsgKiBhbmQgaXMgaW5j cmVtZW50ZWQgb24gZWFjaCBhdHRhY2guCj4gPiA+ICAgICoKPiA+ID4gICAgKiBUaGlzIHJlcHJl c2VudHMgYSBzaGFyZWQgYnVmZmVyLCBjcmVhdGVkIGJ5IGNhbGxpbmcgZG1hX2J1Zl9leHBvcnQo KS4gVGhlCj4gPiA+ICAgICogdXNlcnNwYWNlIHJlcHJlc2VudGF0aW9uIGlzIGEgbm9ybWFsIGZp bGUgZGVzY3JpcHRvciwgd2hpY2ggY2FuIGJlIGNyZWF0ZWQgYnkKPiA+ID4gQEAgLTMyOSw2ICsz MzIsMTUgQEAgc3RydWN0IGRtYV9idWYgewo+ID4gPgo+ID4gPiAgICAgICAgICAgICAgIF9fcG9s bF90IGFjdGl2ZTsKPiA+ID4gICAgICAgfSBjYl9leGNsLCBjYl9zaGFyZWQ7Cj4gPiA+ICsjaWZk ZWYgQ09ORklHX0RNQUJVRl9TWVNGU19TVEFUUwo+ID4gPiArICAgICAvKiBmb3Igc3lzZnMgc3Rh dHMgKi8KPiA+ID4gKyAgICAgc3RydWN0IGRtYV9idWZfc3lzZnNfZW50cnkgewo+ID4gPiArICAg ICAgICAgICAgIHN0cnVjdCBrb2JqZWN0IGtvYmo7Cj4gPiA+ICsgICAgICAgICAgICAgc3RydWN0 IGRtYV9idWYgKmRtYWJ1ZjsKPiA+ID4gKyAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgYXR0YWNo bWVudF91aWQ7Cj4gPiA+ICsgICAgICAgICAgICAgc3RydWN0IGtzZXQgKmF0dGFjaF9zdGF0c19r c2V0Owo+ID4gPiArICAgICB9ICpzeXNmc19lbnRyeTsKPiA+ID4gKyNlbmRpZgo+ID4KPiA+IFdo eSBub3QgZGlyZWN0bHkgZW1iZWQgdGhhdD8KPiA+Cj4gPiA+ICAgfTsKPiA+ID4KPiA+ID4gICAv KioKPiA+ID4gQEAgLTM3OCw2ICszOTAsNyBAQCBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2hfb3BzIHsK PiA+ID4gICAgKiBAaW1wb3J0ZXJfb3BzOiBpbXBvcnRlciBvcGVyYXRpb25zIGZvciB0aGlzIGF0 dGFjaG1lbnQsIGlmIHByb3ZpZGVkCj4gPiA+ICAgICogZG1hX2J1Zl9tYXAvdW5tYXBfYXR0YWNo bWVudCgpIG11c3QgYmUgY2FsbGVkIHdpdGggdGhlIGRtYV9yZXN2IGxvY2sgaGVsZC4KPiA+ID4g ICAgKiBAaW1wb3J0ZXJfcHJpdjogaW1wb3J0ZXIgc3BlY2lmaWMgYXR0YWNobWVudCBkYXRhLgo+ ID4gPiArICogQHN5c2ZzX2VudHJ5OiBGb3IgZXhwb3NpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhp cyBhdHRhY2htZW50IGluIHN5c2ZzLgo+ID4gPiAgICAqCj4gPiA+ICAgICogVGhpcyBzdHJ1Y3R1 cmUgaG9sZHMgdGhlIGF0dGFjaG1lbnQgaW5mb3JtYXRpb24gYmV0d2VlbiB0aGUgZG1hX2J1ZiBi dWZmZXIKPiA+ID4gICAgKiBhbmQgaXRzIHVzZXIgZGV2aWNlKHMpLiBUaGUgbGlzdCBjb250YWlu cyBvbmUgYXR0YWNobWVudCBzdHJ1Y3QgcGVyIGRldmljZQo+ID4gPiBAQCAtMzk4LDYgKzQxMSwx MyBAQCBzdHJ1Y3QgZG1hX2J1Zl9hdHRhY2htZW50IHsKPiA+ID4gICAgICAgY29uc3Qgc3RydWN0 IGRtYV9idWZfYXR0YWNoX29wcyAqaW1wb3J0ZXJfb3BzOwo+ID4gPiAgICAgICB2b2lkICppbXBv cnRlcl9wcml2Owo+ID4gPiAgICAgICB2b2lkICpwcml2Owo+ID4gPiArI2lmZGVmIENPTkZJR19E TUFCVUZfU1lTRlNfU1RBVFMKPiA+ID4gKyAgICAgLyogZm9yIHN5c2ZzIHN0YXRzICovCj4gPiA+ ICsgICAgIHN0cnVjdCBkbWFfYnVmX2F0dGFjaF9zeXNmc19lbnRyeSB7Cj4gPiA+ICsgICAgICAg ICAgICAgc3RydWN0IGtvYmplY3Qga29iajsKPiA+ID4gKyAgICAgICAgICAgICB1bnNpZ25lZCBp bnQgbWFwX2NvdW50ZXI7Cj4gPiA+ICsgICAgIH0gKnN5c2ZzX2VudHJ5Owo+ID4gPiArI2VuZGlm Cj4gPgo+ID4gU2FtZSBxdWVzdGlvbiBoZXJlLgo+ID4KPiA+IEFwYXJ0IGZyb20gdGhhdCB0aGUg Z2VuZXJhbCBhcHByb2FjaCBsb29rcyBzb2xpZCB0byBtZSBub3cuCj4gPgo+ID4gQnV0IHNvbWVi b2R5IHdpdGggbW9yZSBzeXNmcyBiYWNrZ3JvdW5kIHNob3VsZCBjaGVjayBpZiBldmVyeXRoaW5n IHRoZXJlCj4gPiBpcyB0aGUgcmlnaHQgdGhpbmcgdG8gZG8uCj4KPiBTbyBhcHBhcmVudGx5IEFu ZHJvaWQgaXMgY29tcGxldGVseSByZXZhbXBpbmcgYWxsIG9mIHRoaXMsIGJ1dCBmZWVkaW5nCj4g aXQgdG8gdXBzdHJlYW0gaW4gcGllY2VzLCBhbmQgdGhhdCBkb2Vzbid0IHdvcmsuIEhlcmUncyBh bm90aGVyIHBhcnQ6Cj4KPiBodHRwczovL2xvcmUua2VybmVsLm9yZy9kcmktZGV2ZWwvQ0FLTUs3 dUUzeEY4MEFzSjF6R2ZTTS1LVHJ5PWlrSi1TLURuNm5LOFpBdkNTV3cyRkhRQG1haWwuZ21haWwu Y29tLwoKVGhhbmsgeW91IGZvciB0YWtpbmcgYSBsb29rIGFuZCB0aGUgZ3VpZGFuY2Ugc28gZmFy IERhbmllbCEgVGhlIGFib3ZlCnBhdGNoICh3aGljaCBhZGRzIHRyYWNlcG9pbnRzIHRvIHRyYWNr IHRvdGFsIEdQVSBtZW1vcnkgYWxsb2NhdGlvbnMpCmlzIGluZGVwZW5kZW50IG9mIHRoZSBETUEt QlVGIHN5c2ZzIHN0YXRzIGVmZm9ydC4gSSBhZ3JlZSB0aGF0IHRoZQp2YWx1ZSBmcm9tIHRoZSB0 cmFjZXBvaW50IHdpbGwgaW5jbHVkZSBtZW1vcnkgdGhhdCBpcyBzaGFyZWQgYXMKRE1BLUJVRnMu IEhvd2V2ZXIsIHRoZXJlIGlzIG5vIGludGVyZGVwZW5kZW5jeSBiZXR3ZWVuIHRoZSB0d28KZWZm b3J0cy4gSSBoYXZlIGxpbmtlZCB0byB0aGUgQU9TUCBjb2RlIHRoYXQgd2lsbCBwYXJzZSB0aGUg RE1BLUJVRgpzeXNmcyBzdGF0aXN0aWNzIGluIHRoZSBjb21taXQgbWVzc2FnZS4gV2UgZG8gaGF2 ZSBwbGFucyB0byBleHBhbmQgdGhlCnN5c2ZzIGludGVyZmFjZSBpdHNlbGYgaW4gZnV0dXJlKHRo YW5rIHlvdSBmb3Igc3VnZ2VzdGluZyB0byBtYWtlIGl0CmV4cGFuZGFibGUgaW4gdjEhKSBidXQg d2hlbiB3ZSBkbywgd2Ugd2lsbCBtYWtlIHN1cmUgdG8gc2VuZCB0aGUKdXNlcnNwYWNlIGNvZGUg dGhhdCB1c2VzIGl0IGFzIHdlbGwgc28gdGhhdCB5b3UgY2FuIGdldCB0aGUgZnVsbApwaWN0dXJl LgoKUmVnYXJkcywKSHJpZHlhCgo+Cj4gSSB0aGluayB3ZSBuZWVkIGFuIG92ZXJhbGwgaW50ZWdy YXRlZCBzb2x1dGlvbiBoZXJlLCBvciB3ZSdyZSBqdXN0Cj4gYnVpbGRpbmcgdWFwaSB0aGF0IHdv bid0IGxhc3QgKGJ1dCB3ZSBzdGlsbCBoYXZlIHRvIHN1cHBvcnQgaXQKPiBmb3JldmVyKS4KPgo+ IEkgdGhpbmsgYXNpZGUgZnJvbSBoYXZpbmcgdGhlIGZ1bGwgYW5kcm9pZCBzaWRlIGNvdmVyZWQg KGJ1dCBvbgo+IHVwc3RyZWFtIGRyaXZlcnMsIGFuZCBpbmNsdWRpbmcgZG1hLWJ1ZiBzaGFyaW5n LCBub3QganVzdCBvbmx5Cj4gdmlydGlvLWdwdSkgd2UgYWxzbyBuZWVkIHRvIGZpZ3VyZSBvdXQg aG93IHRoaXMgd2lsbCBmaXQgaW50byBvdGhlcgo+IHRyYWNraW5nIGVmZm9ydHMgbGlrZSBjZ3Jv dXBzLiBPdGhlcndpc2Ugd2UgZW5kIHVwIHdpdGggb25lIHdheSBvZgo+IHRyYWNraW5nIGdwdSBt ZW1vcnkgdXNhZ2UgZm9yIGFuZHJvaWQsIGltcGxlbWVudGVkIGJ5IG91dC1vZi10cmVlCj4gZHJp dmVycyBtb3N0bHkuIEFub3RoZXIgb25lIGZvciBzZXJ2ZXJzIGluIGNncm91cHMsIGltcGxlbWVu dGVkIGJ5IGFtZAo+IGFuZCBpbnRlbCwgYW5kIHRoZW4gcHJvYmFibHkgYSB0aGlyZCBvbmUgZm9y IGNyb3MKPiB2aXJ0dWFsaXphdGlvbi9jb250YWluZXJzLCBqdXN0IGJlY2F1c2UuIFRoYXQgZG9l c24ndCB3b3JrIHRvbyB3ZWxsLgo+IC1EYW5pZWwKPiAtLQo+IERhbmllbCBWZXR0ZXIKPiBTb2Z0 d2FyZSBFbmdpbmVlciwgSW50ZWwgQ29ycG9yYXRpb24KPiBodHRwOi8vYmxvZy5mZndsbC5jaApf X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwg bWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0 cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK