From patchwork Wed Sep 23 22:45:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 11795773 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 081F66CB for ; Wed, 23 Sep 2020 22:47:19 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 BF282208E4 for ; Wed, 23 Sep 2020 22:47:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="UrL2gmDl" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BF282208E4 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1n+dURdFEKDLKGqzdajALdJfM6/Rr4Hnn41IvUDwbMw=; b=UrL2gmDlGJ7kWn8N0lq8OfGRK wzPZqI3dijj2Os5OIZaaJwvmGbMJoE+GjpZIrwWrAWp9agGxovicZLILPKnnCLSt/DmtF9K4DqIvO xwE77kGHx7pv2q+QMhbbvkr/Vj0jr6zJDKHaJlOX+8jJX9vd4wR/enF5Z/QDc4eI4H5+xMhDfrZ6i g7ljMnDhT8VUqIE/3ZqbVUB2QGGNOIf5A7r+ryagD651bkS0chZvBL/3PC8tFYgjpZNoz/nhdwII6 /C0CHlYpiSvmHMyqaHutQzf1bj+wacRJ59vaVcRwpYUMy6QGGjOyfg9bB1ZCoJ/N+FiiTIbXu7Nl2 Su0Y1OZOw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLDWG-0004Ua-La; Wed, 23 Sep 2020 22:45:48 +0000 Received: from mga01.intel.com ([192.55.52.88]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kLDW5-0004Rf-W0 for linux-arm-kernel@lists.infradead.org; Wed, 23 Sep 2020 22:45:39 +0000 IronPort-SDR: whPL5bS92AZXStzgoND0tIAK4a2Co7ZPm5JwR/fnf+YmxgfkMW3n3TAo44hHKVxiu1hD+vF/51 xHbMNOJ9E7pw== X-IronPort-AV: E=McAfee;i="6000,8403,9753"; a="179119922" X-IronPort-AV: E=Sophos;i="5.77,295,1596524400"; d="scan'208";a="179119922" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Sep 2020 15:45:33 -0700 IronPort-SDR: AbPVqCuESrKK1QagClfee2VePOWMPCaSkPXjb5p9UqLqHJ2x8Bv825CzMgGhRh7vaqFV5ysJZu LlvB4682AtLg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.77,295,1596524400"; d="scan'208";a="335660066" Received: from sjchrist-coffee.jf.intel.com ([10.54.74.160]) by fmsmga004.fm.intel.com with ESMTP; 23 Sep 2020 15:45:32 -0700 From: Sean Christopherson To: Paolo Bonzini Subject: [RFC PATCH 2/3] KVM: Add infrastructure and macro to mark VM as bugged Date: Wed, 23 Sep 2020 15:45:29 -0700 Message-Id: <20200923224530.17735-3-sean.j.christopherson@intel.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200923224530.17735-1-sean.j.christopherson@intel.com> References: <20200923224530.17735-1-sean.j.christopherson@intel.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200923_184538_231601_9211F4ED X-CRM114-Status: GOOD ( 20.74 ) X-Spam-Score: -5.0 (-----) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-5.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at https://www.dnswl.org/, high trust [192.55.52.88 listed in list.dnswl.org] 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [192.55.52.88 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Wanpeng Li , kvm@vger.kernel.org, David Hildenbrand , linux-mips@vger.kernel.org, Paul Mackerras , Huacai Chen , Claudio Imbrenda , Janosch Frank , Marc Zyngier , Joerg Roedel , Christian Borntraeger , Aleksandar Markovic , Julien Thierry , Suzuki K Poulose , kvm-ppc@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Jim Mattson , Cornelia Huck , linux-kernel@vger.kernel.org, Sean Christopherson , James Morse , Vitaly Kuznetsov Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Introduce the concept of a "bugged VM", i.e. a VM that has encountered a KVM bug and/or a CPU bug and is, for all intents and purposes, dead in the water. Marking a VM as bugged is especially helpful to handle scenarios that can only be reach if there is a software/hardware bug, but can't easily return an error, e.g. x86's register caching callbacks. Reject all ioctls() if a VM is bugged, and provide a new request so that arch specific code can kick running vCPUs out to userspace. Cc: Marc Zyngier Cc: James Morse Cc: Julien Thierry Cc: Suzuki K Poulose Cc: linux-arm-kernel@lists.infradead.org Cc: Huacai Chen Cc: Aleksandar Markovic Cc: linux-mips@vger.kernel.org Cc: Paul Mackerras Cc: kvm-ppc@vger.kernel.org Cc: Christian Borntraeger Cc: Janosch Frank Cc: David Hildenbrand Cc: Cornelia Huck Cc: Claudio Imbrenda Cc: Vitaly Kuznetsov Cc: Wanpeng Li Cc: Jim Mattson Cc: Joerg Roedel Signed-off-by: Sean Christopherson --- include/linux/kvm_host.h | 27 +++++++++++++++++++++++++++ virt/kvm/kvm_main.c | 10 +++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 1d70aeeb7ec3..cb527d55908d 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -146,6 +146,7 @@ static inline bool is_error_page(struct page *page) #define KVM_REQ_MMU_RELOAD (1 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_PENDING_TIMER 2 #define KVM_REQ_UNHALT 3 +#define KVM_REQ_VM_BUGGED (4 | KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQUEST_ARCH_BASE 8 #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \ @@ -513,6 +514,8 @@ struct kvm { struct srcu_struct irq_srcu; pid_t userspace_pid; unsigned int max_halt_poll_ns; + + bool vm_bugged; }; #define kvm_err(fmt, ...) \ @@ -541,6 +544,30 @@ struct kvm { #define vcpu_err(vcpu, fmt, ...) \ kvm_err("vcpu%i " fmt, (vcpu)->vcpu_id, ## __VA_ARGS__) +static inline void kvm_vm_bugged(struct kvm *kvm) +{ + kvm->vm_bugged = true; + kvm_make_all_cpus_request(kvm, KVM_REQ_VM_BUGGED); +} + +#define KVM_BUG(cond, kvm, fmt...) \ +({ \ + int __ret = (cond); \ + \ + if (WARN_ONCE(__ret && !(kvm)->vm_bugged, fmt)) \ + kvm_vm_bugged(kvm); \ + unlikely(__ret); \ +}) + +#define KVM_BUG_ON(cond, kvm) \ +({ \ + int __ret = (cond); \ + \ + if (WARN_ON_ONCE(__ret && !(kvm)->vm_bugged)) \ + kvm_vm_bugged(kvm); \ + unlikely(__ret); \ +}) + static inline bool kvm_dirty_log_manual_protect_and_init_set(struct kvm *kvm) { return !!(kvm->manual_dirty_log_protect & KVM_DIRTY_LOG_INITIALLY_SET); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index bf3f333c7a19..e216ce9d1c39 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3191,7 +3191,7 @@ static long kvm_vcpu_ioctl(struct file *filp, struct kvm_fpu *fpu = NULL; struct kvm_sregs *kvm_sregs = NULL; - if (vcpu->kvm->mm != current->mm) + if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged) return -EIO; if (unlikely(_IOC_TYPE(ioctl) != KVMIO)) @@ -3397,7 +3397,7 @@ static long kvm_vcpu_compat_ioctl(struct file *filp, void __user *argp = compat_ptr(arg); int r; - if (vcpu->kvm->mm != current->mm) + if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_bugged) return -EIO; switch (ioctl) { @@ -3463,7 +3463,7 @@ static long kvm_device_ioctl(struct file *filp, unsigned int ioctl, { struct kvm_device *dev = filp->private_data; - if (dev->kvm->mm != current->mm) + if (dev->kvm->mm != current->mm || dev->kvm->vm_bugged) return -EIO; switch (ioctl) { @@ -3679,7 +3679,7 @@ static long kvm_vm_ioctl(struct file *filp, void __user *argp = (void __user *)arg; int r; - if (kvm->mm != current->mm) + if (kvm->mm != current->mm || kvm->vm_bugged) return -EIO; switch (ioctl) { case KVM_CREATE_VCPU: @@ -3874,7 +3874,7 @@ static long kvm_vm_compat_ioctl(struct file *filp, struct kvm *kvm = filp->private_data; int r; - if (kvm->mm != current->mm) + if (kvm->mm != current->mm || kvm->vm_bugged) return -EIO; switch (ioctl) { case KVM_GET_DIRTY_LOG: {