Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp16255390rwd; Mon, 26 Jun 2023 07:43:14 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ68pZjGk/0TCblEuwlU06DwqW38l2BtXOh+IaMSOFugdXTVqxuTOv62zXC/cPE7Ohl24qxk X-Received: by 2002:a17:906:4793:b0:974:32e:7de9 with SMTP id cw19-20020a170906479300b00974032e7de9mr26638865ejc.56.1687790593737; Mon, 26 Jun 2023 07:43:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687790593; cv=none; d=google.com; s=arc-20160816; b=hx9FDRIHtag0p9Jw//4cLNMe4XgZJ4fbe4TYMLwVuXbkIQsjZog9lSzpYm/pRSHQ2n Lt3YvH8aCCh7+xEhJ6z30J/xppRwgLw7uh/ojnL/ec9RsxAiCBPCJ4apnY4Yre9NgQ1H z0+1Ms4Qwitgcb+D/HwBDk7hbYC5keQ5e854qWgQCWCV9XlYlZJtnYqf7DdU28RSrc9R iLJduC4ZxxYa7YwUQenWXpYnuZrckz3GbewHPX/8PT5bzKH7ANphtcMRzMlLNEQjFiD7 v6q+sybvrDJB4svXblwm8V0aoB2aK+tRMB5w+IGOZvBVlQdXL0BIpF9b9I7DFnvZ7EHN Zvjg== 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=6PCGgVO7q7I0moesqS1gO84H3m2tPfOGSckDbfdCqfY=; fh=6HfxY0KVNaGJjlkZjh3Hzm5TphdbqQTBO+53/7gNlSk=; b=bBRBMrLSNaunE/q9M04h2q7kOQ3PAgNp2kLaIIRuW/LvSaSeF0K+Y6pOl45+LdHUYR 0NUzYcbi8ZGfdLvPeGAva9O9NsnIPG10oFJolZys7tnO+vvN2aMZvxw1+TsduZtiJjw5 s7bA6NXypVgbaRomxzFAj7QuSftAja5N4Wj14CBM2NUZnd9ADcUzmSm1arYxD+v0TjeO MzqtgvtST2TVt/FQgSsYyN+2UXEqit+Nt3Y9w7+3DN3WvWsVFGlY85l9pqqtDPlBpUY/ ShGXDqGKp+VJJ+hghWgaNFosu4pSn7ywGBMZArWEkqMK55aerOlFeVeOM2pg5bntRGHU rRYg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=SYpXkxy3; 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 lm15-20020a170906980f00b00991ece4c961si447824ejb.267.2023.06.26.07.42.48; Mon, 26 Jun 2023 07:43:13 -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=SYpXkxy3; 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 S231303AbjFZOOi (ORCPT + 99 others); Mon, 26 Jun 2023 10:14:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34610 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231236AbjFZOO1 (ORCPT ); Mon, 26 Jun 2023 10:14:27 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 888C21993; Mon, 26 Jun 2023 07:14:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687788846; x=1719324846; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=t6DeTcVVz69NU4jP/RLKnV8J3tDyrmh8ZA/L9s72880=; b=SYpXkxy3zRO0hX8Q9yGFg3NW9UuR8ZXeBWf6jx0DxK+zOcUT61y6V2CN jw6KVAvd+8RNSDyQ1UC7eADu3HzTbCnEpFRbkwbPJPMj32twPcY6drKDi fmW7R+lyqARqD3rg57ikVV6NgrEAFqu5xXuVNmczErDRg5Z/oljt/DAmF oXnWUBmN13gA5t+zgOnpsXBcZ6nZvfEcWoJJdDfeFFWL5KasFpcLG4oi2 JAAlerYflSiBwqLG0u2G2ozRqHDbi037O3ttz0cQxigW86td74/5MRABI 4V6VaQI2NtKKgMMK+EgDCQ/gpoLeIe8+txIcEn+h80fErIGsYJb+CWjVr w==; X-IronPort-AV: E=McAfee;i="6600,9927,10753"; a="346033636" X-IronPort-AV: E=Sophos;i="6.01,159,1684825200"; d="scan'208";a="346033636" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jun 2023 07:14:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10753"; a="890292288" X-IronPort-AV: E=Sophos;i="6.01,159,1684825200"; d="scan'208";a="890292288" Received: from smithau-mobl1.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.213.179.223]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Jun 2023 07:13:59 -0700 From: Kai Huang To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Cc: linux-mm@kvack.org, x86@kernel.org, dave.hansen@intel.com, kirill.shutemov@linux.intel.com, tony.luck@intel.com, peterz@infradead.org, tglx@linutronix.de, bp@alien8.de, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, david@redhat.com, dan.j.williams@intel.com, rafael.j.wysocki@intel.com, ashok.raj@intel.com, reinette.chatre@intel.com, len.brown@intel.com, ak@linux.intel.com, isaku.yamahata@intel.com, ying.huang@intel.com, chao.gao@intel.com, sathyanarayanan.kuppuswamy@linux.intel.com, nik.borisov@suse.com, bagasdotme@gmail.com, sagis@google.com, imammedo@redhat.com, kai.huang@intel.com Subject: [PATCH v12 05/22] x86/virt/tdx: Add SEAMCALL infrastructure Date: Tue, 27 Jun 2023 02:12:35 +1200 Message-Id: X-Mailer: git-send-email 2.40.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE 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 TDX introduces a new CPU mode: Secure Arbitration Mode (SEAM). This mode runs only the TDX module itself or other code to load the TDX module. The host kernel communicates with SEAM software via a new SEAMCALL instruction. This is conceptually similar to a guest->host hypercall, except it is made from the host to SEAM software instead. The TDX module establishes a new SEAMCALL ABI which allows the host to initialize the module and to manage VMs. Add infrastructure to make SEAMCALLs. The SEAMCALL ABI is very similar to the TDCALL ABI and leverages much TDCALL infrastructure. Also add a wrapper function of SEAMCALL to convert SEAMCALL error code to the kernel error code, and print out SEAMCALL error code to help the user to understand what went wrong. Signed-off-by: Kai Huang Reviewed-by: Isaku Yamahata --- v11 -> v12: - Moved _ASM_EXT_TABLE() for #UD/#GP to a later patch for better patch review, and removed related part from changelog. - Minor code changes in seamcall() (David) - Added Isaku's tag v10 -> v11: - No update v9 -> v10: - Make the TDX_SEAMCALL_{GP|UD} error codes unconditional but doesn't define them when INTEL_TDX_HOST is enabled. (Dave) - Slightly improved changelog to explain why add assembly code to handle #UD and #GP. v8 -> v9: - Changed patch title (Dave). - Enhanced seamcall() to include the cpu id to the error message when SEAMCALL fails. v7 -> v8: - Improved changelog (Dave): - Trim down some sentences (Dave). - Removed __seamcall() and seamcall() function name and changed accordingly (Dave). - Improved the sentence explaining why to handle #GP (Dave). - Added code to print out error message in seamcall(), following the idea that tdx_enable() to return universal error and print out error message to make clear what's going wrong (Dave). Also mention this in changelog. v6 -> v7: - No change. v5 -> v6: - Added code to handle #UD and #GP (Dave). - Moved the seamcall() wrapper function to this patch, and used a temporary __always_unused to avoid compile warning (Dave). - v3 -> v5 (no feedback on v4): - Explicitly tell TDX_SEAMCALL_VMFAILINVALID is returned if the SEAMCALL itself fails. - Improve the changelog. --- arch/x86/virt/vmx/tdx/Makefile | 2 +- arch/x86/virt/vmx/tdx/seamcall.S | 52 ++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.c | 42 ++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 10 ++++++ 4 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 arch/x86/virt/vmx/tdx/seamcall.S create mode 100644 arch/x86/virt/vmx/tdx/tdx.h diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile index 93ca8b73e1f1..38d534f2c113 100644 --- a/arch/x86/virt/vmx/tdx/Makefile +++ b/arch/x86/virt/vmx/tdx/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-y += tdx.o +obj-y += tdx.o seamcall.o diff --git a/arch/x86/virt/vmx/tdx/seamcall.S b/arch/x86/virt/vmx/tdx/seamcall.S new file mode 100644 index 000000000000..f81be6b9c133 --- /dev/null +++ b/arch/x86/virt/vmx/tdx/seamcall.S @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include + +#include "tdxcall.S" + +/* + * __seamcall() - Host-side interface functions to SEAM software module + * (the P-SEAMLDR or the TDX module). + * + * Transform function call register arguments into the SEAMCALL register + * ABI. Return TDX_SEAMCALL_VMFAILINVALID if the SEAMCALL itself fails, + * or the completion status of the SEAMCALL leaf function. Additional + * output operands are saved in @out (if it is provided by the caller). + * + *------------------------------------------------------------------------- + * SEAMCALL ABI: + *------------------------------------------------------------------------- + * Input Registers: + * + * RAX - SEAMCALL Leaf number. + * RCX,RDX,R8-R9 - SEAMCALL Leaf specific input registers. + * + * Output Registers: + * + * RAX - SEAMCALL completion status code. + * RCX,RDX,R8-R11 - SEAMCALL Leaf specific output registers. + * + *------------------------------------------------------------------------- + * + * __seamcall() function ABI: + * + * @fn (RDI) - SEAMCALL Leaf number, moved to RAX + * @rcx (RSI) - Input parameter 1, moved to RCX + * @rdx (RDX) - Input parameter 2, moved to RDX + * @r8 (RCX) - Input parameter 3, moved to R8 + * @r9 (R8) - Input parameter 4, moved to R9 + * + * @out (R9) - struct tdx_module_output pointer + * stored temporarily in R12 (not + * used by the P-SEAMLDR or the TDX + * module). It can be NULL. + * + * Return (via RAX) the completion status of the SEAMCALL, or + * TDX_SEAMCALL_VMFAILINVALID. + */ +SYM_FUNC_START(__seamcall) + FRAME_BEGIN + TDX_MODULE_CALL host=1 + FRAME_END + RET +SYM_FUNC_END(__seamcall) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 908590e85749..f8233cba5931 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -12,14 +12,56 @@ #include #include #include +#include #include #include #include +#include "tdx.h" static u32 tdx_global_keyid __ro_after_init; static u32 tdx_guest_keyid_start __ro_after_init; static u32 tdx_nr_guest_keyids __ro_after_init; +/* + * Wrapper of __seamcall() to convert SEAMCALL leaf function error code + * to kernel error code. @seamcall_ret and @out contain the SEAMCALL + * leaf function return code and the additional output respectively if + * not NULL. + */ +static int __always_unused seamcall(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, + u64 *seamcall_ret, + struct tdx_module_output *out) +{ + u64 sret; + int cpu; + + /* Need a stable CPU id for printing error message */ + cpu = get_cpu(); + sret = __seamcall(fn, rcx, rdx, r8, r9, out); + put_cpu(); + + /* Save SEAMCALL return code if the caller wants it */ + if (seamcall_ret) + *seamcall_ret = sret; + + switch (sret) { + case 0: + /* SEAMCALL was successful */ + return 0; + case TDX_SEAMCALL_VMFAILINVALID: + pr_err_once("module is not loaded.\n"); + return -ENODEV; + default: + pr_err_once("SEAMCALL failed: CPU %d: leaf %llu, error 0x%llx.\n", + cpu, fn, sret); + if (out) + pr_err_once("additional output: rcx 0x%llx, rdx 0x%llx, r8 0x%llx, r9 0x%llx, r10 0x%llx, r11 0x%llx.\n", + out->rcx, out->rdx, out->r8, + out->r9, out->r10, out->r11); + return -EIO; + } +} + static int __init record_keyid_partitioning(u32 *tdx_keyid_start, u32 *nr_tdx_keyids) { diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h new file mode 100644 index 000000000000..48ad1a1ba737 --- /dev/null +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _X86_VIRT_TDX_H +#define _X86_VIRT_TDX_H + +#include + +struct tdx_module_output; +u64 __seamcall(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, + struct tdx_module_output *out); +#endif -- 2.40.1