From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AA79C31E40 for ; Fri, 9 Aug 2019 16:15:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 36C7A214C6 for ; Fri, 9 Aug 2019 16:15:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437162AbfHIQPa (ORCPT ); Fri, 9 Aug 2019 12:15:30 -0400 Received: from mx01.bbu.dsd.mx.bitdefender.com ([91.199.104.161]:52914 "EHLO mx01.bbu.dsd.mx.bitdefender.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437159AbfHIQPK (ORCPT ); Fri, 9 Aug 2019 12:15:10 -0400 Received: from smtp.bitdefender.com (smtp02.buh.bitdefender.net [10.17.80.76]) by mx01.bbu.dsd.mx.bitdefender.com (Postfix) with ESMTPS id 4C2C2305D347; Fri, 9 Aug 2019 19:01:17 +0300 (EEST) Received: from localhost.localdomain (unknown [89.136.169.210]) by smtp.bitdefender.com (Postfix) with ESMTPSA id 6E75F305B7A3; Fri, 9 Aug 2019 19:01:16 +0300 (EEST) From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= To: kvm@vger.kernel.org Cc: linux-mm@kvack.org, virtualization@lists.linux-foundation.org, Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Konrad Rzeszutek Wilk , Tamas K Lengyel , Mathieu Tarral , =?UTF-8?q?Samuel=20Laur=C3=A9n?= , Patrick Colp , Jan Kiszka , Stefan Hajnoczi , Weijiang Yang , Zhang@vger.kernel.org, Yu C , =?UTF-8?q?Mihai=20Don=C8=9Bu?= , =?UTF-8?q?Adalbert=20Laz=C4=83r?= Subject: [RFC PATCH v6 46/92] kvm: introspection: add KVMI_SET_PAGE_WRITE_BITMAP Date: Fri, 9 Aug 2019 19:00:01 +0300 Message-Id: <20190809160047.8319-47-alazar@bitdefender.com> In-Reply-To: <20190809160047.8319-1-alazar@bitdefender.com> References: <20190809160047.8319-1-alazar@bitdefender.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org This command sets the subpage protection (SPP) write bitmap for an array of guest physical addresses of 4KB bytes. Co-developed-by: Yang Weijiang Signed-off-by: Yang Weijiang Co-developed-by: Adalbert Lazăr Signed-off-by: Adalbert Lazăr --- Documentation/virtual/kvm/kvmi.rst | 66 ++++++++++++++++++++++++++++++ arch/x86/kvm/kvmi.c | 30 ++++++++++++++ include/uapi/linux/kvmi.h | 13 ++++++ virt/kvm/kvmi.c | 37 +++++++++++++++++ virt/kvm/kvmi_int.h | 4 ++ virt/kvm/kvmi_msg.c | 13 ++++++ 6 files changed, 163 insertions(+) diff --git a/Documentation/virtual/kvm/kvmi.rst b/Documentation/virtual/kvm/kvmi.rst index 2ffb92b0fa71..69557c63ff94 100644 --- a/Documentation/virtual/kvm/kvmi.rst +++ b/Documentation/virtual/kvm/kvmi.rst @@ -694,6 +694,72 @@ EPT view (0 is primary). On all other hardware it must be zero. * -KVM_EAGAIN - the selected vCPU can't be introspected yet * -KVM_ENOMEM - not enough memory to allocate the reply +13. KVMI_SET_PAGE_WRITE_BITMAP +------------------------------ + +:Architectures: x86 +:Versions: >= 1 +:Parameters: + +:: + + struct kvmi_set_page_write_bitmap { + __u16 view; + __u16 count; + __u32 padding; + struct kvmi_page_write_bitmap_entry entries[0]; + }; + +where:: + + struct kvmi_page_write_bitmap_entry { + __u64 gpa; + __u32 bitmap; + __u32 padding; + }; + +:Returns: + +:: + + struct kvmi_error_code; + +Sets the subpage protection (SPP) write bitmap for an array of ``count`` +guest physical addresses of 4KB bytes. + +The command will make the changes starting with the first entry and +it will stop on the first error. The introspection tool should handle +the rollback. + +While the *KVMI_SET_PAGE_ACCESS* command can be used to write-protect a +4KB page, this command can write-protect 128-bytes subpages inside of a +4KB page by setting the corresponding bit to 1 (write allowed) or to 0 +(write disallowed). For example, to allow write access to the A and B +subpages only, the bitmap must be set to:: + + BIT(A) | BIT(B) + +A and B must be a number between 0 (first subpage) and 31 (last subpage). + +Using this command to set all bits to 1 (allow write access for +all subpages) will allow write access to the whole 4KB page (like a +*KVMI_SET_PAGE_ACCESS* command with the *KVMI_PAGE_ACCESS_W* flag set) +and vice versa. + +Using this command to set any bit to 0 will write-protect the whole 4KB +page (like a *KVMI_SET_PAGE_ACCESS* command with the *KVMI_PAGE_ACCESS_W* +flag cleared) and allow write access only for subpages with the +corresponding bit set to 1. + +:Errors: + +* -KVM_EINVAL - the selected SPT view is invalid +* -KVM_EOPNOTSUPP - a SPT view was selected but the hardware doesn't support it +* -KVM_EOPNOTSUPP - the hardware doesn't support SPP or hasn't been enabled +* -KVM_EINVAL - the write access is already allowed for the whole 4KB page +* -KVM_EAGAIN - the selected vCPU can't be introspected yet +* -KVM_ENOMEM - not enough memory to add the page tracking structures + Events ====== diff --git a/arch/x86/kvm/kvmi.c b/arch/x86/kvm/kvmi.c index 356ec79936b3..fa290fbf1f75 100644 --- a/arch/x86/kvm/kvmi.c +++ b/arch/x86/kvm/kvmi.c @@ -304,6 +304,36 @@ int kvmi_arch_cmd_set_page_access(struct kvmi *ikvm, return ec; } +int kvmi_arch_cmd_set_page_write_bitmap(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, + const struct kvmi_set_page_write_bitmap + *req) +{ + u16 k, n = req->count; + int ec = 0; + + if (req->padding) + return -KVM_EINVAL; + + if (msg->size < sizeof(*req) + req->count * sizeof(req->entries[0])) + return -KVM_EINVAL; + + if (!kvmi_spp_enabled(ikvm)) + return -KVM_EOPNOTSUPP; + + if (req->view != 0) /* TODO */ + return -KVM_EOPNOTSUPP; + + for (k = 0; k < n && ec == 0; k++) { + u64 gpa = req->entries[k].gpa; + u32 bitmap = req->entries[k].bitmap; + + ec = kvmi_cmd_set_page_write_bitmap(ikvm, gpa, bitmap); + } + + return ec; +} + int kvmi_arch_cmd_control_spp(struct kvmi *ikvm) { return kvm_arch_init_spp(ikvm->kvm); diff --git a/include/uapi/linux/kvmi.h b/include/uapi/linux/kvmi.h index 19a6a50df96b..0b3139c52a30 100644 --- a/include/uapi/linux/kvmi.h +++ b/include/uapi/linux/kvmi.h @@ -160,6 +160,19 @@ struct kvmi_get_page_write_bitmap_reply { __u32 bitmap[0]; }; +struct kvmi_page_write_bitmap_entry { + __u64 gpa; + __u32 bitmap; + __u32 padding; +}; + +struct kvmi_set_page_write_bitmap { + __u16 view; + __u16 count; + __u32 padding; + struct kvmi_page_write_bitmap_entry entries[0]; +}; + struct kvmi_get_vcpu_info_reply { __u64 tsc_speed; }; diff --git a/virt/kvm/kvmi.c b/virt/kvm/kvmi.c index 22e233ca474c..d2bebef98d8d 100644 --- a/virt/kvm/kvmi.c +++ b/virt/kvm/kvmi.c @@ -99,6 +99,24 @@ static int kvmi_set_gfn_access(struct kvm *kvm, gfn_t gfn, u8 access, m->access = access; m->write_bitmap = write_bitmap; + /* + * Only try to set SPP bitmap when the page is writable. + * Be careful, kvm_mmu_set_subpages() will enable page write-protection + * by default when set SPP bitmap. If bitmap contains all 1s, it'll + * make the page writable by default too. + */ + if (!(access & KVMI_PAGE_ACCESS_W) && kvmi_spp_enabled(ikvm)) { + struct kvm_subpage spp_info; + + spp_info.base_gfn = gfn; + spp_info.npages = 1; + spp_info.access_map[0] = write_bitmap; + + err = kvm_arch_set_subpages(kvm, &spp_info); + if (err) + goto exit; + } + if (radix_tree_preload(GFP_KERNEL)) { err = -KVM_ENOMEM; goto exit; @@ -1183,6 +1201,25 @@ int kvmi_cmd_set_page_access(struct kvmi *ikvm, u64 gpa, u8 access) return kvmi_set_gfn_access(ikvm->kvm, gfn, access, write_bitmap); } +int kvmi_cmd_set_page_write_bitmap(struct kvmi *ikvm, u64 gpa, + u32 write_bitmap) +{ + bool write_allowed_for_all; + gfn_t gfn = gpa_to_gfn(gpa); + u32 ignored_write_bitmap; + u8 access; + + kvmi_get_gfn_access(ikvm, gfn, &access, &ignored_write_bitmap); + + write_allowed_for_all = (write_bitmap == (u32)((1ULL << 32) - 1)); + if (write_allowed_for_all) + access |= KVMI_PAGE_ACCESS_W; + else + access &= ~KVMI_PAGE_ACCESS_W; + + return kvmi_set_gfn_access(ikvm->kvm, gfn, access, write_bitmap); +} + int kvmi_cmd_control_events(struct kvm_vcpu *vcpu, unsigned int event_id, bool enable) { diff --git a/virt/kvm/kvmi_int.h b/virt/kvm/kvmi_int.h index 7243c57be27a..18c00dae0f2f 100644 --- a/virt/kvm/kvmi_int.h +++ b/virt/kvm/kvmi_int.h @@ -173,6 +173,7 @@ void kvmi_msg_free(void *addr); int kvmi_cmd_get_page_access(struct kvmi *ikvm, u64 gpa, u8 *access); int kvmi_cmd_set_page_access(struct kvmi *ikvm, u64 gpa, u8 access); int kvmi_cmd_get_page_write_bitmap(struct kvmi *ikvm, u64 gpa, u32 *bitmap); +int kvmi_cmd_set_page_write_bitmap(struct kvmi *ikvm, u64 gpa, u32 bitmap); int kvmi_cmd_control_events(struct kvm_vcpu *vcpu, unsigned int event_id, bool enable); int kvmi_cmd_control_vm_events(struct kvmi *ikvm, unsigned int event_id, @@ -202,6 +203,9 @@ int kvmi_arch_cmd_get_page_write_bitmap(struct kvmi *ikvm, const struct kvmi_get_page_write_bitmap *req, struct kvmi_get_page_write_bitmap_reply **dest, size_t *dest_size); +int kvmi_arch_cmd_set_page_write_bitmap(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, + const struct kvmi_set_page_write_bitmap *req); void kvmi_arch_setup_event(struct kvm_vcpu *vcpu, struct kvmi_event *ev); bool kvmi_arch_pf_event(struct kvm_vcpu *vcpu, gpa_t gpa, gva_t gva, u8 access); diff --git a/virt/kvm/kvmi_msg.c b/virt/kvm/kvmi_msg.c index eb247ac3e037..f9efb52d49c3 100644 --- a/virt/kvm/kvmi_msg.c +++ b/virt/kvm/kvmi_msg.c @@ -35,6 +35,7 @@ static const char *const msg_IDs[] = { [KVMI_GET_VCPU_INFO] = "KVMI_GET_VCPU_INFO", [KVMI_GET_VERSION] = "KVMI_GET_VERSION", [KVMI_SET_PAGE_ACCESS] = "KVMI_SET_PAGE_ACCESS", + [KVMI_SET_PAGE_WRITE_BITMAP] = "KVMI_SET_PAGE_WRITE_BITMAP", }; static bool is_known_message(u16 id) @@ -400,6 +401,17 @@ static int handle_get_page_write_bitmap(struct kvmi *ikvm, return err; } +static int handle_set_page_write_bitmap(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, + const void *req) +{ + int ec; + + ec = kvmi_arch_cmd_set_page_write_bitmap(ikvm, msg, req); + + return kvmi_msg_vm_maybe_reply(ikvm, msg, ec, NULL, 0); +} + static bool invalid_vcpu_hdr(const struct kvmi_vcpu_hdr *hdr) { return hdr->padding1 || hdr->padding2; @@ -420,6 +432,7 @@ static int(*const msg_vm[])(struct kvmi *, const struct kvmi_msg_hdr *, [KVMI_GET_PAGE_WRITE_BITMAP] = handle_get_page_write_bitmap, [KVMI_GET_VERSION] = handle_get_version, [KVMI_SET_PAGE_ACCESS] = handle_set_page_access, + [KVMI_SET_PAGE_WRITE_BITMAP] = handle_set_page_write_bitmap, }; static int handle_event_reply(struct kvm_vcpu *vcpu, From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 107A5C433FF for ; Fri, 9 Aug 2019 16:03:20 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 8C0CF2089E for ; Fri, 9 Aug 2019 16:03:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8C0CF2089E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bitdefender.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id AA3EE6B028B; Fri, 9 Aug 2019 12:01:20 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id A7BF76B028C; Fri, 9 Aug 2019 12:01:20 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 96E106B028D; Fri, 9 Aug 2019 12:01:20 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by kanga.kvack.org (Postfix) with ESMTP id 321906B028B for ; Fri, 9 Aug 2019 12:01:20 -0400 (EDT) Received: by mail-wr1-f70.google.com with SMTP id f9so46816843wrq.14 for ; Fri, 09 Aug 2019 09:01:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-original-authentication-results:x-gm-message-state:from:to:cc :subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=+t8bGc+DEm851YBsh+1Mr3Pc9OnE9/HEPmHUoF6kTwI=; b=lWMPtKruNi0tq75jdUKfyz/7kbx9L7t0oJmRIVv28L1lsQJ5VScgKk79Rpf96mZ3MG UO8Auy4O1tG7uIceSTMPdZuHUBhM/GuiJGUINizAFopPI4Rd4aKFSor6fBvhNk3kMist PoNuJkhsr96r85sjXEpiEymB0iHLMmGJ8wq7YLJ89010KFhPWhssH0mEHmnckDlkMIZa ii7ztqCq7P7mHfZGHhcUFgrGv6173Gu2hZFeF1Wgacx00YdUw5nVTjH7c//hNssAztoW xlSnOEPHkBhTxYGf8ZAZO32XXx1f9lNwqL6MM105mGWvYXa4xJIS+Qlbt2K977SvOnXH udPg== X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of alazar@bitdefender.com designates 91.199.104.161 as permitted sender) smtp.mailfrom=alazar@bitdefender.com X-Gm-Message-State: APjAAAWqMF7zMlN2aAxGcILqtpopHX3tHq26Pc5KAdfTYOn0OGFf3ssm bVgIrkB3jCkL81aP9xcMOx+dquZhG2nPiqrpBepTnLsyFWCa5a36bt5p+raUiLLcBCORRaxvun9 jL47Qwnsve9zv/Nbsza0deOt77Fgh9CP7g+frviLuEXqNcX9TOGL4sUYFXolHPkzUjw== X-Received: by 2002:a1c:18a:: with SMTP id 132mr11786697wmb.15.1565366479711; Fri, 09 Aug 2019 09:01:19 -0700 (PDT) X-Google-Smtp-Source: APXvYqwg9PC0AQmq103uBFygkYX+c9MCmI8AIMY2z+UeJXP9TNjXI5ReP/vkttCXKDQj72KtECp1 X-Received: by 2002:a1c:18a:: with SMTP id 132mr11786539wmb.15.1565366478022; Fri, 09 Aug 2019 09:01:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565366478; cv=none; d=google.com; s=arc-20160816; b=n0YsRd1umUmRhN0+KJDY9zKb20kJecTO5LPA0uMmsFExvFoN0BYzQys6XxZFI0L0T1 IfSmXS+q+YcGZFR/JRVUsefFLunGG0UxU1VFZ5qznGCtiu9SZN1s3NaNiTJYQ5lX6kMI nkHtwxVjoYgAJlAv9ARj9myDCoJw+f8JZLzTQi/6DWpGBnrJGZqiDcubXsoPZQ/QVASJ dqQzbKTVpmSOr9hEcea2kQyf7V+4GNe9zqMEYUoVMVAn8Vt3H0P1vSuepMKl29NkdW2g xXVTKMLhgVYqSX5R9QZdrlkgHAdSdKgdBbLdwTOKzdy4WvckxEVpIJQQjGh4FKsopqfH UpYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=+t8bGc+DEm851YBsh+1Mr3Pc9OnE9/HEPmHUoF6kTwI=; b=p+H6ZzbTK23nowUBxO4lcDbT0GfmZQP0MbwemZ4z+k+dxmuUuJt9QqSspnw2HdlIpN su0Jppp7DrvVEtWXPJNoqC5WWM7+02dKd7mTEiSeSeAxxvCGjDTDGbcRjUTj7CI+Ocp9 ZRb6IKU78Izlbanmh4DUYsQg96CEQvphbPLmAIDP8PoRmAxElFBtOT+y5i4bu7+XL8O8 t+kY2ty8+rJz59cQ5seoiy3gP9oWjWGXlaD/LJWb5yhy+a6shuZCAN8xDX1RA0jh6XFz fYJT+ggXolm+o7CJ0U/ECCadF5DHYXyNQqjsY+pKFWxh8qCo0kFnnc6Sh7XGwXbx++Ic pu0g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of alazar@bitdefender.com designates 91.199.104.161 as permitted sender) smtp.mailfrom=alazar@bitdefender.com Received: from mx01.bbu.dsd.mx.bitdefender.com (mx01.bbu.dsd.mx.bitdefender.com. [91.199.104.161]) by mx.google.com with ESMTPS id r17si88166113wro.143.2019.08.09.09.01.17 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Aug 2019 09:01:18 -0700 (PDT) Received-SPF: pass (google.com: domain of alazar@bitdefender.com designates 91.199.104.161 as permitted sender) client-ip=91.199.104.161; Authentication-Results: mx.google.com; spf=pass (google.com: domain of alazar@bitdefender.com designates 91.199.104.161 as permitted sender) smtp.mailfrom=alazar@bitdefender.com Received: from smtp.bitdefender.com (smtp02.buh.bitdefender.net [10.17.80.76]) by mx01.bbu.dsd.mx.bitdefender.com (Postfix) with ESMTPS id 4C2C2305D347; Fri, 9 Aug 2019 19:01:17 +0300 (EEST) Received: from localhost.localdomain (unknown [89.136.169.210]) by smtp.bitdefender.com (Postfix) with ESMTPSA id 6E75F305B7A3; Fri, 9 Aug 2019 19:01:16 +0300 (EEST) From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= To: kvm@vger.kernel.org Cc: linux-mm@kvack.org, virtualization@lists.linux-foundation.org, Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Konrad Rzeszutek Wilk , Tamas K Lengyel , Mathieu Tarral , =?UTF-8?q?Samuel=20Laur=C3=A9n?= , Patrick Colp , Jan Kiszka , Stefan Hajnoczi , Weijiang Yang , Zhang@kvack.org, Yu C , =?UTF-8?q?Mihai=20Don=C8=9Bu?= , =?UTF-8?q?Adalbert=20Laz=C4=83r?= Subject: [RFC PATCH v6 46/92] kvm: introspection: add KVMI_SET_PAGE_WRITE_BITMAP Date: Fri, 9 Aug 2019 19:00:01 +0300 Message-Id: <20190809160047.8319-47-alazar@bitdefender.com> In-Reply-To: <20190809160047.8319-1-alazar@bitdefender.com> References: <20190809160047.8319-1-alazar@bitdefender.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This command sets the subpage protection (SPP) write bitmap for an array of guest physical addresses of 4KB bytes. Co-developed-by: Yang Weijiang Signed-off-by: Yang Weijiang Co-developed-by: Adalbert Lazăr Signed-off-by: Adalbert Lazăr --- Documentation/virtual/kvm/kvmi.rst | 66 ++++++++++++++++++++++++++++++ arch/x86/kvm/kvmi.c | 30 ++++++++++++++ include/uapi/linux/kvmi.h | 13 ++++++ virt/kvm/kvmi.c | 37 +++++++++++++++++ virt/kvm/kvmi_int.h | 4 ++ virt/kvm/kvmi_msg.c | 13 ++++++ 6 files changed, 163 insertions(+) diff --git a/Documentation/virtual/kvm/kvmi.rst b/Documentation/virtual/kvm/kvmi.rst index 2ffb92b0fa71..69557c63ff94 100644 --- a/Documentation/virtual/kvm/kvmi.rst +++ b/Documentation/virtual/kvm/kvmi.rst @@ -694,6 +694,72 @@ EPT view (0 is primary). On all other hardware it must be zero. * -KVM_EAGAIN - the selected vCPU can't be introspected yet * -KVM_ENOMEM - not enough memory to allocate the reply +13. KVMI_SET_PAGE_WRITE_BITMAP +------------------------------ + +:Architectures: x86 +:Versions: >= 1 +:Parameters: + +:: + + struct kvmi_set_page_write_bitmap { + __u16 view; + __u16 count; + __u32 padding; + struct kvmi_page_write_bitmap_entry entries[0]; + }; + +where:: + + struct kvmi_page_write_bitmap_entry { + __u64 gpa; + __u32 bitmap; + __u32 padding; + }; + +:Returns: + +:: + + struct kvmi_error_code; + +Sets the subpage protection (SPP) write bitmap for an array of ``count`` +guest physical addresses of 4KB bytes. + +The command will make the changes starting with the first entry and +it will stop on the first error. The introspection tool should handle +the rollback. + +While the *KVMI_SET_PAGE_ACCESS* command can be used to write-protect a +4KB page, this command can write-protect 128-bytes subpages inside of a +4KB page by setting the corresponding bit to 1 (write allowed) or to 0 +(write disallowed). For example, to allow write access to the A and B +subpages only, the bitmap must be set to:: + + BIT(A) | BIT(B) + +A and B must be a number between 0 (first subpage) and 31 (last subpage). + +Using this command to set all bits to 1 (allow write access for +all subpages) will allow write access to the whole 4KB page (like a +*KVMI_SET_PAGE_ACCESS* command with the *KVMI_PAGE_ACCESS_W* flag set) +and vice versa. + +Using this command to set any bit to 0 will write-protect the whole 4KB +page (like a *KVMI_SET_PAGE_ACCESS* command with the *KVMI_PAGE_ACCESS_W* +flag cleared) and allow write access only for subpages with the +corresponding bit set to 1. + +:Errors: + +* -KVM_EINVAL - the selected SPT view is invalid +* -KVM_EOPNOTSUPP - a SPT view was selected but the hardware doesn't support it +* -KVM_EOPNOTSUPP - the hardware doesn't support SPP or hasn't been enabled +* -KVM_EINVAL - the write access is already allowed for the whole 4KB page +* -KVM_EAGAIN - the selected vCPU can't be introspected yet +* -KVM_ENOMEM - not enough memory to add the page tracking structures + Events ====== diff --git a/arch/x86/kvm/kvmi.c b/arch/x86/kvm/kvmi.c index 356ec79936b3..fa290fbf1f75 100644 --- a/arch/x86/kvm/kvmi.c +++ b/arch/x86/kvm/kvmi.c @@ -304,6 +304,36 @@ int kvmi_arch_cmd_set_page_access(struct kvmi *ikvm, return ec; } +int kvmi_arch_cmd_set_page_write_bitmap(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, + const struct kvmi_set_page_write_bitmap + *req) +{ + u16 k, n = req->count; + int ec = 0; + + if (req->padding) + return -KVM_EINVAL; + + if (msg->size < sizeof(*req) + req->count * sizeof(req->entries[0])) + return -KVM_EINVAL; + + if (!kvmi_spp_enabled(ikvm)) + return -KVM_EOPNOTSUPP; + + if (req->view != 0) /* TODO */ + return -KVM_EOPNOTSUPP; + + for (k = 0; k < n && ec == 0; k++) { + u64 gpa = req->entries[k].gpa; + u32 bitmap = req->entries[k].bitmap; + + ec = kvmi_cmd_set_page_write_bitmap(ikvm, gpa, bitmap); + } + + return ec; +} + int kvmi_arch_cmd_control_spp(struct kvmi *ikvm) { return kvm_arch_init_spp(ikvm->kvm); diff --git a/include/uapi/linux/kvmi.h b/include/uapi/linux/kvmi.h index 19a6a50df96b..0b3139c52a30 100644 --- a/include/uapi/linux/kvmi.h +++ b/include/uapi/linux/kvmi.h @@ -160,6 +160,19 @@ struct kvmi_get_page_write_bitmap_reply { __u32 bitmap[0]; }; +struct kvmi_page_write_bitmap_entry { + __u64 gpa; + __u32 bitmap; + __u32 padding; +}; + +struct kvmi_set_page_write_bitmap { + __u16 view; + __u16 count; + __u32 padding; + struct kvmi_page_write_bitmap_entry entries[0]; +}; + struct kvmi_get_vcpu_info_reply { __u64 tsc_speed; }; diff --git a/virt/kvm/kvmi.c b/virt/kvm/kvmi.c index 22e233ca474c..d2bebef98d8d 100644 --- a/virt/kvm/kvmi.c +++ b/virt/kvm/kvmi.c @@ -99,6 +99,24 @@ static int kvmi_set_gfn_access(struct kvm *kvm, gfn_t gfn, u8 access, m->access = access; m->write_bitmap = write_bitmap; + /* + * Only try to set SPP bitmap when the page is writable. + * Be careful, kvm_mmu_set_subpages() will enable page write-protection + * by default when set SPP bitmap. If bitmap contains all 1s, it'll + * make the page writable by default too. + */ + if (!(access & KVMI_PAGE_ACCESS_W) && kvmi_spp_enabled(ikvm)) { + struct kvm_subpage spp_info; + + spp_info.base_gfn = gfn; + spp_info.npages = 1; + spp_info.access_map[0] = write_bitmap; + + err = kvm_arch_set_subpages(kvm, &spp_info); + if (err) + goto exit; + } + if (radix_tree_preload(GFP_KERNEL)) { err = -KVM_ENOMEM; goto exit; @@ -1183,6 +1201,25 @@ int kvmi_cmd_set_page_access(struct kvmi *ikvm, u64 gpa, u8 access) return kvmi_set_gfn_access(ikvm->kvm, gfn, access, write_bitmap); } +int kvmi_cmd_set_page_write_bitmap(struct kvmi *ikvm, u64 gpa, + u32 write_bitmap) +{ + bool write_allowed_for_all; + gfn_t gfn = gpa_to_gfn(gpa); + u32 ignored_write_bitmap; + u8 access; + + kvmi_get_gfn_access(ikvm, gfn, &access, &ignored_write_bitmap); + + write_allowed_for_all = (write_bitmap == (u32)((1ULL << 32) - 1)); + if (write_allowed_for_all) + access |= KVMI_PAGE_ACCESS_W; + else + access &= ~KVMI_PAGE_ACCESS_W; + + return kvmi_set_gfn_access(ikvm->kvm, gfn, access, write_bitmap); +} + int kvmi_cmd_control_events(struct kvm_vcpu *vcpu, unsigned int event_id, bool enable) { diff --git a/virt/kvm/kvmi_int.h b/virt/kvm/kvmi_int.h index 7243c57be27a..18c00dae0f2f 100644 --- a/virt/kvm/kvmi_int.h +++ b/virt/kvm/kvmi_int.h @@ -173,6 +173,7 @@ void kvmi_msg_free(void *addr); int kvmi_cmd_get_page_access(struct kvmi *ikvm, u64 gpa, u8 *access); int kvmi_cmd_set_page_access(struct kvmi *ikvm, u64 gpa, u8 access); int kvmi_cmd_get_page_write_bitmap(struct kvmi *ikvm, u64 gpa, u32 *bitmap); +int kvmi_cmd_set_page_write_bitmap(struct kvmi *ikvm, u64 gpa, u32 bitmap); int kvmi_cmd_control_events(struct kvm_vcpu *vcpu, unsigned int event_id, bool enable); int kvmi_cmd_control_vm_events(struct kvmi *ikvm, unsigned int event_id, @@ -202,6 +203,9 @@ int kvmi_arch_cmd_get_page_write_bitmap(struct kvmi *ikvm, const struct kvmi_get_page_write_bitmap *req, struct kvmi_get_page_write_bitmap_reply **dest, size_t *dest_size); +int kvmi_arch_cmd_set_page_write_bitmap(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, + const struct kvmi_set_page_write_bitmap *req); void kvmi_arch_setup_event(struct kvm_vcpu *vcpu, struct kvmi_event *ev); bool kvmi_arch_pf_event(struct kvm_vcpu *vcpu, gpa_t gpa, gva_t gva, u8 access); diff --git a/virt/kvm/kvmi_msg.c b/virt/kvm/kvmi_msg.c index eb247ac3e037..f9efb52d49c3 100644 --- a/virt/kvm/kvmi_msg.c +++ b/virt/kvm/kvmi_msg.c @@ -35,6 +35,7 @@ static const char *const msg_IDs[] = { [KVMI_GET_VCPU_INFO] = "KVMI_GET_VCPU_INFO", [KVMI_GET_VERSION] = "KVMI_GET_VERSION", [KVMI_SET_PAGE_ACCESS] = "KVMI_SET_PAGE_ACCESS", + [KVMI_SET_PAGE_WRITE_BITMAP] = "KVMI_SET_PAGE_WRITE_BITMAP", }; static bool is_known_message(u16 id) @@ -400,6 +401,17 @@ static int handle_get_page_write_bitmap(struct kvmi *ikvm, return err; } +static int handle_set_page_write_bitmap(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, + const void *req) +{ + int ec; + + ec = kvmi_arch_cmd_set_page_write_bitmap(ikvm, msg, req); + + return kvmi_msg_vm_maybe_reply(ikvm, msg, ec, NULL, 0); +} + static bool invalid_vcpu_hdr(const struct kvmi_vcpu_hdr *hdr) { return hdr->padding1 || hdr->padding2; @@ -420,6 +432,7 @@ static int(*const msg_vm[])(struct kvmi *, const struct kvmi_msg_hdr *, [KVMI_GET_PAGE_WRITE_BITMAP] = handle_get_page_write_bitmap, [KVMI_GET_VERSION] = handle_get_version, [KVMI_SET_PAGE_ACCESS] = handle_set_page_access, + [KVMI_SET_PAGE_WRITE_BITMAP] = handle_set_page_write_bitmap, }; static int handle_event_reply(struct kvm_vcpu *vcpu, From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Adalbert=20Laz=C4=83r?= Subject: [RFC PATCH v6 46/92] kvm: introspection: add KVMI_SET_PAGE_WRITE_BITMAP Date: Fri, 9 Aug 2019 19:00:01 +0300 Message-ID: <20190809160047.8319-47-alazar@bitdefender.com> References: <20190809160047.8319-1-alazar@bitdefender.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20190809160047.8319-1-alazar@bitdefender.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: virtualization-bounces@lists.linux-foundation.org Errors-To: virtualization-bounces@lists.linux-foundation.org To: kvm@vger.kernel.org Cc: Tamas K Lengyel , Weijiang Yang , Yu C , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Jan Kiszka , =?UTF-8?q?Samuel=20Laur=C3=A9n?= , Konrad Rzeszutek Wilk , virtualization@lists.linux-foundation.org, =?UTF-8?q?Adalbert=20Laz=C4=83r?= , linux-mm@kvack.org, Patrick Colp , Mathieu Tarral , Stefan Hajnoczi , Paolo Bonzini , Zhang@mail.linuxfoundation.org, =?UTF-8?q?Mihai=20Don=C8=9Bu?= List-Id: virtualization@lists.linuxfoundation.org VGhpcyBjb21tYW5kIHNldHMgdGhlIHN1YnBhZ2UgcHJvdGVjdGlvbiAoU1BQKSB3cml0ZSBiaXRt YXAgZm9yIGFuIGFycmF5Cm9mIGd1ZXN0IHBoeXNpY2FsIGFkZHJlc3NlcyBvZiA0S0IgYnl0ZXMu CgpDby1kZXZlbG9wZWQtYnk6IFlhbmcgV2VpamlhbmcgPHdlaWppYW5nLnlhbmdAaW50ZWwuY29t PgpTaWduZWQtb2ZmLWJ5OiBZYW5nIFdlaWppYW5nIDx3ZWlqaWFuZy55YW5nQGludGVsLmNvbT4K Q28tZGV2ZWxvcGVkLWJ5OiBBZGFsYmVydCBMYXrEg3IgPGFsYXphckBiaXRkZWZlbmRlci5jb20+ ClNpZ25lZC1vZmYtYnk6IEFkYWxiZXJ0IExhesSDciA8YWxhemFyQGJpdGRlZmVuZGVyLmNvbT4K LS0tCiBEb2N1bWVudGF0aW9uL3ZpcnR1YWwva3ZtL2t2bWkucnN0IHwgNjYgKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrCiBhcmNoL3g4Ni9rdm0va3ZtaS5jICAgICAgICAgICAgICAgIHwg MzAgKysrKysrKysrKysrKysKIGluY2x1ZGUvdWFwaS9saW51eC9rdm1pLmggICAgICAgICAgfCAx MyArKysrKysKIHZpcnQva3ZtL2t2bWkuYyAgICAgICAgICAgICAgICAgICAgfCAzNyArKysrKysr KysrKysrKysrKwogdmlydC9rdm0va3ZtaV9pbnQuaCAgICAgICAgICAgICAgICB8ICA0ICsrCiB2 aXJ0L2t2bS9rdm1pX21zZy5jICAgICAgICAgICAgICAgIHwgMTMgKysrKysrCiA2IGZpbGVzIGNo YW5nZWQsIDE2MyBpbnNlcnRpb25zKCspCgpkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi92aXJ0 dWFsL2t2bS9rdm1pLnJzdCBiL0RvY3VtZW50YXRpb24vdmlydHVhbC9rdm0va3ZtaS5yc3QKaW5k ZXggMmZmYjkyYjBmYTcxLi42OTU1N2M2M2ZmOTQgMTAwNjQ0Ci0tLSBhL0RvY3VtZW50YXRpb24v dmlydHVhbC9rdm0va3ZtaS5yc3QKKysrIGIvRG9jdW1lbnRhdGlvbi92aXJ0dWFsL2t2bS9rdm1p LnJzdApAQCAtNjk0LDYgKzY5NCw3MiBAQCBFUFQgdmlldyAoMCBpcyBwcmltYXJ5KS4gT24gYWxs IG90aGVyIGhhcmR3YXJlIGl0IG11c3QgYmUgemVyby4KICogLUtWTV9FQUdBSU4gLSB0aGUgc2Vs ZWN0ZWQgdkNQVSBjYW4ndCBiZSBpbnRyb3NwZWN0ZWQgeWV0CiAqIC1LVk1fRU5PTUVNIC0gbm90 IGVub3VnaCBtZW1vcnkgdG8gYWxsb2NhdGUgdGhlIHJlcGx5CiAKKzEzLiBLVk1JX1NFVF9QQUdF X1dSSVRFX0JJVE1BUAorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKzpBcmNoaXRl Y3R1cmVzOiB4ODYKKzpWZXJzaW9uczogPj0gMQorOlBhcmFtZXRlcnM6CisKKzo6CisKKwlzdHJ1 Y3Qga3ZtaV9zZXRfcGFnZV93cml0ZV9iaXRtYXAgeworCQlfX3UxNiB2aWV3OworCQlfX3UxNiBj b3VudDsKKwkJX191MzIgcGFkZGluZzsKKwkJc3RydWN0IGt2bWlfcGFnZV93cml0ZV9iaXRtYXBf ZW50cnkgZW50cmllc1swXTsKKwl9OworCit3aGVyZTo6CisKKwlzdHJ1Y3Qga3ZtaV9wYWdlX3dy aXRlX2JpdG1hcF9lbnRyeSB7CisJCV9fdTY0IGdwYTsKKwkJX191MzIgYml0bWFwOworCQlfX3Uz MiBwYWRkaW5nOworCX07CisKKzpSZXR1cm5zOgorCis6OgorCisJc3RydWN0IGt2bWlfZXJyb3Jf Y29kZTsKKworU2V0cyB0aGUgc3VicGFnZSBwcm90ZWN0aW9uIChTUFApIHdyaXRlIGJpdG1hcCBm b3IgYW4gYXJyYXkgb2YgYGBjb3VudGBgCitndWVzdCBwaHlzaWNhbCBhZGRyZXNzZXMgb2YgNEtC IGJ5dGVzLgorCitUaGUgY29tbWFuZCB3aWxsIG1ha2UgdGhlIGNoYW5nZXMgc3RhcnRpbmcgd2l0 aCB0aGUgZmlyc3QgZW50cnkgYW5kCitpdCB3aWxsIHN0b3Agb24gdGhlIGZpcnN0IGVycm9yLiBU aGUgaW50cm9zcGVjdGlvbiB0b29sIHNob3VsZCBoYW5kbGUKK3RoZSByb2xsYmFjay4KKworV2hp bGUgdGhlICpLVk1JX1NFVF9QQUdFX0FDQ0VTUyogY29tbWFuZCBjYW4gYmUgdXNlZCB0byB3cml0 ZS1wcm90ZWN0IGEKKzRLQiBwYWdlLCB0aGlzIGNvbW1hbmQgY2FuIHdyaXRlLXByb3RlY3QgMTI4 LWJ5dGVzIHN1YnBhZ2VzIGluc2lkZSBvZiBhCis0S0IgcGFnZSBieSBzZXR0aW5nIHRoZSBjb3Jy ZXNwb25kaW5nIGJpdCB0byAxICh3cml0ZSBhbGxvd2VkKSBvciB0byAwCisod3JpdGUgZGlzYWxs b3dlZCkuIEZvciBleGFtcGxlLCB0byBhbGxvdyB3cml0ZSBhY2Nlc3MgdG8gdGhlIEEgYW5kIEIK K3N1YnBhZ2VzIG9ubHksIHRoZSBiaXRtYXAgbXVzdCBiZSBzZXQgdG86OgorCisJQklUKEEpIHwg QklUKEIpCisKK0EgYW5kIEIgbXVzdCBiZSBhIG51bWJlciBiZXR3ZWVuIDAgKGZpcnN0IHN1YnBh Z2UpIGFuZCAzMSAobGFzdCBzdWJwYWdlKS4KKworVXNpbmcgdGhpcyBjb21tYW5kIHRvIHNldCBh bGwgYml0cyB0byAxIChhbGxvdyB3cml0ZSBhY2Nlc3MgZm9yCithbGwgc3VicGFnZXMpIHdpbGwg YWxsb3cgd3JpdGUgYWNjZXNzIHRvIHRoZSB3aG9sZSA0S0IgcGFnZSAobGlrZSBhCisqS1ZNSV9T RVRfUEFHRV9BQ0NFU1MqIGNvbW1hbmQgd2l0aCB0aGUgKktWTUlfUEFHRV9BQ0NFU1NfVyogZmxh ZyBzZXQpCithbmQgdmljZSB2ZXJzYS4KKworVXNpbmcgdGhpcyBjb21tYW5kIHRvIHNldCBhbnkg Yml0IHRvIDAgd2lsbCB3cml0ZS1wcm90ZWN0IHRoZSB3aG9sZSA0S0IKK3BhZ2UgKGxpa2UgYSAq S1ZNSV9TRVRfUEFHRV9BQ0NFU1MqIGNvbW1hbmQgd2l0aCB0aGUgKktWTUlfUEFHRV9BQ0NFU1Nf VyoKK2ZsYWcgY2xlYXJlZCkgYW5kIGFsbG93IHdyaXRlIGFjY2VzcyBvbmx5IGZvciBzdWJwYWdl cyB3aXRoIHRoZQorY29ycmVzcG9uZGluZyBiaXQgc2V0IHRvIDEuCisKKzpFcnJvcnM6CisKKyog LUtWTV9FSU5WQUwgLSB0aGUgc2VsZWN0ZWQgU1BUIHZpZXcgaXMgaW52YWxpZAorKiAtS1ZNX0VP UE5PVFNVUFAgLSBhIFNQVCB2aWV3IHdhcyBzZWxlY3RlZCBidXQgdGhlIGhhcmR3YXJlIGRvZXNu J3Qgc3VwcG9ydCBpdAorKiAtS1ZNX0VPUE5PVFNVUFAgLSB0aGUgaGFyZHdhcmUgZG9lc24ndCBz dXBwb3J0IFNQUCBvciBoYXNuJ3QgYmVlbiBlbmFibGVkCisqIC1LVk1fRUlOVkFMIC0gdGhlIHdy aXRlIGFjY2VzcyBpcyBhbHJlYWR5IGFsbG93ZWQgZm9yIHRoZSB3aG9sZSA0S0IgcGFnZQorKiAt S1ZNX0VBR0FJTiAtIHRoZSBzZWxlY3RlZCB2Q1BVIGNhbid0IGJlIGludHJvc3BlY3RlZCB5ZXQK KyogLUtWTV9FTk9NRU0gLSBub3QgZW5vdWdoIG1lbW9yeSB0byBhZGQgdGhlIHBhZ2UgdHJhY2tp bmcgc3RydWN0dXJlcworCiBFdmVudHMKID09PT09PQogCmRpZmYgLS1naXQgYS9hcmNoL3g4Ni9r dm0va3ZtaS5jIGIvYXJjaC94ODYva3ZtL2t2bWkuYwppbmRleCAzNTZlYzc5OTM2YjMuLmZhMjkw ZmJmMWY3NSAxMDA2NDQKLS0tIGEvYXJjaC94ODYva3ZtL2t2bWkuYworKysgYi9hcmNoL3g4Ni9r dm0va3ZtaS5jCkBAIC0zMDQsNiArMzA0LDM2IEBAIGludCBrdm1pX2FyY2hfY21kX3NldF9wYWdl X2FjY2VzcyhzdHJ1Y3Qga3ZtaSAqaWt2bSwKIAlyZXR1cm4gZWM7CiB9CiAKK2ludCBrdm1pX2Fy Y2hfY21kX3NldF9wYWdlX3dyaXRlX2JpdG1hcChzdHJ1Y3Qga3ZtaSAqaWt2bSwKKwkJCQkJY29u c3Qgc3RydWN0IGt2bWlfbXNnX2hkciAqbXNnLAorCQkJCQljb25zdCBzdHJ1Y3Qga3ZtaV9zZXRf cGFnZV93cml0ZV9iaXRtYXAKKwkJCQkJKnJlcSkKK3sKKwl1MTYgaywgbiA9IHJlcS0+Y291bnQ7 CisJaW50IGVjID0gMDsKKworCWlmIChyZXEtPnBhZGRpbmcpCisJCXJldHVybiAtS1ZNX0VJTlZB TDsKKworCWlmIChtc2ctPnNpemUgPCBzaXplb2YoKnJlcSkgKyByZXEtPmNvdW50ICogc2l6ZW9m KHJlcS0+ZW50cmllc1swXSkpCisJCXJldHVybiAtS1ZNX0VJTlZBTDsKKworCWlmICgha3ZtaV9z cHBfZW5hYmxlZChpa3ZtKSkKKwkJcmV0dXJuIC1LVk1fRU9QTk9UU1VQUDsKKworCWlmIChyZXEt PnZpZXcgIT0gMCkJLyogVE9ETyAqLworCQlyZXR1cm4gLUtWTV9FT1BOT1RTVVBQOworCisJZm9y IChrID0gMDsgayA8IG4gJiYgZWMgPT0gMDsgaysrKSB7CisJCXU2NCBncGEgPSByZXEtPmVudHJp ZXNba10uZ3BhOworCQl1MzIgYml0bWFwID0gcmVxLT5lbnRyaWVzW2tdLmJpdG1hcDsKKworCQll YyA9IGt2bWlfY21kX3NldF9wYWdlX3dyaXRlX2JpdG1hcChpa3ZtLCBncGEsIGJpdG1hcCk7CisJ fQorCisJcmV0dXJuIGVjOworfQorCiBpbnQga3ZtaV9hcmNoX2NtZF9jb250cm9sX3NwcChzdHJ1 Y3Qga3ZtaSAqaWt2bSkKIHsKIAlyZXR1cm4ga3ZtX2FyY2hfaW5pdF9zcHAoaWt2bS0+a3ZtKTsK ZGlmZiAtLWdpdCBhL2luY2x1ZGUvdWFwaS9saW51eC9rdm1pLmggYi9pbmNsdWRlL3VhcGkvbGlu dXgva3ZtaS5oCmluZGV4IDE5YTZhNTBkZjk2Yi4uMGIzMTM5YzUyYTMwIDEwMDY0NAotLS0gYS9p bmNsdWRlL3VhcGkvbGludXgva3ZtaS5oCisrKyBiL2luY2x1ZGUvdWFwaS9saW51eC9rdm1pLmgK QEAgLTE2MCw2ICsxNjAsMTkgQEAgc3RydWN0IGt2bWlfZ2V0X3BhZ2Vfd3JpdGVfYml0bWFwX3Jl cGx5IHsKIAlfX3UzMiBiaXRtYXBbMF07CiB9OwogCitzdHJ1Y3Qga3ZtaV9wYWdlX3dyaXRlX2Jp dG1hcF9lbnRyeSB7CisJX191NjQgZ3BhOworCV9fdTMyIGJpdG1hcDsKKwlfX3UzMiBwYWRkaW5n OworfTsKKworc3RydWN0IGt2bWlfc2V0X3BhZ2Vfd3JpdGVfYml0bWFwIHsKKwlfX3UxNiB2aWV3 OworCV9fdTE2IGNvdW50OworCV9fdTMyIHBhZGRpbmc7CisJc3RydWN0IGt2bWlfcGFnZV93cml0 ZV9iaXRtYXBfZW50cnkgZW50cmllc1swXTsKK307CisKIHN0cnVjdCBrdm1pX2dldF92Y3B1X2lu Zm9fcmVwbHkgewogCV9fdTY0IHRzY19zcGVlZDsKIH07CmRpZmYgLS1naXQgYS92aXJ0L2t2bS9r dm1pLmMgYi92aXJ0L2t2bS9rdm1pLmMKaW5kZXggMjJlMjMzY2E0NzRjLi5kMmJlYmVmOThkOGQg MTAwNjQ0Ci0tLSBhL3ZpcnQva3ZtL2t2bWkuYworKysgYi92aXJ0L2t2bS9rdm1pLmMKQEAgLTk5 LDYgKzk5LDI0IEBAIHN0YXRpYyBpbnQga3ZtaV9zZXRfZ2ZuX2FjY2VzcyhzdHJ1Y3Qga3ZtICpr dm0sIGdmbl90IGdmbiwgdTggYWNjZXNzLAogCW0tPmFjY2VzcyA9IGFjY2VzczsKIAltLT53cml0 ZV9iaXRtYXAgPSB3cml0ZV9iaXRtYXA7CiAKKwkvKgorCSAqIE9ubHkgdHJ5IHRvIHNldCBTUFAg Yml0bWFwIHdoZW4gdGhlIHBhZ2UgaXMgd3JpdGFibGUuCisJICogQmUgY2FyZWZ1bCwga3ZtX21t dV9zZXRfc3VicGFnZXMoKSB3aWxsIGVuYWJsZSBwYWdlIHdyaXRlLXByb3RlY3Rpb24KKwkgKiBi eSBkZWZhdWx0IHdoZW4gc2V0IFNQUCBiaXRtYXAuIElmIGJpdG1hcCBjb250YWlucyBhbGwgMXMs IGl0J2xsCisJICogbWFrZSB0aGUgcGFnZSB3cml0YWJsZSBieSBkZWZhdWx0IHRvby4KKwkgKi8K KwlpZiAoIShhY2Nlc3MgJiBLVk1JX1BBR0VfQUNDRVNTX1cpICYmIGt2bWlfc3BwX2VuYWJsZWQo aWt2bSkpIHsKKwkJc3RydWN0IGt2bV9zdWJwYWdlIHNwcF9pbmZvOworCisJCXNwcF9pbmZvLmJh c2VfZ2ZuID0gZ2ZuOworCQlzcHBfaW5mby5ucGFnZXMgPSAxOworCQlzcHBfaW5mby5hY2Nlc3Nf bWFwWzBdID0gd3JpdGVfYml0bWFwOworCisJCWVyciA9IGt2bV9hcmNoX3NldF9zdWJwYWdlcyhr dm0sICZzcHBfaW5mbyk7CisJCWlmIChlcnIpCisJCQlnb3RvIGV4aXQ7CisJfQorCiAJaWYgKHJh ZGl4X3RyZWVfcHJlbG9hZChHRlBfS0VSTkVMKSkgewogCQllcnIgPSAtS1ZNX0VOT01FTTsKIAkJ Z290byBleGl0OwpAQCAtMTE4Myw2ICsxMjAxLDI1IEBAIGludCBrdm1pX2NtZF9zZXRfcGFnZV9h Y2Nlc3Moc3RydWN0IGt2bWkgKmlrdm0sIHU2NCBncGEsIHU4IGFjY2VzcykKIAlyZXR1cm4ga3Zt aV9zZXRfZ2ZuX2FjY2Vzcyhpa3ZtLT5rdm0sIGdmbiwgYWNjZXNzLCB3cml0ZV9iaXRtYXApOwog fQogCitpbnQga3ZtaV9jbWRfc2V0X3BhZ2Vfd3JpdGVfYml0bWFwKHN0cnVjdCBrdm1pICppa3Zt LCB1NjQgZ3BhLAorCQkJCSAgIHUzMiB3cml0ZV9iaXRtYXApCit7CisJYm9vbCB3cml0ZV9hbGxv d2VkX2Zvcl9hbGw7CisJZ2ZuX3QgZ2ZuID0gZ3BhX3RvX2dmbihncGEpOworCXUzMiBpZ25vcmVk X3dyaXRlX2JpdG1hcDsKKwl1OCBhY2Nlc3M7CisKKwlrdm1pX2dldF9nZm5fYWNjZXNzKGlrdm0s IGdmbiwgJmFjY2VzcywgJmlnbm9yZWRfd3JpdGVfYml0bWFwKTsKKworCXdyaXRlX2FsbG93ZWRf Zm9yX2FsbCA9ICh3cml0ZV9iaXRtYXAgPT0gKHUzMikoKDFVTEwgPDwgMzIpIC0gMSkpOworCWlm ICh3cml0ZV9hbGxvd2VkX2Zvcl9hbGwpCisJCWFjY2VzcyB8PSBLVk1JX1BBR0VfQUNDRVNTX1c7 CisJZWxzZQorCQlhY2Nlc3MgJj0gfktWTUlfUEFHRV9BQ0NFU1NfVzsKKworCXJldHVybiBrdm1p X3NldF9nZm5fYWNjZXNzKGlrdm0tPmt2bSwgZ2ZuLCBhY2Nlc3MsIHdyaXRlX2JpdG1hcCk7Cit9 CisKIGludCBrdm1pX2NtZF9jb250cm9sX2V2ZW50cyhzdHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUsIHVu c2lnbmVkIGludCBldmVudF9pZCwKIAkJCSAgICBib29sIGVuYWJsZSkKIHsKZGlmZiAtLWdpdCBh L3ZpcnQva3ZtL2t2bWlfaW50LmggYi92aXJ0L2t2bS9rdm1pX2ludC5oCmluZGV4IDcyNDNjNTdi ZTI3YS4uMThjMDBkYWUwZjJmIDEwMDY0NAotLS0gYS92aXJ0L2t2bS9rdm1pX2ludC5oCisrKyBi L3ZpcnQva3ZtL2t2bWlfaW50LmgKQEAgLTE3Myw2ICsxNzMsNyBAQCB2b2lkIGt2bWlfbXNnX2Zy ZWUodm9pZCAqYWRkcik7CiBpbnQga3ZtaV9jbWRfZ2V0X3BhZ2VfYWNjZXNzKHN0cnVjdCBrdm1p ICppa3ZtLCB1NjQgZ3BhLCB1OCAqYWNjZXNzKTsKIGludCBrdm1pX2NtZF9zZXRfcGFnZV9hY2Nl c3Moc3RydWN0IGt2bWkgKmlrdm0sIHU2NCBncGEsIHU4IGFjY2Vzcyk7CiBpbnQga3ZtaV9jbWRf Z2V0X3BhZ2Vfd3JpdGVfYml0bWFwKHN0cnVjdCBrdm1pICppa3ZtLCB1NjQgZ3BhLCB1MzIgKmJp dG1hcCk7CitpbnQga3ZtaV9jbWRfc2V0X3BhZ2Vfd3JpdGVfYml0bWFwKHN0cnVjdCBrdm1pICpp a3ZtLCB1NjQgZ3BhLCB1MzIgYml0bWFwKTsKIGludCBrdm1pX2NtZF9jb250cm9sX2V2ZW50cyhz dHJ1Y3Qga3ZtX3ZjcHUgKnZjcHUsIHVuc2lnbmVkIGludCBldmVudF9pZCwKIAkJCSAgICBib29s IGVuYWJsZSk7CiBpbnQga3ZtaV9jbWRfY29udHJvbF92bV9ldmVudHMoc3RydWN0IGt2bWkgKmlr dm0sIHVuc2lnbmVkIGludCBldmVudF9pZCwKQEAgLTIwMiw2ICsyMDMsOSBAQCBpbnQga3ZtaV9h cmNoX2NtZF9nZXRfcGFnZV93cml0ZV9iaXRtYXAoc3RydWN0IGt2bWkgKmlrdm0sCiAJCQkJCWNv bnN0IHN0cnVjdCBrdm1pX2dldF9wYWdlX3dyaXRlX2JpdG1hcCAqcmVxLAogCQkJCQlzdHJ1Y3Qg a3ZtaV9nZXRfcGFnZV93cml0ZV9iaXRtYXBfcmVwbHkgKipkZXN0LAogCQkJCQlzaXplX3QgKmRl c3Rfc2l6ZSk7CitpbnQga3ZtaV9hcmNoX2NtZF9zZXRfcGFnZV93cml0ZV9iaXRtYXAoc3RydWN0 IGt2bWkgKmlrdm0sCisJCQkJCWNvbnN0IHN0cnVjdCBrdm1pX21zZ19oZHIgKm1zZywKKwkJCQkJ Y29uc3Qgc3RydWN0IGt2bWlfc2V0X3BhZ2Vfd3JpdGVfYml0bWFwICpyZXEpOwogdm9pZCBrdm1p X2FyY2hfc2V0dXBfZXZlbnQoc3RydWN0IGt2bV92Y3B1ICp2Y3B1LCBzdHJ1Y3Qga3ZtaV9ldmVu dCAqZXYpOwogYm9vbCBrdm1pX2FyY2hfcGZfZXZlbnQoc3RydWN0IGt2bV92Y3B1ICp2Y3B1LCBn cGFfdCBncGEsIGd2YV90IGd2YSwKIAkJCXU4IGFjY2Vzcyk7CmRpZmYgLS1naXQgYS92aXJ0L2t2 bS9rdm1pX21zZy5jIGIvdmlydC9rdm0va3ZtaV9tc2cuYwppbmRleCBlYjI0N2FjM2UwMzcuLmY5 ZWZiNTJkNDljMyAxMDA2NDQKLS0tIGEvdmlydC9rdm0va3ZtaV9tc2cuYworKysgYi92aXJ0L2t2 bS9rdm1pX21zZy5jCkBAIC0zNSw2ICszNSw3IEBAIHN0YXRpYyBjb25zdCBjaGFyICpjb25zdCBt c2dfSURzW10gPSB7CiAJW0tWTUlfR0VUX1ZDUFVfSU5GT10gICAgICAgICA9ICJLVk1JX0dFVF9W Q1BVX0lORk8iLAogCVtLVk1JX0dFVF9WRVJTSU9OXSAgICAgICAgICAgPSAiS1ZNSV9HRVRfVkVS U0lPTiIsCiAJW0tWTUlfU0VUX1BBR0VfQUNDRVNTXSAgICAgICA9ICJLVk1JX1NFVF9QQUdFX0FD Q0VTUyIsCisJW0tWTUlfU0VUX1BBR0VfV1JJVEVfQklUTUFQXSA9ICJLVk1JX1NFVF9QQUdFX1dS SVRFX0JJVE1BUCIsCiB9OwogCiBzdGF0aWMgYm9vbCBpc19rbm93bl9tZXNzYWdlKHUxNiBpZCkK QEAgLTQwMCw2ICs0MDEsMTcgQEAgc3RhdGljIGludCBoYW5kbGVfZ2V0X3BhZ2Vfd3JpdGVfYml0 bWFwKHN0cnVjdCBrdm1pICppa3ZtLAogCXJldHVybiBlcnI7CiB9CiAKK3N0YXRpYyBpbnQgaGFu ZGxlX3NldF9wYWdlX3dyaXRlX2JpdG1hcChzdHJ1Y3Qga3ZtaSAqaWt2bSwKKwkJCQkJY29uc3Qg c3RydWN0IGt2bWlfbXNnX2hkciAqbXNnLAorCQkJCQljb25zdCB2b2lkICpyZXEpCit7CisJaW50 IGVjOworCisJZWMgPSBrdm1pX2FyY2hfY21kX3NldF9wYWdlX3dyaXRlX2JpdG1hcChpa3ZtLCBt c2csIHJlcSk7CisKKwlyZXR1cm4ga3ZtaV9tc2dfdm1fbWF5YmVfcmVwbHkoaWt2bSwgbXNnLCBl YywgTlVMTCwgMCk7Cit9CisKIHN0YXRpYyBib29sIGludmFsaWRfdmNwdV9oZHIoY29uc3Qgc3Ry dWN0IGt2bWlfdmNwdV9oZHIgKmhkcikKIHsKIAlyZXR1cm4gaGRyLT5wYWRkaW5nMSB8fCBoZHIt PnBhZGRpbmcyOwpAQCAtNDIwLDYgKzQzMiw3IEBAIHN0YXRpYyBpbnQoKmNvbnN0IG1zZ192bVtd KShzdHJ1Y3Qga3ZtaSAqLCBjb25zdCBzdHJ1Y3Qga3ZtaV9tc2dfaGRyICosCiAJW0tWTUlfR0VU X1BBR0VfV1JJVEVfQklUTUFQXSA9IGhhbmRsZV9nZXRfcGFnZV93cml0ZV9iaXRtYXAsCiAJW0tW TUlfR0VUX1ZFUlNJT05dICAgICAgICAgICA9IGhhbmRsZV9nZXRfdmVyc2lvbiwKIAlbS1ZNSV9T RVRfUEFHRV9BQ0NFU1NdICAgICAgID0gaGFuZGxlX3NldF9wYWdlX2FjY2VzcywKKwlbS1ZNSV9T RVRfUEFHRV9XUklURV9CSVRNQVBdID0gaGFuZGxlX3NldF9wYWdlX3dyaXRlX2JpdG1hcCwKIH07 CiAKIHN0YXRpYyBpbnQgaGFuZGxlX2V2ZW50X3JlcGx5KHN0cnVjdCBrdm1fdmNwdSAqdmNwdSwK X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KVmlydHVhbGl6 YXRpb24gbWFpbGluZyBsaXN0ClZpcnR1YWxpemF0aW9uQGxpc3RzLmxpbnV4LWZvdW5kYXRpb24u b3JnCmh0dHBzOi8vbGlzdHMubGludXhmb3VuZGF0aW9uLm9yZy9tYWlsbWFuL2xpc3RpbmZvL3Zp cnR1YWxpemF0aW9u