Received: by 2002:a05:7412:5112:b0:fa:6e18:a558 with SMTP id fm18csp167688rdb; Mon, 22 Jan 2024 16:08:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IGiorCtaJag/S4eH0Obo7hKRlWet0O1R/tmWDdweaWJe7d+9u2QAiJilLX4oZwhw8Rpq6Eq X-Received: by 2002:a05:6214:2b0a:b0:681:55e0:f228 with SMTP id jx10-20020a0562142b0a00b0068155e0f228mr54136qvb.66.1705968490792; Mon, 22 Jan 2024 16:08:10 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1705968490; cv=pass; d=google.com; s=arc-20160816; b=o7/u+dTwbmQS2UoFRfCzoiOrTYLuSgdgPjhbjzs1NleF4zJhMWW1/+xoxzXuUGNrL+ ONrRGNY7a4LW4rfQjMK1lHvbOmTn1+PQaJT3oNaQe5+S42F/mcWnmkHupNHx49BfhTJo MFz+mNm6FkwVnK1RObjo5EheuF+xE9VbU/4e7RPQ7pqC73aygtrMjcPmTJOaBZ0o2KWV uqhULSVdnUuzCgqP1/xTxtjbDrIlaFNR+IOaLLI1tooSqmRXnV0g1u1UdBlXSzprHKIR ebpmDzPApvqE/iyX4176o+Zddg4ELtvFa1QLD5mAuVZVTMJ/huwJd06lphHXeqSfIjmA GZAA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Yw6zfhZgt++qE5McWonZy5BndxYOjAX9I2XiJjWJRcY=; fh=Itbyk7CEvizIrzGEESCqq3I2tZgG1kc/GkVOa3S7Hsg=; b=Vo+mdze0Bmu9vy+IXES6lWHkWWT+rSD1boYRsOUealKJ/GGxdiDQ3gBkIRfv4F+mkB OCxPPmGL487HDmqhLINkmh3lD3AQgtByT7GNK6R1vNZ4Wf+8zwXwV4uRW1jUeKawn4xn kIoYa59EavXDdgJJwxU8jfJ6z0LGhMbE8j2o3bpVgAeqe1JbD39k5fG2HlMQdGAYlwOR JesFpnTESYPkbzGKoeMiFWS+Eb3TKMYcCe9zxBqmZrq8jYj45243Rm/mfqjvX56KVKVE T25LCaxOL0X3N95dg72835vl9gkKmYNsKRS9cVJgG+PW8LqDfGPWBuc2JGh2FXGwDQRj wyHA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=CsEg5hHy; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-34382-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-34382-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id a2-20020a0c8bc2000000b006819935f9casi6976561qvc.8.2024.01.22.16.08.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Jan 2024 16:08:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-34382-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=CsEg5hHy; arc=pass (i=1 spf=pass spfdomain=intel.com dkim=pass dkdomain=intel.com dmarc=pass fromdomain=intel.com); spf=pass (google.com: domain of linux-kernel+bounces-34382-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-34382-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 5B8B61C23819 for ; Tue, 23 Jan 2024 00:08:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4FE8B66B48; Mon, 22 Jan 2024 23:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="CsEg5hHy" Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A54D651B2; Mon, 22 Jan 2024 23:55:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.55.52.120 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705967754; cv=none; b=g6+DSAU4PCGvKIvsKP0fkHa/tNsNbjLY3lvRiItYbOxXAVOMDYT0n2ITUud2fcxYT6iABlafObzFKIPhtIQx4+CCoiMirxUzKQatdc8Tk1fRrGKvjM0ah/AWwgMjWFaCM5HtojEcXxVdbcqOZyunuz5rS6y/HT/wyTxlTGBglSQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705967754; c=relaxed/simple; bh=NXfFkHU3sT8gOQ5QWXobSNbMezM0fu2qAxXSIJaVL0Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=otcCItC2xSUvZlxn8e7W8To/eOKBwk8Au2OPBi/NjgpvoeOBEJ26idFETZQ00q4fcIhxitUP5oNSYGReP3n7uZ+5oCWHKr48KJ8D6ccPzNNT773MimnoNXy4gZH83KJoiEB1Y+oX6PQ7oPrcvDMit87sbSAmlshMRWj8Z5/z0wQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=CsEg5hHy; arc=none smtp.client-ip=192.55.52.120 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1705967752; x=1737503752; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NXfFkHU3sT8gOQ5QWXobSNbMezM0fu2qAxXSIJaVL0Y=; b=CsEg5hHySW+OSTrgW4QDk9cSz66Ksk7kj1nefKbxZUXdG1PYyDy7M2ob AefY/7xgB2HKrKJhAr0G73LgoUmW7jrgMD58cuhJBFNka+wMZt2Xd3/xj WTkD9fmI+AKyLz026Slp1MEKRiwQQUNKuSzwhTCOZUzCs9r5mGrRhjD27 3lnztxABAx2G6XJquUxUbAht3D6VEWnOMaQDUzJHQARZEBnRwZ3ySyycn M880ySZo95ae7zWvaDy5FfPEmWYEAlp1k9AH6oVEzFoiFovlKgIPpTl2B 0vprI43q9payuYXKj2c8byTe+cI+wqdKFSV534Js95tPvyP0tq8EtZstr A==; X-IronPort-AV: E=McAfee;i="6600,9927,10961"; a="400217799" X-IronPort-AV: E=Sophos;i="6.05,212,1701158400"; d="scan'208";a="400217799" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2024 15:55:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.05,212,1701158400"; d="scan'208";a="27817928" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jan 2024 15:55:45 -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 , Kai Huang , chen.bo@intel.com, hang.yuan@intel.com, tina.zhang@intel.com Subject: [PATCH v18 083/121] KVM: TDX: Implement methods to inject NMI Date: Mon, 22 Jan 2024 15:53:59 -0800 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 | 64 +++++++++++++++++++++++++++++++++++--- arch/x86/kvm/vmx/tdx.c | 6 ++++ arch/x86/kvm/vmx/x86_ops.h | 2 ++ 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c index aef78aa393ad..3751e6ed2388 100644 --- a/arch/x86/kvm/vmx/main.c +++ b/arch/x86/kvm/vmx/main.c @@ -319,6 +319,60 @@ 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)) { + tdx_inject_nmi(vcpu); + return; + } + + 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) { @@ -497,14 +551,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 9913f735788c..0f0f1ea8a712 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -924,6 +924,12 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu) return EXIT_FASTPATH_NONE; } +void tdx_inject_nmi(struct kvm_vcpu *vcpu) +{ + ++vcpu->stat.nmi_injections; + 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 df14a930c80e..58053daf52d1 100644 --- a/arch/x86/kvm/vmx/x86_ops.h +++ b/arch/x86/kvm/vmx/x86_ops.h @@ -159,6 +159,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_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp); @@ -195,6 +196,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_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) { return -EOPNOTSUPP; } -- 2.25.1