Received: by 2002:a05:6358:a55:b0:ec:fcf4:3ecf with SMTP id 21csp552055rwb; Thu, 12 Jan 2023 09:13:51 -0800 (PST) X-Google-Smtp-Source: AMrXdXuqhfds6PWfQHUaJVP6aSEQTemBXIpMib//GtlIDUOVnUgCH2KvvogkH0pvwhi0V5UFkKn2 X-Received: by 2002:a17:906:99d1:b0:7ad:cf9c:b210 with SMTP id s17-20020a17090699d100b007adcf9cb210mr61970603ejn.18.1673543631156; Thu, 12 Jan 2023 09:13:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1673543631; cv=none; d=google.com; s=arc-20160816; b=HScstxDsJK5mT4iuQimHKJER4TBnr431g7O/dwef5wvH6+20BbrAygLAmG8A2RhuZ3 buqp6gSMkTP4TmIvtut7hQXyGYGeQlv6mq4uknKatYYYHy8288juEAACdLFCgoV1MasX o9rHIDTK2utL9UQJkjjPnOtZJPNAvmBxQmAuGQ1fgt/G9hkKQndjtFM3/kCQa5mH249b MAqNQyYa2mKZWe/Bxn5omlhLhOOEfKeQMQe8v1szLpdiclYd77h1HE7OQpw6cA+NDO16 XgVkrtl/9li3n5J2zUF6MI4y2aMKDs6w5fP49I3K71neNtRfA2C1uE5JXoFQCwhm1e7x pShg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wKz8a6WinKYZXHAsW4rPIIHg5jXedOJH3C+TR0sBTnE=; b=YxCbElUp94l4x7muwAuJOxMJFaNfAWiGuBBJibAdr+83y5TFefaUEQ/yNaZMYhpWkn K9nkIBNgbOK9AWHbh8jdcHe0qp69u8rRKG73ps52ZUDyFz9J9pdblNRlOv6pPWFfMU3g TLb/cmkU90zzr4tUyq8YLQuD2IgkLXoFhGct/N266l6+W0kF3nyA1kkDaq9lHv6+OJOa aVOsqLugx50kwpSDOrPLVLOfTsg+/hL4klwRbVepOA0nIa7NK4qa6Rff2GiPGWMnd/Ry GWCdxoLcFkeP0K+uK2+ytbdlV4yeFLcD6CsGvy7mvEy9723i0DNfTyizQDQCFM0fK0qj 1rvg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=REkDx0l4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z7-20020a50eb47000000b00483347f1b8esi17545260edp.402.2023.01.12.09.13.38; Thu, 12 Jan 2023 09:13:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=REkDx0l4; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240167AbjALQi1 (ORCPT + 50 others); Thu, 12 Jan 2023 11:38:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234912AbjALQhR (ORCPT ); Thu, 12 Jan 2023 11:37:17 -0500 Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF94EBC93; Thu, 12 Jan 2023 08:33:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1673541219; x=1705077219; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=t044CvSipCIX4wv2835IvXTYbKK/FfH7eZpOfSup8Kw=; b=REkDx0l4XaT1l5U4g9cC+a1ZK1ppOy8ZoZwYVPPiRlH9aFxdBUlocQKV /u1NgnnphHSogF7eLOT5mCRJCR6RjLVayeKlmBEENcz5zKg4WeQzCocIQ DD3lxpPO99sQxAd8v4/Kh/bbdnAy3a4QpQa3RjplXILNyMjt3pfLoHU3j WEABqcyLGEgxHajLhQ8bPstAYlab3iq6lsm/vbdnLb2E/nEupCkkWeHwa 0hZmiahWB8Z3SlTy/oi/JxgNamIfR7cj3p8bN34CIqsGdoSC9x8xxrUam nI9ykoKS1+E8Fyr2Q9ayfW7E2pLGMGEPUvAk/b8qJJoO5jZBN0UESh9Zo A==; X-IronPort-AV: E=McAfee;i="6500,9779,10588"; a="386089661" X-IronPort-AV: E=Sophos;i="5.97,211,1669104000"; d="scan'208";a="386089661" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jan 2023 08:33:34 -0800 X-IronPort-AV: E=McAfee;i="6500,9779,10588"; a="726372506" X-IronPort-AV: E=Sophos;i="5.97,211,1669104000"; d="scan'208";a="726372506" Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jan 2023 08:33:33 -0800 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack Subject: [PATCH v11 080/113] KVM: TDX: Implement methods to inject NMI Date: Thu, 12 Jan 2023 08:32:28 -0800 Message-Id: <35e4ab187301e2533b47c51151d27d29a7b74f0b.1673539699.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Isaku Yamahata TDX vcpu control structure defines one bit for pending NMI for VMM to inject NMI by setting the bit without knowing TDX vcpu NMI states. Because the vcpu state is protected, VMM can't know about NMI states of TDX vcpu. The TDX module handles actual injection and NMI states transition. Add methods for NMI and treat NMI can be injected always. Signed-off-by: Isaku Yamahata Reviewed-by: Paolo Bonzini --- arch/x86/kvm/vmx/main.c | 62 +++++++++++++++++++++++++++++++++++--- arch/x86/kvm/vmx/tdx.c | 5 +++ arch/x86/kvm/vmx/x86_ops.h | 2 ++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index 7962f03e222d..2b31ae11f46d 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -243,6 +243,58 @@ static void vt_flush_tlb_guest(struct kvm_vcpu *vcpu) vmx_flush_tlb_guest(vcpu); } +static void vt_inject_nmi(struct kvm_vcpu *vcpu) +{ + if (is_td_vcpu(vcpu)) + return tdx_inject_nmi(vcpu); + + vmx_inject_nmi(vcpu); +} + +static int vt_nmi_allowed(struct kvm_vcpu *vcpu, bool for_injection) +{ + /* + * The TDX module manages NMI windows and NMI reinjection, and hides NMI + * blocking, all KVM can do is throw an NMI over the wall. + */ + if (is_td_vcpu(vcpu)) + return true; + + return vmx_nmi_allowed(vcpu, for_injection); +} + +static bool vt_get_nmi_mask(struct kvm_vcpu *vcpu) +{ + /* + * Assume NMIs are always unmasked. KVM could query PEND_NMI and treat + * NMIs as masked if a previous NMI is still pending, but SEAMCALLs are + * expensive and the end result is unchanged as the only relevant usage + * of get_nmi_mask() is to limit the number of pending NMIs, i.e. it + * only changes whether KVM or the TDX module drops an NMI. + */ + if (is_td_vcpu(vcpu)) + return false; + + return vmx_get_nmi_mask(vcpu); +} + +static void vt_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked) +{ + if (is_td_vcpu(vcpu)) + return; + + vmx_set_nmi_mask(vcpu, masked); +} + +static void vt_enable_nmi_window(struct kvm_vcpu *vcpu) +{ + /* Refer the comment in vt_get_nmi_mask(). */ + if (is_td_vcpu(vcpu)) + return; + + vmx_enable_nmi_window(vcpu); +} + static void vt_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level) { @@ -407,14 +459,14 @@ struct kvm_x86_ops vt_x86_ops __initdata = { .get_interrupt_shadow = vt_get_interrupt_shadow, .patch_hypercall = vmx_patch_hypercall, .inject_irq = vt_inject_irq, - .inject_nmi = vmx_inject_nmi, + .inject_nmi = vt_inject_nmi, .inject_exception = vmx_inject_exception, .cancel_injection = vt_cancel_injection, .interrupt_allowed = vt_interrupt_allowed, - .nmi_allowed = vmx_nmi_allowed, - .get_nmi_mask = vmx_get_nmi_mask, - .set_nmi_mask = vmx_set_nmi_mask, - .enable_nmi_window = vmx_enable_nmi_window, + .nmi_allowed = vt_nmi_allowed, + .get_nmi_mask = vt_get_nmi_mask, + .set_nmi_mask = vt_set_nmi_mask, + .enable_nmi_window = vt_enable_nmi_window, .enable_irq_window = vt_enable_irq_window, .update_cr8_intercept = vmx_update_cr8_intercept, .set_virtual_apic_mode = vmx_set_virtual_apic_mode, diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 742f0747d4d0..95c9a1906b62 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -705,6 +705,11 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu) return EXIT_FASTPATH_NONE; } +void tdx_inject_nmi(struct kvm_vcpu *vcpu) +{ + td_management_write8(to_tdx(vcpu), TD_VCPU_PEND_NMI, 1); +} + void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int pgd_level) { td_vmcs_write64(to_tdx(vcpu), SHARED_EPT_POINTER, root_hpa & PAGE_MASK); diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h index fa7a431c45da..a05ae400f1ae 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -165,6 +165,7 @@ u8 tdx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); void tdx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode, int trig_mode, int vector); +void tdx_inject_nmi(struct kvm_vcpu *vcpu); int tdx_vm_ioctl(struct kvm *kvm, void __user *argp); int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp); @@ -198,6 +199,7 @@ static inline u8 tdx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) static inline void tdx_deliver_interrupt(struct kvm_lapic *apic, int delivery_mode, int trig_mode, int vector) {} +static inline void tdx_inject_nmi(struct kvm_vcpu *vcpu) {} static inline int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) { return -EOPNOTSUPP; } static inline int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; } -- 2.25.1