From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752613AbeEQI0r (ORCPT ); Thu, 17 May 2018 04:26:47 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:35626 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752346AbeEQI0Q (ORCPT ); Thu, 17 May 2018 04:26:16 -0400 X-Google-Smtp-Source: AB8JxZqobwv0P/FNeu7ICyLXV7kUvhSFr4eQFrco/R6Iuwaoy2TLo3aIC1CwSkQwipgl8SudOxO79A== From: Oleksandr Andrushchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Cc: daniel.vetter@intel.com, andr2000@gmail.com, dongwon.kim@intel.com, matthew.d.roper@intel.com, Oleksandr Andrushchenko Subject: [Xen-devel][RFC 1/3] xen/balloon: Allow allocating DMA buffers Date: Thu, 17 May 2018 11:26:02 +0300 Message-Id: <20180517082604.14828-2-andr2000@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180517082604.14828-1-andr2000@gmail.com> References: <20180517082604.14828-1-andr2000@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Oleksandr Andrushchenko Signed-off-by: Oleksandr Andrushchenko --- drivers/xen/balloon.c | 214 +++++++++++++++++++++++++++++++------- drivers/xen/xen-balloon.c | 2 + include/xen/balloon.h | 11 +- 3 files changed, 188 insertions(+), 39 deletions(-) diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index e4db19e88ab1..e3a145aa9f29 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -415,8 +415,10 @@ static bool balloon_is_inflated(void) return balloon_stats.balloon_low || balloon_stats.balloon_high; } -static enum bp_state increase_reservation(unsigned long nr_pages) +static enum bp_state increase_reservation(unsigned long nr_pages, + struct page **ext_pages) { + enum bp_state ret = BP_DONE; int rc; unsigned long i; struct page *page; @@ -425,32 +427,49 @@ static enum bp_state increase_reservation(unsigned long nr_pages) .extent_order = EXTENT_ORDER, .domid = DOMID_SELF }; + xen_pfn_t *frames; - if (nr_pages > ARRAY_SIZE(frame_list)) - nr_pages = ARRAY_SIZE(frame_list); + if (nr_pages > ARRAY_SIZE(frame_list)) { + frames = kcalloc(nr_pages, sizeof(xen_pfn_t), GFP_KERNEL); + if (!frames) + return BP_ECANCELED; + } else { + frames = frame_list; + } - page = list_first_entry_or_null(&ballooned_pages, struct page, lru); - for (i = 0; i < nr_pages; i++) { - if (!page) { - nr_pages = i; - break; - } + /* XENMEM_populate_physmap requires a PFN based on Xen + * granularity. + */ + if (ext_pages) { + for (i = 0; i < nr_pages; i++) + frames[i] = page_to_xen_pfn(ext_pages[i]); + } else { + page = list_first_entry_or_null(&ballooned_pages, + struct page, lru); + for (i = 0; i < nr_pages; i++) { + if (!page) { + nr_pages = i; + break; + } - /* XENMEM_populate_physmap requires a PFN based on Xen - * granularity. - */ - frame_list[i] = page_to_xen_pfn(page); - page = balloon_next_page(page); + frames[i] = page_to_xen_pfn(page); + page = balloon_next_page(page); + } } - set_xen_guest_handle(reservation.extent_start, frame_list); + set_xen_guest_handle(reservation.extent_start, frames); reservation.nr_extents = nr_pages; rc = HYPERVISOR_memory_op(XENMEM_populate_physmap, &reservation); - if (rc <= 0) - return BP_EAGAIN; + if (rc <= 0) { + ret = BP_EAGAIN; + goto out; + } for (i = 0; i < rc; i++) { - page = balloon_retrieve(false); + if (ext_pages) + page = ext_pages[i]; + else + page = balloon_retrieve(false); BUG_ON(page == NULL); #ifdef CONFIG_XEN_HAVE_PVMMU @@ -463,14 +482,14 @@ static enum bp_state increase_reservation(unsigned long nr_pages) if (!xen_feature(XENFEAT_auto_translated_physmap)) { unsigned long pfn = page_to_pfn(page); - set_phys_to_machine(pfn, frame_list[i]); + set_phys_to_machine(pfn, frames[i]); /* Link back into the page tables if not highmem. */ if (!PageHighMem(page)) { int ret; ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), - mfn_pte(frame_list[i], PAGE_KERNEL), + mfn_pte(frames[i], PAGE_KERNEL), 0); BUG_ON(ret); } @@ -478,15 +497,22 @@ static enum bp_state increase_reservation(unsigned long nr_pages) #endif /* Relinquish the page back to the allocator. */ - __free_reserved_page(page); + if (!ext_pages) + __free_reserved_page(page); } - balloon_stats.current_pages += rc; + if (!ext_pages) + balloon_stats.current_pages += rc; - return BP_DONE; +out: + if (frames != frame_list) + kfree(frames); + + return ret; } -static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) +static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp, + struct page **ext_pages) { enum bp_state state = BP_DONE; unsigned long i; @@ -498,16 +524,26 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) .domid = DOMID_SELF }; LIST_HEAD(pages); + xen_pfn_t *frames; - if (nr_pages > ARRAY_SIZE(frame_list)) - nr_pages = ARRAY_SIZE(frame_list); + if (nr_pages > ARRAY_SIZE(frame_list)) { + frames = kcalloc(nr_pages, sizeof(xen_pfn_t), GFP_KERNEL); + if (!frames) + return BP_ECANCELED; + } else { + frames = frame_list; + } for (i = 0; i < nr_pages; i++) { - page = alloc_page(gfp); - if (page == NULL) { - nr_pages = i; - state = BP_EAGAIN; - break; + if (ext_pages) { + page = ext_pages[i]; + } else { + page = alloc_page(gfp); + if (page == NULL) { + nr_pages = i; + state = BP_EAGAIN; + break; + } } scrub_page(page); list_add(&page->lru, &pages); @@ -529,7 +565,7 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) i = 0; list_for_each_entry_safe(page, tmp, &pages, lru) { /* XENMEM_decrease_reservation requires a GFN */ - frame_list[i++] = xen_page_to_gfn(page); + frames[i++] = xen_page_to_gfn(page); #ifdef CONFIG_XEN_HAVE_PVMMU /* @@ -552,18 +588,22 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp) #endif list_del(&page->lru); - balloon_append(page); + if (!ext_pages) + balloon_append(page); } flush_tlb_all(); - set_xen_guest_handle(reservation.extent_start, frame_list); + set_xen_guest_handle(reservation.extent_start, frames); reservation.nr_extents = nr_pages; ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); BUG_ON(ret != nr_pages); - balloon_stats.current_pages -= nr_pages; + if (!ext_pages) + balloon_stats.current_pages -= nr_pages; + if (frames != frame_list) + kfree(frames); return state; } @@ -586,13 +626,13 @@ static void balloon_process(struct work_struct *work) if (credit > 0) { if (balloon_is_inflated()) - state = increase_reservation(credit); + state = increase_reservation(credit, NULL); else state = reserve_additional_memory(); } if (credit < 0) - state = decrease_reservation(-credit, GFP_BALLOON); + state = decrease_reservation(-credit, GFP_BALLOON, NULL); state = update_schedule(state); @@ -631,7 +671,7 @@ static int add_ballooned_pages(int nr_pages) } } - st = decrease_reservation(nr_pages, GFP_USER); + st = decrease_reservation(nr_pages, GFP_USER, NULL); if (st != BP_DONE) return -ENOMEM; @@ -710,6 +750,102 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) } EXPORT_SYMBOL(free_xenballooned_pages); +int alloc_dma_xenballooned_pages(struct device *dev, bool coherent, + int nr_pages, struct page **pages, + void **vaddr, dma_addr_t *dev_bus_addr) +{ + enum bp_state state; + unsigned long pfn, start_pfn; + int i, ret; + + mutex_lock(&balloon_mutex); + + balloon_stats.dma_pages += nr_pages; + + if (coherent) + *vaddr = dma_alloc_coherent(dev, nr_pages << PAGE_SHIFT, + dev_bus_addr, + GFP_KERNEL | __GFP_NOWARN); + + else + *vaddr = dma_alloc_wc(dev, nr_pages << PAGE_SHIFT, + dev_bus_addr, + GFP_KERNEL | __GFP_NOWARN); + if (!*vaddr) { + pr_err("Failed to allocate DMA buffer of size %d\n", + nr_pages << PAGE_SHIFT); + mutex_unlock(&balloon_mutex); + return -ENOMEM; + } + + start_pfn = __phys_to_pfn(*dev_bus_addr); + for (pfn = start_pfn, i = 0; pfn < start_pfn + nr_pages; pfn++, i++) + pages[i] = pfn_to_page(pfn); + + state = decrease_reservation(nr_pages, GFP_KERNEL, pages); + if (state != BP_DONE) { + pr_err("Failed to decrease reservation for DMA buffer\n"); + ret = -ENOMEM; + goto out_undo; + } + +#ifdef CONFIG_XEN_HAVE_PVMMU + for (i = 0; i < nr_pages; i++) { + struct page *page = pages[i]; + + /* + * We don't support PV MMU when Linux and Xen is using + * different page granularity. + */ + BUILD_BUG_ON(XEN_PAGE_SIZE != PAGE_SIZE); + + ret = xen_alloc_p2m_entry(page_to_pfn(page)); + if (ret < 0) + goto out_undo; + } +#endif + mutex_unlock(&balloon_mutex); + return 0; + +out_undo: + mutex_unlock(&balloon_mutex); + free_dma_xenballooned_pages(dev, coherent, nr_pages, pages, + *vaddr, *dev_bus_addr); + return ret; +} +EXPORT_SYMBOL(alloc_dma_xenballooned_pages); + +void free_dma_xenballooned_pages(struct device *dev, bool coherent, + int nr_pages, struct page **pages, + void *vaddr, dma_addr_t dev_bus_addr) +{ + enum bp_state state; + + mutex_lock(&balloon_mutex); + + balloon_stats.dma_pages -= nr_pages; + + state = increase_reservation(nr_pages, pages); + if (state != BP_DONE) { + pr_err("Failed to increase reservation for DMA buffer\n"); + goto out; + } + + if (vaddr) { + if (coherent) + dma_free_coherent(dev, nr_pages << PAGE_SHIFT, + vaddr, dev_bus_addr); + else + dma_free_wc(dev, nr_pages << PAGE_SHIFT, + vaddr, dev_bus_addr); + } + +out: + mutex_unlock(&balloon_mutex); +} +EXPORT_SYMBOL(free_dma_xenballooned_pages); + + static void __init balloon_add_region(unsigned long start_pfn, unsigned long pages) { @@ -756,6 +892,8 @@ static int __init balloon_init(void) balloon_stats.retry_count = 1; balloon_stats.max_retry_count = RETRY_UNLIMITED; + balloon_stats.dma_pages = 0; + #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG set_online_page_callback(&xen_online_page); register_memory_notifier(&xen_memory_nb); diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index 79865b8901ba..62b8c1e4422b 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c @@ -123,6 +123,7 @@ subsys_initcall(balloon_init); BALLOON_SHOW(current_kb, "%lu\n", PAGES2KB(balloon_stats.current_pages)); BALLOON_SHOW(low_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_low)); BALLOON_SHOW(high_kb, "%lu\n", PAGES2KB(balloon_stats.balloon_high)); +BALLOON_SHOW(dma_kb, "%lu\n", PAGES2KB(balloon_stats.dma_pages)); static DEVICE_ULONG_ATTR(schedule_delay, 0444, balloon_stats.schedule_delay); static DEVICE_ULONG_ATTR(max_schedule_delay, 0644, balloon_stats.max_schedule_delay); @@ -205,6 +206,7 @@ static struct attribute *balloon_info_attrs[] = { &dev_attr_current_kb.attr, &dev_attr_low_kb.attr, &dev_attr_high_kb.attr, + &dev_attr_dma_kb.attr, NULL }; diff --git a/include/xen/balloon.h b/include/xen/balloon.h index d1767dfb0d95..eb917aa911e6 100644 --- a/include/xen/balloon.h +++ b/include/xen/balloon.h @@ -17,16 +17,25 @@ struct balloon_stats { unsigned long max_schedule_delay; unsigned long retry_count; unsigned long max_retry_count; + unsigned long dma_pages; }; extern struct balloon_stats balloon_stats; +struct device; + void balloon_set_new_target(unsigned long target); int alloc_xenballooned_pages(int nr_pages, struct page **pages); void free_xenballooned_pages(int nr_pages, struct page **pages); -struct device; +int alloc_dma_xenballooned_pages(struct device *dev, bool coherent, + int nr_pages, struct page **pages, + void **vaddr, dma_addr_t *dev_bus_addr); +void free_dma_xenballooned_pages(struct device *dev, bool coherent, + int nr_pages, struct page **pages, + void *vaddr, dma_addr_t dev_bus_addr); + #ifdef CONFIG_XEN_SELFBALLOONING extern int register_xen_selfballooning(struct device *dev); #else -- 2.17.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Oleksandr Andrushchenko Subject: [Xen-devel][RFC 1/3] xen/balloon: Allow allocating DMA buffers Date: Thu, 17 May 2018 11:26:02 +0300 Message-ID: <20180517082604.14828-2-andr2000@gmail.com> References: <20180517082604.14828-1-andr2000@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x243.google.com (mail-lf0-x243.google.com [IPv6:2a00:1450:4010:c07::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6AE756E6D0 for ; Thu, 17 May 2018 08:26:15 +0000 (UTC) Received: by mail-lf0-x243.google.com with SMTP id r2-v6so7470439lff.4 for ; Thu, 17 May 2018 01:26:15 -0700 (PDT) In-Reply-To: <20180517082604.14828-1-andr2000@gmail.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com Cc: andr2000@gmail.com, daniel.vetter@intel.com, dongwon.kim@intel.com, Oleksandr Andrushchenko List-Id: dri-devel@lists.freedesktop.org RnJvbTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5kcl9hbmRydXNoY2hlbmtvQGVw YW0uY29tPgoKU2lnbmVkLW9mZi1ieTogT2xla3NhbmRyIEFuZHJ1c2hjaGVua28gPG9sZWtzYW5k cl9hbmRydXNoY2hlbmtvQGVwYW0uY29tPgotLS0KIGRyaXZlcnMveGVuL2JhbGxvb24uYyAgICAg fCAyMTQgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0KIGRyaXZlcnMveGVu L3hlbi1iYWxsb29uLmMgfCAgIDIgKwogaW5jbHVkZS94ZW4vYmFsbG9vbi5oICAgICB8ICAxMSAr LQogMyBmaWxlcyBjaGFuZ2VkLCAxODggaW5zZXJ0aW9ucygrKSwgMzkgZGVsZXRpb25zKC0pCgpk aWZmIC0tZ2l0IGEvZHJpdmVycy94ZW4vYmFsbG9vbi5jIGIvZHJpdmVycy94ZW4vYmFsbG9vbi5j CmluZGV4IGU0ZGIxOWU4OGFiMS4uZTNhMTQ1YWE5ZjI5IDEwMDY0NAotLS0gYS9kcml2ZXJzL3hl bi9iYWxsb29uLmMKKysrIGIvZHJpdmVycy94ZW4vYmFsbG9vbi5jCkBAIC00MTUsOCArNDE1LDEw IEBAIHN0YXRpYyBib29sIGJhbGxvb25faXNfaW5mbGF0ZWQodm9pZCkKIAlyZXR1cm4gYmFsbG9v bl9zdGF0cy5iYWxsb29uX2xvdyB8fCBiYWxsb29uX3N0YXRzLmJhbGxvb25faGlnaDsKIH0KIAot c3RhdGljIGVudW0gYnBfc3RhdGUgaW5jcmVhc2VfcmVzZXJ2YXRpb24odW5zaWduZWQgbG9uZyBu cl9wYWdlcykKK3N0YXRpYyBlbnVtIGJwX3N0YXRlIGluY3JlYXNlX3Jlc2VydmF0aW9uKHVuc2ln bmVkIGxvbmcgbnJfcGFnZXMsCisJCQkJCSAgc3RydWN0IHBhZ2UgKipleHRfcGFnZXMpCiB7CisJ ZW51bSBicF9zdGF0ZSByZXQgPSBCUF9ET05FOwogCWludCByYzsKIAl1bnNpZ25lZCBsb25nIGk7 CiAJc3RydWN0IHBhZ2UgICAqcGFnZTsKQEAgLTQyNSwzMiArNDI3LDQ5IEBAIHN0YXRpYyBlbnVt IGJwX3N0YXRlIGluY3JlYXNlX3Jlc2VydmF0aW9uKHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMpCiAJ CS5leHRlbnRfb3JkZXIgPSBFWFRFTlRfT1JERVIsCiAJCS5kb21pZCAgICAgICAgPSBET01JRF9T RUxGCiAJfTsKKwl4ZW5fcGZuX3QgKmZyYW1lczsKIAotCWlmIChucl9wYWdlcyA+IEFSUkFZX1NJ WkUoZnJhbWVfbGlzdCkpCi0JCW5yX3BhZ2VzID0gQVJSQVlfU0laRShmcmFtZV9saXN0KTsKKwlp ZiAobnJfcGFnZXMgPiBBUlJBWV9TSVpFKGZyYW1lX2xpc3QpKSB7CisJCWZyYW1lcyA9IGtjYWxs b2MobnJfcGFnZXMsIHNpemVvZih4ZW5fcGZuX3QpLCBHRlBfS0VSTkVMKTsKKwkJaWYgKCFmcmFt ZXMpCisJCQlyZXR1cm4gQlBfRUNBTkNFTEVEOworCX0gZWxzZSB7CisJCWZyYW1lcyA9IGZyYW1l X2xpc3Q7CisJfQogCi0JcGFnZSA9IGxpc3RfZmlyc3RfZW50cnlfb3JfbnVsbCgmYmFsbG9vbmVk X3BhZ2VzLCBzdHJ1Y3QgcGFnZSwgbHJ1KTsKLQlmb3IgKGkgPSAwOyBpIDwgbnJfcGFnZXM7IGkr KykgewotCQlpZiAoIXBhZ2UpIHsKLQkJCW5yX3BhZ2VzID0gaTsKLQkJCWJyZWFrOwotCQl9CisJ LyogWEVOTUVNX3BvcHVsYXRlX3BoeXNtYXAgcmVxdWlyZXMgYSBQRk4gYmFzZWQgb24gWGVuCisJ ICogZ3JhbnVsYXJpdHkuCisJICovCisJaWYgKGV4dF9wYWdlcykgeworCQlmb3IgKGkgPSAwOyBp IDwgbnJfcGFnZXM7IGkrKykKKwkJCWZyYW1lc1tpXSA9IHBhZ2VfdG9feGVuX3BmbihleHRfcGFn ZXNbaV0pOworCX0gZWxzZSB7CisJCXBhZ2UgPSBsaXN0X2ZpcnN0X2VudHJ5X29yX251bGwoJmJh bGxvb25lZF9wYWdlcywKKwkJCQkJCXN0cnVjdCBwYWdlLCBscnUpOworCQlmb3IgKGkgPSAwOyBp IDwgbnJfcGFnZXM7IGkrKykgeworCQkJaWYgKCFwYWdlKSB7CisJCQkJbnJfcGFnZXMgPSBpOwor CQkJCWJyZWFrOworCQkJfQogCi0JCS8qIFhFTk1FTV9wb3B1bGF0ZV9waHlzbWFwIHJlcXVpcmVz IGEgUEZOIGJhc2VkIG9uIFhlbgotCQkgKiBncmFudWxhcml0eS4KLQkJICovCi0JCWZyYW1lX2xp c3RbaV0gPSBwYWdlX3RvX3hlbl9wZm4ocGFnZSk7Ci0JCXBhZ2UgPSBiYWxsb29uX25leHRfcGFn ZShwYWdlKTsKKwkJCWZyYW1lc1tpXSA9IHBhZ2VfdG9feGVuX3BmbihwYWdlKTsKKwkJCXBhZ2Ug PSBiYWxsb29uX25leHRfcGFnZShwYWdlKTsKKwkJfQogCX0KIAotCXNldF94ZW5fZ3Vlc3RfaGFu ZGxlKHJlc2VydmF0aW9uLmV4dGVudF9zdGFydCwgZnJhbWVfbGlzdCk7CisJc2V0X3hlbl9ndWVz dF9oYW5kbGUocmVzZXJ2YXRpb24uZXh0ZW50X3N0YXJ0LCBmcmFtZXMpOwogCXJlc2VydmF0aW9u Lm5yX2V4dGVudHMgPSBucl9wYWdlczsKIAlyYyA9IEhZUEVSVklTT1JfbWVtb3J5X29wKFhFTk1F TV9wb3B1bGF0ZV9waHlzbWFwLCAmcmVzZXJ2YXRpb24pOwotCWlmIChyYyA8PSAwKQotCQlyZXR1 cm4gQlBfRUFHQUlOOworCWlmIChyYyA8PSAwKSB7CisJCXJldCA9IEJQX0VBR0FJTjsKKwkJZ290 byBvdXQ7CisJfQogCiAJZm9yIChpID0gMDsgaSA8IHJjOyBpKyspIHsKLQkJcGFnZSA9IGJhbGxv b25fcmV0cmlldmUoZmFsc2UpOworCQlpZiAoZXh0X3BhZ2VzKQorCQkJcGFnZSA9IGV4dF9wYWdl c1tpXTsKKwkJZWxzZQorCQkJcGFnZSA9IGJhbGxvb25fcmV0cmlldmUoZmFsc2UpOwogCQlCVUdf T04ocGFnZSA9PSBOVUxMKTsKIAogI2lmZGVmIENPTkZJR19YRU5fSEFWRV9QVk1NVQpAQCAtNDYz LDE0ICs0ODIsMTQgQEAgc3RhdGljIGVudW0gYnBfc3RhdGUgaW5jcmVhc2VfcmVzZXJ2YXRpb24o dW5zaWduZWQgbG9uZyBucl9wYWdlcykKIAkJaWYgKCF4ZW5fZmVhdHVyZShYRU5GRUFUX2F1dG9f dHJhbnNsYXRlZF9waHlzbWFwKSkgewogCQkJdW5zaWduZWQgbG9uZyBwZm4gPSBwYWdlX3RvX3Bm bihwYWdlKTsKIAotCQkJc2V0X3BoeXNfdG9fbWFjaGluZShwZm4sIGZyYW1lX2xpc3RbaV0pOwor CQkJc2V0X3BoeXNfdG9fbWFjaGluZShwZm4sIGZyYW1lc1tpXSk7CiAKIAkJCS8qIExpbmsgYmFj ayBpbnRvIHRoZSBwYWdlIHRhYmxlcyBpZiBub3QgaGlnaG1lbS4gKi8KIAkJCWlmICghUGFnZUhp Z2hNZW0ocGFnZSkpIHsKIAkJCQlpbnQgcmV0OwogCQkJCXJldCA9IEhZUEVSVklTT1JfdXBkYXRl X3ZhX21hcHBpbmcoCiAJCQkJCQkodW5zaWduZWQgbG9uZylfX3ZhKHBmbiA8PCBQQUdFX1NISUZU KSwKLQkJCQkJCW1mbl9wdGUoZnJhbWVfbGlzdFtpXSwgUEFHRV9LRVJORUwpLAorCQkJCQkJbWZu X3B0ZShmcmFtZXNbaV0sIFBBR0VfS0VSTkVMKSwKIAkJCQkJCTApOwogCQkJCUJVR19PTihyZXQp OwogCQkJfQpAQCAtNDc4LDE1ICs0OTcsMjIgQEAgc3RhdGljIGVudW0gYnBfc3RhdGUgaW5jcmVh c2VfcmVzZXJ2YXRpb24odW5zaWduZWQgbG9uZyBucl9wYWdlcykKICNlbmRpZgogCiAJCS8qIFJl bGlucXVpc2ggdGhlIHBhZ2UgYmFjayB0byB0aGUgYWxsb2NhdG9yLiAqLwotCQlfX2ZyZWVfcmVz ZXJ2ZWRfcGFnZShwYWdlKTsKKwkJaWYgKCFleHRfcGFnZXMpCisJCQlfX2ZyZWVfcmVzZXJ2ZWRf cGFnZShwYWdlKTsKIAl9CiAKLQliYWxsb29uX3N0YXRzLmN1cnJlbnRfcGFnZXMgKz0gcmM7CisJ aWYgKCFleHRfcGFnZXMpCisJCWJhbGxvb25fc3RhdHMuY3VycmVudF9wYWdlcyArPSByYzsKIAot CXJldHVybiBCUF9ET05FOworb3V0OgorCWlmIChmcmFtZXMgIT0gZnJhbWVfbGlzdCkKKwkJa2Zy ZWUoZnJhbWVzKTsKKworCXJldHVybiByZXQ7CiB9CiAKLXN0YXRpYyBlbnVtIGJwX3N0YXRlIGRl Y3JlYXNlX3Jlc2VydmF0aW9uKHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMsIGdmcF90IGdmcCkKK3N0 YXRpYyBlbnVtIGJwX3N0YXRlIGRlY3JlYXNlX3Jlc2VydmF0aW9uKHVuc2lnbmVkIGxvbmcgbnJf cGFnZXMsIGdmcF90IGdmcCwKKwkJCQkJICBzdHJ1Y3QgcGFnZSAqKmV4dF9wYWdlcykKIHsKIAll bnVtIGJwX3N0YXRlIHN0YXRlID0gQlBfRE9ORTsKIAl1bnNpZ25lZCBsb25nIGk7CkBAIC00OTgs MTYgKzUyNCwyNiBAQCBzdGF0aWMgZW51bSBicF9zdGF0ZSBkZWNyZWFzZV9yZXNlcnZhdGlvbih1 bnNpZ25lZCBsb25nIG5yX3BhZ2VzLCBnZnBfdCBnZnApCiAJCS5kb21pZCAgICAgICAgPSBET01J RF9TRUxGCiAJfTsKIAlMSVNUX0hFQUQocGFnZXMpOworCXhlbl9wZm5fdCAqZnJhbWVzOwogCi0J aWYgKG5yX3BhZ2VzID4gQVJSQVlfU0laRShmcmFtZV9saXN0KSkKLQkJbnJfcGFnZXMgPSBBUlJB WV9TSVpFKGZyYW1lX2xpc3QpOworCWlmIChucl9wYWdlcyA+IEFSUkFZX1NJWkUoZnJhbWVfbGlz dCkpIHsKKwkJZnJhbWVzID0ga2NhbGxvYyhucl9wYWdlcywgc2l6ZW9mKHhlbl9wZm5fdCksIEdG UF9LRVJORUwpOworCQlpZiAoIWZyYW1lcykKKwkJCXJldHVybiBCUF9FQ0FOQ0VMRUQ7CisJfSBl bHNlIHsKKwkJZnJhbWVzID0gZnJhbWVfbGlzdDsKKwl9CiAKIAlmb3IgKGkgPSAwOyBpIDwgbnJf cGFnZXM7IGkrKykgewotCQlwYWdlID0gYWxsb2NfcGFnZShnZnApOwotCQlpZiAocGFnZSA9PSBO VUxMKSB7Ci0JCQlucl9wYWdlcyA9IGk7Ci0JCQlzdGF0ZSA9IEJQX0VBR0FJTjsKLQkJCWJyZWFr OworCQlpZiAoZXh0X3BhZ2VzKSB7CisJCQlwYWdlID0gZXh0X3BhZ2VzW2ldOworCQl9IGVsc2Ug eworCQkJcGFnZSA9IGFsbG9jX3BhZ2UoZ2ZwKTsKKwkJCWlmIChwYWdlID09IE5VTEwpIHsKKwkJ CQlucl9wYWdlcyA9IGk7CisJCQkJc3RhdGUgPSBCUF9FQUdBSU47CisJCQkJYnJlYWs7CisJCQl9 CiAJCX0KIAkJc2NydWJfcGFnZShwYWdlKTsKIAkJbGlzdF9hZGQoJnBhZ2UtPmxydSwgJnBhZ2Vz KTsKQEAgLTUyOSw3ICs1NjUsNyBAQCBzdGF0aWMgZW51bSBicF9zdGF0ZSBkZWNyZWFzZV9yZXNl cnZhdGlvbih1bnNpZ25lZCBsb25nIG5yX3BhZ2VzLCBnZnBfdCBnZnApCiAJaSA9IDA7CiAJbGlz dF9mb3JfZWFjaF9lbnRyeV9zYWZlKHBhZ2UsIHRtcCwgJnBhZ2VzLCBscnUpIHsKIAkJLyogWEVO TUVNX2RlY3JlYXNlX3Jlc2VydmF0aW9uIHJlcXVpcmVzIGEgR0ZOICovCi0JCWZyYW1lX2xpc3Rb aSsrXSA9IHhlbl9wYWdlX3RvX2dmbihwYWdlKTsKKwkJZnJhbWVzW2krK10gPSB4ZW5fcGFnZV90 b19nZm4ocGFnZSk7CiAKICNpZmRlZiBDT05GSUdfWEVOX0hBVkVfUFZNTVUKIAkJLyoKQEAgLTU1 MiwxOCArNTg4LDIyIEBAIHN0YXRpYyBlbnVtIGJwX3N0YXRlIGRlY3JlYXNlX3Jlc2VydmF0aW9u KHVuc2lnbmVkIGxvbmcgbnJfcGFnZXMsIGdmcF90IGdmcCkKICNlbmRpZgogCQlsaXN0X2RlbCgm cGFnZS0+bHJ1KTsKIAotCQliYWxsb29uX2FwcGVuZChwYWdlKTsKKwkJaWYgKCFleHRfcGFnZXMp CisJCQliYWxsb29uX2FwcGVuZChwYWdlKTsKIAl9CiAKIAlmbHVzaF90bGJfYWxsKCk7CiAKLQlz ZXRfeGVuX2d1ZXN0X2hhbmRsZShyZXNlcnZhdGlvbi5leHRlbnRfc3RhcnQsIGZyYW1lX2xpc3Qp OworCXNldF94ZW5fZ3Vlc3RfaGFuZGxlKHJlc2VydmF0aW9uLmV4dGVudF9zdGFydCwgZnJhbWVz KTsKIAlyZXNlcnZhdGlvbi5ucl9leHRlbnRzICAgPSBucl9wYWdlczsKIAlyZXQgPSBIWVBFUlZJ U09SX21lbW9yeV9vcChYRU5NRU1fZGVjcmVhc2VfcmVzZXJ2YXRpb24sICZyZXNlcnZhdGlvbik7 CiAJQlVHX09OKHJldCAhPSBucl9wYWdlcyk7CiAKLQliYWxsb29uX3N0YXRzLmN1cnJlbnRfcGFn ZXMgLT0gbnJfcGFnZXM7CisJaWYgKCFleHRfcGFnZXMpCisJCWJhbGxvb25fc3RhdHMuY3VycmVu dF9wYWdlcyAtPSBucl9wYWdlczsKIAorCWlmIChmcmFtZXMgIT0gZnJhbWVfbGlzdCkKKwkJa2Zy ZWUoZnJhbWVzKTsKIAlyZXR1cm4gc3RhdGU7CiB9CiAKQEAgLTU4NiwxMyArNjI2LDEzIEBAIHN0 YXRpYyB2b2lkIGJhbGxvb25fcHJvY2VzcyhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCiAKIAkJ aWYgKGNyZWRpdCA+IDApIHsKIAkJCWlmIChiYWxsb29uX2lzX2luZmxhdGVkKCkpCi0JCQkJc3Rh dGUgPSBpbmNyZWFzZV9yZXNlcnZhdGlvbihjcmVkaXQpOworCQkJCXN0YXRlID0gaW5jcmVhc2Vf cmVzZXJ2YXRpb24oY3JlZGl0LCBOVUxMKTsKIAkJCWVsc2UKIAkJCQlzdGF0ZSA9IHJlc2VydmVf YWRkaXRpb25hbF9tZW1vcnkoKTsKIAkJfQogCiAJCWlmIChjcmVkaXQgPCAwKQotCQkJc3RhdGUg PSBkZWNyZWFzZV9yZXNlcnZhdGlvbigtY3JlZGl0LCBHRlBfQkFMTE9PTik7CisJCQlzdGF0ZSA9 IGRlY3JlYXNlX3Jlc2VydmF0aW9uKC1jcmVkaXQsIEdGUF9CQUxMT09OLCBOVUxMKTsKIAogCQlz dGF0ZSA9IHVwZGF0ZV9zY2hlZHVsZShzdGF0ZSk7CiAKQEAgLTYzMSw3ICs2NzEsNyBAQCBzdGF0 aWMgaW50IGFkZF9iYWxsb29uZWRfcGFnZXMoaW50IG5yX3BhZ2VzKQogCQl9CiAJfQogCi0Jc3Qg PSBkZWNyZWFzZV9yZXNlcnZhdGlvbihucl9wYWdlcywgR0ZQX1VTRVIpOworCXN0ID0gZGVjcmVh c2VfcmVzZXJ2YXRpb24obnJfcGFnZXMsIEdGUF9VU0VSLCBOVUxMKTsKIAlpZiAoc3QgIT0gQlBf RE9ORSkKIAkJcmV0dXJuIC1FTk9NRU07CiAKQEAgLTcxMCw2ICs3NTAsMTAyIEBAIHZvaWQgZnJl ZV94ZW5iYWxsb29uZWRfcGFnZXMoaW50IG5yX3BhZ2VzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKQog fQogRVhQT1JUX1NZTUJPTChmcmVlX3hlbmJhbGxvb25lZF9wYWdlcyk7CiAKK2ludCBhbGxvY19k bWFfeGVuYmFsbG9vbmVkX3BhZ2VzKHN0cnVjdCBkZXZpY2UgKmRldiwgYm9vbCBjb2hlcmVudCwK KwkJCQkgaW50IG5yX3BhZ2VzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzLAorCQkJCSB2b2lkICoqdmFk ZHIsIGRtYV9hZGRyX3QgKmRldl9idXNfYWRkcikKK3sKKwllbnVtIGJwX3N0YXRlIHN0YXRlOwor CXVuc2lnbmVkIGxvbmcgcGZuLCBzdGFydF9wZm47CisJaW50IGksIHJldDsKKworCW11dGV4X2xv Y2soJmJhbGxvb25fbXV0ZXgpOworCisJYmFsbG9vbl9zdGF0cy5kbWFfcGFnZXMgKz0gbnJfcGFn ZXM7CisKKwlpZiAoY29oZXJlbnQpCisJCSp2YWRkciA9IGRtYV9hbGxvY19jb2hlcmVudChkZXYs IG5yX3BhZ2VzIDw8IFBBR0VfU0hJRlQsCisJCQkJCSAgICBkZXZfYnVzX2FkZHIsCisJCQkJCSAg ICBHRlBfS0VSTkVMIHwgX19HRlBfTk9XQVJOKTsKKworCWVsc2UKKwkJKnZhZGRyID0gZG1hX2Fs bG9jX3djKGRldiwgbnJfcGFnZXMgPDwgUEFHRV9TSElGVCwKKwkJCQkgICAgICBkZXZfYnVzX2Fk ZHIsCisJCQkJICAgICAgR0ZQX0tFUk5FTCB8IF9fR0ZQX05PV0FSTik7CisJaWYgKCEqdmFkZHIp IHsKKwkJcHJfZXJyKCJGYWlsZWQgdG8gYWxsb2NhdGUgRE1BIGJ1ZmZlciBvZiBzaXplICVkXG4i LAorCQkgICAgICAgbnJfcGFnZXMgPDwgUEFHRV9TSElGVCk7CisJCW11dGV4X3VubG9jaygmYmFs bG9vbl9tdXRleCk7CisJCXJldHVybiAtRU5PTUVNOworCX0KKworCXN0YXJ0X3BmbiA9IF9fcGh5 c190b19wZm4oKmRldl9idXNfYWRkcik7CisJZm9yIChwZm4gPSBzdGFydF9wZm4sIGkgPSAwOyBw Zm4gPCBzdGFydF9wZm4gKyBucl9wYWdlczsgcGZuKyssIGkrKykKKwkJcGFnZXNbaV0gPSBwZm5f dG9fcGFnZShwZm4pOworCisJc3RhdGUgPSBkZWNyZWFzZV9yZXNlcnZhdGlvbihucl9wYWdlcywg R0ZQX0tFUk5FTCwgcGFnZXMpOworCWlmIChzdGF0ZSAhPSBCUF9ET05FKSB7CisJCXByX2Vycigi RmFpbGVkIHRvIGRlY3JlYXNlIHJlc2VydmF0aW9uIGZvciBETUEgYnVmZmVyXG4iKTsKKwkJcmV0 ID0gLUVOT01FTTsKKwkJZ290byBvdXRfdW5kbzsKKwl9CisKKyNpZmRlZiBDT05GSUdfWEVOX0hB VkVfUFZNTVUKKwlmb3IgKGkgPSAwOyBpIDwgbnJfcGFnZXM7IGkrKykgeworCQlzdHJ1Y3QgcGFn ZSAqcGFnZSA9IHBhZ2VzW2ldOworCisJCS8qCisJCSAqIFdlIGRvbid0IHN1cHBvcnQgUFYgTU1V IHdoZW4gTGludXggYW5kIFhlbiBpcyB1c2luZworCQkgKiBkaWZmZXJlbnQgcGFnZSBncmFudWxh cml0eS4KKwkJICovCisJCUJVSUxEX0JVR19PTihYRU5fUEFHRV9TSVpFICE9IFBBR0VfU0laRSk7 CisKKwkJcmV0ID0geGVuX2FsbG9jX3AybV9lbnRyeShwYWdlX3RvX3BmbihwYWdlKSk7CisJCWlm IChyZXQgPCAwKQorCQkJZ290byBvdXRfdW5kbzsKKwl9CisjZW5kaWYKKwltdXRleF91bmxvY2so JmJhbGxvb25fbXV0ZXgpOworCXJldHVybiAwOworCitvdXRfdW5kbzoKKwltdXRleF91bmxvY2so JmJhbGxvb25fbXV0ZXgpOworCWZyZWVfZG1hX3hlbmJhbGxvb25lZF9wYWdlcyhkZXYsIGNvaGVy ZW50LCBucl9wYWdlcywgcGFnZXMsCisJCQkJICAgICp2YWRkciwgKmRldl9idXNfYWRkcik7CisJ cmV0dXJuIHJldDsKK30KK0VYUE9SVF9TWU1CT0woYWxsb2NfZG1hX3hlbmJhbGxvb25lZF9wYWdl cyk7CisKK3ZvaWQgZnJlZV9kbWFfeGVuYmFsbG9vbmVkX3BhZ2VzKHN0cnVjdCBkZXZpY2UgKmRl diwgYm9vbCBjb2hlcmVudCwKKwkJCQkgaW50IG5yX3BhZ2VzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2Vz LAorCQkJCSB2b2lkICp2YWRkciwgZG1hX2FkZHJfdCBkZXZfYnVzX2FkZHIpCit7CisJZW51bSBi cF9zdGF0ZSBzdGF0ZTsKKworCW11dGV4X2xvY2soJmJhbGxvb25fbXV0ZXgpOworCisJYmFsbG9v bl9zdGF0cy5kbWFfcGFnZXMgLT0gbnJfcGFnZXM7CisKKwlzdGF0ZSA9IGluY3JlYXNlX3Jlc2Vy dmF0aW9uKG5yX3BhZ2VzLCBwYWdlcyk7CisJaWYgKHN0YXRlICE9IEJQX0RPTkUpIHsKKwkJcHJf ZXJyKCJGYWlsZWQgdG8gaW5jcmVhc2UgcmVzZXJ2YXRpb24gZm9yIERNQSBidWZmZXJcbiIpOwor CQlnb3RvIG91dDsKKwl9CisKKwlpZiAodmFkZHIpIHsKKwkJaWYgKGNvaGVyZW50KQorCQkJZG1h X2ZyZWVfY29oZXJlbnQoZGV2LCBucl9wYWdlcyA8PCBQQUdFX1NISUZULAorCQkJCQkgIHZhZGRy LCBkZXZfYnVzX2FkZHIpOworCQllbHNlCisJCQlkbWFfZnJlZV93YyhkZXYsIG5yX3BhZ2VzIDw8 IFBBR0VfU0hJRlQsCisJCQkJICAgIHZhZGRyLCBkZXZfYnVzX2FkZHIpOworCX0KKworb3V0Ogor CW11dGV4X3VubG9jaygmYmFsbG9vbl9tdXRleCk7Cit9CitFWFBPUlRfU1lNQk9MKGZyZWVfZG1h X3hlbmJhbGxvb25lZF9wYWdlcyk7CisKKwogc3RhdGljIHZvaWQgX19pbml0IGJhbGxvb25fYWRk X3JlZ2lvbih1bnNpZ25lZCBsb25nIHN0YXJ0X3BmbiwKIAkJCQkgICAgICB1bnNpZ25lZCBsb25n IHBhZ2VzKQogewpAQCAtNzU2LDYgKzg5Miw4IEBAIHN0YXRpYyBpbnQgX19pbml0IGJhbGxvb25f aW5pdCh2b2lkKQogCWJhbGxvb25fc3RhdHMucmV0cnlfY291bnQgPSAxOwogCWJhbGxvb25fc3Rh dHMubWF4X3JldHJ5X2NvdW50ID0gUkVUUllfVU5MSU1JVEVEOwogCisJYmFsbG9vbl9zdGF0cy5k bWFfcGFnZXMgPSAwOworCiAjaWZkZWYgQ09ORklHX1hFTl9CQUxMT09OX01FTU9SWV9IT1RQTFVH CiAJc2V0X29ubGluZV9wYWdlX2NhbGxiYWNrKCZ4ZW5fb25saW5lX3BhZ2UpOwogCXJlZ2lzdGVy X21lbW9yeV9ub3RpZmllcigmeGVuX21lbW9yeV9uYik7CmRpZmYgLS1naXQgYS9kcml2ZXJzL3hl bi94ZW4tYmFsbG9vbi5jIGIvZHJpdmVycy94ZW4veGVuLWJhbGxvb24uYwppbmRleCA3OTg2NWI4 OTAxYmEuLjYyYjhjMWU0NDIyYiAxMDA2NDQKLS0tIGEvZHJpdmVycy94ZW4veGVuLWJhbGxvb24u YworKysgYi9kcml2ZXJzL3hlbi94ZW4tYmFsbG9vbi5jCkBAIC0xMjMsNiArMTIzLDcgQEAgc3Vi c3lzX2luaXRjYWxsKGJhbGxvb25faW5pdCk7CiBCQUxMT09OX1NIT1coY3VycmVudF9rYiwgIiVs dVxuIiwgUEFHRVMyS0IoYmFsbG9vbl9zdGF0cy5jdXJyZW50X3BhZ2VzKSk7CiBCQUxMT09OX1NI T1cobG93X2tiLCAiJWx1XG4iLCBQQUdFUzJLQihiYWxsb29uX3N0YXRzLmJhbGxvb25fbG93KSk7 CiBCQUxMT09OX1NIT1coaGlnaF9rYiwgIiVsdVxuIiwgUEFHRVMyS0IoYmFsbG9vbl9zdGF0cy5i YWxsb29uX2hpZ2gpKTsKK0JBTExPT05fU0hPVyhkbWFfa2IsICIlbHVcbiIsIFBBR0VTMktCKGJh bGxvb25fc3RhdHMuZG1hX3BhZ2VzKSk7CiAKIHN0YXRpYyBERVZJQ0VfVUxPTkdfQVRUUihzY2hl ZHVsZV9kZWxheSwgMDQ0NCwgYmFsbG9vbl9zdGF0cy5zY2hlZHVsZV9kZWxheSk7CiBzdGF0aWMg REVWSUNFX1VMT05HX0FUVFIobWF4X3NjaGVkdWxlX2RlbGF5LCAwNjQ0LCBiYWxsb29uX3N0YXRz Lm1heF9zY2hlZHVsZV9kZWxheSk7CkBAIC0yMDUsNiArMjA2LDcgQEAgc3RhdGljIHN0cnVjdCBh dHRyaWJ1dGUgKmJhbGxvb25faW5mb19hdHRyc1tdID0gewogCSZkZXZfYXR0cl9jdXJyZW50X2ti LmF0dHIsCiAJJmRldl9hdHRyX2xvd19rYi5hdHRyLAogCSZkZXZfYXR0cl9oaWdoX2tiLmF0dHIs CisJJmRldl9hdHRyX2RtYV9rYi5hdHRyLAogCU5VTEwKIH07CiAKZGlmZiAtLWdpdCBhL2luY2x1 ZGUveGVuL2JhbGxvb24uaCBiL2luY2x1ZGUveGVuL2JhbGxvb24uaAppbmRleCBkMTc2N2RmYjBk OTUuLmViOTE3YWE5MTFlNiAxMDA2NDQKLS0tIGEvaW5jbHVkZS94ZW4vYmFsbG9vbi5oCisrKyBi L2luY2x1ZGUveGVuL2JhbGxvb24uaApAQCAtMTcsMTYgKzE3LDI1IEBAIHN0cnVjdCBiYWxsb29u X3N0YXRzIHsKIAl1bnNpZ25lZCBsb25nIG1heF9zY2hlZHVsZV9kZWxheTsKIAl1bnNpZ25lZCBs b25nIHJldHJ5X2NvdW50OwogCXVuc2lnbmVkIGxvbmcgbWF4X3JldHJ5X2NvdW50OworCXVuc2ln bmVkIGxvbmcgZG1hX3BhZ2VzOwogfTsKIAogZXh0ZXJuIHN0cnVjdCBiYWxsb29uX3N0YXRzIGJh bGxvb25fc3RhdHM7CiAKK3N0cnVjdCBkZXZpY2U7CisKIHZvaWQgYmFsbG9vbl9zZXRfbmV3X3Rh cmdldCh1bnNpZ25lZCBsb25nIHRhcmdldCk7CiAKIGludCBhbGxvY194ZW5iYWxsb29uZWRfcGFn ZXMoaW50IG5yX3BhZ2VzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKIHZvaWQgZnJlZV94ZW5iYWxs b29uZWRfcGFnZXMoaW50IG5yX3BhZ2VzLCBzdHJ1Y3QgcGFnZSAqKnBhZ2VzKTsKIAotc3RydWN0 IGRldmljZTsKK2ludCBhbGxvY19kbWFfeGVuYmFsbG9vbmVkX3BhZ2VzKHN0cnVjdCBkZXZpY2Ug KmRldiwgYm9vbCBjb2hlcmVudCwKKwkJCQkgaW50IG5yX3BhZ2VzLCBzdHJ1Y3QgcGFnZSAqKnBh Z2VzLAorCQkJCSB2b2lkICoqdmFkZHIsIGRtYV9hZGRyX3QgKmRldl9idXNfYWRkcik7Cit2b2lk IGZyZWVfZG1hX3hlbmJhbGxvb25lZF9wYWdlcyhzdHJ1Y3QgZGV2aWNlICpkZXYsIGJvb2wgY29o ZXJlbnQsCisJCQkJIGludCBucl9wYWdlcywgc3RydWN0IHBhZ2UgKipwYWdlcywKKwkJCQkgdm9p ZCAqdmFkZHIsIGRtYV9hZGRyX3QgZGV2X2J1c19hZGRyKTsKKwogI2lmZGVmIENPTkZJR19YRU5f U0VMRkJBTExPT05JTkcKIGV4dGVybiBpbnQgcmVnaXN0ZXJfeGVuX3NlbGZiYWxsb29uaW5nKHN0 cnVjdCBkZXZpY2UgKmRldik7CiAjZWxzZQotLSAKMi4xNy4wCgpfX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1k ZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcv bWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK