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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 544F2C433F5 for ; Wed, 6 Oct 2021 17:41:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 414E86052B for ; Wed, 6 Oct 2021 17:41:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239570AbhJFRnL (ORCPT ); Wed, 6 Oct 2021 13:43:11 -0400 Received: from mx01.bbu.dsd.mx.bitdefender.com ([91.199.104.161]:53634 "EHLO mx01.bbu.dsd.mx.bitdefender.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233287AbhJFRmj (ORCPT ); Wed, 6 Oct 2021 13:42:39 -0400 Received: from smtp.bitdefender.com (smtp01.buh.bitdefender.com [10.17.80.75]) by mx01.bbu.dsd.mx.bitdefender.com (Postfix) with ESMTPS id 92F14307CAFD; Wed, 6 Oct 2021 20:31:11 +0300 (EEST) Received: from localhost (unknown [91.199.104.28]) by smtp.bitdefender.com (Postfix) with ESMTPSA id 777A9300F73A; Wed, 6 Oct 2021 20:31:11 +0300 (EEST) X-Is-Junk-Enabled: fGZTSsP0qEJE2AIKtlSuFiRRwg9xyHmJ From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= To: kvm@vger.kernel.org Cc: virtualization@lists.linux-foundation.org, Paolo Bonzini , Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Mathieu Tarral , Tamas K Lengyel , =?UTF-8?q?Mihai=20Don=C8=9Bu?= , =?UTF-8?q?Nicu=C8=99or=20C=C3=AE=C8=9Bu?= , =?UTF-8?q?Adalbert=20Laz=C4=83r?= Subject: [PATCH v12 43/77] KVM: introspection: handle vCPU commands Date: Wed, 6 Oct 2021 20:30:39 +0300 Message-Id: <20211006173113.26445-44-alazar@bitdefender.com> In-Reply-To: <20211006173113.26445-1-alazar@bitdefender.com> References: <20211006173113.26445-1-alazar@bitdefender.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Mihai Donțu Based on the common structure (kvmi_vcpu_hdr) used for all vCPU commands, the receiving thread validates and dispatches the message to the proper vCPU (adding the handling function to its jobs list). Signed-off-by: Mihai Donțu Co-developed-by: Nicușor Cîțu Signed-off-by: Nicușor Cîțu Co-developed-by: Adalbert Lazăr Signed-off-by: Adalbert Lazăr --- Documentation/virt/kvm/kvmi.rst | 8 ++ arch/x86/kvm/Makefile | 2 +- arch/x86/kvm/kvmi_msg.c | 17 ++++ include/uapi/linux/kvmi.h | 6 ++ virt/kvm/introspection/kvmi_int.h | 16 ++++ virt/kvm/introspection/kvmi_msg.c | 150 +++++++++++++++++++++++++++++- 6 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 arch/x86/kvm/kvmi_msg.c diff --git a/Documentation/virt/kvm/kvmi.rst b/Documentation/virt/kvm/kvmi.rst index c424acf01784..79152f47b30f 100644 --- a/Documentation/virt/kvm/kvmi.rst +++ b/Documentation/virt/kvm/kvmi.rst @@ -221,6 +221,14 @@ The following C structures are meant to be used directly when communicating over the wire. The peer that detects any size mismatch should simply close the connection and report the error. +The vCPU commands start with:: + + struct kvmi_vcpu_hdr { + __u16 vcpu; + __u16 padding1; + __u32 padding2; + } + 1. KVMI_GET_VERSION ------------------- diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index af58e1daf7cf..6b2e5f0524e5 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -14,7 +14,7 @@ kvm-y += $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ $(KVM)/eventfd.o $(KVM)/irqchip.o $(KVM)/vfio.o \ $(KVM)/dirty_ring.o $(KVM)/binary_stats.o kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o -kvm-$(CONFIG_KVM_INTROSPECTION) += $(KVMI)/kvmi.o $(KVMI)/kvmi_msg.o kvmi.o +kvm-$(CONFIG_KVM_INTROSPECTION) += $(KVMI)/kvmi.o $(KVMI)/kvmi_msg.o kvmi.o kvmi_msg.o kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \ i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \ diff --git a/arch/x86/kvm/kvmi_msg.c b/arch/x86/kvm/kvmi_msg.c new file mode 100644 index 000000000000..0a6edfe16f17 --- /dev/null +++ b/arch/x86/kvm/kvmi_msg.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KVM introspection (message handling) - x86 + * + * Copyright (C) 2020-2021 Bitdefender S.R.L. + * + */ + +#include "../../../virt/kvm/introspection/kvmi_int.h" + +static const kvmi_vcpu_msg_job_fct msg_vcpu[] = { +}; + +kvmi_vcpu_msg_job_fct kvmi_arch_vcpu_msg_handler(u16 id) +{ + return id < ARRAY_SIZE(msg_vcpu) ? msg_vcpu[id] : NULL; +} diff --git a/include/uapi/linux/kvmi.h b/include/uapi/linux/kvmi.h index 048afad01be6..7ba1c8758aba 100644 --- a/include/uapi/linux/kvmi.h +++ b/include/uapi/linux/kvmi.h @@ -107,4 +107,10 @@ struct kvmi_vm_write_physical { __u8 data[0]; }; +struct kvmi_vcpu_hdr { + __u16 vcpu; + __u16 padding1; + __u32 padding2; +}; + #endif /* _UAPI__LINUX_KVMI_H */ diff --git a/virt/kvm/introspection/kvmi_int.h b/virt/kvm/introspection/kvmi_int.h index c3aa12554c2b..c3e4da7e7f20 100644 --- a/virt/kvm/introspection/kvmi_int.h +++ b/virt/kvm/introspection/kvmi_int.h @@ -14,6 +14,18 @@ */ #define KVMI_MAX_MSG_SIZE (4096 * 2 - sizeof(struct kvmi_msg_hdr)) +struct kvmi_vcpu_msg_job { + struct { + struct kvmi_msg_hdr hdr; + struct kvmi_vcpu_hdr vcpu_hdr; + } *msg; + struct kvm_vcpu *vcpu; +}; + +typedef int (*kvmi_vcpu_msg_job_fct)(const struct kvmi_vcpu_msg_job *job, + const struct kvmi_msg_hdr *msg, + const void *req); + /* kvmi_msg.c */ bool kvmi_sock_get(struct kvm_introspection *kvmi, int fd); void kvmi_sock_shutdown(struct kvm_introspection *kvmi); @@ -28,6 +40,9 @@ bool kvmi_is_command_allowed(struct kvm_introspection *kvmi, u16 id); bool kvmi_is_event_allowed(struct kvm_introspection *kvmi, u16 id); bool kvmi_is_known_event(u16 id); bool kvmi_is_known_vm_event(u16 id); +int kvmi_add_job(struct kvm_vcpu *vcpu, + void (*fct)(struct kvm_vcpu *vcpu, void *ctx), + void *ctx, void (*free_fct)(void *ctx)); int kvmi_cmd_vm_control_events(struct kvm_introspection *kvmi, u16 event_id, bool enable); int kvmi_cmd_read_physical(struct kvm *kvm, u64 gpa, size_t size, @@ -40,5 +55,6 @@ int kvmi_cmd_write_physical(struct kvm *kvm, u64 gpa, size_t size, /* arch */ void kvmi_arch_init_vcpu_events_mask(unsigned long *supported); +kvmi_vcpu_msg_job_fct kvmi_arch_vcpu_msg_handler(u16 id); #endif diff --git a/virt/kvm/introspection/kvmi_msg.c b/virt/kvm/introspection/kvmi_msg.c index 697c307ea745..82e2b49a960e 100644 --- a/virt/kvm/introspection/kvmi_msg.c +++ b/virt/kvm/introspection/kvmi_msg.c @@ -13,6 +13,7 @@ typedef int (*kvmi_vm_msg_fct)(struct kvm_introspection *kvmi, const void *req); static bool is_vm_command(u16 id); +static bool is_vcpu_command(u16 id); bool kvmi_sock_get(struct kvm_introspection *kvmi, int fd) { @@ -104,6 +105,17 @@ static int kvmi_msg_vm_reply(struct kvm_introspection *kvmi, return kvmi_msg_reply(kvmi, msg, err, rpl, rpl_size); } +static struct kvm_vcpu *kvmi_get_vcpu(struct kvm_introspection *kvmi, + unsigned int vcpu_idx) +{ + struct kvm *kvm = kvmi->kvm; + + if (vcpu_idx >= atomic_read(&kvm->online_vcpus)) + return NULL; + + return kvm_get_vcpu(kvm, vcpu_idx); +} + static int handle_get_version(struct kvm_introspection *kvmi, const struct kvmi_msg_hdr *msg, const void *req) { @@ -125,7 +137,7 @@ static int handle_vm_check_command(struct kvm_introspection *kvmi, if (req->padding1 || req->padding2) ec = -KVM_EINVAL; - else if (!is_vm_command(req->id)) + else if (!is_vm_command(req->id) && !is_vcpu_command(req->id)) ec = -KVM_ENOENT; else if (!kvmi_is_command_allowed(kvmi, req->id)) ec = -KVM_EPERM; @@ -254,6 +266,74 @@ static bool is_vm_command(u16 id) return is_vm_message(id) && id != KVMI_VM_EVENT; } +/* + * These functions are executed from the vCPU thread. The receiving thread + * passes the messages using a newly allocated 'struct kvmi_vcpu_msg_job' + * and signals the vCPU to handle the message (which includes + * sending back the reply). + */ +static const kvmi_vcpu_msg_job_fct msg_vcpu[] = { +}; + +static kvmi_vcpu_msg_job_fct get_vcpu_msg_handler(u16 id) +{ + kvmi_vcpu_msg_job_fct fct; + + fct = id < ARRAY_SIZE(msg_vcpu) ? msg_vcpu[id] : NULL; + + if (!fct) + fct = kvmi_arch_vcpu_msg_handler(id); + + return fct; +} + +static bool is_vcpu_message(u16 id) +{ + bool is_vcpu_msg_id = id & 1; + + return is_vcpu_msg_id && !!get_vcpu_msg_handler(id); +} + +static bool is_vcpu_command(u16 id) +{ + return is_vcpu_message(id); +} + +static void kvmi_job_vcpu_msg(struct kvm_vcpu *vcpu, void *ctx) +{ + struct kvmi_vcpu_msg_job *job = ctx; + kvmi_vcpu_msg_job_fct fct; + int err; + + job->vcpu = vcpu; + + fct = get_vcpu_msg_handler(job->msg->hdr.id); + err = fct(job, &job->msg->hdr, job->msg + 1); + + /* + * The soft errors are sent with the reply. + * On hard errors, like this one, + * we shut down the socket. + */ + if (err) + kvmi_sock_shutdown(KVMI(vcpu->kvm)); +} + +static void kvmi_free_ctx(void *_ctx) +{ + const struct kvmi_vcpu_msg_job *ctx = _ctx; + + kvmi_msg_free(ctx->msg); + kfree(ctx); +} + +static int kvmi_msg_queue_to_vcpu(struct kvm_vcpu *vcpu, + const struct kvmi_vcpu_msg_job *cmd) +{ + return kvmi_add_job(vcpu, kvmi_job_vcpu_msg, (void *)cmd, + kvmi_free_ctx); +} + static struct kvmi_msg_hdr *kvmi_msg_recv(struct kvm_introspection *kvmi) { struct kvmi_msg_hdr *msg; @@ -307,9 +387,72 @@ static int kvmi_msg_handle_vm_cmd(struct kvm_introspection *kvmi, return kvmi_msg_do_vm_cmd(kvmi, msg); } +static bool vcpu_can_handle_messages(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.mp_state != KVM_MP_STATE_UNINITIALIZED; +} + +static int kvmi_get_vcpu_if_ready(struct kvm_introspection *kvmi, + unsigned int vcpu_idx, + struct kvm_vcpu **vcpu) +{ + *vcpu = kvmi_get_vcpu(kvmi, vcpu_idx); + if (*vcpu == NULL) + return -KVM_EINVAL; + + if (!vcpu_can_handle_messages(*vcpu)) + return -KVM_EAGAIN; + + return 0; +} + +static int kvmi_msg_dispatch_vcpu_msg(struct kvm_introspection *kvmi, + struct kvmi_msg_hdr *msg, + struct kvm_vcpu *vcpu) +{ + struct kvmi_vcpu_msg_job *job_cmd; + int err; + + job_cmd = kzalloc(sizeof(*job_cmd), GFP_KERNEL); + if (!job_cmd) + return -ENOMEM; + + job_cmd->msg = (void *)msg; + + err = kvmi_msg_queue_to_vcpu(vcpu, job_cmd); + if (err) + kfree(job_cmd); + + return err; +} + +static int kvmi_msg_handle_vcpu_msg(struct kvm_introspection *kvmi, + struct kvmi_msg_hdr *msg, + bool *queued) +{ + struct kvmi_vcpu_hdr *vcpu_hdr = (struct kvmi_vcpu_hdr *)(msg + 1); + struct kvm_vcpu *vcpu = NULL; + int err, ec; + + if (!kvmi_is_command_allowed(kvmi, msg->id)) + return kvmi_msg_vm_reply_ec(kvmi, msg, -KVM_EPERM); + + if (vcpu_hdr->padding1 || vcpu_hdr->padding2) + return kvmi_msg_vm_reply_ec(kvmi, msg, -KVM_EINVAL); + + ec = kvmi_get_vcpu_if_ready(kvmi, vcpu_hdr->vcpu, &vcpu); + if (ec) + return kvmi_msg_vm_reply_ec(kvmi, msg, ec); + + err = kvmi_msg_dispatch_vcpu_msg(kvmi, msg, vcpu); + *queued = err == 0; + return err; +} + bool kvmi_msg_process(struct kvm_introspection *kvmi) { struct kvmi_msg_hdr *msg; + bool queued = false; int err = -1; msg = kvmi_msg_recv(kvmi); @@ -318,10 +461,13 @@ bool kvmi_msg_process(struct kvm_introspection *kvmi) if (is_vm_command(msg->id)) err = kvmi_msg_handle_vm_cmd(kvmi, msg); + else if (is_vcpu_message(msg->id)) + err = kvmi_msg_handle_vcpu_msg(kvmi, msg, &queued); else err = kvmi_msg_vm_reply_ec(kvmi, msg, -KVM_ENOSYS); - kvmi_msg_free(msg); + if (!queued) + kvmi_msg_free(msg); out: return err == 0; } 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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12D64C433EF for ; Wed, 6 Oct 2021 17:50:48 +0000 (UTC) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (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 BDD71610EA for ; Wed, 6 Oct 2021 17:50:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org BDD71610EA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=bitdefender.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.linux-foundation.org Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 8F39860EF0; Wed, 6 Oct 2021 17:50:47 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id I0a2TH3eJzKL; Wed, 6 Oct 2021 17:50:46 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id F321A60EE9; Wed, 6 Oct 2021 17:50:45 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id CF1A5C0011; Wed, 6 Oct 2021 17:50:45 +0000 (UTC) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7999EC0028 for ; Wed, 6 Oct 2021 17:50:42 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 4186E405CC for ; Wed, 6 Oct 2021 17:50:41 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rD5S-eCj50-u for ; Wed, 6 Oct 2021 17:50:40 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.8.0 Received: from mx01.bbu.dsd.mx.bitdefender.com (mx01.bbu.dsd.mx.bitdefender.com [91.199.104.161]) by smtp4.osuosl.org (Postfix) with ESMTPS id 221E4405CD for ; Wed, 6 Oct 2021 17:50:40 +0000 (UTC) Received: from smtp.bitdefender.com (smtp01.buh.bitdefender.com [10.17.80.75]) by mx01.bbu.dsd.mx.bitdefender.com (Postfix) with ESMTPS id 92F14307CAFD; Wed, 6 Oct 2021 20:31:11 +0300 (EEST) Received: from localhost (unknown [91.199.104.28]) by smtp.bitdefender.com (Postfix) with ESMTPSA id 777A9300F73A; Wed, 6 Oct 2021 20:31:11 +0300 (EEST) X-Is-Junk-Enabled: fGZTSsP0qEJE2AIKtlSuFiRRwg9xyHmJ From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= To: kvm@vger.kernel.org Subject: [PATCH v12 43/77] KVM: introspection: handle vCPU commands Date: Wed, 6 Oct 2021 20:30:39 +0300 Message-Id: <20211006173113.26445-44-alazar@bitdefender.com> In-Reply-To: <20211006173113.26445-1-alazar@bitdefender.com> References: <20211006173113.26445-1-alazar@bitdefender.com> MIME-Version: 1.0 Cc: Tamas K Lengyel , Wanpeng Li , =?UTF-8?q?Nicu=C8=99or=20C=C3=AE=C8=9Bu?= , Sean Christopherson , Joerg Roedel , virtualization@lists.linux-foundation.org, =?UTF-8?q?Adalbert=20Laz=C4=83r?= , Mathieu Tarral , Paolo Bonzini , =?UTF-8?q?Mihai=20Don=C8=9Bu?= , Jim Mattson X-BeenThere: virtualization@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux virtualization List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: virtualization-bounces@lists.linux-foundation.org Sender: "Virtualization" RnJvbTogTWloYWkgRG9uyJt1IDxtZG9udHVAYml0ZGVmZW5kZXIuY29tPgoKQmFzZWQgb24gdGhl IGNvbW1vbiBzdHJ1Y3R1cmUgKGt2bWlfdmNwdV9oZHIpIHVzZWQgZm9yIGFsbCB2Q1BVIGNvbW1h bmRzLAp0aGUgcmVjZWl2aW5nIHRocmVhZCB2YWxpZGF0ZXMgYW5kIGRpc3BhdGNoZXMgdGhlIG1l c3NhZ2UgdG8gdGhlIHByb3Blcgp2Q1BVIChhZGRpbmcgdGhlIGhhbmRsaW5nIGZ1bmN0aW9uIHRv IGl0cyBqb2JzIGxpc3QpLgoKU2lnbmVkLW9mZi1ieTogTWloYWkgRG9uyJt1IDxtZG9udHVAYml0 ZGVmZW5kZXIuY29tPgpDby1kZXZlbG9wZWQtYnk6IE5pY3XImW9yIEPDrsibdSA8bmljdS5jaXR1 QGljbG91ZC5jb20+ClNpZ25lZC1vZmYtYnk6IE5pY3XImW9yIEPDrsibdSA8bmljdS5jaXR1QGlj bG91ZC5jb20+CkNvLWRldmVsb3BlZC1ieTogQWRhbGJlcnQgTGF6xINyIDxhbGF6YXJAYml0ZGVm ZW5kZXIuY29tPgpTaWduZWQtb2ZmLWJ5OiBBZGFsYmVydCBMYXrEg3IgPGFsYXphckBiaXRkZWZl bmRlci5jb20+Ci0tLQogRG9jdW1lbnRhdGlvbi92aXJ0L2t2bS9rdm1pLnJzdCAgIHwgICA4ICsr CiBhcmNoL3g4Ni9rdm0vTWFrZWZpbGUgICAgICAgICAgICAgfCAgIDIgKy0KIGFyY2gveDg2L2t2 bS9rdm1pX21zZy5jICAgICAgICAgICB8ICAxNyArKysrCiBpbmNsdWRlL3VhcGkvbGludXgva3Zt aS5oICAgICAgICAgfCAgIDYgKysKIHZpcnQva3ZtL2ludHJvc3BlY3Rpb24va3ZtaV9pbnQuaCB8 ICAxNiArKysrCiB2aXJ0L2t2bS9pbnRyb3NwZWN0aW9uL2t2bWlfbXNnLmMgfCAxNTAgKysrKysr KysrKysrKysrKysrKysrKysrKysrKystCiA2IGZpbGVzIGNoYW5nZWQsIDE5NiBpbnNlcnRpb25z KCspLCAzIGRlbGV0aW9ucygtKQogY3JlYXRlIG1vZGUgMTAwNjQ0IGFyY2gveDg2L2t2bS9rdm1p X21zZy5jCgpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi92aXJ0L2t2bS9rdm1pLnJzdCBiL0Rv Y3VtZW50YXRpb24vdmlydC9rdm0va3ZtaS5yc3QKaW5kZXggYzQyNGFjZjAxNzg0Li43OTE1MmY0 N2IzMGYgMTAwNjQ0Ci0tLSBhL0RvY3VtZW50YXRpb24vdmlydC9rdm0va3ZtaS5yc3QKKysrIGIv RG9jdW1lbnRhdGlvbi92aXJ0L2t2bS9rdm1pLnJzdApAQCAtMjIxLDYgKzIyMSwxNCBAQCBUaGUg Zm9sbG93aW5nIEMgc3RydWN0dXJlcyBhcmUgbWVhbnQgdG8gYmUgdXNlZCBkaXJlY3RseSB3aGVu IGNvbW11bmljYXRpbmcKIG92ZXIgdGhlIHdpcmUuIFRoZSBwZWVyIHRoYXQgZGV0ZWN0cyBhbnkg c2l6ZSBtaXNtYXRjaCBzaG91bGQgc2ltcGx5IGNsb3NlCiB0aGUgY29ubmVjdGlvbiBhbmQgcmVw b3J0IHRoZSBlcnJvci4KIAorVGhlIHZDUFUgY29tbWFuZHMgc3RhcnQgd2l0aDo6CisKKwlzdHJ1 Y3Qga3ZtaV92Y3B1X2hkciB7CisJCV9fdTE2IHZjcHU7CisJCV9fdTE2IHBhZGRpbmcxOworCQlf X3UzMiBwYWRkaW5nMjsKKwl9CisKIDEuIEtWTUlfR0VUX1ZFUlNJT04KIC0tLS0tLS0tLS0tLS0t LS0tLS0KIApkaWZmIC0tZ2l0IGEvYXJjaC94ODYva3ZtL01ha2VmaWxlIGIvYXJjaC94ODYva3Zt L01ha2VmaWxlCmluZGV4IGFmNThlMWRhZjdjZi4uNmIyZTVmMDUyNGU1IDEwMDY0NAotLS0gYS9h cmNoL3g4Ni9rdm0vTWFrZWZpbGUKKysrIGIvYXJjaC94ODYva3ZtL01ha2VmaWxlCkBAIC0xNCw3 ICsxNCw3IEBAIGt2bS15CQkJKz0gJChLVk0pL2t2bV9tYWluLm8gJChLVk0pL2NvYWxlc2NlZF9t bWlvLm8gXAogCQkJCSQoS1ZNKS9ldmVudGZkLm8gJChLVk0pL2lycWNoaXAubyAkKEtWTSkvdmZp by5vIFwKIAkJCQkkKEtWTSkvZGlydHlfcmluZy5vICQoS1ZNKS9iaW5hcnlfc3RhdHMubwoga3Zt LSQoQ09ORklHX0tWTV9BU1lOQ19QRikJKz0gJChLVk0pL2FzeW5jX3BmLm8KLWt2bS0kKENPTkZJ R19LVk1fSU5UUk9TUEVDVElPTikgKz0gJChLVk1JKS9rdm1pLm8gJChLVk1JKS9rdm1pX21zZy5v IGt2bWkubwora3ZtLSQoQ09ORklHX0tWTV9JTlRST1NQRUNUSU9OKSArPSAkKEtWTUkpL2t2bWku byAkKEtWTUkpL2t2bWlfbXNnLm8ga3ZtaS5vIGt2bWlfbXNnLm8KIAoga3ZtLXkJCQkrPSB4ODYu byBlbXVsYXRlLm8gaTgyNTkubyBpcnEubyBsYXBpYy5vIFwKIAkJCSAgIGk4MjU0Lm8gaW9hcGlj Lm8gaXJxX2NvbW0ubyBjcHVpZC5vIHBtdS5vIG10cnIubyBcCmRpZmYgLS1naXQgYS9hcmNoL3g4 Ni9rdm0va3ZtaV9tc2cuYyBiL2FyY2gveDg2L2t2bS9rdm1pX21zZy5jCm5ldyBmaWxlIG1vZGUg MTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uMGE2ZWRmZTE2ZjE3Ci0tLSAvZGV2L251bGwKKysr IGIvYXJjaC94ODYva3ZtL2t2bWlfbXNnLmMKQEAgLTAsMCArMSwxNyBAQAorLy8gU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKKy8qCisgKiBLVk0gaW50cm9zcGVjdGlvbiAobWVzc2Fn ZSBoYW5kbGluZykgLSB4ODYKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyMSBCaXRkZWZl bmRlciBTLlIuTC4KKyAqCisgKi8KKworI2luY2x1ZGUgIi4uLy4uLy4uL3ZpcnQva3ZtL2ludHJv c3BlY3Rpb24va3ZtaV9pbnQuaCIKKworc3RhdGljIGNvbnN0IGt2bWlfdmNwdV9tc2dfam9iX2Zj dCBtc2dfdmNwdVtdID0geworfTsKKwora3ZtaV92Y3B1X21zZ19qb2JfZmN0IGt2bWlfYXJjaF92 Y3B1X21zZ19oYW5kbGVyKHUxNiBpZCkKK3sKKwlyZXR1cm4gaWQgPCBBUlJBWV9TSVpFKG1zZ192 Y3B1KSA/IG1zZ192Y3B1W2lkXSA6IE5VTEw7Cit9CmRpZmYgLS1naXQgYS9pbmNsdWRlL3VhcGkv bGludXgva3ZtaS5oIGIvaW5jbHVkZS91YXBpL2xpbnV4L2t2bWkuaAppbmRleCAwNDhhZmFkMDFi ZTYuLjdiYTFjODc1OGFiYSAxMDA2NDQKLS0tIGEvaW5jbHVkZS91YXBpL2xpbnV4L2t2bWkuaAor KysgYi9pbmNsdWRlL3VhcGkvbGludXgva3ZtaS5oCkBAIC0xMDcsNCArMTA3LDEwIEBAIHN0cnVj dCBrdm1pX3ZtX3dyaXRlX3BoeXNpY2FsIHsKIAlfX3U4ICBkYXRhWzBdOwogfTsKIAorc3RydWN0 IGt2bWlfdmNwdV9oZHIgeworCV9fdTE2IHZjcHU7CisJX191MTYgcGFkZGluZzE7CisJX191MzIg cGFkZGluZzI7Cit9OworCiAjZW5kaWYgLyogX1VBUElfX0xJTlVYX0tWTUlfSCAqLwpkaWZmIC0t Z2l0IGEvdmlydC9rdm0vaW50cm9zcGVjdGlvbi9rdm1pX2ludC5oIGIvdmlydC9rdm0vaW50cm9z cGVjdGlvbi9rdm1pX2ludC5oCmluZGV4IGMzYWExMjU1NGMyYi4uYzNlNGRhN2U3ZjIwIDEwMDY0 NAotLS0gYS92aXJ0L2t2bS9pbnRyb3NwZWN0aW9uL2t2bWlfaW50LmgKKysrIGIvdmlydC9rdm0v aW50cm9zcGVjdGlvbi9rdm1pX2ludC5oCkBAIC0xNCw2ICsxNCwxOCBAQAogICovCiAjZGVmaW5l IEtWTUlfTUFYX01TR19TSVpFICg0MDk2ICogMiAtIHNpemVvZihzdHJ1Y3Qga3ZtaV9tc2dfaGRy KSkKIAorc3RydWN0IGt2bWlfdmNwdV9tc2dfam9iIHsKKwlzdHJ1Y3QgeworCQlzdHJ1Y3Qga3Zt aV9tc2dfaGRyIGhkcjsKKwkJc3RydWN0IGt2bWlfdmNwdV9oZHIgdmNwdV9oZHI7CisJfSAqbXNn OworCXN0cnVjdCBrdm1fdmNwdSAqdmNwdTsKK307CisKK3R5cGVkZWYgaW50ICgqa3ZtaV92Y3B1 X21zZ19qb2JfZmN0KShjb25zdCBzdHJ1Y3Qga3ZtaV92Y3B1X21zZ19qb2IgKmpvYiwKKwkJCQkg ICAgIGNvbnN0IHN0cnVjdCBrdm1pX21zZ19oZHIgKm1zZywKKwkJCQkgICAgIGNvbnN0IHZvaWQg KnJlcSk7CisKIC8qIGt2bWlfbXNnLmMgKi8KIGJvb2wga3ZtaV9zb2NrX2dldChzdHJ1Y3Qga3Zt X2ludHJvc3BlY3Rpb24gKmt2bWksIGludCBmZCk7CiB2b2lkIGt2bWlfc29ja19zaHV0ZG93bihz dHJ1Y3Qga3ZtX2ludHJvc3BlY3Rpb24gKmt2bWkpOwpAQCAtMjgsNiArNDAsOSBAQCBib29sIGt2 bWlfaXNfY29tbWFuZF9hbGxvd2VkKHN0cnVjdCBrdm1faW50cm9zcGVjdGlvbiAqa3ZtaSwgdTE2 IGlkKTsKIGJvb2wga3ZtaV9pc19ldmVudF9hbGxvd2VkKHN0cnVjdCBrdm1faW50cm9zcGVjdGlv biAqa3ZtaSwgdTE2IGlkKTsKIGJvb2wga3ZtaV9pc19rbm93bl9ldmVudCh1MTYgaWQpOwogYm9v bCBrdm1pX2lzX2tub3duX3ZtX2V2ZW50KHUxNiBpZCk7CitpbnQga3ZtaV9hZGRfam9iKHN0cnVj dCBrdm1fdmNwdSAqdmNwdSwKKwkJIHZvaWQgKCpmY3QpKHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwg dm9pZCAqY3R4KSwKKwkJIHZvaWQgKmN0eCwgdm9pZCAoKmZyZWVfZmN0KSh2b2lkICpjdHgpKTsK IGludCBrdm1pX2NtZF92bV9jb250cm9sX2V2ZW50cyhzdHJ1Y3Qga3ZtX2ludHJvc3BlY3Rpb24g Kmt2bWksCiAJCQkgICAgICAgdTE2IGV2ZW50X2lkLCBib29sIGVuYWJsZSk7CiBpbnQga3ZtaV9j bWRfcmVhZF9waHlzaWNhbChzdHJ1Y3Qga3ZtICprdm0sIHU2NCBncGEsIHNpemVfdCBzaXplLApA QCAtNDAsNSArNTUsNiBAQCBpbnQga3ZtaV9jbWRfd3JpdGVfcGh5c2ljYWwoc3RydWN0IGt2bSAq a3ZtLCB1NjQgZ3BhLCBzaXplX3Qgc2l6ZSwKIAogLyogYXJjaCAqLwogdm9pZCBrdm1pX2FyY2hf aW5pdF92Y3B1X2V2ZW50c19tYXNrKHVuc2lnbmVkIGxvbmcgKnN1cHBvcnRlZCk7Citrdm1pX3Zj cHVfbXNnX2pvYl9mY3Qga3ZtaV9hcmNoX3ZjcHVfbXNnX2hhbmRsZXIodTE2IGlkKTsKIAogI2Vu ZGlmCmRpZmYgLS1naXQgYS92aXJ0L2t2bS9pbnRyb3NwZWN0aW9uL2t2bWlfbXNnLmMgYi92aXJ0 L2t2bS9pbnRyb3NwZWN0aW9uL2t2bWlfbXNnLmMKaW5kZXggNjk3YzMwN2VhNzQ1Li44MmUyYjQ5 YTk2MGUgMTAwNjQ0Ci0tLSBhL3ZpcnQva3ZtL2ludHJvc3BlY3Rpb24va3ZtaV9tc2cuYworKysg Yi92aXJ0L2t2bS9pbnRyb3NwZWN0aW9uL2t2bWlfbXNnLmMKQEAgLTEzLDYgKzEzLDcgQEAgdHlw ZWRlZiBpbnQgKCprdm1pX3ZtX21zZ19mY3QpKHN0cnVjdCBrdm1faW50cm9zcGVjdGlvbiAqa3Zt aSwKIAkJCSAgICAgICBjb25zdCB2b2lkICpyZXEpOwogCiBzdGF0aWMgYm9vbCBpc192bV9jb21t YW5kKHUxNiBpZCk7CitzdGF0aWMgYm9vbCBpc192Y3B1X2NvbW1hbmQodTE2IGlkKTsKIAogYm9v bCBrdm1pX3NvY2tfZ2V0KHN0cnVjdCBrdm1faW50cm9zcGVjdGlvbiAqa3ZtaSwgaW50IGZkKQog ewpAQCAtMTA0LDYgKzEwNSwxNyBAQCBzdGF0aWMgaW50IGt2bWlfbXNnX3ZtX3JlcGx5KHN0cnVj dCBrdm1faW50cm9zcGVjdGlvbiAqa3ZtaSwKIAlyZXR1cm4ga3ZtaV9tc2dfcmVwbHkoa3ZtaSwg bXNnLCBlcnIsIHJwbCwgcnBsX3NpemUpOwogfQogCitzdGF0aWMgc3RydWN0IGt2bV92Y3B1ICpr dm1pX2dldF92Y3B1KHN0cnVjdCBrdm1faW50cm9zcGVjdGlvbiAqa3ZtaSwKKwkJCQkgICAgICB1 bnNpZ25lZCBpbnQgdmNwdV9pZHgpCit7CisJc3RydWN0IGt2bSAqa3ZtID0ga3ZtaS0+a3ZtOwor CisJaWYgKHZjcHVfaWR4ID49IGF0b21pY19yZWFkKCZrdm0tPm9ubGluZV92Y3B1cykpCisJCXJl dHVybiBOVUxMOworCisJcmV0dXJuIGt2bV9nZXRfdmNwdShrdm0sIHZjcHVfaWR4KTsKK30KKwog c3RhdGljIGludCBoYW5kbGVfZ2V0X3ZlcnNpb24oc3RydWN0IGt2bV9pbnRyb3NwZWN0aW9uICpr dm1pLAogCQkJICAgICAgY29uc3Qgc3RydWN0IGt2bWlfbXNnX2hkciAqbXNnLCBjb25zdCB2b2lk ICpyZXEpCiB7CkBAIC0xMjUsNyArMTM3LDcgQEAgc3RhdGljIGludCBoYW5kbGVfdm1fY2hlY2tf Y29tbWFuZChzdHJ1Y3Qga3ZtX2ludHJvc3BlY3Rpb24gKmt2bWksCiAKIAlpZiAocmVxLT5wYWRk aW5nMSB8fCByZXEtPnBhZGRpbmcyKQogCQllYyA9IC1LVk1fRUlOVkFMOwotCWVsc2UgaWYgKCFp c192bV9jb21tYW5kKHJlcS0+aWQpKQorCWVsc2UgaWYgKCFpc192bV9jb21tYW5kKHJlcS0+aWQp ICYmICFpc192Y3B1X2NvbW1hbmQocmVxLT5pZCkpCiAJCWVjID0gLUtWTV9FTk9FTlQ7CiAJZWxz ZSBpZiAoIWt2bWlfaXNfY29tbWFuZF9hbGxvd2VkKGt2bWksIHJlcS0+aWQpKQogCQllYyA9IC1L Vk1fRVBFUk07CkBAIC0yNTQsNiArMjY2LDc0IEBAIHN0YXRpYyBib29sIGlzX3ZtX2NvbW1hbmQo dTE2IGlkKQogCXJldHVybiBpc192bV9tZXNzYWdlKGlkKSAmJiBpZCAhPSBLVk1JX1ZNX0VWRU5U OwogfQogCisvKgorICogVGhlc2UgZnVuY3Rpb25zIGFyZSBleGVjdXRlZCBmcm9tIHRoZSB2Q1BV IHRocmVhZC4gVGhlIHJlY2VpdmluZyB0aHJlYWQKKyAqIHBhc3NlcyB0aGUgbWVzc2FnZXMgdXNp bmcgYSBuZXdseSBhbGxvY2F0ZWQgJ3N0cnVjdCBrdm1pX3ZjcHVfbXNnX2pvYicKKyAqIGFuZCBz aWduYWxzIHRoZSB2Q1BVIHRvIGhhbmRsZSB0aGUgbWVzc2FnZSAod2hpY2ggaW5jbHVkZXMKKyAq IHNlbmRpbmcgYmFjayB0aGUgcmVwbHkpLgorICovCitzdGF0aWMgY29uc3Qga3ZtaV92Y3B1X21z Z19qb2JfZmN0IG1zZ192Y3B1W10gPSB7Cit9OworCitzdGF0aWMga3ZtaV92Y3B1X21zZ19qb2Jf ZmN0IGdldF92Y3B1X21zZ19oYW5kbGVyKHUxNiBpZCkKK3sKKwlrdm1pX3ZjcHVfbXNnX2pvYl9m Y3QgZmN0OworCisJZmN0ID0gaWQgPCBBUlJBWV9TSVpFKG1zZ192Y3B1KSA/IG1zZ192Y3B1W2lk XSA6IE5VTEw7CisKKwlpZiAoIWZjdCkKKwkJZmN0ID0ga3ZtaV9hcmNoX3ZjcHVfbXNnX2hhbmRs ZXIoaWQpOworCisJcmV0dXJuIGZjdDsKK30KKworc3RhdGljIGJvb2wgaXNfdmNwdV9tZXNzYWdl KHUxNiBpZCkKK3sKKwlib29sIGlzX3ZjcHVfbXNnX2lkID0gaWQgJiAxOworCisJcmV0dXJuIGlz X3ZjcHVfbXNnX2lkICYmICEhZ2V0X3ZjcHVfbXNnX2hhbmRsZXIoaWQpOworfQorCitzdGF0aWMg Ym9vbCBpc192Y3B1X2NvbW1hbmQodTE2IGlkKQoreworCXJldHVybiBpc192Y3B1X21lc3NhZ2Uo aWQpOworfQorCitzdGF0aWMgdm9pZCBrdm1pX2pvYl92Y3B1X21zZyhzdHJ1Y3Qga3ZtX3ZjcHUg KnZjcHUsIHZvaWQgKmN0eCkKK3sKKwlzdHJ1Y3Qga3ZtaV92Y3B1X21zZ19qb2IgKmpvYiA9IGN0 eDsKKwlrdm1pX3ZjcHVfbXNnX2pvYl9mY3QgZmN0OworCWludCBlcnI7CisKKwlqb2ItPnZjcHUg PSB2Y3B1OworCisJZmN0ID0gZ2V0X3ZjcHVfbXNnX2hhbmRsZXIoam9iLT5tc2ctPmhkci5pZCk7 CisJZXJyID0gZmN0KGpvYiwgJmpvYi0+bXNnLT5oZHIsIGpvYi0+bXNnICsgMSk7CisKKwkvKgor CSAqIFRoZSBzb2Z0IGVycm9ycyBhcmUgc2VudCB3aXRoIHRoZSByZXBseS4KKwkgKiBPbiBoYXJk IGVycm9ycywgbGlrZSB0aGlzIG9uZSwKKwkgKiB3ZSBzaHV0IGRvd24gdGhlIHNvY2tldC4KKwkg Ki8KKwlpZiAoZXJyKQorCQlrdm1pX3NvY2tfc2h1dGRvd24oS1ZNSSh2Y3B1LT5rdm0pKTsKK30K Kworc3RhdGljIHZvaWQga3ZtaV9mcmVlX2N0eCh2b2lkICpfY3R4KQoreworCWNvbnN0IHN0cnVj dCBrdm1pX3ZjcHVfbXNnX2pvYiAqY3R4ID0gX2N0eDsKKworCWt2bWlfbXNnX2ZyZWUoY3R4LT5t c2cpOworCWtmcmVlKGN0eCk7Cit9CisKK3N0YXRpYyBpbnQga3ZtaV9tc2dfcXVldWVfdG9fdmNw dShzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUsCisJCQkJICBjb25zdCBzdHJ1Y3Qga3ZtaV92Y3B1X21z Z19qb2IgKmNtZCkKK3sKKwlyZXR1cm4ga3ZtaV9hZGRfam9iKHZjcHUsIGt2bWlfam9iX3ZjcHVf bXNnLCAodm9pZCAqKWNtZCwKKwkJCSAgICBrdm1pX2ZyZWVfY3R4KTsKK30KKwogc3RhdGljIHN0 cnVjdCBrdm1pX21zZ19oZHIgKmt2bWlfbXNnX3JlY3Yoc3RydWN0IGt2bV9pbnRyb3NwZWN0aW9u ICprdm1pKQogewogCXN0cnVjdCBrdm1pX21zZ19oZHIgKm1zZzsKQEAgLTMwNyw5ICszODcsNzIg QEAgc3RhdGljIGludCBrdm1pX21zZ19oYW5kbGVfdm1fY21kKHN0cnVjdCBrdm1faW50cm9zcGVj dGlvbiAqa3ZtaSwKIAlyZXR1cm4ga3ZtaV9tc2dfZG9fdm1fY21kKGt2bWksIG1zZyk7CiB9CiAK K3N0YXRpYyBib29sIHZjcHVfY2FuX2hhbmRsZV9tZXNzYWdlcyhzdHJ1Y3Qga3ZtX3ZjcHUgKnZj cHUpCit7CisJcmV0dXJuIHZjcHUtPmFyY2gubXBfc3RhdGUgIT0gS1ZNX01QX1NUQVRFX1VOSU5J VElBTElaRUQ7Cit9CisKK3N0YXRpYyBpbnQga3ZtaV9nZXRfdmNwdV9pZl9yZWFkeShzdHJ1Y3Qg a3ZtX2ludHJvc3BlY3Rpb24gKmt2bWksCisJCQkJICB1bnNpZ25lZCBpbnQgdmNwdV9pZHgsCisJ CQkJICBzdHJ1Y3Qga3ZtX3ZjcHUgKip2Y3B1KQoreworCSp2Y3B1ID0ga3ZtaV9nZXRfdmNwdShr dm1pLCB2Y3B1X2lkeCk7CisJaWYgKCp2Y3B1ID09IE5VTEwpCisJCXJldHVybiAtS1ZNX0VJTlZB TDsKKworCWlmICghdmNwdV9jYW5faGFuZGxlX21lc3NhZ2VzKCp2Y3B1KSkKKwkJcmV0dXJuIC1L Vk1fRUFHQUlOOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQga3ZtaV9tc2dfZGlzcGF0 Y2hfdmNwdV9tc2coc3RydWN0IGt2bV9pbnRyb3NwZWN0aW9uICprdm1pLAorCQkJCSAgICAgIHN0 cnVjdCBrdm1pX21zZ19oZHIgKm1zZywKKwkJCQkgICAgICBzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUp Cit7CisJc3RydWN0IGt2bWlfdmNwdV9tc2dfam9iICpqb2JfY21kOworCWludCBlcnI7CisKKwlq b2JfY21kID0ga3phbGxvYyhzaXplb2YoKmpvYl9jbWQpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIWpv Yl9jbWQpCisJCXJldHVybiAtRU5PTUVNOworCisJam9iX2NtZC0+bXNnID0gKHZvaWQgKiltc2c7 CisKKwllcnIgPSBrdm1pX21zZ19xdWV1ZV90b192Y3B1KHZjcHUsIGpvYl9jbWQpOworCWlmIChl cnIpCisJCWtmcmVlKGpvYl9jbWQpOworCisJcmV0dXJuIGVycjsKK30KKworc3RhdGljIGludCBr dm1pX21zZ19oYW5kbGVfdmNwdV9tc2coc3RydWN0IGt2bV9pbnRyb3NwZWN0aW9uICprdm1pLAor CQkJCSAgICBzdHJ1Y3Qga3ZtaV9tc2dfaGRyICptc2csCisJCQkJICAgIGJvb2wgKnF1ZXVlZCkK K3sKKwlzdHJ1Y3Qga3ZtaV92Y3B1X2hkciAqdmNwdV9oZHIgPSAoc3RydWN0IGt2bWlfdmNwdV9o ZHIgKikobXNnICsgMSk7CisJc3RydWN0IGt2bV92Y3B1ICp2Y3B1ID0gTlVMTDsKKwlpbnQgZXJy LCBlYzsKKworCWlmICgha3ZtaV9pc19jb21tYW5kX2FsbG93ZWQoa3ZtaSwgbXNnLT5pZCkpCisJ CXJldHVybiBrdm1pX21zZ192bV9yZXBseV9lYyhrdm1pLCBtc2csIC1LVk1fRVBFUk0pOworCisJ aWYgKHZjcHVfaGRyLT5wYWRkaW5nMSB8fCB2Y3B1X2hkci0+cGFkZGluZzIpCisJCXJldHVybiBr dm1pX21zZ192bV9yZXBseV9lYyhrdm1pLCBtc2csIC1LVk1fRUlOVkFMKTsKKworCWVjID0ga3Zt aV9nZXRfdmNwdV9pZl9yZWFkeShrdm1pLCB2Y3B1X2hkci0+dmNwdSwgJnZjcHUpOworCWlmIChl YykKKwkJcmV0dXJuIGt2bWlfbXNnX3ZtX3JlcGx5X2VjKGt2bWksIG1zZywgZWMpOworCisJZXJy ID0ga3ZtaV9tc2dfZGlzcGF0Y2hfdmNwdV9tc2coa3ZtaSwgbXNnLCB2Y3B1KTsKKwkqcXVldWVk ID0gZXJyID09IDA7CisJcmV0dXJuIGVycjsKK30KKwogYm9vbCBrdm1pX21zZ19wcm9jZXNzKHN0 cnVjdCBrdm1faW50cm9zcGVjdGlvbiAqa3ZtaSkKIHsKIAlzdHJ1Y3Qga3ZtaV9tc2dfaGRyICpt c2c7CisJYm9vbCBxdWV1ZWQgPSBmYWxzZTsKIAlpbnQgZXJyID0gLTE7CiAKIAltc2cgPSBrdm1p X21zZ19yZWN2KGt2bWkpOwpAQCAtMzE4LDEwICs0NjEsMTMgQEAgYm9vbCBrdm1pX21zZ19wcm9j ZXNzKHN0cnVjdCBrdm1faW50cm9zcGVjdGlvbiAqa3ZtaSkKIAogCWlmIChpc192bV9jb21tYW5k KG1zZy0+aWQpKQogCQllcnIgPSBrdm1pX21zZ19oYW5kbGVfdm1fY21kKGt2bWksIG1zZyk7CisJ ZWxzZSBpZiAoaXNfdmNwdV9tZXNzYWdlKG1zZy0+aWQpKQorCQllcnIgPSBrdm1pX21zZ19oYW5k bGVfdmNwdV9tc2coa3ZtaSwgbXNnLCAmcXVldWVkKTsKIAllbHNlCiAJCWVyciA9IGt2bWlfbXNn X3ZtX3JlcGx5X2VjKGt2bWksIG1zZywgLUtWTV9FTk9TWVMpOwogCi0Ja3ZtaV9tc2dfZnJlZSht c2cpOworCWlmICghcXVldWVkKQorCQlrdm1pX21zZ19mcmVlKG1zZyk7CiBvdXQ6CiAJcmV0dXJu IGVyciA9PSAwOwogfQpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fXwpWaXJ0dWFsaXphdGlvbiBtYWlsaW5nIGxpc3QKVmlydHVhbGl6YXRpb25AbGlzdHMubGlu dXgtZm91bmRhdGlvbi5vcmcKaHR0cHM6Ly9saXN0cy5saW51eGZvdW5kYXRpb24ub3JnL21haWxt YW4vbGlzdGluZm8vdmlydHVhbGl6YXRpb24=