From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42279) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bXAv4-0007HN-R0 for qemu-devel@nongnu.org; Tue, 09 Aug 2016 13:34:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bXAuy-0004az-LF for qemu-devel@nongnu.org; Tue, 09 Aug 2016 13:34:25 -0400 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:36767) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bXAuy-0004aP-9L for qemu-devel@nongnu.org; Tue, 09 Aug 2016 13:34:20 -0400 Received: by mail-wm0-x244.google.com with SMTP id i138so4558077wmf.3 for ; Tue, 09 Aug 2016 10:34:19 -0700 (PDT) References: <1470146790-6168-1-git-send-email-paulinaszubarczyk@gmail.com> <1470146790-6168-3-git-send-email-paulinaszubarczyk@gmail.com> <20160809165602.GD1835@perard.uk.xensource.com> From: Paulina Szubarczyk Message-ID: <57AA1416.6020307@gmail.com> Date: Tue, 9 Aug 2016 19:34:14 +0200 MIME-Version: 1.0 In-Reply-To: <20160809165602.GD1835@perard.uk.xensource.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v4 2/2] qdisk - hw/block/xen_disk: grant copy implementation List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony PERARD Cc: xen-devel@lists.xenproject.org, roger.pau@citrix.com, wei.liu2@citrix.com, ian.jackson@eu.citrix.com, david.vrabel@citrix.com, sstabellini@kernel.org, qemu-devel@nongnu.org On 08/09/2016 06:56 PM, Anthony PERARD wrote: > On Tue, Aug 02, 2016 at 04:06:30PM +0200, Paulina Szubarczyk wrote: >> Copy data operated on during request from/to local buffers to/from >> the grant references. >> >> Before grant copy operation local buffers must be allocated what is >> done by calling ioreq_init_copy_buffers. For the 'read' operation, >> first, the qemu device invokes the read operation on local buffers >> and on the completion grant copy is called and buffers are freed. >> For the 'write' operation grant copy is performed before invoking >> write by qemu device. >> >> A new value 'feature_grant_copy' is added to recognize when the >> grant copy operation is supported by a guest. >> >> Signed-off-by: Paulina Szubarczyk >> --- >> Changes since v3: >> - qemu_memalign/qemu_free is used instead function allocating >> memory from xc. >> - removed the get_buffer function instead there is a direct call >> to qemu_memalign. >> - moved ioreq_copy for write operation to ioreq_runio_qemu_aio. >> - added struct xengnttab_grant_copy_segment_t and stub in >> xen_common.h for version of xen earlier then 480. >> - added checking for version 480 to configure. The test repeats >> all the operation that are required for version < 480 and >> checks if xengnttab_grant_copy() is implemented. >> >> * I did not change the way of testing if grant_copy operation is >> implemented. As far as I understand if the code from >> gnttab_unimp.c is used then the gnttab device is unavailable >> and the handler to gntdev would be invalid. But if the handler >> is valid then the ioctl should return operation unimplemented >> if the gntdev does not implement the operation. >> --- >> configure | 56 +++++++++++++++++ >> hw/block/xen_disk.c | 142 ++++++++++++++++++++++++++++++++++++++++++-- >> include/hw/xen/xen_common.h | 25 ++++++++ >> 3 files changed, 218 insertions(+), 5 deletions(-) >> >> diff --git a/configure b/configure >> index f57fcc6..b5bf7d4 100755 >> --- a/configure >> +++ b/configure >> @@ -1956,6 +1956,62 @@ EOF >> /* >> * If we have stable libs the we don't want the libxc compat >> * layers, regardless of what CFLAGS we may have been given. >> + * >> + * Also, check if xengnttab_grant_copy_segment_t is defined and >> + * grant copy operation is implemented. >> + */ >> +#undef XC_WANT_COMPAT_EVTCHN_API >> +#undef XC_WANT_COMPAT_GNTTAB_API >> +#undef XC_WANT_COMPAT_MAP_FOREIGN_API >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#if !defined(HVM_MAX_VCPUS) >> +# error HVM_MAX_VCPUS not defined >> +#endif >> +int main(void) { >> + xc_interface *xc = NULL; >> + xenforeignmemory_handle *xfmem; >> + xenevtchn_handle *xe; >> + xengnttab_handle *xg; >> + xen_domain_handle_t handle; >> + xengnttab_grant_copy_segment_t* seg = NULL; >> + >> + xs_daemon_open(); >> + >> + xc = xc_interface_open(0, 0, 0); >> + xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0); >> + xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0); >> + xc_hvm_inject_msi(xc, 0, 0xf0000000, 0x00000000); >> + xc_hvm_create_ioreq_server(xc, 0, HVM_IOREQSRV_BUFIOREQ_ATOMIC, NULL); >> + xc_domain_create(xc, 0, handle, 0, NULL, NULL); >> + >> + xfmem = xenforeignmemory_open(0, 0); >> + xenforeignmemory_map(xfmem, 0, 0, 0, 0, 0); >> + >> + xe = xenevtchn_open(0, 0); >> + xenevtchn_fd(xe); >> + >> + xg = xengnttab_open(0, 0); >> + xengnttab_map_grant_ref(xg, 0, 0, 0); >> + xengnttab_grant_copy(xg, 0, seg); >> + >> + return 0; >> +} >> +EOF >> + compile_prog "" "$xen_libs $xen_stable_libs" >> + then >> + xen_ctrl_version=480 >> + xen=yes >> + elif >> + cat > $TMPC <> +/* >> + * If we have stable libs the we don't want the libxc compat >> + * layers, regardless of what CFLAGS we may have been given. >> */ >> #undef XC_WANT_COMPAT_EVTCHN_API >> #undef XC_WANT_COMPAT_GNTTAB_API >> diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c >> index 3b8ad33..2dd1464 100644 >> --- a/hw/block/xen_disk.c >> +++ b/hw/block/xen_disk.c >> @@ -119,6 +119,9 @@ struct XenBlkDev { >> unsigned int persistent_gnt_count; >> unsigned int max_grants; >> >> + /* Grant copy */ >> + gboolean feature_grant_copy; >> + >> /* qemu block driver */ >> DriveInfo *dinfo; >> BlockBackend *blk; >> @@ -489,6 +492,95 @@ static int ioreq_map(struct ioreq *ioreq) >> return 0; >> } >> >> +static void free_buffers(struct ioreq *ioreq) >> +{ >> + int i; >> + >> + for (i = 0; i < ioreq->v.niov; i++) { >> + ioreq->page[i] = NULL; >> + } >> + >> + qemu_vfree(ioreq->pages); >> +} >> + >> +static int ioreq_init_copy_buffers(struct ioreq *ioreq) >> +{ >> + int i; >> + >> + if (ioreq->v.niov == 0) { >> + return 0; >> + } >> + >> + ioreq->pages = qemu_memalign(XC_PAGE_SIZE, ioreq->v.niov * XC_PAGE_SIZE); >> + if (!ioreq->pages) { > > qemu_memalign never returns NULL, you don't have to check. > >> + return -1; >> + } >> + >> + for (i = 0; i < ioreq->v.niov; i++) { >> + ioreq->page[i] = ioreq->pages + i * XC_PAGE_SIZE; >> + ioreq->v.iov[i].iov_base = ioreq->page[i]; >> + } >> + >> + return 0; >> +} >> + >> +static int ioreq_copy(struct ioreq *ioreq) >> +{ >> + xengnttab_handle *gnt = ioreq->blkdev->xendev.gnttabdev; >> + xengnttab_grant_copy_segment_t segs[BLKIF_MAX_SEGMENTS_PER_REQUEST]; >> + int i, count = 0, r, rc; >> + int64_t file_blk = ioreq->blkdev->file_blk; >> + >> + if (ioreq->v.niov == 0) { >> + return 0; >> + } >> + >> + count = ioreq->v.niov; >> + >> + for (i = 0; i < count; i++) { >> + >> + if (ioreq->req.operation == BLKIF_OP_READ) { >> + segs[i].flags = GNTCOPY_dest_gref; >> + segs[i].dest.foreign.ref = ioreq->refs[i]; >> + segs[i].dest.foreign.domid = ioreq->domids[i]; >> + segs[i].dest.foreign.offset = ioreq->req.seg[i].first_sect * file_blk; >> + segs[i].source.virt = ioreq->v.iov[i].iov_base; >> + } else { >> + segs[i].flags = GNTCOPY_source_gref; >> + segs[i].source.foreign.ref = ioreq->refs[i]; >> + segs[i].source.foreign.domid = ioreq->domids[i]; >> + segs[i].source.foreign.offset = ioreq->req.seg[i].first_sect * file_blk; >> + segs[i].dest.virt = ioreq->v.iov[i].iov_base; >> + } >> + segs[i].len = (ioreq->req.seg[i].last_sect >> + - ioreq->req.seg[i].first_sect + 1) * file_blk; >> + >> + } >> + >> + rc = xengnttab_grant_copy(gnt, count, segs); >> + >> + if (rc) { >> + xen_be_printf(&ioreq->blkdev->xendev, 0, >> + "failed to copy data %d\n", rc); >> + ioreq->aio_errors++; >> + return -1; >> + } else { >> + r = 0; >> + } >> + >> + for (i = 0; i < count; i++) { >> + if (segs[i].status != GNTST_okay) { >> + xen_be_printf(&ioreq->blkdev->xendev, 3, >> + "failed to copy data %d for gref %d, domid %d\n", rc, >> + ioreq->refs[i], ioreq->domids[i]); >> + ioreq->aio_errors++; >> + r = -1; >> + } >> + } >> + >> + return r; >> +} >> + >> static int ioreq_runio_qemu_aio(struct ioreq *ioreq); >> >> static void qemu_aio_complete(void *opaque, int ret) >> @@ -511,8 +603,29 @@ static void qemu_aio_complete(void *opaque, int ret) >> return; >> } >> >> + if (ioreq->blkdev->feature_grant_copy) { >> + switch (ioreq->req.operation) { >> + case BLKIF_OP_READ: >> + /* in case of failure ioreq->aio_errors is increased */ >> + ioreq_copy(ioreq); >> + free_buffers(ioreq); >> + break; >> + case BLKIF_OP_WRITE: >> + case BLKIF_OP_FLUSH_DISKCACHE: >> + if (!ioreq->req.nr_segments) { >> + break; >> + } >> + free_buffers(ioreq); >> + break; >> + default: >> + break; >> + } >> + } >> + >> ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY; >> - ioreq_unmap(ioreq); >> + if (!ioreq->blkdev->feature_grant_copy) { >> + ioreq_unmap(ioreq); >> + } >> ioreq_finish(ioreq); >> switch (ioreq->req.operation) { >> case BLKIF_OP_WRITE: >> @@ -538,8 +651,20 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) >> { >> struct XenBlkDev *blkdev = ioreq->blkdev; >> >> - if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1) { >> - goto err_no_map; >> + if (ioreq->blkdev->feature_grant_copy) { >> + ioreq_init_copy_buffers(ioreq); >> + if (ioreq->req.nr_segments && (ioreq->req.operation == BLKIF_OP_WRITE || >> + ioreq->req.operation == BLKIF_OP_FLUSH_DISKCACHE)) { >> + if (ioreq_copy(ioreq)) { >> + free_buffers(ioreq); >> + goto err; >> + } >> + } >> + >> + } else { >> + if (ioreq->req.nr_segments && ioreq_map(ioreq)) { >> + goto err; >> + } >> } >> >> ioreq->aio_inflight++; >> @@ -582,6 +707,9 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) >> } >> default: >> /* unknown operation (shouldn't happen -- parse catches this) */ >> + if (!ioreq->blkdev->feature_grant_copy) { >> + ioreq_unmap(ioreq); >> + } >> goto err; >> } >> >> @@ -590,8 +718,6 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq) >> return 0; >> >> err: >> - ioreq_unmap(ioreq); >> -err_no_map: >> ioreq_finish(ioreq); >> ioreq->status = BLKIF_RSP_ERROR; >> return -1; >> @@ -1032,6 +1158,12 @@ static int blk_connect(struct XenDevice *xendev) >> >> xen_be_bind_evtchn(&blkdev->xendev); >> >> + blkdev->feature_grant_copy = >> + (xengnttab_grant_copy(blkdev->xendev.gnttabdev, 0, NULL) == 0); >> + >> + xen_be_printf(&blkdev->xendev, 3, "grant copy operation %s\n", >> + blkdev->feature_grant_copy ? "enabled" : "disabled"); >> + >> xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, " >> "remote port %d, local port %d\n", >> blkdev->xendev.protocol, blkdev->ring_ref, >> diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h >> index 640c31e..e80c61f 100644 >> --- a/include/hw/xen/xen_common.h >> +++ b/include/hw/xen/xen_common.h >> @@ -25,6 +25,31 @@ >> */ >> >> /* Xen 4.2 through 4.6 */ >> +#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 480 >> + >> +struct xengnttab_grant_copy_segment { >> + union xengnttab_copy_ptr { >> + void *virt; >> + struct { >> + uint32_t ref; >> + uint16_t offset; >> + uint16_t domid; >> + } foreign; >> + } source, dest; >> + uint16_t len; >> + uint16_t flags; >> + int16_t status; >> +}; > > I don't think it's a good idee to define a struct that is not going to > be used, and does not belong here. The typedef is OK. I added it since it is needed to know all the fields of that struct in ioreq_copy but if I could replace that function with stubs I will do that. > > In xen_disk.c, you could use "#if CONFIG_XEN_CTRL_INTERFACE_VERSION ..." > around free_buffers, ioreq_init_copy_buffers and ioreq_copy, and replace > them by stubs when Xen does not support grant copy. I think that would > be better. > > Also, could you try to compile again xen unstable, without your other patch? > Right now, it does not compile. That is true, I am sorry. I need to add the headers that are included in the #else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 471 */ #include #include #include #endif May I move that part to separate #if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 471 in that header? > >> +typedef struct xengnttab_grant_copy_segment xengnttab_grant_copy_segment_t; >> + >> +static inline int xengnttab_grant_copy(xengnttab_handle *xgt, uint32_t count, >> + xengnttab_grant_copy_segment_t *segs) >> +{ >> + return -1; > > return -ENOSYS would be more appropriate. > > > Otherwise, the patch looks good. > > Thanks, > Thank you, Paulina From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paulina Szubarczyk Subject: Re: [PATCH v4 2/2] qdisk - hw/block/xen_disk: grant copy implementation Date: Tue, 9 Aug 2016 19:34:14 +0200 Message-ID: <57AA1416.6020307@gmail.com> References: <1470146790-6168-1-git-send-email-paulinaszubarczyk@gmail.com> <1470146790-6168-3-git-send-email-paulinaszubarczyk@gmail.com> <20160809165602.GD1835@perard.uk.xensource.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bXAuz-00051p-6M for xen-devel@lists.xenproject.org; Tue, 09 Aug 2016 17:34:21 +0000 Received: by mail-wm0-f67.google.com with SMTP id o80so4581619wme.0 for ; Tue, 09 Aug 2016 10:34:19 -0700 (PDT) In-Reply-To: <20160809165602.GD1835@perard.uk.xensource.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: Anthony PERARD Cc: sstabellini@kernel.org, wei.liu2@citrix.com, ian.jackson@eu.citrix.com, qemu-devel@nongnu.org, david.vrabel@citrix.com, xen-devel@lists.xenproject.org, roger.pau@citrix.com List-Id: xen-devel@lists.xenproject.org CgpPbiAwOC8wOS8yMDE2IDA2OjU2IFBNLCBBbnRob255IFBFUkFSRCB3cm90ZToKPiBPbiBUdWUs IEF1ZyAwMiwgMjAxNiBhdCAwNDowNjozMFBNICswMjAwLCBQYXVsaW5hIFN6dWJhcmN6eWsgd3Jv dGU6Cj4+IENvcHkgZGF0YSBvcGVyYXRlZCBvbiBkdXJpbmcgcmVxdWVzdCBmcm9tL3RvIGxvY2Fs IGJ1ZmZlcnMgdG8vZnJvbQo+PiB0aGUgZ3JhbnQgcmVmZXJlbmNlcy4KPj4KPj4gQmVmb3JlIGdy YW50IGNvcHkgb3BlcmF0aW9uIGxvY2FsIGJ1ZmZlcnMgbXVzdCBiZSBhbGxvY2F0ZWQgd2hhdCBp cwo+PiBkb25lIGJ5IGNhbGxpbmcgaW9yZXFfaW5pdF9jb3B5X2J1ZmZlcnMuIEZvciB0aGUgJ3Jl YWQnIG9wZXJhdGlvbiwKPj4gZmlyc3QsIHRoZSBxZW11IGRldmljZSBpbnZva2VzIHRoZSByZWFk IG9wZXJhdGlvbiBvbiBsb2NhbCBidWZmZXJzCj4+IGFuZCBvbiB0aGUgY29tcGxldGlvbiBncmFu dCBjb3B5IGlzIGNhbGxlZCBhbmQgYnVmZmVycyBhcmUgZnJlZWQuCj4+IEZvciB0aGUgJ3dyaXRl JyBvcGVyYXRpb24gZ3JhbnQgY29weSBpcyBwZXJmb3JtZWQgYmVmb3JlIGludm9raW5nCj4+IHdy aXRlIGJ5IHFlbXUgZGV2aWNlLgo+Pgo+PiBBIG5ldyB2YWx1ZSAnZmVhdHVyZV9ncmFudF9jb3B5 JyBpcyBhZGRlZCB0byByZWNvZ25pemUgd2hlbiB0aGUKPj4gZ3JhbnQgY29weSBvcGVyYXRpb24g aXMgc3VwcG9ydGVkIGJ5IGEgZ3Vlc3QuCj4+Cj4+IFNpZ25lZC1vZmYtYnk6IFBhdWxpbmEgU3p1 YmFyY3p5ayA8cGF1bGluYXN6dWJhcmN6eWtAZ21haWwuY29tPgo+PiAtLS0KPj4gQ2hhbmdlcyBz aW5jZSB2MzoKPj4gLSBxZW11X21lbWFsaWduL3FlbXVfZnJlZSBpcyB1c2VkIGluc3RlYWQgZnVu Y3Rpb24gYWxsb2NhdGluZwo+PiAgICBtZW1vcnkgZnJvbSB4Yy4KPj4gLSByZW1vdmVkIHRoZSBn ZXRfYnVmZmVyIGZ1bmN0aW9uIGluc3RlYWQgdGhlcmUgaXMgYSBkaXJlY3QgY2FsbAo+PiAgICB0 byBxZW11X21lbWFsaWduLgo+PiAtIG1vdmVkIGlvcmVxX2NvcHkgZm9yIHdyaXRlIG9wZXJhdGlv biB0byBpb3JlcV9ydW5pb19xZW11X2Fpby4KPj4gLSBhZGRlZCBzdHJ1Y3QgeGVuZ250dGFiX2dy YW50X2NvcHlfc2VnbWVudF90IGFuZCBzdHViIGluCj4+ICAgIHhlbl9jb21tb24uaCBmb3IgdmVy c2lvbiBvZiB4ZW4gZWFybGllciB0aGVuIDQ4MC4KPj4gLSBhZGRlZCBjaGVja2luZyBmb3IgdmVy c2lvbiA0ODAgdG8gY29uZmlndXJlLiBUaGUgdGVzdCByZXBlYXRzCj4+ICAgIGFsbCB0aGUgb3Bl cmF0aW9uIHRoYXQgYXJlIHJlcXVpcmVkIGZvciB2ZXJzaW9uIDwgNDgwIGFuZAo+PiAgICBjaGVj a3MgaWYgeGVuZ250dGFiX2dyYW50X2NvcHkoKSBpcyBpbXBsZW1lbnRlZC4KPj4KPj4gKiBJIGRp ZCBub3QgY2hhbmdlIHRoZSB3YXkgb2YgdGVzdGluZyBpZiBncmFudF9jb3B5IG9wZXJhdGlvbiBp cwo+PiAgICBpbXBsZW1lbnRlZC4gQXMgZmFyIGFzIEkgdW5kZXJzdGFuZCBpZiB0aGUgY29kZSBm cm9tCj4+ICAgIGdudHRhYl91bmltcC5jIGlzIHVzZWQgdGhlbiB0aGUgZ250dGFiIGRldmljZSBp cyB1bmF2YWlsYWJsZQo+PiAgICBhbmQgdGhlIGhhbmRsZXIgdG8gZ250ZGV2IHdvdWxkIGJlIGlu dmFsaWQuIEJ1dCBpZiB0aGUgaGFuZGxlcgo+PiAgICBpcyB2YWxpZCB0aGVuIHRoZSBpb2N0bCBz aG91bGQgcmV0dXJuIG9wZXJhdGlvbiB1bmltcGxlbWVudGVkCj4+ICAgIGlmIHRoZSBnbnRkZXYg ZG9lcyBub3QgaW1wbGVtZW50IHRoZSBvcGVyYXRpb24uCj4+IC0tLQo+PiAgIGNvbmZpZ3VyZSAg ICAgICAgICAgICAgICAgICB8ICA1NiArKysrKysrKysrKysrKysrKwo+PiAgIGh3L2Jsb2NrL3hl bl9kaXNrLmMgICAgICAgICB8IDE0MiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKystLQo+PiAgIGluY2x1ZGUvaHcveGVuL3hlbl9jb21tb24uaCB8ICAyNSArKysrKysr Kwo+PiAgIDMgZmlsZXMgY2hhbmdlZCwgMjE4IGluc2VydGlvbnMoKyksIDUgZGVsZXRpb25zKC0p Cj4+Cj4+IGRpZmYgLS1naXQgYS9jb25maWd1cmUgYi9jb25maWd1cmUKPj4gaW5kZXggZjU3ZmNj Ni4uYjViZjdkNCAxMDA3NTUKPj4gLS0tIGEvY29uZmlndXJlCj4+ICsrKyBiL2NvbmZpZ3VyZQo+ PiBAQCAtMTk1Niw2ICsxOTU2LDYyIEBAIEVPRgo+PiAgIC8qCj4+ICAgICogSWYgd2UgaGF2ZSBz dGFibGUgbGlicyB0aGUgd2UgZG9uJ3Qgd2FudCB0aGUgbGlieGMgY29tcGF0Cj4+ICAgICogbGF5 ZXJzLCByZWdhcmRsZXNzIG9mIHdoYXQgQ0ZMQUdTIHdlIG1heSBoYXZlIGJlZW4gZ2l2ZW4uCj4+ ICsgKgo+PiArICogQWxzbywgY2hlY2sgaWYgeGVuZ250dGFiX2dyYW50X2NvcHlfc2VnbWVudF90 IGlzIGRlZmluZWQgYW5kCj4+ICsgKiBncmFudCBjb3B5IG9wZXJhdGlvbiBpcyBpbXBsZW1lbnRl ZC4KPj4gKyAqLwo+PiArI3VuZGVmIFhDX1dBTlRfQ09NUEFUX0VWVENITl9BUEkKPj4gKyN1bmRl ZiBYQ19XQU5UX0NPTVBBVF9HTlRUQUJfQVBJCj4+ICsjdW5kZWYgWENfV0FOVF9DT01QQVRfTUFQ X0ZPUkVJR05fQVBJCj4+ICsjaW5jbHVkZSA8eGVuY3RybC5oPgo+PiArI2luY2x1ZGUgPHhlbnN0 b3JlLmg+Cj4+ICsjaW5jbHVkZSA8eGVuZXZ0Y2huLmg+Cj4+ICsjaW5jbHVkZSA8eGVuZ250dGFi Lmg+Cj4+ICsjaW5jbHVkZSA8eGVuZm9yZWlnbm1lbW9yeS5oPgo+PiArI2luY2x1ZGUgPHN0ZGlu dC5oPgo+PiArI2luY2x1ZGUgPHhlbi9odm0vaHZtX2luZm9fdGFibGUuaD4KPj4gKyNpZiAhZGVm aW5lZChIVk1fTUFYX1ZDUFVTKQo+PiArIyBlcnJvciBIVk1fTUFYX1ZDUFVTIG5vdCBkZWZpbmVk Cj4+ICsjZW5kaWYKPj4gK2ludCBtYWluKHZvaWQpIHsKPj4gKyAgeGNfaW50ZXJmYWNlICp4YyA9 IE5VTEw7Cj4+ICsgIHhlbmZvcmVpZ25tZW1vcnlfaGFuZGxlICp4Zm1lbTsKPj4gKyAgeGVuZXZ0 Y2huX2hhbmRsZSAqeGU7Cj4+ICsgIHhlbmdudHRhYl9oYW5kbGUgKnhnOwo+PiArICB4ZW5fZG9t YWluX2hhbmRsZV90IGhhbmRsZTsKPj4gKyAgeGVuZ250dGFiX2dyYW50X2NvcHlfc2VnbWVudF90 KiBzZWcgPSBOVUxMOwo+PiArCj4+ICsgIHhzX2RhZW1vbl9vcGVuKCk7Cj4+ICsKPj4gKyAgeGMg PSB4Y19pbnRlcmZhY2Vfb3BlbigwLCAwLCAwKTsKPj4gKyAgeGNfaHZtX3NldF9tZW1fdHlwZSgw LCAwLCBIVk1NRU1fcmFtX3JvLCAwLCAwKTsKPj4gKyAgeGNfZG9tYWluX2FkZF90b19waHlzbWFw KDAsIDAsIFhFTk1BUFNQQUNFX2dtZm4sIDAsIDApOwo+PiArICB4Y19odm1faW5qZWN0X21zaSh4 YywgMCwgMHhmMDAwMDAwMCwgMHgwMDAwMDAwMCk7Cj4+ICsgIHhjX2h2bV9jcmVhdGVfaW9yZXFf c2VydmVyKHhjLCAwLCBIVk1fSU9SRVFTUlZfQlVGSU9SRVFfQVRPTUlDLCBOVUxMKTsKPj4gKyAg eGNfZG9tYWluX2NyZWF0ZSh4YywgMCwgaGFuZGxlLCAwLCBOVUxMLCBOVUxMKTsKPj4gKwo+PiAr ICB4Zm1lbSA9IHhlbmZvcmVpZ25tZW1vcnlfb3BlbigwLCAwKTsKPj4gKyAgeGVuZm9yZWlnbm1l bW9yeV9tYXAoeGZtZW0sIDAsIDAsIDAsIDAsIDApOwo+PiArCj4+ICsgIHhlID0geGVuZXZ0Y2hu X29wZW4oMCwgMCk7Cj4+ICsgIHhlbmV2dGNobl9mZCh4ZSk7Cj4+ICsKPj4gKyAgeGcgPSB4ZW5n bnR0YWJfb3BlbigwLCAwKTsKPj4gKyAgeGVuZ250dGFiX21hcF9ncmFudF9yZWYoeGcsIDAsIDAs IDApOwo+PiArICB4ZW5nbnR0YWJfZ3JhbnRfY29weSh4ZywgMCwgc2VnKTsKPj4gKwo+PiArICBy ZXR1cm4gMDsKPj4gK30KPj4gK0VPRgo+PiArICAgICAgY29tcGlsZV9wcm9nICIiICIkeGVuX2xp YnMgJHhlbl9zdGFibGVfbGlicyIKPj4gKyAgICB0aGVuCj4+ICsgICAgeGVuX2N0cmxfdmVyc2lv bj00ODAKPj4gKyAgICB4ZW49eWVzCj4+ICsgIGVsaWYKPj4gKyAgICAgIGNhdCA+ICRUTVBDIDw8 RU9GICYmCj4+ICsvKgo+PiArICogSWYgd2UgaGF2ZSBzdGFibGUgbGlicyB0aGUgd2UgZG9uJ3Qg d2FudCB0aGUgbGlieGMgY29tcGF0Cj4+ICsgKiBsYXllcnMsIHJlZ2FyZGxlc3Mgb2Ygd2hhdCBD RkxBR1Mgd2UgbWF5IGhhdmUgYmVlbiBnaXZlbi4KPj4gICAgKi8KPj4gICAjdW5kZWYgWENfV0FO VF9DT01QQVRfRVZUQ0hOX0FQSQo+PiAgICN1bmRlZiBYQ19XQU5UX0NPTVBBVF9HTlRUQUJfQVBJ Cj4+IGRpZmYgLS1naXQgYS9ody9ibG9jay94ZW5fZGlzay5jIGIvaHcvYmxvY2sveGVuX2Rpc2su Ywo+PiBpbmRleCAzYjhhZDMzLi4yZGQxNDY0IDEwMDY0NAo+PiAtLS0gYS9ody9ibG9jay94ZW5f ZGlzay5jCj4+ICsrKyBiL2h3L2Jsb2NrL3hlbl9kaXNrLmMKPj4gQEAgLTExOSw2ICsxMTksOSBA QCBzdHJ1Y3QgWGVuQmxrRGV2IHsKPj4gICAgICAgdW5zaWduZWQgaW50ICAgICAgICBwZXJzaXN0 ZW50X2dudF9jb3VudDsKPj4gICAgICAgdW5zaWduZWQgaW50ICAgICAgICBtYXhfZ3JhbnRzOwo+ Pgo+PiArICAgIC8qIEdyYW50IGNvcHkgKi8KPj4gKyAgICBnYm9vbGVhbiAgICAgICAgICAgIGZl YXR1cmVfZ3JhbnRfY29weTsKPj4gKwo+PiAgICAgICAvKiBxZW11IGJsb2NrIGRyaXZlciAqLwo+ PiAgICAgICBEcml2ZUluZm8gICAgICAgICAgICpkaW5mbzsKPj4gICAgICAgQmxvY2tCYWNrZW5k ICAgICAgICAqYmxrOwo+PiBAQCAtNDg5LDYgKzQ5Miw5NSBAQCBzdGF0aWMgaW50IGlvcmVxX21h cChzdHJ1Y3QgaW9yZXEgKmlvcmVxKQo+PiAgICAgICByZXR1cm4gMDsKPj4gICB9Cj4+Cj4+ICtz dGF0aWMgdm9pZCBmcmVlX2J1ZmZlcnMoc3RydWN0IGlvcmVxICppb3JlcSkKPj4gK3sKPj4gKyAg ICBpbnQgaTsKPj4gKwo+PiArICAgIGZvciAoaSA9IDA7IGkgPCBpb3JlcS0+di5uaW92OyBpKysp IHsKPj4gKyAgICAgICAgaW9yZXEtPnBhZ2VbaV0gPSBOVUxMOwo+PiArICAgIH0KPj4gKwo+PiAr ICAgIHFlbXVfdmZyZWUoaW9yZXEtPnBhZ2VzKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBp b3JlcV9pbml0X2NvcHlfYnVmZmVycyhzdHJ1Y3QgaW9yZXEgKmlvcmVxKQo+PiArewo+PiArICAg IGludCBpOwo+PiArCj4+ICsgICAgaWYgKGlvcmVxLT52Lm5pb3YgPT0gMCkgewo+PiArICAgICAg ICByZXR1cm4gMDsKPj4gKyAgICB9Cj4+ICsKPj4gKyAgICBpb3JlcS0+cGFnZXMgPSBxZW11X21l bWFsaWduKFhDX1BBR0VfU0laRSwgaW9yZXEtPnYubmlvdiAqIFhDX1BBR0VfU0laRSk7Cj4+ICsg ICAgaWYgKCFpb3JlcS0+cGFnZXMpIHsKPgo+IHFlbXVfbWVtYWxpZ24gbmV2ZXIgcmV0dXJucyBO VUxMLCB5b3UgZG9uJ3QgaGF2ZSB0byBjaGVjay4KPgo+PiArICAgICAgICByZXR1cm4gLTE7Cj4+ ICsgICAgfQo+PiArCj4+ICsgICAgZm9yIChpID0gMDsgaSA8IGlvcmVxLT52Lm5pb3Y7IGkrKykg ewo+PiArICAgICAgICBpb3JlcS0+cGFnZVtpXSA9IGlvcmVxLT5wYWdlcyArIGkgKiBYQ19QQUdF X1NJWkU7Cj4+ICsgICAgICAgIGlvcmVxLT52LmlvdltpXS5pb3ZfYmFzZSA9IGlvcmVxLT5wYWdl W2ldOwo+PiArICAgIH0KPj4gKwo+PiArICAgIHJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0 aWMgaW50IGlvcmVxX2NvcHkoc3RydWN0IGlvcmVxICppb3JlcSkKPj4gK3sKPj4gKyAgICB4ZW5n bnR0YWJfaGFuZGxlICpnbnQgPSBpb3JlcS0+YmxrZGV2LT54ZW5kZXYuZ250dGFiZGV2Owo+PiAr ICAgIHhlbmdudHRhYl9ncmFudF9jb3B5X3NlZ21lbnRfdCBzZWdzW0JMS0lGX01BWF9TRUdNRU5U U19QRVJfUkVRVUVTVF07Cj4+ICsgICAgaW50IGksIGNvdW50ID0gMCwgciwgcmM7Cj4+ICsgICAg aW50NjRfdCBmaWxlX2JsayA9IGlvcmVxLT5ibGtkZXYtPmZpbGVfYmxrOwo+PiArCj4+ICsgICAg aWYgKGlvcmVxLT52Lm5pb3YgPT0gMCkgewo+PiArICAgICAgICByZXR1cm4gMDsKPj4gKyAgICB9 Cj4+ICsKPj4gKyAgICBjb3VudCA9IGlvcmVxLT52Lm5pb3Y7Cj4+ICsKPj4gKyAgICBmb3IgKGkg PSAwOyBpIDwgY291bnQ7IGkrKykgewo+PiArCj4+ICsgICAgICAgIGlmIChpb3JlcS0+cmVxLm9w ZXJhdGlvbiA9PSBCTEtJRl9PUF9SRUFEKSB7Cj4+ICsgICAgICAgICAgICBzZWdzW2ldLmZsYWdz ID0gR05UQ09QWV9kZXN0X2dyZWY7Cj4+ICsgICAgICAgICAgICBzZWdzW2ldLmRlc3QuZm9yZWln bi5yZWYgPSBpb3JlcS0+cmVmc1tpXTsKPj4gKyAgICAgICAgICAgIHNlZ3NbaV0uZGVzdC5mb3Jl aWduLmRvbWlkID0gaW9yZXEtPmRvbWlkc1tpXTsKPj4gKyAgICAgICAgICAgIHNlZ3NbaV0uZGVz dC5mb3JlaWduLm9mZnNldCA9IGlvcmVxLT5yZXEuc2VnW2ldLmZpcnN0X3NlY3QgKiBmaWxlX2Js azsKPj4gKyAgICAgICAgICAgIHNlZ3NbaV0uc291cmNlLnZpcnQgPSBpb3JlcS0+di5pb3ZbaV0u aW92X2Jhc2U7Cj4+ICsgICAgICAgIH0gZWxzZSB7Cj4+ICsgICAgICAgICAgICBzZWdzW2ldLmZs YWdzID0gR05UQ09QWV9zb3VyY2VfZ3JlZjsKPj4gKyAgICAgICAgICAgIHNlZ3NbaV0uc291cmNl LmZvcmVpZ24ucmVmID0gaW9yZXEtPnJlZnNbaV07Cj4+ICsgICAgICAgICAgICBzZWdzW2ldLnNv dXJjZS5mb3JlaWduLmRvbWlkID0gaW9yZXEtPmRvbWlkc1tpXTsKPj4gKyAgICAgICAgICAgIHNl Z3NbaV0uc291cmNlLmZvcmVpZ24ub2Zmc2V0ID0gaW9yZXEtPnJlcS5zZWdbaV0uZmlyc3Rfc2Vj dCAqIGZpbGVfYmxrOwo+PiArICAgICAgICAgICAgc2Vnc1tpXS5kZXN0LnZpcnQgPSBpb3JlcS0+ di5pb3ZbaV0uaW92X2Jhc2U7Cj4+ICsgICAgICAgIH0KPj4gKyAgICAgICAgc2Vnc1tpXS5sZW4g PSAoaW9yZXEtPnJlcS5zZWdbaV0ubGFzdF9zZWN0Cj4+ICsgICAgICAgICAgICAgICAgICAgICAg IC0gaW9yZXEtPnJlcS5zZWdbaV0uZmlyc3Rfc2VjdCArIDEpICogZmlsZV9ibGs7Cj4+ICsKPj4g KyAgICB9Cj4+ICsKPj4gKyAgICByYyA9IHhlbmdudHRhYl9ncmFudF9jb3B5KGdudCwgY291bnQs IHNlZ3MpOwo+PiArCj4+ICsgICAgaWYgKHJjKSB7Cj4+ICsgICAgICAgIHhlbl9iZV9wcmludGYo JmlvcmVxLT5ibGtkZXYtPnhlbmRldiwgMCwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAiZmFp bGVkIHRvIGNvcHkgZGF0YSAlZFxuIiwgcmMpOwo+PiArICAgICAgICBpb3JlcS0+YWlvX2Vycm9y cysrOwo+PiArICAgICAgICByZXR1cm4gLTE7Cj4+ICsgICAgfSBlbHNlIHsKPj4gKyAgICAgICAg ciA9IDA7Cj4+ICsgICAgfQo+PiArCj4+ICsgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKysp IHsKPj4gKyAgICAgICAgaWYgKHNlZ3NbaV0uc3RhdHVzICE9IEdOVFNUX29rYXkpIHsKPj4gKyAg ICAgICAgICAgIHhlbl9iZV9wcmludGYoJmlvcmVxLT5ibGtkZXYtPnhlbmRldiwgMywKPj4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgImZhaWxlZCB0byBjb3B5IGRhdGEgJWQgZm9yIGdyZWYg JWQsIGRvbWlkICVkXG4iLCByYywKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW9yZXEt PnJlZnNbaV0sIGlvcmVxLT5kb21pZHNbaV0pOwo+PiArICAgICAgICAgICAgaW9yZXEtPmFpb19l cnJvcnMrKzsKPj4gKyAgICAgICAgICAgIHIgPSAtMTsKPj4gKyAgICAgICAgfQo+PiArICAgIH0K Pj4gKwo+PiArICAgIHJldHVybiByOwo+PiArfQo+PiArCj4+ICAgc3RhdGljIGludCBpb3JlcV9y dW5pb19xZW11X2FpbyhzdHJ1Y3QgaW9yZXEgKmlvcmVxKTsKPj4KPj4gICBzdGF0aWMgdm9pZCBx ZW11X2Fpb19jb21wbGV0ZSh2b2lkICpvcGFxdWUsIGludCByZXQpCj4+IEBAIC01MTEsOCArNjAz LDI5IEBAIHN0YXRpYyB2b2lkIHFlbXVfYWlvX2NvbXBsZXRlKHZvaWQgKm9wYXF1ZSwgaW50IHJl dCkKPj4gICAgICAgICAgIHJldHVybjsKPj4gICAgICAgfQo+Pgo+PiArICAgIGlmIChpb3JlcS0+ YmxrZGV2LT5mZWF0dXJlX2dyYW50X2NvcHkpIHsKPj4gKyAgICAgICAgc3dpdGNoIChpb3JlcS0+ cmVxLm9wZXJhdGlvbikgewo+PiArICAgICAgICBjYXNlIEJMS0lGX09QX1JFQUQ6Cj4+ICsgICAg ICAgICAgICAvKiBpbiBjYXNlIG9mIGZhaWx1cmUgaW9yZXEtPmFpb19lcnJvcnMgaXMgaW5jcmVh c2VkICovCj4+ICsgICAgICAgICAgICBpb3JlcV9jb3B5KGlvcmVxKTsKPj4gKyAgICAgICAgICAg IGZyZWVfYnVmZmVycyhpb3JlcSk7Cj4+ICsgICAgICAgICAgICBicmVhazsKPj4gKyAgICAgICAg Y2FzZSBCTEtJRl9PUF9XUklURToKPj4gKyAgICAgICAgY2FzZSBCTEtJRl9PUF9GTFVTSF9ESVNL Q0FDSEU6Cj4+ICsgICAgICAgICAgICBpZiAoIWlvcmVxLT5yZXEubnJfc2VnbWVudHMpIHsKPj4g KyAgICAgICAgICAgICAgICBicmVhazsKPj4gKyAgICAgICAgICAgIH0KPj4gKyAgICAgICAgICAg IGZyZWVfYnVmZmVycyhpb3JlcSk7Cj4+ICsgICAgICAgICAgICBicmVhazsKPj4gKyAgICAgICAg ZGVmYXVsdDoKPj4gKyAgICAgICAgICAgIGJyZWFrOwo+PiArICAgICAgICB9Cj4+ICsgICAgfQo+ PiArCj4+ICAgICAgIGlvcmVxLT5zdGF0dXMgPSBpb3JlcS0+YWlvX2Vycm9ycyA/IEJMS0lGX1JT UF9FUlJPUiA6IEJMS0lGX1JTUF9PS0FZOwo+PiAtICAgIGlvcmVxX3VubWFwKGlvcmVxKTsKPj4g KyAgICBpZiAoIWlvcmVxLT5ibGtkZXYtPmZlYXR1cmVfZ3JhbnRfY29weSkgewo+PiArICAgICAg ICBpb3JlcV91bm1hcChpb3JlcSk7Cj4+ICsgICAgfQo+PiAgICAgICBpb3JlcV9maW5pc2goaW9y ZXEpOwo+PiAgICAgICBzd2l0Y2ggKGlvcmVxLT5yZXEub3BlcmF0aW9uKSB7Cj4+ICAgICAgIGNh c2UgQkxLSUZfT1BfV1JJVEU6Cj4+IEBAIC01MzgsOCArNjUxLDIwIEBAIHN0YXRpYyBpbnQgaW9y ZXFfcnVuaW9fcWVtdV9haW8oc3RydWN0IGlvcmVxICppb3JlcSkKPj4gICB7Cj4+ICAgICAgIHN0 cnVjdCBYZW5CbGtEZXYgKmJsa2RldiA9IGlvcmVxLT5ibGtkZXY7Cj4+Cj4+IC0gICAgaWYgKGlv cmVxLT5yZXEubnJfc2VnbWVudHMgJiYgaW9yZXFfbWFwKGlvcmVxKSA9PSAtMSkgewo+PiAtICAg ICAgICBnb3RvIGVycl9ub19tYXA7Cj4+ICsgICAgaWYgKGlvcmVxLT5ibGtkZXYtPmZlYXR1cmVf Z3JhbnRfY29weSkgewo+PiArICAgICAgICBpb3JlcV9pbml0X2NvcHlfYnVmZmVycyhpb3JlcSk7 Cj4+ICsgICAgICAgIGlmIChpb3JlcS0+cmVxLm5yX3NlZ21lbnRzICYmIChpb3JlcS0+cmVxLm9w ZXJhdGlvbiA9PSBCTEtJRl9PUF9XUklURSB8fAo+PiArICAgICAgICAgICAgaW9yZXEtPnJlcS5v cGVyYXRpb24gPT0gQkxLSUZfT1BfRkxVU0hfRElTS0NBQ0hFKSkgewo+PiArICAgICAgICAgICAg aWYgKGlvcmVxX2NvcHkoaW9yZXEpKSB7Cj4+ICsgICAgICAgICAgICAgICAgZnJlZV9idWZmZXJz KGlvcmVxKTsKPj4gKyAgICAgICAgICAgICAgICBnb3RvIGVycjsKPj4gKyAgICAgICAgICAgIH0K Pj4gKyAgICAgICAgfQo+PiArCj4+ICsgICAgfSBlbHNlIHsKPj4gKyAgICAgICAgaWYgKGlvcmVx LT5yZXEubnJfc2VnbWVudHMgJiYgaW9yZXFfbWFwKGlvcmVxKSkgewo+PiArICAgICAgICAgICAg Z290byBlcnI7Cj4+ICsgICAgICAgIH0KPj4gICAgICAgfQo+Pgo+PiAgICAgICBpb3JlcS0+YWlv X2luZmxpZ2h0Kys7Cj4+IEBAIC01ODIsNiArNzA3LDkgQEAgc3RhdGljIGludCBpb3JlcV9ydW5p b19xZW11X2FpbyhzdHJ1Y3QgaW9yZXEgKmlvcmVxKQo+PiAgICAgICB9Cj4+ICAgICAgIGRlZmF1 bHQ6Cj4+ICAgICAgICAgICAvKiB1bmtub3duIG9wZXJhdGlvbiAoc2hvdWxkbid0IGhhcHBlbiAt LSBwYXJzZSBjYXRjaGVzIHRoaXMpICovCj4+ICsgICAgICAgIGlmICghaW9yZXEtPmJsa2Rldi0+ ZmVhdHVyZV9ncmFudF9jb3B5KSB7Cj4+ICsgICAgICAgICAgICBpb3JlcV91bm1hcChpb3JlcSk7 Cj4+ICsgICAgICAgIH0KPj4gICAgICAgICAgIGdvdG8gZXJyOwo+PiAgICAgICB9Cj4+Cj4+IEBA IC01OTAsOCArNzE4LDYgQEAgc3RhdGljIGludCBpb3JlcV9ydW5pb19xZW11X2FpbyhzdHJ1Y3Qg aW9yZXEgKmlvcmVxKQo+PiAgICAgICByZXR1cm4gMDsKPj4KPj4gICBlcnI6Cj4+IC0gICAgaW9y ZXFfdW5tYXAoaW9yZXEpOwo+PiAtZXJyX25vX21hcDoKPj4gICAgICAgaW9yZXFfZmluaXNoKGlv cmVxKTsKPj4gICAgICAgaW9yZXEtPnN0YXR1cyA9IEJMS0lGX1JTUF9FUlJPUjsKPj4gICAgICAg cmV0dXJuIC0xOwo+PiBAQCAtMTAzMiw2ICsxMTU4LDEyIEBAIHN0YXRpYyBpbnQgYmxrX2Nvbm5l Y3Qoc3RydWN0IFhlbkRldmljZSAqeGVuZGV2KQo+Pgo+PiAgICAgICB4ZW5fYmVfYmluZF9ldnRj aG4oJmJsa2Rldi0+eGVuZGV2KTsKPj4KPj4gKyAgICBibGtkZXYtPmZlYXR1cmVfZ3JhbnRfY29w eSA9Cj4+ICsgICAgICAgICAgICAgICAgKHhlbmdudHRhYl9ncmFudF9jb3B5KGJsa2Rldi0+eGVu ZGV2LmdudHRhYmRldiwgMCwgTlVMTCkgPT0gMCk7Cj4+ICsKPj4gKyAgICB4ZW5fYmVfcHJpbnRm KCZibGtkZXYtPnhlbmRldiwgMywgImdyYW50IGNvcHkgb3BlcmF0aW9uICVzXG4iLAo+PiArICAg ICAgICAgICAgICAgICAgYmxrZGV2LT5mZWF0dXJlX2dyYW50X2NvcHkgPyAiZW5hYmxlZCIgOiAi ZGlzYWJsZWQiKTsKPj4gKwo+PiAgICAgICB4ZW5fYmVfcHJpbnRmKCZibGtkZXYtPnhlbmRldiwg MSwgIm9rOiBwcm90byAlcywgcmluZy1yZWYgJWQsICIKPj4gICAgICAgICAgICAgICAgICAgICAi cmVtb3RlIHBvcnQgJWQsIGxvY2FsIHBvcnQgJWRcbiIsCj4+ICAgICAgICAgICAgICAgICAgICAg YmxrZGV2LT54ZW5kZXYucHJvdG9jb2wsIGJsa2Rldi0+cmluZ19yZWYsCj4+IGRpZmYgLS1naXQg YS9pbmNsdWRlL2h3L3hlbi94ZW5fY29tbW9uLmggYi9pbmNsdWRlL2h3L3hlbi94ZW5fY29tbW9u LmgKPj4gaW5kZXggNjQwYzMxZS4uZTgwYzYxZiAxMDA2NDQKPj4gLS0tIGEvaW5jbHVkZS9ody94 ZW4veGVuX2NvbW1vbi5oCj4+ICsrKyBiL2luY2x1ZGUvaHcveGVuL3hlbl9jb21tb24uaAo+PiBA QCAtMjUsNiArMjUsMzEgQEAKPj4gICAgKi8KPj4KPj4gICAvKiBYZW4gNC4yIHRocm91Z2ggNC42 ICovCj4+ICsjaWYgQ09ORklHX1hFTl9DVFJMX0lOVEVSRkFDRV9WRVJTSU9OIDwgNDgwCj4+ICsK Pj4gK3N0cnVjdCB4ZW5nbnR0YWJfZ3JhbnRfY29weV9zZWdtZW50IHsKPj4gKyAgICB1bmlvbiB4 ZW5nbnR0YWJfY29weV9wdHIgewo+PiArICAgICAgICB2b2lkICp2aXJ0Owo+PiArICAgICAgICBz dHJ1Y3Qgewo+PiArICAgICAgICAgICAgdWludDMyX3QgcmVmOwo+PiArICAgICAgICAgICAgdWlu dDE2X3Qgb2Zmc2V0Owo+PiArICAgICAgICAgICAgdWludDE2X3QgZG9taWQ7Cj4+ICsgICAgICAg IH0gZm9yZWlnbjsKPj4gKyAgICB9IHNvdXJjZSwgZGVzdDsKPj4gKyAgICB1aW50MTZfdCBsZW47 Cj4+ICsgICAgdWludDE2X3QgZmxhZ3M7Cj4+ICsgICAgaW50MTZfdCBzdGF0dXM7Cj4+ICt9Owo+ Cj4gSSBkb24ndCB0aGluayBpdCdzIGEgZ29vZCBpZGVlIHRvIGRlZmluZSBhIHN0cnVjdCB0aGF0 IGlzIG5vdCBnb2luZyB0bwo+IGJlIHVzZWQsIGFuZCBkb2VzIG5vdCBiZWxvbmcgaGVyZS4gVGhl IHR5cGVkZWYgaXMgT0suCgpJIGFkZGVkIGl0IHNpbmNlIGl0IGlzIG5lZWRlZCB0byBrbm93IGFs bCB0aGUgZmllbGRzIG9mIHRoYXQgc3RydWN0IGluIAppb3JlcV9jb3B5IGJ1dCBpZiBJIGNvdWxk IHJlcGxhY2UgdGhhdCBmdW5jdGlvbiB3aXRoIHN0dWJzIEkgd2lsbCBkbyB0aGF0LgoKPgo+IElu IHhlbl9kaXNrLmMsIHlvdSBjb3VsZCB1c2UgIiNpZiBDT05GSUdfWEVOX0NUUkxfSU5URVJGQUNF X1ZFUlNJT04gLi4uIgo+IGFyb3VuZCBmcmVlX2J1ZmZlcnMsIGlvcmVxX2luaXRfY29weV9idWZm ZXJzIGFuZCBpb3JlcV9jb3B5LCBhbmQgcmVwbGFjZQo+IHRoZW0gYnkgc3R1YnMgd2hlbiBYZW4g ZG9lcyBub3Qgc3VwcG9ydCBncmFudCBjb3B5LiBJIHRoaW5rIHRoYXQgd291bGQKPiBiZSBiZXR0 ZXIuCj4KPiBBbHNvLCBjb3VsZCB5b3UgdHJ5IHRvIGNvbXBpbGUgYWdhaW4geGVuIHVuc3RhYmxl LCB3aXRob3V0IHlvdXIgb3RoZXIgcGF0Y2g/Cj4gUmlnaHQgbm93LCBpdCBkb2VzIG5vdCBjb21w aWxlLgoKVGhhdCBpcyB0cnVlLCBJIGFtIHNvcnJ5LiBJIG5lZWQgdG8gYWRkIHRoZSBoZWFkZXJz IHRoYXQgYXJlIGluY2x1ZGVkIGluIAp0aGUKI2Vsc2UgLyogQ09ORklHX1hFTl9DVFJMX0lOVEVS RkFDRV9WRVJTSU9OID49IDQ3MSAqLwoKI2luY2x1ZGUgPHhlbmV2dGNobi5oPgojaW5jbHVkZSA8 eGVuZ250dGFiLmg+CiNpbmNsdWRlIDx4ZW5mb3JlaWdubWVtb3J5Lmg+CgojZW5kaWYKCk1heSBJ IG1vdmUgdGhhdCBwYXJ0IHRvIHNlcGFyYXRlICNpZiBDT05GSUdfWEVOX0NUUkxfSU5URVJGQUNF X1ZFUlNJT04gCiA+PSA0NzEgaW4gdGhhdCBoZWFkZXI/Cgo+Cj4+ICt0eXBlZGVmIHN0cnVjdCB4 ZW5nbnR0YWJfZ3JhbnRfY29weV9zZWdtZW50IHhlbmdudHRhYl9ncmFudF9jb3B5X3NlZ21lbnRf dDsKPj4gKwo+PiArc3RhdGljIGlubGluZSBpbnQgeGVuZ250dGFiX2dyYW50X2NvcHkoeGVuZ250 dGFiX2hhbmRsZSAqeGd0LCB1aW50MzJfdCBjb3VudCwKPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIHhlbmdudHRhYl9ncmFudF9jb3B5X3NlZ21lbnRfdCAqc2VncykK Pj4gK3sKPj4gKyAgICByZXR1cm4gLTE7Cj4KPiByZXR1cm4gLUVOT1NZUyB3b3VsZCBiZSBtb3Jl IGFwcHJvcHJpYXRlLgo+Cj4KPiBPdGhlcndpc2UsIHRoZSBwYXRjaCBsb29rcyBnb29kLgo+Cj4g VGhhbmtzLAo+ClRoYW5rIHlvdSwKClBhdWxpbmEKCl9fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fClhlbi1kZXZlbCBtYWlsaW5nIGxpc3QKWGVuLWRldmVsQGxp c3RzLnhlbi5vcmcKaHR0cHM6Ly9saXN0cy54ZW4ub3JnL3hlbi1kZXZlbAo=