From patchwork Fri Aug 9 15:59:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Adalbert_Laz=C4=83r?= X-Patchwork-Id: 11086995 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BF1061709 for ; Fri, 9 Aug 2019 16:09:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AB651201BD for ; Fri, 9 Aug 2019 16:09:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9EE13201F5; Fri, 9 Aug 2019 16:09:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0F24A201BD for ; Fri, 9 Aug 2019 16:09:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2437048AbfHIQJ5 (ORCPT ); Fri, 9 Aug 2019 12:09:57 -0400 Received: from mx01.bbu.dsd.mx.bitdefender.com ([91.199.104.161]:52684 "EHLO mx01.bbu.dsd.mx.bitdefender.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437001AbfHIQJ4 (ORCPT ); Fri, 9 Aug 2019 12:09:56 -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 C03DD301AB36; Fri, 9 Aug 2019 19:00:53 +0300 (EEST) Received: from localhost.localdomain (unknown [89.136.169.210]) by smtp.bitdefender.com (Postfix) with ESMTPSA id 82DC0305B7A0; Fri, 9 Aug 2019 19:00:53 +0300 (EEST) From: =?utf-8?q?Adalbert_Laz=C4=83r?= To: kvm@vger.kernel.org Cc: linux-mm@kvack.org, virtualization@lists.linux-foundation.org, Paolo Bonzini , =?utf-8?b?UmFkaW0gS3LEjW3DocWZ?= , Konrad Rzeszutek Wilk , Tamas K Lengyel , Mathieu Tarral , =?utf-8?q?Samuel_Laur=C3=A9?= =?utf-8?q?n?= , Patrick Colp , Jan Kiszka , Stefan Hajnoczi , Weijiang Yang , Zhang@vger.kernel.org, Yu C , =?utf-8?q?Mihai_Don=C8=9Bu?= , =?utf-8?q?Adalbert_L?= =?utf-8?q?az=C4=83r?= Subject: [RFC PATCH v6 05/92] kvm: introspection: add KVMI_GET_VERSION Date: Fri, 9 Aug 2019 18:59:20 +0300 Message-Id: <20190809160047.8319-6-alazar@bitdefender.com> In-Reply-To: <20190809160047.8319-1-alazar@bitdefender.com> References: <20190809160047.8319-1-alazar@bitdefender.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This command should be used by the introspection tool to identify the commands/events supported by the KVMi subsystem and, most important, what messages must be used for event replies. The kernel side will accept smaller or bigger command messages, but it can be more strict with bigger event reply messages. The command is always allowed and any attempt from userspace to disallow it through KVM_INTROSPECTION_COMMAND will get -EPERM (unless userspace choose to disable all commands, using id=-1, in which case KVMI_GET_VERSION is quietly allowed, without an error). Signed-off-by: Adalbert Lazăr --- Documentation/virtual/kvm/kvmi.rst | 28 ++++++++++++++++++++++++++++ include/uapi/linux/kvmi.h | 5 +++++ virt/kvm/kvmi.c | 14 ++++++++++++++ virt/kvm/kvmi_msg.c | 13 +++++++++++++ 4 files changed, 60 insertions(+) diff --git a/Documentation/virtual/kvm/kvmi.rst b/Documentation/virtual/kvm/kvmi.rst index 1d4a1dcd7d2f..0f296e3c4244 100644 --- a/Documentation/virtual/kvm/kvmi.rst +++ b/Documentation/virtual/kvm/kvmi.rst @@ -224,3 +224,31 @@ device-specific memory (DMA, emulated MMIO, reserved by a passthrough device etc.). It is up to the user to determine, using the guest operating system data structures, the areas that are safe to access (code, stack, heap etc.). + +Commands +-------- + +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. + +1. KVMI_GET_VERSION +------------------- + +:Architectures: all +:Versions: >= 1 +:Parameters: none +:Returns: + +:: + + struct kvmi_error_code; + struct kvmi_get_version_reply { + __u32 version; + __u32 padding; + }; + +Returns the introspection API version. + +This command is always allowed and successful (if the introspection is +built in kernel). diff --git a/include/uapi/linux/kvmi.h b/include/uapi/linux/kvmi.h index 6c7600ed4564..9574ba0b9565 100644 --- a/include/uapi/linux/kvmi.h +++ b/include/uapi/linux/kvmi.h @@ -78,4 +78,9 @@ struct kvmi_error_code { __u32 padding; }; +struct kvmi_get_version_reply { + __u32 version; + __u32 padding; +}; + #endif /* _UAPI__LINUX_KVMI_H */ diff --git a/virt/kvm/kvmi.c b/virt/kvm/kvmi.c index afa31748d7f4..d5b6af21564e 100644 --- a/virt/kvm/kvmi.c +++ b/virt/kvm/kvmi.c @@ -68,6 +68,8 @@ static bool alloc_kvmi(struct kvm *kvm, const struct kvm_introspection *qemu) if (!ikvm) return false; + set_bit(KVMI_GET_VERSION, ikvm->cmd_allow_mask); + memcpy(&ikvm->uuid, &qemu->uuid, sizeof(ikvm->uuid)); ikvm->kvm = kvm; @@ -290,6 +292,18 @@ int kvmi_ioctl_command(struct kvm *kvm, void __user *argp) bitmap_from_u64(known, KVMI_KNOWN_COMMANDS); bitmap_and(requested, requested, known, KVMI_NUM_COMMANDS); + if (!allow) { + DECLARE_BITMAP(always_allowed, KVMI_NUM_COMMANDS); + + if (id == KVMI_GET_VERSION) + return -EPERM; + + set_bit(KVMI_GET_VERSION, always_allowed); + + bitmap_andnot(requested, requested, always_allowed, + KVMI_NUM_COMMANDS); + } + return kvmi_ioctl_feature(kvm, allow, requested, offsetof(struct kvmi, cmd_allow_mask), KVMI_NUM_COMMANDS); diff --git a/virt/kvm/kvmi_msg.c b/virt/kvm/kvmi_msg.c index af6bc47dc031..6fe04de29f7e 100644 --- a/virt/kvm/kvmi_msg.c +++ b/virt/kvm/kvmi_msg.c @@ -9,6 +9,7 @@ #include "kvmi_int.h" static const char *const msg_IDs[] = { + [KVMI_GET_VERSION] = "KVMI_GET_VERSION", }; static bool is_known_message(u16 id) @@ -129,6 +130,17 @@ static int kvmi_msg_vm_reply(struct kvmi *ikvm, return kvmi_msg_reply(ikvm, msg, err, rpl, rpl_size); } +static int handle_get_version(struct kvmi *ikvm, + const struct kvmi_msg_hdr *msg, const void *req) +{ + struct kvmi_get_version_reply rpl; + + memset(&rpl, 0, sizeof(rpl)); + rpl.version = KVMI_VERSION; + + return kvmi_msg_vm_reply(ikvm, msg, 0, &rpl, sizeof(rpl)); +} + static bool is_command_allowed(struct kvmi *ikvm, int id) { return test_bit(id, ikvm->cmd_allow_mask); @@ -139,6 +151,7 @@ static bool is_command_allowed(struct kvmi *ikvm, int id) */ static int(*const msg_vm[])(struct kvmi *, const struct kvmi_msg_hdr *, const void *) = { + [KVMI_GET_VERSION] = handle_get_version, }; static bool is_vm_message(u16 id)