Received: by 2002:ab2:7041:0:b0:1f4:bcc8:f211 with SMTP id x1csp105361lql; Fri, 12 Apr 2024 05:22:23 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVZR52XyopM0oFAoqIETLcgFTRQNu85yeY/e4U1OiNsLM8UFucvhR+jnsvTRp/ToZFPGVCKZwYvFaXZsk8lJTu5uZLELZSztcMKLAOb2A== X-Google-Smtp-Source: AGHT+IFuIg2IErg6Y5PNZD5pQaZlntxQs06drOa+wqjxdI7cIJW2PzPijs05prU6w6b/mVzo5CJM X-Received: by 2002:a17:906:2496:b0:a52:3e91:ac0a with SMTP id e22-20020a170906249600b00a523e91ac0amr478562ejb.62.1712924543040; Fri, 12 Apr 2024 05:22:23 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712924543; cv=pass; d=google.com; s=arc-20160816; b=EmXSUEqRkwlQJl+V59VmRyuEor+a86zq4CGNAKXyGtdHecJ900Lq9bSRnOON4LSe2K 4TdyOOveJ5IxvUbG2cVea6Df54mNn8WDmKoVLVpFCfYYvakaWJWfXe2M3yWAtmS6ZMk8 AVjSjomu+NmVeScxitJcIq3gWJ1a3CDBAag0gR1XWDAsGG/gsVXaMH+m3qYT4NpQIuH5 k1eGd14QnGy77tttN2rM3CBPT9BYDFWrtgInvuigv9cWGScp+h0E0LgZ7R84X8dV1kxU GTa6WBUsc58ObzdGveB6oFhC6gKzu/nGMcGLcujESnRioWg3sURgqqIdwCXa8fDbHXFl 5yeQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:organization:from :content-language:references:cc:to:subject:user-agent:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:date:message-id :dkim-signature; bh=YxK67/4Z9eypsJO8xP2M5aX9p5lgsA2Eey5jY12iFv8=; fh=1AId0jXl9LiJrVLqf7CV8W0SWNl5LlbkExgYUh48sNY=; b=nsLu6qj1wQG2fwJhzgafvm7eRNMBNEFifQdXc6ygp/DUpkmy2w2Ki6eWcW1mdstrb2 nuij5prRADY8y97ER9nsKhOVp/IQVGOnPFeINal7KiCdsz+C3Y5iblWu3U4TG4DtGDNN HJIAB9clUX3/Qdy5aLRb0wJLIqv9Zfg4giHxieESK0CqTupPal9YwOvZIQJFw2Z2wOGg DnqoX3Lo+nTQWHn86qa2LGP2qQymHg6uOMbKCswB1jzAYvR0L4iLSEkX6QmRDgJmsQuu q0jVmtYUcDOj6xx+Gkl/oDJ1+kpQ+xOHjI57xUtDYX4fMHV+c6y7POz75Rx1fu/f5+Ly 8vtA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Lpaeb2kn; 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-142640-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-142640-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id dr15-20020a170907720f00b00a523c5c895fsi333557ejc.144.2024.04.12.05.22.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Apr 2024 05:22:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-142640-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=Lpaeb2kn; 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-142640-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-142640-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 999691F2268A for ; Fri, 12 Apr 2024 12:22:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8688756763; Fri, 12 Apr 2024 12:22:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Lpaeb2kn" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) (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 8309A54FB1; Fri, 12 Apr 2024 12:22:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.19 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712924532; cv=none; b=FwWTLskLK+G4Eo86x8EmhCV81Veia7BgTbtnAD/eA+w4XAHfeoEfwljKQseJfqbU4N1bGIsgbNZNGG0hYq4Km/5JsmXhVzVQxkNKSYkwYmOfEIirPpD76Dfuaa47VkMYygmUWsU3hToYBJDxrY6MKo3vgFbeS6iaTi7kTgop4u0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712924532; c=relaxed/simple; bh=TTl55aY4/Vx/aiX0tkcJhaSZDYNmqg+ceKBbpV2xhpI=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=hZY5eI24rnBROvrhyv68CjigClsBDXl4Z/2ts6LL9O0njdQBrAmiHfwmuMytFJu48OtHvgVpsrw2vz4HZ6pI5LbXQA4QzkScDFBMTne6mTfHsxf/jMeeunT1VZkMTZpK+DFCkVFN8slLmH86r7z+IvI7GHIIHws6G1HcjA2JHq0= 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=Lpaeb2kn; arc=none smtp.client-ip=192.198.163.19 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=1712924530; x=1744460530; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=TTl55aY4/Vx/aiX0tkcJhaSZDYNmqg+ceKBbpV2xhpI=; b=Lpaeb2knZ/38K/04sGRsKZ6DWTXoCLWPd38jPRmI4PIcWdAn3HQ3+IAa 1OiGUYWum06bikEVs2Mp1tEmb3Loz9mH60Akr2HY/xgtxdQfeDASxF1Sa CocH+TXCQ3MYMM31AM+YM0U27FHqko+n9XFk1mRjtVWD14o1MNKoqb3gL eJJ0GT2N1kHbxbnbA4qluwvn2rBbWAOq0zvyeJ2j8ddz0lFqqgGFgVFEJ +LzwKm/3qlxQsknpkKMbxQOWFt/lLzZTUMtSXGgenBdnbBD8q38YC8o0+ P0+s6HIUMk8PjhzjlcbnDIE/+gCWfZnqRH88MDYOzOcMeJ9cxI33S+Lpp g==; X-CSE-ConnectionGUID: MaFm/kQlQlCscaoy2B4eeg== X-CSE-MsgGUID: YR4vNGVTTlua/TGNscfx1w== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="8236167" X-IronPort-AV: E=Sophos;i="6.07,196,1708416000"; d="scan'208";a="8236167" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 05:22:09 -0700 X-CSE-ConnectionGUID: YueSwZA+TWiGmEfFjYLlfA== X-CSE-MsgGUID: SvjLaqCFSoKCRW6BWiGWBw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,196,1708416000"; d="scan'208";a="21645224" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO [10.0.2.15]) ([10.251.215.136]) by orviesa006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 05:22:06 -0700 Message-ID: Date: Fri, 12 Apr 2024 15:22:00 +0300 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v19 076/130] KVM: TDX: Finalize VM initialization To: Isaku Yamahata Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, "Edgecombe, Rick P" , 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, isaku.yamahata@linux.intel.com References: <20240412010848.GG3039520@ls.amr.corp.intel.com> Content-Language: en-US From: Adrian Hunter Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki In-Reply-To: <20240412010848.GG3039520@ls.amr.corp.intel.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 12/04/24 04:08, Isaku Yamahata wrote: > On Thu, Apr 11, 2024 at 07:39:11PM +0300, > Adrian Hunter wrote: > >> On 26/02/24 10:26, isaku.yamahata@intel.com wrote: >>> From: Isaku Yamahata >>> >>> To protect the initial contents of the guest TD, the TDX module measures >>> the guest TD during the build process as SHA-384 measurement. The >>> measurement of the guest TD contents needs to be completed to make the >>> guest TD ready to run. >>> >>> Add a new subcommand, KVM_TDX_FINALIZE_VM, for VM-scoped >>> KVM_MEMORY_ENCRYPT_OP to finalize the measurement and mark the TDX VM ready >>> to run. >> >> Perhaps a spruced up commit message would be: >> >> >> Add a new VM-scoped KVM_MEMORY_ENCRYPT_OP IOCTL subcommand, >> KVM_TDX_FINALIZE_VM, to perform TD Measurement Finalization. >> >> Documentation for the API is added in another patch: >> "Documentation/virt/kvm: Document on Trust Domain Extensions(TDX)" >> >> For the purpose of attestation, a measurement must be made of the TDX VM >> initial state. This is referred to as TD Measurement Finalization, and >> uses SEAMCALL TDH.MR.FINALIZE, after which: >> 1. The VMM adding TD private pages with arbitrary content is no longer >> allowed >> 2. The TDX VM is runnable >> >> >> History: >> >> This code is essentially unchanged from V1, as below. >> Except for V5, the code has never had any comments. >> Paolo's comment from then still appears unaddressed. >> >> V19: Unchanged >> V18: Undoes change of V17 >> V17: Also change tools/arch/x86/include/uapi/asm/kvm.h >> V16: Unchanged >> V15: Undoes change of V10 >> V11-V14: Unchanged >> V10: Adds a hack (related to TDH_MEM_TRACK) >> that was later removed in V15 >> V6-V9: Unchanged >> V5 Broke out the code into a separate patch and >> received its only comments, which were from Paolo: >> >> "Reviewed-by: Paolo Bonzini >> Note however that errors should be passed back in the struct." >> >> This presumably refers to struct kvm_tdx_cmd which has an "error" >> member, but that is not updated by tdx_td_finalizemr() >> >> V4 was a cut-down series and the code was not present >> V3 introduced WARN_ON_ONCE for the error condition >> V2 accommodated renaming the seamcall function and ID > > Thank you for creating histories. Let me update the commit message. > > >> Outstanding: >> >> 1. Address Paolo's comment about the error code >> 2. Is WARN_ON sensible? > > See below. > > >> Final note: >> >> It might be possible to make TD Measurement Finalization >> transparent to the user space VMM and forego another API, but it seems >> doubtful that would really make anything much simpler. >> >>> >>> Signed-off-by: Isaku Yamahata >>> >>> --- >>> v18: >>> - Remove the change of tools/arch/x86/include/uapi/asm/kvm.h. >>> >>> v14 -> v15: >>> - removed unconditional tdx_track() by tdx_flush_tlb_current() that >>> does tdx_track(). >>> >>> Signed-off-by: Isaku Yamahata >>> --- >>> arch/x86/include/uapi/asm/kvm.h | 1 + >>> arch/x86/kvm/vmx/tdx.c | 21 +++++++++++++++++++++ >>> 2 files changed, 22 insertions(+) >>> >>> diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h >>> index 34167404020c..c160f60189d1 100644 >>> --- a/arch/x86/include/uapi/asm/kvm.h >>> +++ b/arch/x86/include/uapi/asm/kvm.h >>> @@ -573,6 +573,7 @@ enum kvm_tdx_cmd_id { >>> KVM_TDX_INIT_VM, >>> KVM_TDX_INIT_VCPU, >>> KVM_TDX_EXTEND_MEMORY, >>> + KVM_TDX_FINALIZE_VM, >>> >>> KVM_TDX_CMD_NR_MAX, >>> }; >>> diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c >>> index 3cfba63a7762..6aff3f7e2488 100644 >>> --- a/arch/x86/kvm/vmx/tdx.c >>> +++ b/arch/x86/kvm/vmx/tdx.c >>> @@ -1400,6 +1400,24 @@ static int tdx_extend_memory(struct kvm *kvm, struct kvm_tdx_cmd *cmd) >>> return ret; >>> } >>> >>> +static int tdx_td_finalizemr(struct kvm *kvm) >>> +{ >>> + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); >>> + u64 err; >>> + >>> + if (!is_hkid_assigned(kvm_tdx) || is_td_finalized(kvm_tdx)) >>> + return -EINVAL; >>> + >>> + err = tdh_mr_finalize(kvm_tdx->tdr_pa); >>> + if (WARN_ON_ONCE(err)) { >> >> Is a failed SEAMCALL really something to WARN over? > > Because user can trigger an error in some cases, we shouldn't WARN in such case. > Except those, TDH.MR.FINALIZE() shouldn't return error. If we hit such error, > it typically implies serious error so that the recovery is difficult. For > example, the TDX module was broken by the host overwriting private pages. > That's the reason why we have KVM_BUN_ON. So the error check should be > something like > > > /* We can hit busy error to exclusively access TDR. */ > if (err == (TDX_OPERAND_BUSY | TDX_OPERAND_ID_RCX)) > return -EAGAIN; > /* User can call KVM_TDX_INIT_VM without any vCPUs created. */ > if (err == TDX_NO_VCPUS) > return -EIO; > /* Other error shouldn't happen. */ > if (KVM_BUG_ON(err, kvm)) { > pr_tdx_error(TDH_MR_FINALIZE, err); > return -EIO; > } > > >>> + pr_tdx_error(TDH_MR_FINALIZE, err, NULL); >> >> As per Paolo, error code is not returned in struct kvm_tdx_cmd > > > It will be something like the followings. No compile test yet. > > > diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c > index 0d3b79b5c42a..c7ff819ccaf1 100644 > --- a/arch/x86/kvm/vmx/tdx.c > +++ b/arch/x86/kvm/vmx/tdx.c > @@ -2757,6 +2757,12 @@ static int tdx_td_finalizemr(struct kvm *kvm) > return -EINVAL; > > err = tdh_mr_finalize(kvm_tdx); > + kvm_tdx->hw_error = err; > + > + if (err == (TDX_OPERAND_BUSY | TDX_OPERAND_ID_RCX)) There seem to be also implicit operand codes. How sure are we that TDX_OPERAND_ID_RCX is the only valid busy operand? > + return -EAGAIN; > + if (err == TDX_NO_VCPUS) TDX_NO_VCPUS is not one of the completion status codes for TDH.MR.FINALIZE > + return -EIO; > if (KVM_BUG_ON(err, kvm)) { > pr_tdx_error(TDH_MR_FINALIZE, err); > return -EIO; > @@ -2768,6 +2774,7 @@ static int tdx_td_finalizemr(struct kvm *kvm) > > int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) > { > + struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm); > struct kvm_tdx_cmd tdx_cmd; > int r; > > @@ -2777,6 +2784,7 @@ int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) > return -EINVAL; > > mutex_lock(&kvm->lock); > + kvm_tdx->hw_error = 0; > > switch (tdx_cmd.id) { > case KVM_TDX_CAPABILITIES: > @@ -2793,6 +2801,7 @@ int tdx_vm_ioctl(struct kvm *kvm, void __user *argp) > goto out; > } > > + tdx_cmd.error = kvm_tdx->hw_error; > if (copy_to_user(argp, &tdx_cmd, sizeof(struct kvm_tdx_cmd))) > r = -EFAULT; > > diff --git a/arch/x86/kvm/vmx/tdx.h b/arch/x86/kvm/vmx/tdx.h > index 98f5d7c5891a..dc150b8bdd5f 100644 > --- a/arch/x86/kvm/vmx/tdx.h > +++ b/arch/x86/kvm/vmx/tdx.h > @@ -18,6 +18,9 @@ struct kvm_tdx { > u64 xfam; > int hkid; > > + /* For KVM_TDX ioctl to return SEAMCALL status code. */ > + u64 hw_error; For this case, it seems weird to have a struct member to pass back a return status code, why not make it a parameter of tdx_td_finalizemr() or pass &tdx_cmd? > + > /* > * Used on each TD-exit, see tdx_user_return_update_cache(). > * TSX_CTRL value on TD exit > diff --git a/arch/x86/kvm/vmx/tdx_errno.h b/arch/x86/kvm/vmx/tdx_errno.h > index a8aa8b79e9a1..6c701856c9a8 100644 > --- a/arch/x86/kvm/vmx/tdx_errno.h > +++ b/arch/x86/kvm/vmx/tdx_errno.h > @@ -41,6 +41,7 @@ > #define TDX_TD_FATAL 0xC000060400000000ULL > #define TDX_TD_NON_DEBUG 0xC000060500000000ULL > #define TDX_LIFECYCLE_STATE_INCORRECT 0xC000060700000000ULL > +#define TDX_NO_VCPUS 0xC000060900000000ULL > #define TDX_TDCX_NUM_INCORRECT 0xC000061000000000ULL > #define TDX_VCPU_STATE_INCORRECT 0xC000070000000000ULL > #define TDX_VCPU_ASSOCIATED 0x8000070100000000ULL