From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753642AbdLSTlK (ORCPT ); Tue, 19 Dec 2017 14:41:10 -0500 Received: from mga01.intel.com ([192.55.52.88]:17647 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753262AbdLSThC (ORCPT ); Tue, 19 Dec 2017 14:37:02 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,428,1508828400"; d="scan'208";a="4018644" From: Dongwon Kim To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dongwon.kim@intel.com Subject: [RFC PATCH 46/60] hyper_dmabuf: delay auto initialization of comm_env Date: Tue, 19 Dec 2017 11:30:02 -0800 Message-Id: <1513711816-2618-46-git-send-email-dongwon.kim@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> References: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Comm env intialization is now scheduled to be done when xenstore is initialized. This scheduling is done in driver's init routine. Also, adding a recursively scheduled routine that monitors any new tx ch setup from other domains and automaticlaly configure rx channel accordingly (every 10 sec). Only limitation is it currently checks domain ID 0 to 10. We could increase this range if needed. With this patch, we don't have to call comm channel setup IOCTL on importer side anymore. For example, we can remove ioctl call in init_hyper_dmabuf from vmdisplay. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/Kconfig | 10 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 64 +++++---- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h | 3 + .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 153 ++++++++++++++++++++- 4 files changed, 199 insertions(+), 31 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/Kconfig b/drivers/xen/hyper_dmabuf/Kconfig index eb1b637..5efcd44 100644 --- a/drivers/xen/hyper_dmabuf/Kconfig +++ b/drivers/xen/hyper_dmabuf/Kconfig @@ -29,4 +29,14 @@ config HYPER_DMABUF_EVENT_GEN shared DMA-BUF is available. Events in the list can be retrieved by read operation. +config HYPER_DMABUF_XEN_AUTO_RX_CH_ADD + bool "Enable automatic rx-ch add with 10 secs interval" + default y + depends on HYPER_DMABUF && HYPER_DMABUF_XEN + help + If enabled, driver reads a node in xenstore every 10 seconds + to check whether there is any tx comm ch configured by another + domain then initialize matched rx comm ch automatically for any + existing tx comm chs. + endmenu diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 2845224..005677d 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -67,27 +67,6 @@ int hyper_dmabuf_open(struct inode *inode, struct file *filp) if (filp->f_flags & O_EXCL) return -EBUSY; - /* - * Initialize backend if needed, - * use mutex to prevent race conditions when - * two userspace apps will open device at the same time - */ - mutex_lock(&hyper_dmabuf_private.lock); - - if (!hyper_dmabuf_private.backend_initialized) { - hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); - - ret = hyper_dmabuf_private.backend_ops->init_comm_env(); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "failed to initiailize hypervisor-specific comm env\n"); - } else { - hyper_dmabuf_private.backend_initialized = true; - } - } - - mutex_unlock(&hyper_dmabuf_private.lock); - return ret; } @@ -260,17 +239,22 @@ static int __init hyper_dmabuf_drv_init(void) return ret; } +/* currently only supports XEN hypervisor */ + #ifdef CONFIG_HYPER_DMABUF_XEN hyper_dmabuf_private.backend_ops = &xen_backend_ops; +#else + hyper_dmabuf_private.backend_ops = NULL; + printk( KERN_ERR "hyper_dmabuf drv currently supports XEN only.\n"); #endif - /* - * Defer backend setup to first open call. - * Due to fact that some hypervisors eg. Xen, may have dependencies - * to userspace daemons like xenstored, in that case all xenstore - * calls done from kernel will block until that deamon will be - * started, in case where module is built in that will block entire - * kernel initialization. - */ + + if (hyper_dmabuf_private.backend_ops == NULL) { + printk( KERN_ERR "Hyper_dmabuf: failed to be loaded - no backend found\n"); + return -1; + } + + mutex_lock(&hyper_dmabuf_private.lock); + hyper_dmabuf_private.backend_initialized = false; dev_info(hyper_dmabuf_private.device, @@ -301,6 +285,22 @@ static int __init hyper_dmabuf_drv_init(void) init_waitqueue_head(&hyper_dmabuf_private.event_wait); hyper_dmabuf_private.curr_num_event = 0; + hyper_dmabuf_private.exited = false; + + hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); + + ret = hyper_dmabuf_private.backend_ops->init_comm_env(); + if (ret < 0) { + dev_dbg(hyper_dmabuf_private.device, + "failed to initialize comm-env but it will re-attempt.\n"); + } else { + hyper_dmabuf_private.backend_initialized = true; + } + + mutex_unlock(&hyper_dmabuf_private.lock); + + dev_info(hyper_dmabuf_private.device, + "Finishing up initialization of hyper_dmabuf drv\n"); /* interrupt for comm should be registered here: */ return ret; @@ -312,6 +312,8 @@ static void hyper_dmabuf_drv_exit(void) hyper_dmabuf_unregister_sysfs(hyper_dmabuf_private.device); #endif + mutex_lock(&hyper_dmabuf_private.lock); + /* hash tables for export/import entries and ring_infos */ hyper_dmabuf_table_destroy(); @@ -325,6 +327,10 @@ static void hyper_dmabuf_drv_exit(void) if (hyper_dmabuf_private.id_queue) destroy_reusable_list(); + hyper_dmabuf_private.exited = true; + + mutex_unlock(&hyper_dmabuf_private.lock); + dev_info(hyper_dmabuf_private.device, "hyper_dmabuf driver: Exiting\n"); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 08e8ed7..a4acdd9f 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -64,6 +64,9 @@ struct hyper_dmabuf_private { struct mutex event_read_lock; int curr_num_event; + + /* indicate whether the driver is unloaded */ + bool exited; }; struct list_reusable_id { diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c index 370a07d..920ecf4 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c @@ -47,6 +47,14 @@ struct hyper_dmabuf_req req_pending = {0}; extern struct hyper_dmabuf_private hyper_dmabuf_private; +extern int xenstored_ready; + +static void xen_get_domid_delayed(struct work_struct *unused); +static void xen_init_comm_env_delayed(struct work_struct *unused); + +static DECLARE_DELAYED_WORK(get_vm_id_work, xen_get_domid_delayed); +static DECLARE_DELAYED_WORK(xen_init_comm_env_work, xen_init_comm_env_delayed); + /* Creates entry in xen store that will keep details of all * exporter rings created by this domain */ @@ -54,7 +62,7 @@ static int xen_comm_setup_data_dir(void) { char buf[255]; - sprintf(buf, "/local/domain/%d/data/hyper_dmabuf", hyper_dmabuf_xen_get_domid()); + sprintf(buf, "/local/domain/%d/data/hyper_dmabuf", hyper_dmabuf_private.domid); return xenbus_mkdir(XBT_NIL, buf, ""); } @@ -68,7 +76,7 @@ static int xen_comm_destroy_data_dir(void) { char buf[255]; - sprintf(buf, "/local/domain/%d/data/hyper_dmabuf", hyper_dmabuf_xen_get_domid()); + sprintf(buf, "/local/domain/%d/data/hyper_dmabuf", hyper_dmabuf_private.domid); return xenbus_rm(XBT_NIL, buf, ""); } @@ -131,16 +139,58 @@ static int xen_comm_get_ring_details(int domid, int rdomid, int *grefid, int *po return (ret <= 0 ? 1 : 0); } +void xen_get_domid_delayed(struct work_struct *unused) +{ + struct xenbus_transaction xbt; + int domid, ret; + + /* scheduling another if driver is still running + * and xenstore has not been initialized */ + if (hyper_dmabuf_private.exited == false && + likely(xenstored_ready == 0)) { + dev_dbg(hyper_dmabuf_private.device, + "Xenstore is not quite ready yet. Will retry it in 500ms\n"); + schedule_delayed_work(&get_vm_id_work, msecs_to_jiffies(500)); + } else { + xenbus_transaction_start(&xbt); + + ret = xenbus_scanf(xbt, "domid","", "%d", &domid); + + if (ret <= 0) + domid = -1; + + xenbus_transaction_end(xbt, 0); + + /* try again since -1 is an invalid id for domain + * (but only if driver is still running) */ + if (hyper_dmabuf_private.exited == false && unlikely(domid == -1)) { + dev_dbg(hyper_dmabuf_private.device, + "domid==-1 is invalid. Will retry it in 500ms\n"); + schedule_delayed_work(&get_vm_id_work, msecs_to_jiffies(500)); + } else { + dev_info(hyper_dmabuf_private.device, + "Successfully retrieved domid from Xenstore:%d\n", domid); + hyper_dmabuf_private.domid = domid; + } + } +} + int hyper_dmabuf_xen_get_domid(void) { struct xenbus_transaction xbt; int domid; + if (unlikely(xenstored_ready == 0)) { + xen_get_domid_delayed(NULL); + return -1; + } + xenbus_transaction_start(&xbt); if (!xenbus_scanf(xbt, "domid","", "%d", &domid)) { domid = -1; } + xenbus_transaction_end(xbt, 0); return domid; @@ -193,6 +243,8 @@ static void remote_dom_exporter_watch_cb(struct xenbus_watch *watch, * it means that remote domain has setup it for us and we should connect * to it. */ + + ret = xen_comm_get_ring_details(hyper_dmabuf_xen_get_domid(), rdom, &grefid, &port); @@ -389,6 +441,7 @@ int hyper_dmabuf_xen_init_rx_rbuf(int domid) return 0; } + ret = xen_comm_get_ring_details(hyper_dmabuf_xen_get_domid(), domid, &rx_gref, &rx_port); @@ -519,12 +572,108 @@ void hyper_dmabuf_xen_cleanup_rx_rbuf(int domid) FRONT_RING_INIT(&(tx_ring_info->ring_front), tx_ring_info->ring_front.sring, PAGE_SIZE); } +#ifdef CONFIG_HYPER_DMABUF_XEN_AUTO_RX_CH_ADD + +static void xen_rx_ch_add_delayed(struct work_struct *unused); + +static DECLARE_DELAYED_WORK(xen_rx_ch_auto_add_work, xen_rx_ch_add_delayed); + +#define DOMID_SCAN_START 1 /* domid = 1 */ +#define DOMID_SCAN_END 10 /* domid = 10 */ + +static void xen_rx_ch_add_delayed(struct work_struct *unused) +{ + int ret; + char buf[128]; + int i, dummy; + + dev_dbg(hyper_dmabuf_private.device, + "Scanning new tx channel comming from another domain\n"); + + /* check other domains and schedule another work if driver + * is still running and backend is valid + */ + if (hyper_dmabuf_private.exited == false && + hyper_dmabuf_private.backend_initialized == true) { + for (i = DOMID_SCAN_START; i < DOMID_SCAN_END + 1; i++) { + if (i == hyper_dmabuf_private.domid) + continue; + + sprintf(buf, "/local/domain/%d/data/hyper_dmabuf/%d", i, + hyper_dmabuf_private.domid); + + ret = xenbus_scanf(XBT_NIL, buf, "port", "%d", &dummy); + + if (ret > 0) { + if (xen_comm_find_rx_ring(i) != NULL) + continue; + + ret = hyper_dmabuf_xen_init_rx_rbuf(i); + + if (!ret) + dev_info(hyper_dmabuf_private.device, + "Finishing up setting up rx channel for domain %d\n", i); + } + } + + /* check every 10 seconds */ + schedule_delayed_work(&xen_rx_ch_auto_add_work, msecs_to_jiffies(10000)); + } +} + +#endif /* CONFIG_HYPER_DMABUF_XEN_AUTO_RX_CH_ADD */ + +void xen_init_comm_env_delayed(struct work_struct *unused) +{ + int ret; + + /* scheduling another work if driver is still running + * and xenstore hasn't been initialized or dom_id hasn't + * been correctly retrieved. */ + if (hyper_dmabuf_private.exited == false && + likely(xenstored_ready == 0 || + hyper_dmabuf_private.domid == -1)) { + dev_dbg(hyper_dmabuf_private.device, + "Xenstore is not ready yet. Re-try this again in 500ms\n"); + schedule_delayed_work(&xen_init_comm_env_work, msecs_to_jiffies(500)); + } else { + ret = xen_comm_setup_data_dir(); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "Failed to create data dir in Xenstore\n"); + } else { + dev_info(hyper_dmabuf_private.device, + "Successfully finished comm env initialization\n"); + hyper_dmabuf_private.backend_initialized = true; + +#ifdef CONFIG_HYPER_DMABUF_XEN_AUTO_RX_CH_ADD + xen_rx_ch_add_delayed(NULL); +#endif /* CONFIG_HYPER_DMABUF_XEN_AUTO_RX_CH_ADD */ + } + } +} + int hyper_dmabuf_xen_init_comm_env(void) { int ret; xen_comm_ring_table_init(); + + if (unlikely(xenstored_ready == 0 || hyper_dmabuf_private.domid == -1)) { + xen_init_comm_env_delayed(NULL); + return -1; + } + ret = xen_comm_setup_data_dir(); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "Failed to create data dir in Xenstore\n"); + } else { + dev_info(hyper_dmabuf_private.device, + "Successfully finished comm env initialization\n"); + + hyper_dmabuf_private.backend_initialized = true; + } return ret; } -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dongwon Kim Subject: [RFC PATCH 46/60] hyper_dmabuf: delay auto initialization of comm_env Date: Tue, 19 Dec 2017 11:30:02 -0800 Message-ID: <1513711816-2618-46-git-send-email-dongwon.kim@intel.com> References: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To: linux-kernel@vger.kernel.org Cc: xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dri-devel@lists.freedesktop.org, dongwon.kim@intel.com List-Id: dri-devel@lists.freedesktop.org Q29tbSBlbnYgaW50aWFsaXphdGlvbiBpcyBub3cgc2NoZWR1bGVkIHRvIGJlIGRvbmUKd2hlbiB4 ZW5zdG9yZSBpcyBpbml0aWFsaXplZC4gVGhpcyBzY2hlZHVsaW5nIGlzIGRvbmUKaW4gZHJpdmVy J3MgaW5pdCByb3V0aW5lLgoKQWxzbywgYWRkaW5nIGEgcmVjdXJzaXZlbHkgc2NoZWR1bGVkIHJv dXRpbmUKdGhhdCBtb25pdG9ycyBhbnkgbmV3IHR4IGNoIHNldHVwIGZyb20gb3RoZXIgZG9tYWlu cwphbmQgYXV0b21hdGljbGFseSBjb25maWd1cmUgcnggY2hhbm5lbCBhY2NvcmRpbmdseQooZXZl cnkgMTAgc2VjKS4KCk9ubHkgbGltaXRhdGlvbiBpcyBpdCBjdXJyZW50bHkgY2hlY2tzIGRvbWFp biBJRCAwIHRvIDEwLgpXZSBjb3VsZCBpbmNyZWFzZSB0aGlzIHJhbmdlIGlmIG5lZWRlZC4KCldp dGggdGhpcyBwYXRjaCwgd2UgZG9uJ3QgaGF2ZSB0byBjYWxsIGNvbW0gY2hhbm5lbApzZXR1cCBJ T0NUTCBvbiBpbXBvcnRlciBzaWRlIGFueW1vcmUuIEZvciBleGFtcGxlLAp3ZSBjYW4gcmVtb3Zl IGlvY3RsIGNhbGwgaW4gaW5pdF9oeXBlcl9kbWFidWYgZnJvbQp2bWRpc3BsYXkuCgpTaWduZWQt b2ZmLWJ5OiBEb25nd29uIEtpbSA8ZG9uZ3dvbi5raW1AaW50ZWwuY29tPgotLS0KIGRyaXZlcnMv eGVuL2h5cGVyX2RtYWJ1Zi9LY29uZmlnICAgICAgICAgICAgICAgICAgIHwgIDEwICsrCiBkcml2 ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX2Rydi5jICAgICAgICB8ICA2NCArKysr Ky0tLS0KIGRyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfZHJ2LmggICAgICAg IHwgICAzICsKIC4uLi94ZW4vaHlwZXJfZG1hYnVmL3hlbi9oeXBlcl9kbWFidWZfeGVuX2NvbW0u YyAgIHwgMTUzICsrKysrKysrKysrKysrKysrKysrLQogNCBmaWxlcyBjaGFuZ2VkLCAxOTkgaW5z ZXJ0aW9ucygrKSwgMzEgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vaHlw ZXJfZG1hYnVmL0tjb25maWcgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvS2NvbmZpZwppbmRl eCBlYjFiNjM3Li41ZWZjZDQ0IDEwMDY0NAotLS0gYS9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYv S2NvbmZpZworKysgYi9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvS2NvbmZpZwpAQCAtMjksNCAr MjksMTQgQEAgY29uZmlnIEhZUEVSX0RNQUJVRl9FVkVOVF9HRU4KIAkgIHNoYXJlZCBETUEtQlVG IGlzIGF2YWlsYWJsZS4gRXZlbnRzIGluIHRoZSBsaXN0IGNhbiBiZSByZXRyaWV2ZWQgYnkKIAkg IHJlYWQgb3BlcmF0aW9uLgogCitjb25maWcgSFlQRVJfRE1BQlVGX1hFTl9BVVRPX1JYX0NIX0FE RAorCWJvb2wgIkVuYWJsZSBhdXRvbWF0aWMgcngtY2ggYWRkIHdpdGggMTAgc2VjcyBpbnRlcnZh bCIKKwlkZWZhdWx0IHkKKwlkZXBlbmRzIG9uIEhZUEVSX0RNQUJVRiAmJiBIWVBFUl9ETUFCVUZf WEVOCisJaGVscAorCSAgSWYgZW5hYmxlZCwgZHJpdmVyIHJlYWRzIGEgbm9kZSBpbiB4ZW5zdG9y ZSBldmVyeSAxMCBzZWNvbmRzCisJICB0byBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGFueSB0eCBj b21tIGNoIGNvbmZpZ3VyZWQgYnkgYW5vdGhlcgorCSAgZG9tYWluIHRoZW4gaW5pdGlhbGl6ZSBt YXRjaGVkIHJ4IGNvbW0gY2ggYXV0b21hdGljYWxseSBmb3IgYW55CisJICBleGlzdGluZyB0eCBj b21tIGNocy4KKwogZW5kbWVudQpkaWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vaHlwZXJfZG1hYnVm L2h5cGVyX2RtYWJ1Zl9kcnYuYyBiL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFi dWZfZHJ2LmMKaW5kZXggMjg0NTIyNC4uMDA1Njc3ZCAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4v aHlwZXJfZG1hYnVmL2h5cGVyX2RtYWJ1Zl9kcnYuYworKysgYi9kcml2ZXJzL3hlbi9oeXBlcl9k bWFidWYvaHlwZXJfZG1hYnVmX2Rydi5jCkBAIC02NywyNyArNjcsNiBAQCBpbnQgaHlwZXJfZG1h YnVmX29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbHApCiAJaWYgKGZp bHAtPmZfZmxhZ3MgJiBPX0VYQ0wpCiAJCXJldHVybiAtRUJVU1k7CiAKLQkvKgotCSAqIEluaXRp YWxpemUgYmFja2VuZCBpZiBuZWVkZWQsCi0JICogdXNlIG11dGV4IHRvIHByZXZlbnQgcmFjZSBj b25kaXRpb25zIHdoZW4KLQkgKiB0d28gdXNlcnNwYWNlIGFwcHMgd2lsbCBvcGVuIGRldmljZSBh dCB0aGUgc2FtZSB0aW1lCi0JICovCi0JbXV0ZXhfbG9jaygmaHlwZXJfZG1hYnVmX3ByaXZhdGUu bG9jayk7Ci0KLQlpZiAoIWh5cGVyX2RtYWJ1Zl9wcml2YXRlLmJhY2tlbmRfaW5pdGlhbGl6ZWQp IHsKLQkJaHlwZXJfZG1hYnVmX3ByaXZhdGUuZG9taWQgPSBoeXBlcl9kbWFidWZfcHJpdmF0ZS5i YWNrZW5kX29wcy0+Z2V0X3ZtX2lkKCk7Ci0KLQkJcmV0ID0gaHlwZXJfZG1hYnVmX3ByaXZhdGUu YmFja2VuZF9vcHMtPmluaXRfY29tbV9lbnYoKTsKLQkgICAgICAgIGlmIChyZXQgPCAwKSB7Ci0J CQlkZXZfZXJyKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKLQkJCQkiZmFpbGVkIHRvIGlu aXRpYWlsaXplIGh5cGVydmlzb3Itc3BlY2lmaWMgY29tbSBlbnZcbiIpOwotCQl9IGVsc2Ugewot CQkJaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9pbml0aWFsaXplZCA9IHRydWU7Ci0JCX0K LQl9Ci0KLQltdXRleF91bmxvY2soJmh5cGVyX2RtYWJ1Zl9wcml2YXRlLmxvY2spOwotCiAJcmV0 dXJuIHJldDsKIH0KIApAQCAtMjYwLDE3ICsyMzksMjIgQEAgc3RhdGljIGludCBfX2luaXQgaHlw ZXJfZG1hYnVmX2Rydl9pbml0KHZvaWQpCiAJCXJldHVybiByZXQ7CiAJfQogCisvKiBjdXJyZW50 bHkgb25seSBzdXBwb3J0cyBYRU4gaHlwZXJ2aXNvciAqLworCiAjaWZkZWYgQ09ORklHX0hZUEVS X0RNQUJVRl9YRU4KIAloeXBlcl9kbWFidWZfcHJpdmF0ZS5iYWNrZW5kX29wcyA9ICZ4ZW5fYmFj a2VuZF9vcHM7CisjZWxzZQorCWh5cGVyX2RtYWJ1Zl9wcml2YXRlLmJhY2tlbmRfb3BzID0gTlVM TDsKKwlwcmludGsoIEtFUk5fRVJSICJoeXBlcl9kbWFidWYgZHJ2IGN1cnJlbnRseSBzdXBwb3J0 cyBYRU4gb25seS5cbiIpOwogI2VuZGlmCi0JLyoKLQkgKiBEZWZlciBiYWNrZW5kIHNldHVwIHRv IGZpcnN0IG9wZW4gY2FsbC4KLQkgKiBEdWUgdG8gZmFjdCB0aGF0IHNvbWUgaHlwZXJ2aXNvcnMg ZWcuIFhlbiwgbWF5IGhhdmUgZGVwZW5kZW5jaWVzCi0JICogdG8gdXNlcnNwYWNlIGRhZW1vbnMg bGlrZSB4ZW5zdG9yZWQsIGluIHRoYXQgY2FzZSBhbGwgeGVuc3RvcmUKLQkgKiBjYWxscyBkb25l IGZyb20ga2VybmVsIHdpbGwgYmxvY2sgdW50aWwgdGhhdCBkZWFtb24gd2lsbCBiZQotCSAqIHN0 YXJ0ZWQsIGluIGNhc2Ugd2hlcmUgbW9kdWxlIGlzIGJ1aWx0IGluIHRoYXQgd2lsbCBibG9jayBl bnRpcmUKLQkgKiBrZXJuZWwgaW5pdGlhbGl6YXRpb24uCi0JICovCisKKwlpZiAoaHlwZXJfZG1h YnVmX3ByaXZhdGUuYmFja2VuZF9vcHMgPT0gTlVMTCkgeworCQlwcmludGsoIEtFUk5fRVJSICJI eXBlcl9kbWFidWY6IGZhaWxlZCB0byBiZSBsb2FkZWQgLSBubyBiYWNrZW5kIGZvdW5kXG4iKTsK KwkJcmV0dXJuIC0xOworCX0KKworCW11dGV4X2xvY2soJmh5cGVyX2RtYWJ1Zl9wcml2YXRlLmxv Y2spOworCiAJaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9pbml0aWFsaXplZCA9IGZhbHNl OwogCiAJZGV2X2luZm8oaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLApAQCAtMzAxLDYgKzI4 NSwyMiBAQCBzdGF0aWMgaW50IF9faW5pdCBoeXBlcl9kbWFidWZfZHJ2X2luaXQodm9pZCkKIAlp bml0X3dhaXRxdWV1ZV9oZWFkKCZoeXBlcl9kbWFidWZfcHJpdmF0ZS5ldmVudF93YWl0KTsKIAog CWh5cGVyX2RtYWJ1Zl9wcml2YXRlLmN1cnJfbnVtX2V2ZW50ID0gMDsKKwloeXBlcl9kbWFidWZf cHJpdmF0ZS5leGl0ZWQgPSBmYWxzZTsKKworCWh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRvbWlkID0g aHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9vcHMtPmdldF92bV9pZCgpOworCisJcmV0ID0g aHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9vcHMtPmluaXRfY29tbV9lbnYoKTsKKwlpZiAo cmV0IDwgMCkgeworCQlkZXZfZGJnKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJCSJm YWlsZWQgdG8gaW5pdGlhbGl6ZSBjb21tLWVudiBidXQgaXQgd2lsbCByZS1hdHRlbXB0LlxuIik7 CisJfSBlbHNlIHsKKwkJaHlwZXJfZG1hYnVmX3ByaXZhdGUuYmFja2VuZF9pbml0aWFsaXplZCA9 IHRydWU7CisJfQorCisJbXV0ZXhfdW5sb2NrKCZoeXBlcl9kbWFidWZfcHJpdmF0ZS5sb2NrKTsK KworCWRldl9pbmZvKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJIkZpbmlzaGluZyB1 cCBpbml0aWFsaXphdGlvbiBvZiBoeXBlcl9kbWFidWYgZHJ2XG4iKTsKIAogCS8qIGludGVycnVw dCBmb3IgY29tbSBzaG91bGQgYmUgcmVnaXN0ZXJlZCBoZXJlOiAqLwogCXJldHVybiByZXQ7CkBA IC0zMTIsNiArMzEyLDggQEAgc3RhdGljIHZvaWQgaHlwZXJfZG1hYnVmX2Rydl9leGl0KHZvaWQp CiAJaHlwZXJfZG1hYnVmX3VucmVnaXN0ZXJfc3lzZnMoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2 aWNlKTsKICNlbmRpZgogCisJbXV0ZXhfbG9jaygmaHlwZXJfZG1hYnVmX3ByaXZhdGUubG9jayk7 CisKIAkvKiBoYXNoIHRhYmxlcyBmb3IgZXhwb3J0L2ltcG9ydCBlbnRyaWVzIGFuZCByaW5nX2lu Zm9zICovCiAJaHlwZXJfZG1hYnVmX3RhYmxlX2Rlc3Ryb3koKTsKIApAQCAtMzI1LDYgKzMyNywx MCBAQCBzdGF0aWMgdm9pZCBoeXBlcl9kbWFidWZfZHJ2X2V4aXQodm9pZCkKIAlpZiAoaHlwZXJf ZG1hYnVmX3ByaXZhdGUuaWRfcXVldWUpCiAJCWRlc3Ryb3lfcmV1c2FibGVfbGlzdCgpOwogCisJ aHlwZXJfZG1hYnVmX3ByaXZhdGUuZXhpdGVkID0gdHJ1ZTsKKworCW11dGV4X3VubG9jaygmaHlw ZXJfZG1hYnVmX3ByaXZhdGUubG9jayk7CisKIAlkZXZfaW5mbyhoeXBlcl9kbWFidWZfcHJpdmF0 ZS5kZXZpY2UsCiAJCSAiaHlwZXJfZG1hYnVmIGRyaXZlcjogRXhpdGluZ1xuIik7CiAKZGlmZiAt LWdpdCBhL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfZHJ2LmggYi9kcml2 ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVmX2Rydi5oCmluZGV4IDA4ZThlZDcuLmE0 YWNkZDlmIDEwMDY0NAotLS0gYS9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYvaHlwZXJfZG1hYnVm X2Rydi5oCisrKyBiL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi9oeXBlcl9kbWFidWZfZHJ2LmgK QEAgLTY0LDYgKzY0LDkgQEAgc3RydWN0IGh5cGVyX2RtYWJ1Zl9wcml2YXRlIHsKIAlzdHJ1Y3Qg bXV0ZXggZXZlbnRfcmVhZF9sb2NrOwogCiAJaW50IGN1cnJfbnVtX2V2ZW50OworCisJLyogaW5k aWNhdGUgd2hldGhlciB0aGUgZHJpdmVyIGlzIHVubG9hZGVkICovCisJYm9vbCBleGl0ZWQ7CiB9 OwogCiBzdHJ1Y3QgbGlzdF9yZXVzYWJsZV9pZCB7CmRpZmYgLS1naXQgYS9kcml2ZXJzL3hlbi9o eXBlcl9kbWFidWYveGVuL2h5cGVyX2RtYWJ1Zl94ZW5fY29tbS5jIGIvZHJpdmVycy94ZW4vaHlw ZXJfZG1hYnVmL3hlbi9oeXBlcl9kbWFidWZfeGVuX2NvbW0uYwppbmRleCAzNzBhMDdkLi45MjBl Y2Y0IDEwMDY0NAotLS0gYS9kcml2ZXJzL3hlbi9oeXBlcl9kbWFidWYveGVuL2h5cGVyX2RtYWJ1 Zl94ZW5fY29tbS5jCisrKyBiL2RyaXZlcnMveGVuL2h5cGVyX2RtYWJ1Zi94ZW4vaHlwZXJfZG1h YnVmX3hlbl9jb21tLmMKQEAgLTQ3LDYgKzQ3LDE0IEBAIHN0cnVjdCBoeXBlcl9kbWFidWZfcmVx IHJlcV9wZW5kaW5nID0gezB9OwogCiBleHRlcm4gc3RydWN0IGh5cGVyX2RtYWJ1Zl9wcml2YXRl IGh5cGVyX2RtYWJ1Zl9wcml2YXRlOwogCitleHRlcm4gaW50IHhlbnN0b3JlZF9yZWFkeTsKKwor c3RhdGljIHZvaWQgeGVuX2dldF9kb21pZF9kZWxheWVkKHN0cnVjdCB3b3JrX3N0cnVjdCAqdW51 c2VkKTsKK3N0YXRpYyB2b2lkIHhlbl9pbml0X2NvbW1fZW52X2RlbGF5ZWQoc3RydWN0IHdvcmtf c3RydWN0ICp1bnVzZWQpOworCitzdGF0aWMgREVDTEFSRV9ERUxBWUVEX1dPUksoZ2V0X3ZtX2lk X3dvcmssIHhlbl9nZXRfZG9taWRfZGVsYXllZCk7CitzdGF0aWMgREVDTEFSRV9ERUxBWUVEX1dP UksoeGVuX2luaXRfY29tbV9lbnZfd29yaywgeGVuX2luaXRfY29tbV9lbnZfZGVsYXllZCk7CisK IC8qIENyZWF0ZXMgZW50cnkgaW4geGVuIHN0b3JlIHRoYXQgd2lsbCBrZWVwIGRldGFpbHMgb2Yg YWxsCiAgKiBleHBvcnRlciByaW5ncyBjcmVhdGVkIGJ5IHRoaXMgZG9tYWluCiAgKi8KQEAgLTU0 LDcgKzYyLDcgQEAgc3RhdGljIGludCB4ZW5fY29tbV9zZXR1cF9kYXRhX2Rpcih2b2lkKQogewog CWNoYXIgYnVmWzI1NV07CiAKLQlzcHJpbnRmKGJ1ZiwgIi9sb2NhbC9kb21haW4vJWQvZGF0YS9o eXBlcl9kbWFidWYiLCBoeXBlcl9kbWFidWZfeGVuX2dldF9kb21pZCgpKTsKKwlzcHJpbnRmKGJ1 ZiwgIi9sb2NhbC9kb21haW4vJWQvZGF0YS9oeXBlcl9kbWFidWYiLCBoeXBlcl9kbWFidWZfcHJp dmF0ZS5kb21pZCk7CiAJcmV0dXJuIHhlbmJ1c19ta2RpcihYQlRfTklMLCBidWYsICIiKTsKIH0K IApAQCAtNjgsNyArNzYsNyBAQCBzdGF0aWMgaW50IHhlbl9jb21tX2Rlc3Ryb3lfZGF0YV9kaXIo dm9pZCkKIHsKIAljaGFyIGJ1ZlsyNTVdOwogCi0Jc3ByaW50ZihidWYsICIvbG9jYWwvZG9tYWlu LyVkL2RhdGEvaHlwZXJfZG1hYnVmIiwgaHlwZXJfZG1hYnVmX3hlbl9nZXRfZG9taWQoKSk7CisJ c3ByaW50ZihidWYsICIvbG9jYWwvZG9tYWluLyVkL2RhdGEvaHlwZXJfZG1hYnVmIiwgaHlwZXJf ZG1hYnVmX3ByaXZhdGUuZG9taWQpOwogCXJldHVybiB4ZW5idXNfcm0oWEJUX05JTCwgYnVmLCAi Iik7CiB9CiAKQEAgLTEzMSwxNiArMTM5LDU4IEBAIHN0YXRpYyBpbnQgeGVuX2NvbW1fZ2V0X3Jp bmdfZGV0YWlscyhpbnQgZG9taWQsIGludCByZG9taWQsIGludCAqZ3JlZmlkLCBpbnQgKnBvCiAJ cmV0dXJuIChyZXQgPD0gMCA/IDEgOiAwKTsKIH0KIAordm9pZCB4ZW5fZ2V0X2RvbWlkX2RlbGF5 ZWQoc3RydWN0IHdvcmtfc3RydWN0ICp1bnVzZWQpCit7CisJc3RydWN0IHhlbmJ1c190cmFuc2Fj dGlvbiB4YnQ7CisJaW50IGRvbWlkLCByZXQ7CisKKwkvKiBzY2hlZHVsaW5nIGFub3RoZXIgaWYg ZHJpdmVyIGlzIHN0aWxsIHJ1bm5pbmcKKwkgKiBhbmQgeGVuc3RvcmUgaGFzIG5vdCBiZWVuIGlu aXRpYWxpemVkICovCisJaWYgKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmV4aXRlZCA9PSBmYWxzZSAm JgorCSAgICBsaWtlbHkoeGVuc3RvcmVkX3JlYWR5ID09IDApKSB7CisJCWRldl9kYmcoaHlwZXJf ZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJIlhlbnN0b3JlIGlzIG5vdCBxdWl0ZSByZWFkeSB5 ZXQuIFdpbGwgcmV0cnkgaXQgaW4gNTAwbXNcbiIpOworCQlzY2hlZHVsZV9kZWxheWVkX3dvcmso JmdldF92bV9pZF93b3JrLCBtc2Vjc190b19qaWZmaWVzKDUwMCkpOworCX0gZWxzZSB7CisJICAg ICAgICB4ZW5idXNfdHJhbnNhY3Rpb25fc3RhcnQoJnhidCk7CisKKwkJcmV0ID0geGVuYnVzX3Nj YW5mKHhidCwgImRvbWlkIiwiIiwgIiVkIiwgJmRvbWlkKTsKKworCQlpZiAocmV0IDw9IDApCisJ CQlkb21pZCA9IC0xOworCisJCXhlbmJ1c190cmFuc2FjdGlvbl9lbmQoeGJ0LCAwKTsKKworCQkv KiB0cnkgYWdhaW4gc2luY2UgLTEgaXMgYW4gaW52YWxpZCBpZCBmb3IgZG9tYWluCisJCSAqIChi dXQgb25seSBpZiBkcml2ZXIgaXMgc3RpbGwgcnVubmluZykgKi8KKwkJaWYgKGh5cGVyX2RtYWJ1 Zl9wcml2YXRlLmV4aXRlZCA9PSBmYWxzZSAmJiB1bmxpa2VseShkb21pZCA9PSAtMSkpIHsKKwkJ CWRldl9kYmcoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJCSJkb21pZD09LTEgaXMg aW52YWxpZC4gV2lsbCByZXRyeSBpdCBpbiA1MDBtc1xuIik7CisJCQlzY2hlZHVsZV9kZWxheWVk X3dvcmsoJmdldF92bV9pZF93b3JrLCBtc2Vjc190b19qaWZmaWVzKDUwMCkpOworCQl9IGVsc2Ug eworCQkJZGV2X2luZm8oaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJCSJTdWNjZXNz ZnVsbHkgcmV0cmlldmVkIGRvbWlkIGZyb20gWGVuc3RvcmU6JWRcbiIsIGRvbWlkKTsKKwkJCWh5 cGVyX2RtYWJ1Zl9wcml2YXRlLmRvbWlkID0gZG9taWQ7CisJCX0KKwl9Cit9CisKIGludCBoeXBl cl9kbWFidWZfeGVuX2dldF9kb21pZCh2b2lkKQogewogCXN0cnVjdCB4ZW5idXNfdHJhbnNhY3Rp b24geGJ0OwogCWludCBkb21pZDsKIAorCWlmICh1bmxpa2VseSh4ZW5zdG9yZWRfcmVhZHkgPT0g MCkpIHsKKwkJeGVuX2dldF9kb21pZF9kZWxheWVkKE5VTEwpOworCQlyZXR1cm4gLTE7CisJfQor CiAgICAgICAgIHhlbmJ1c190cmFuc2FjdGlvbl9zdGFydCgmeGJ0KTsKIAogICAgICAgICBpZiAo IXhlbmJ1c19zY2FuZih4YnQsICJkb21pZCIsIiIsICIlZCIsICZkb21pZCkpIHsKIAkJZG9taWQg PSAtMTsKICAgICAgICAgfQorCiAgICAgICAgIHhlbmJ1c190cmFuc2FjdGlvbl9lbmQoeGJ0LCAw KTsKIAogCXJldHVybiBkb21pZDsKQEAgLTE5Myw2ICsyNDMsOCBAQCBzdGF0aWMgdm9pZCByZW1v dGVfZG9tX2V4cG9ydGVyX3dhdGNoX2NiKHN0cnVjdCB4ZW5idXNfd2F0Y2ggKndhdGNoLAogCSAq IGl0IG1lYW5zIHRoYXQgcmVtb3RlIGRvbWFpbiBoYXMgc2V0dXAgaXQgZm9yIHVzIGFuZCB3ZSBz aG91bGQgY29ubmVjdAogCSAqIHRvIGl0LgogCSAqLworCisKIAlyZXQgPSB4ZW5fY29tbV9nZXRf cmluZ19kZXRhaWxzKGh5cGVyX2RtYWJ1Zl94ZW5fZ2V0X2RvbWlkKCksIHJkb20sCiAJCQkJCSZn cmVmaWQsICZwb3J0KTsKIApAQCAtMzg5LDYgKzQ0MSw3IEBAIGludCBoeXBlcl9kbWFidWZfeGVu X2luaXRfcnhfcmJ1ZihpbnQgZG9taWQpCiAJCXJldHVybiAwOwogCX0KIAorCiAJcmV0ID0geGVu X2NvbW1fZ2V0X3JpbmdfZGV0YWlscyhoeXBlcl9kbWFidWZfeGVuX2dldF9kb21pZCgpLCBkb21p ZCwKIAkJCQkJJnJ4X2dyZWYsICZyeF9wb3J0KTsKIApAQCAtNTE5LDEyICs1NzIsMTA4IEBAIHZv aWQgaHlwZXJfZG1hYnVmX3hlbl9jbGVhbnVwX3J4X3JidWYoaW50IGRvbWlkKQogCUZST05UX1JJ TkdfSU5JVCgmKHR4X3JpbmdfaW5mby0+cmluZ19mcm9udCksIHR4X3JpbmdfaW5mby0+cmluZ19m cm9udC5zcmluZywgUEFHRV9TSVpFKTsKIH0KIAorI2lmZGVmIENPTkZJR19IWVBFUl9ETUFCVUZf WEVOX0FVVE9fUlhfQ0hfQURECisKK3N0YXRpYyB2b2lkIHhlbl9yeF9jaF9hZGRfZGVsYXllZChz dHJ1Y3Qgd29ya19zdHJ1Y3QgKnVudXNlZCk7CisKK3N0YXRpYyBERUNMQVJFX0RFTEFZRURfV09S Syh4ZW5fcnhfY2hfYXV0b19hZGRfd29yaywgeGVuX3J4X2NoX2FkZF9kZWxheWVkKTsKKworI2Rl ZmluZSBET01JRF9TQ0FOX1NUQVJUCTEJLyogIGRvbWlkID0gMSAqLworI2RlZmluZSBET01JRF9T Q0FOX0VORAkJMTAJLyogZG9taWQgPSAxMCAqLworCitzdGF0aWMgdm9pZCB4ZW5fcnhfY2hfYWRk X2RlbGF5ZWQoc3RydWN0IHdvcmtfc3RydWN0ICp1bnVzZWQpCit7CisJaW50IHJldDsKKwljaGFy IGJ1ZlsxMjhdOworCWludCBpLCBkdW1teTsKKworCWRldl9kYmcoaHlwZXJfZG1hYnVmX3ByaXZh dGUuZGV2aWNlLAorCQkiU2Nhbm5pbmcgbmV3IHR4IGNoYW5uZWwgY29tbWluZyBmcm9tIGFub3Ro ZXIgZG9tYWluXG4iKTsKKworCS8qIGNoZWNrIG90aGVyIGRvbWFpbnMgYW5kIHNjaGVkdWxlIGFu b3RoZXIgd29yayBpZiBkcml2ZXIKKwkgKiBpcyBzdGlsbCBydW5uaW5nIGFuZCBiYWNrZW5kIGlz IHZhbGlkCisJICovCisJaWYgKGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmV4aXRlZCA9PSBmYWxzZSAm JgorCSAgICBoeXBlcl9kbWFidWZfcHJpdmF0ZS5iYWNrZW5kX2luaXRpYWxpemVkID09IHRydWUp IHsKKwkJZm9yIChpID0gRE9NSURfU0NBTl9TVEFSVDsgaSA8IERPTUlEX1NDQU5fRU5EICsgMTsg aSsrKSB7CisJCQlpZiAoaSA9PSBoeXBlcl9kbWFidWZfcHJpdmF0ZS5kb21pZCkKKwkJCQljb250 aW51ZTsKKworCQkJc3ByaW50ZihidWYsICIvbG9jYWwvZG9tYWluLyVkL2RhdGEvaHlwZXJfZG1h YnVmLyVkIiwgaSwKKwkJCQloeXBlcl9kbWFidWZfcHJpdmF0ZS5kb21pZCk7CisKKwkJCXJldCA9 IHhlbmJ1c19zY2FuZihYQlRfTklMLCBidWYsICJwb3J0IiwgIiVkIiwgJmR1bW15KTsKKworCQkJ aWYgKHJldCA+IDApIHsKKwkJCQlpZiAoeGVuX2NvbW1fZmluZF9yeF9yaW5nKGkpICE9IE5VTEwp CisJCQkJCWNvbnRpbnVlOworCisJCQkJcmV0ID0gaHlwZXJfZG1hYnVmX3hlbl9pbml0X3J4X3Ji dWYoaSk7CisKKwkJCQlpZiAoIXJldCkKKwkJCQkJZGV2X2luZm8oaHlwZXJfZG1hYnVmX3ByaXZh dGUuZGV2aWNlLAorCQkJCQkJICJGaW5pc2hpbmcgdXAgc2V0dGluZyB1cCByeCBjaGFubmVsIGZv ciBkb21haW4gJWRcbiIsIGkpOworCQkJfQorCQl9CisKKwkJLyogY2hlY2sgZXZlcnkgMTAgc2Vj b25kcyAqLworCQlzY2hlZHVsZV9kZWxheWVkX3dvcmsoJnhlbl9yeF9jaF9hdXRvX2FkZF93b3Jr LCBtc2Vjc190b19qaWZmaWVzKDEwMDAwKSk7CisJfQorfQorCisjZW5kaWYgLyogQ09ORklHX0hZ UEVSX0RNQUJVRl9YRU5fQVVUT19SWF9DSF9BREQgKi8KKwordm9pZCB4ZW5faW5pdF9jb21tX2Vu dl9kZWxheWVkKHN0cnVjdCB3b3JrX3N0cnVjdCAqdW51c2VkKQoreworCWludCByZXQ7CisKKwkv KiBzY2hlZHVsaW5nIGFub3RoZXIgd29yayBpZiBkcml2ZXIgaXMgc3RpbGwgcnVubmluZworCSAq IGFuZCB4ZW5zdG9yZSBoYXNuJ3QgYmVlbiBpbml0aWFsaXplZCBvciBkb21faWQgaGFzbid0CisJ ICogYmVlbiBjb3JyZWN0bHkgcmV0cmlldmVkLiAqLworCWlmIChoeXBlcl9kbWFidWZfcHJpdmF0 ZS5leGl0ZWQgPT0gZmFsc2UgJiYKKwkgICAgbGlrZWx5KHhlbnN0b3JlZF9yZWFkeSA9PSAwIHx8 CisJICAgIGh5cGVyX2RtYWJ1Zl9wcml2YXRlLmRvbWlkID09IC0xKSkgeworCQlkZXZfZGJnKGh5 cGVyX2RtYWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJCSJYZW5zdG9yZSBpcyBub3QgcmVhZHkgeWV0 LiBSZS10cnkgdGhpcyBhZ2FpbiBpbiA1MDBtc1xuIik7CisJCXNjaGVkdWxlX2RlbGF5ZWRfd29y aygmeGVuX2luaXRfY29tbV9lbnZfd29yaywgbXNlY3NfdG9famlmZmllcyg1MDApKTsKKwl9IGVs c2UgeworCQlyZXQgPSB4ZW5fY29tbV9zZXR1cF9kYXRhX2RpcigpOworCQlpZiAocmV0IDwgMCkg eworCQkJZGV2X2VycihoeXBlcl9kbWFidWZfcHJpdmF0ZS5kZXZpY2UsCisJCQkJIkZhaWxlZCB0 byBjcmVhdGUgZGF0YSBkaXIgaW4gWGVuc3RvcmVcbiIpOworCQl9IGVsc2UgeworCQkJZGV2X2lu Zm8oaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJCSJTdWNjZXNzZnVsbHkgZmluaXNo ZWQgY29tbSBlbnYgaW5pdGlhbGl6YXRpb25cbiIpOworCQkJaHlwZXJfZG1hYnVmX3ByaXZhdGUu YmFja2VuZF9pbml0aWFsaXplZCA9IHRydWU7CisKKyNpZmRlZiBDT05GSUdfSFlQRVJfRE1BQlVG X1hFTl9BVVRPX1JYX0NIX0FERAorCQkJeGVuX3J4X2NoX2FkZF9kZWxheWVkKE5VTEwpOworI2Vu ZGlmIC8qIENPTkZJR19IWVBFUl9ETUFCVUZfWEVOX0FVVE9fUlhfQ0hfQUREICovCisJCX0KKwl9 Cit9CisKIGludCBoeXBlcl9kbWFidWZfeGVuX2luaXRfY29tbV9lbnYodm9pZCkKIHsKIAlpbnQg cmV0OwogCiAJeGVuX2NvbW1fcmluZ190YWJsZV9pbml0KCk7CisKKwlpZiAodW5saWtlbHkoeGVu c3RvcmVkX3JlYWR5ID09IDAgfHwgaHlwZXJfZG1hYnVmX3ByaXZhdGUuZG9taWQgPT0gLTEpKSB7 CisJCXhlbl9pbml0X2NvbW1fZW52X2RlbGF5ZWQoTlVMTCk7CisJCXJldHVybiAtMTsKKwl9CisK IAlyZXQgPSB4ZW5fY29tbV9zZXR1cF9kYXRhX2RpcigpOworCWlmIChyZXQgPCAwKSB7CisJCWRl dl9lcnIoaHlwZXJfZG1hYnVmX3ByaXZhdGUuZGV2aWNlLAorCQkJIkZhaWxlZCB0byBjcmVhdGUg ZGF0YSBkaXIgaW4gWGVuc3RvcmVcbiIpOworCX0gZWxzZSB7CisJCWRldl9pbmZvKGh5cGVyX2Rt YWJ1Zl9wcml2YXRlLmRldmljZSwKKwkJCSJTdWNjZXNzZnVsbHkgZmluaXNoZWQgY29tbSBlbnYg aW5pdGlhbGl6YXRpb25cbiIpOworCisJCWh5cGVyX2RtYWJ1Zl9wcml2YXRlLmJhY2tlbmRfaW5p dGlhbGl6ZWQgPSB0cnVlOworCX0KIAogCXJldHVybiByZXQ7CiB9Ci0tIAoyLjcuNAoKCl9fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWls aW5nIGxpc3QKWGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnCmh0dHBzOi8vbGlzdHMueGVu cHJvamVjdC5vcmcvbWFpbG1hbi9saXN0aW5mby94ZW4tZGV2ZWw=