Received: by 2002:a05:6358:795:b0:dc:4c66:fc3e with SMTP id n21csp1448162rwj; Sun, 30 Oct 2022 00:31:58 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5nvoyZ4K0UUwQ30QghTLKdHWY5eiu+ubiKXN57eqvf9TpcoU60le0vRiyQZaLgYzP4Tz6U X-Received: by 2002:aa7:8549:0:b0:56c:ba99:7951 with SMTP id y9-20020aa78549000000b0056cba997951mr8234478pfn.83.1667115117775; Sun, 30 Oct 2022 00:31:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667115117; cv=none; d=google.com; s=arc-20160816; b=aVwZb7RKRgUSI3nDmHMp2TnZY+1acp6FbEiDTAMgzEZPC7Lvlqsla/5+fzIqxM1OgY JnF11xuv4CCNUGqZXFJ+rt9lxDTU9Ij37irAKKVKK49iBYYGprCzVcAAI6TeObj1dHcv Vd9lxCFVa7rkg2QIbaPZbPbkGYtLEhL2CEqXRrYlDHCbDRlqxzJwJ3+7S+Qu8lOYCPBg IksjPs5B+w2BnqhKtkCaSN/ipe6it3VQ+00RUJcNXB/j2YdpzmJbNS2EQ026pRMntTTN iXKCZhEcJyMoq1bLRASNIGm9Gtrz91Z639wstIme9Jb7LOMbCbTy93IixNqkjMes0YtD 5c/g== 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=ypNwnhiODNqEQrm1AZhSuWDQe8PpMP3JgaQv0geeRvk=; b=RkmHnALVqMPoQVzF2QpdFGnaA6lvdfbdFzNlWUn0RJHHjTDPkjBtD/RGFY4Yu2dIji RXZYMiFC95tzL7dJREZyh4RDHAWBnk9vuMSY51ARS0e0j5c8NilNm6kjM7x/cGOYyHh4 lF2wbYg51sBfR6qjoDh3L8qLCqAB4ruO2n5MGaNzprbxRLZNz1WfuKKz3GvLjhTTEsZj 04Bk2YROjLM9ibY6YQyOS8qkyqMSQ602k3ND4F3PvMECdW/1w/fy83vfiqg758n4R0MO 1xWPuJd1TIe9DIzd57zy5YKLjQWeuDny3JbA/3V7xRNq6ctNcoyaaGiOA+vDMji5iYFM vNVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=T85Aw3oe; 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 d16-20020a056a00245000b0056d568dc21dsi738995pfj.153.2022.10.30.00.31.45; Sun, 30 Oct 2022 00:31:57 -0700 (PDT) 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=T85Aw3oe; 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 S230482AbiJ3Gb2 (ORCPT + 99 others); Sun, 30 Oct 2022 02:31:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230475AbiJ3G3m (ORCPT ); Sun, 30 Oct 2022 02:29:42 -0400 Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E77B338C; Sat, 29 Oct 2022 23:24:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1667111088; x=1698647088; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=PVCyb5G5M4RHdyzQqlkKvrELC7neLel3F9Dn+hpx67Q=; b=T85Aw3oeNkWukkudtY58PQ/7NlawnBVG+FrrhMdGY6frDdryY9L7ZtgP KcJ1gNn/CBY0s8ZI3irFK+oCEPejcpX9E5Mw64Wews914bKMoI5YCBzj2 aO9N0wk81DtuOU9hVg3VDQMCCElQYNcHgIk8l7/T/bJsl7zeB/qiO6bXT kIzZIhXj2vq3wkh9C5SJdU/1Ypnkm4iT22eKXbi62zZlhrR1/6ZtYeWBp wvQEl59FBr//LQEMJ75uKMqCJzFzTJupdK7aLWWE7m+Hki46APjAypUk+ ihlCvPZ5qT23+HnSZau59wd5ZjlvVM68WdA6hLeFuqQR1C8Q4fB3A7qeB w==; X-IronPort-AV: E=McAfee;i="6500,9779,10515"; a="395037196" X-IronPort-AV: E=Sophos;i="5.95,225,1661842800"; d="scan'208";a="395037196" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Oct 2022 23:24:11 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10515"; a="878393110" X-IronPort-AV: E=Sophos;i="5.95,225,1661842800"; d="scan'208";a="878393110" Received: from ls.sc.intel.com (HELO localhost) ([143.183.96.54]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Oct 2022 23:24:11 -0700 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 v10 083/108] KVM: TDX: Implement methods to inject NMI Date: Sat, 29 Oct 2022 23:23:24 -0700 Message-Id: <2c94568e26710ba09a4879bcf1601119f3c436be.1667110240.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.9 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 3e9007a7edfb..510bffb3e2f6 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -255,6 +255,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) { @@ -410,14 +462,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 7dad75b3b4a6..9805308079f1 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -678,6 +678,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 01fac8ba8c50..ba4e51446e41 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -156,6 +156,7 @@ bool tdx_protected_apic_has_interrupt(struct kvm_vcpu *vcpu); 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); @@ -188,6 +189,7 @@ static inline bool tdx_protected_apic_has_interrupt(struct kvm_vcpu *vcpu) { ret 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