From patchwork Fri Oct 13 23:14:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Yi" X-Patchwork-Id: 10004883 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BC4F860360 for ; Fri, 13 Oct 2017 14:29:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7195628657 for ; Fri, 13 Oct 2017 14:29:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 668B5286BD; Fri, 13 Oct 2017 14:29:37 +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=-5.0 required=2.0 tests=BAYES_00, DATE_IN_FUTURE_06_12, 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 0BE1128657 for ; Fri, 13 Oct 2017 14:29:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758313AbdJMO2F (ORCPT ); Fri, 13 Oct 2017 10:28:05 -0400 Received: from mga11.intel.com ([192.55.52.93]:41197 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756900AbdJMO2D (ORCPT ); Fri, 13 Oct 2017 10:28:03 -0400 Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Oct 2017 07:28:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.43,371,1503385200"; d="scan'208";a="160163271" Received: from linux.intel.com ([10.54.29.200]) by orsmga005.jf.intel.com with ESMTP; 13 Oct 2017 07:28:02 -0700 Received: from dazhang1-ssd.sh.intel.com (unknown [10.239.48.120]) by linux.intel.com (Postfix) with ESMTP id 28A0B5802E7; Fri, 13 Oct 2017 07:28:01 -0700 (PDT) From: Zhang Yi To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: pbonzini@redhat.com, rkrcmar@redhat.com, Zhang Yi Z Subject: [PATCH RFC 05/10] KVM: VMX: Introduce SPP-Induced vm exit and it's handle. Date: Sat, 14 Oct 2017 07:14:06 +0800 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Zhang Yi Z Accesses using guest-physical addresses may cause SPP-induced VM exits due to an SPPT misconfiguration or an SPPT miss. The basic VM exit reason code reported for SPP-induced VM exits is 66. An SPPT misconfiguration VM exit occurs when, in the course of translating a guest-physical address, the logical processor encounters a leaf EPT paging-structure entry mapping a 4KB page for which the sub-page write permission control bit is set and during the SPPT lookup an SPPT paging-structure entry contains an unsupported value. An SPPT miss VM exit occurs when, in the course of translation a guest-physical address, the logical processor encounters a leaf EPT paging-structure entry for which the sub-page write permission control bit is set and during the SPPT lookup there is no SPPT misconfiguration but any level of SPPT paging-structure entries are not-present. SPPT misconfigurations and SPPT misses can occur only due to an attempt to write memory with a guest-physical address. Signed-off-by: Zhang Yi Z Signed-off-by: He Chen --- arch/x86/include/asm/vmx.h | 7 +++++++ arch/x86/include/uapi/asm/vmx.h | 2 ++ arch/x86/kvm/vmx.c | 45 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index 55bac23..7f1b824 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -543,6 +543,13 @@ struct vmx_msr_entry { #define EPT_VIOLATION_GVA_TRANSLATED (1 << EPT_VIOLATION_GVA_TRANSLATED_BIT) /* + * Exit Qualifications for SPPT-Induced VM Exits + */ +#define SPPT_INDUCED_EXIT_TYPE_BIT 11 +#define SPPT_INDUCED_EXIT_TYPE (1 << SPPT_INDUCED_EXIT_TYPE_BIT) +#define SPPT_INTR_INFO_UNBLOCK_NMI INTR_INFO_UNBLOCK_NMI + +/* * VM-instruction error numbers */ enum vm_instruction_error_number { diff --git a/arch/x86/include/uapi/asm/vmx.h b/arch/x86/include/uapi/asm/vmx.h index 690a2dc..d632264 100644 --- a/arch/x86/include/uapi/asm/vmx.h +++ b/arch/x86/include/uapi/asm/vmx.h @@ -84,6 +84,7 @@ #define EXIT_REASON_PML_FULL 62 #define EXIT_REASON_XSAVES 63 #define EXIT_REASON_XRSTORS 64 +#define EXIT_REASON_SPP 66 #define VMX_EXIT_REASONS \ { EXIT_REASON_EXCEPTION_NMI, "EXCEPTION_NMI" }, \ @@ -140,6 +141,7 @@ { EXIT_REASON_ENCLS, "ENCLS" }, \ { EXIT_REASON_RDSEED, "RDSEED" }, \ { EXIT_REASON_PML_FULL, "PML_FULL" }, \ + { EXIT_REASON_SPP, "SPP" }, \ { EXIT_REASON_XSAVES, "XSAVES" }, \ { EXIT_REASON_XRSTORS, "XRSTORS" } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a4ac08a..fa4f548 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -7997,6 +7997,50 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) return kvm_skip_emulated_instruction(vcpu); } +static int handle_spp(struct kvm_vcpu *vcpu) +{ + unsigned long exit_qualification; + + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + + /* + * SPP VM exit happened while executing iret from NMI, + * "blocked by NMI" bit has to be set before next VM entry. + * There are errata that may cause this bit to not be set: + * AAK134, BY25. + */ + if (!(to_vmx(vcpu)->idt_vectoring_info & VECTORING_INFO_VALID_MASK) && + (exit_qualification & SPPT_INTR_INFO_UNBLOCK_NMI)) + vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, + GUEST_INTR_STATE_NMI); + + pr_debug("SPP: SPP exit_qualification=%lx\n", exit_qualification); + + vcpu->arch.exit_qualification = exit_qualification; + + if (exit_qualification & SPPT_INDUCED_EXIT_TYPE) { + /* + * SPPT Miss + * We don't set SPP write access for the corresponding + * GPA, if we haven't setup, we need to construct + * SPP table here. + */ + pr_debug("SPP: %s: SPPT Miss!!!\n", __func__); + return 1; + } + + /* + * SPPT Misconfig + * This is probably possible that your sppt table + * set as an incorrect format + */ + WARN_ON(1); + vcpu->run->exit_reason = KVM_EXIT_UNKNOWN; + vcpu->run->hw.hardware_exit_reason = EXIT_REASON_SPP; + pr_alert("SPP: %s: SPPT Misconfiguration!!!\n", __func__); + return 0; +} + static int handle_pml_full(struct kvm_vcpu *vcpu) { unsigned long exit_qualification; @@ -8194,6 +8238,7 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { [EXIT_REASON_INVVPID] = handle_invvpid, [EXIT_REASON_RDRAND] = handle_invalid_op, [EXIT_REASON_RDSEED] = handle_invalid_op, + [EXIT_REASON_SPP] = handle_spp, [EXIT_REASON_XSAVES] = handle_xsaves, [EXIT_REASON_XRSTORS] = handle_xrstors, [EXIT_REASON_PML_FULL] = handle_pml_full,