Received: by 2002:a89:413:0:b0:1fd:dba5:e537 with SMTP id m19csp1790593lqs; Sun, 16 Jun 2024 05:04:20 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCW3wWaknzFH8lwS30/++oF8GGaU59kfxAinB1TzntKSWTJ/0AuUbpUsU66Zf91Zt0eSisCGRdtVoyySK178vgruOKywoS+ZCeeI8Q8FTw== X-Google-Smtp-Source: AGHT+IH0+79MUZoBxpU5WU+eGFea/dBxlGiyzHtlvhzXnS4OvLd/QT20AjN9FudEEmV9RoGmwWIP X-Received: by 2002:a17:903:1c4:b0:1f7:1525:ddfc with SMTP id d9443c01a7336-1f8625d9e30mr88588995ad.20.1718539459992; Sun, 16 Jun 2024 05:04:19 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1718539459; cv=pass; d=google.com; s=arc-20160816; b=MvPTIVZJ8DTLmHBC/nwvANriX2ByK0evJFzP7DL2DQeBcITQNBVO79In7hXGz/429X YXssyD03Wi3N1hYpEhe1C5JM4FI3MoZtLToby0oBvDmbuPBzwsqHZxd8X+Ni2MRr7od6 Vfe3t9c2fQAVGyuVvQocUg+S2maABO+T2MzrODQKxiL2/t9Qc3zZAqduE3bBf9Mdq3Te gM1FV03HvqIzePNk9EYKmjlXBYVy7+r/7Fj2Ial0Y7hwrPZwzXIPrW6QWY/cpGpVFQyp aB9I57I7YdaK8FW5DOzo1AUB690arE/7ykkc5XXLTUUG5XSdIWbXKcZmOdQ5pkjWnOfe hdCQ== 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=r6S4edYgU2LrDCwZ37oTZVJYsWHqyC7FXVEKDlW1BoA=; fh=tGX/Q7W3UT9xj1a4SiCUgr4GrpxjHjHr5byKd/Rx7k8=; b=TguUazikC+u8LmvRgYDaVX5KOoBzwJf8XYdvRLKi1t3Nv/HMQvsf17Va8RQAi/TpXI 8lMQ0ZGRoBRbc0EcTj7wQ3fpVIvLZ7FP5sZeLVxM8vatDMoqKNSGFK5MF9p8m/Lk4M5r yIfqA74DfkeiJISi5vjestBEgU2xqxTUD5HL5bZs118/LcOgMY36ZpCoarqPNFipsoo2 fJATFwPP5qcfmLkEmatoBdE2KffMFSKScO732wTozduKjbfc++awpzku5Ga5SBs52c9Q /m1pEqZjS1Jk6Eb+5D17mc22bP2FbUeBNbIp1SH2l1tBpd9CpP/szH7Lw4Mgg7Ia+rZ/ cY4Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=I6xWRNnw; 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-216258-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-216258-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id d9443c01a7336-1f855f1af0bsi70765235ad.602.2024.06.16.05.04.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 16 Jun 2024 05:04:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-216258-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=I6xWRNnw; 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-216258-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-216258-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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 93100281694 for ; Sun, 16 Jun 2024 12:04:19 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C1ABF18FDD8; Sun, 16 Jun 2024 12:02:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="I6xWRNnw" Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) (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 2125918FDB8; Sun, 16 Jun 2024 12:02:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.12 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718539330; cv=none; b=CEYq0VG9WF60W4VGTTf1SFDI4TRrBbh7k6kDCMcNmcTQi2yhGQa4C/myQ6Zr13iep8Rds7JBrElyjDDBVgL93P5Td3sBNG+TXw7tNhIA8ipHfWDqE208zVVVUsB0+jDJ3kRIOxLu8H4F8jFdB5Q/bj47TGQ17AlCo4uA8RmDOac= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718539330; c=relaxed/simple; bh=NPmj8dFgrE18hffcZbQUkVcIJfWHNVXzEZiodSQgNNI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FiNJLgSd3N8mibu25/lx2fBNa9zsZG+jrliLldyHc7qY90KZEW4UO1uZpcr0is6uMZorhYlxfftCcT2BPI31IvvX+KuYk7Obc3hi3+iDgLbC+Y8KkYv/3uUw4rCtvw0f1kNni8o1lPJ+hzoqvPVmpv5TeRv+ALDLJdtW7sE+KoM= 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=I6xWRNnw; arc=none smtp.client-ip=198.175.65.12 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=1718539329; x=1750075329; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NPmj8dFgrE18hffcZbQUkVcIJfWHNVXzEZiodSQgNNI=; b=I6xWRNnw1r1qUc3oIVjPohXxf6jM8CecxVK7maHjwoi3lTLDeoJ6gl8Q 7nPrfDCW8lMafntY4eQD7wYKEyNx81ge/H4buLahV8ELfC7HkVkZH6mqa NfF5gJhWiJseNQKuz7Ol/3/Hnz6o4ULmzwHJVQdK5qSWA0AyIY/qqQPEF Zlq1O4yHukF/jCwAh4IMd1F/cS+qB8rPO9b4UNsT23cnbFj5fqHnXwkTE GgYUJ5Fv0tWWHZZquxojQxQMEboZ1bDBDICKYaVHaAO27okL/JTbcyctf /5U6YMvPpkDKaf5E+vnKxoPgFpjYEFw/hE8k3ZgPMCGEayyPtGEbS9OMZ w==; X-CSE-ConnectionGUID: ZA4MHHRKSN+qHVBvhEZrEQ== X-CSE-MsgGUID: vCXrHuxSQ/Wy6BidYnKpvA== X-IronPort-AV: E=McAfee;i="6700,10204,11104"; a="26800052" X-IronPort-AV: E=Sophos;i="6.08,242,1712646000"; d="scan'208";a="26800052" Received: from orviesa004.jf.intel.com ([10.64.159.144]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jun 2024 05:02:09 -0700 X-CSE-ConnectionGUID: gfJxBBPCTx+aGLps5pVu5w== X-CSE-MsgGUID: jx0452ZCTV2I4mLjBDQG5A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,242,1712646000"; d="scan'208";a="46055906" Received: from mgoodin-mobl2.amr.corp.intel.com (HELO khuang2-desk.gar.corp.intel.com) ([10.124.223.226]) by orviesa004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jun 2024 05:02:05 -0700 From: Kai Huang To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, dave.hansen@intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, rick.p.edgecombe@intel.com, peterz@infradead.org, tglx@linutronix.de, bp@alien8.de, mingo@redhat.com, hpa@zytor.com, seanjc@google.com, pbonzini@redhat.com, kvm@vger.kernel.org, isaku.yamahata@intel.com, binbin.wu@linux.intel.com, kai.huang@intel.com Subject: [PATCH 7/9] x86/virt/tdx: Print TDX module basic information Date: Mon, 17 Jun 2024 00:01:17 +1200 Message-ID: X-Mailer: git-send-email 2.43.2 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 Currently the kernel doesn't print any information regarding the TDX module itself, e.g. module version. Printing such information is not mandatory for initializing the TDX module, but in practice such information is useful, especially to the developers. For instance, there are couple of use cases for dumping module basic information: 1) When something goes wrong around using TDX, the information like TDX module version, supported features etc could be helpful [1][2]. 2) For Linux, when the user wants to update the TDX module, one needs to replace the old module in a specific location in the EFI partition with the new one so that after reboot the BIOS can load it. However, after kernel boots, currently the user has no way to verify it is indeed the new module that gets loaded and initialized (e.g., error could happen when replacing the old module). With the module version dumped the user can verify this easily. So dump the basic TDX module information: - TDX module type: Debug or Production. - TDX_FEATURES0: Supported TDX features. - TDX module version, and the build date. And dump the information right after reading global metadata, so that this information is printed no matter whether module initialization fails or not. The actual dmesg will look like: virt/tdx: Production module. virt/tdx: TDX_FEATURES0: 0xfbf virt/tdx: Module version: 1.5.00.00.0481, build_date: 20230323 Link: https://lore.kernel.org/lkml/e2d844ad-182a-4fc0-a06a-d609c9cbef74@suse.com/T/#m352829aedf6680d4628c7e40dc40b332eda93355 [1] Link: https://lore.kernel.org/lkml/e2d844ad-182a-4fc0-a06a-d609c9cbef74@suse.com/T/#m351ebcbc006d2e5bc3e7650206a087cb2708d451 [2] Signed-off-by: Kai Huang --- arch/x86/virt/vmx/tdx/tdx.c | 67 +++++++++++++++++++++++++++++++++++++ arch/x86/virt/vmx/tdx/tdx.h | 33 +++++++++++++++++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 4683884efcc6..ced40e3b516e 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -319,6 +319,61 @@ static int stbuf_read_sysmd_multi(const struct field_mapping *fields, return 0; } +#define TD_SYSINFO_MAP_MOD_INFO(_field_id, _member) \ + TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_module_info, _member) + +static int get_tdx_module_info(struct tdx_sysinfo_module_info *modinfo) +{ + static const struct field_mapping fields[] = { + TD_SYSINFO_MAP_MOD_INFO(SYS_ATTRIBUTES, sys_attributes), + TD_SYSINFO_MAP_MOD_INFO(TDX_FEATURES0, tdx_features0), + }; + + return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), modinfo); +} + +#define TD_SYSINFO_MAP_MOD_VERSION(_field_id, _member) \ + TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_module_version, _member) + +static int get_tdx_module_version(struct tdx_sysinfo_module_version *modver) +{ + static const struct field_mapping fields[] = { + TD_SYSINFO_MAP_MOD_VERSION(MAJOR_VERSION, major), + TD_SYSINFO_MAP_MOD_VERSION(MINOR_VERSION, minor), + TD_SYSINFO_MAP_MOD_VERSION(UPDATE_VERSION, update), + TD_SYSINFO_MAP_MOD_VERSION(INTERNAL_VERSION, internal), + TD_SYSINFO_MAP_MOD_VERSION(BUILD_NUM, build_num), + TD_SYSINFO_MAP_MOD_VERSION(BUILD_DATE, build_date), + }; + + return stbuf_read_sysmd_multi(fields, ARRAY_SIZE(fields), modver); +} + +static void print_basic_sysinfo(struct tdx_sysinfo *sysinfo) +{ + struct tdx_sysinfo_module_version *modver = &sysinfo->module_version; + struct tdx_sysinfo_module_info *modinfo = &sysinfo->module_info; + bool debug = modinfo->sys_attributes & TDX_SYS_ATTR_DEBUG_MODULE; + + pr_info("%s module.\n", debug ? "Debug" : "Production"); + + pr_info("TDX_FEATURES0: 0x%llx\n", modinfo->tdx_features0); + + /* + * TDX module version encoding: + * + * .... + * + * When printed as text, and are 1-digit, + * and are 2-digits and + * is 4-digits. + */ + pr_info("Module version: %u.%u.%02u.%02u.%04u, build_date: %u\n", + modver->major, modver->minor, + modver->update, modver->internal, + modver->build_num, modver->build_date); +} + #define TD_SYSINFO_MAP_TDMR_INFO(_field_id, _member) \ TD_SYSINFO_MAP(_field_id, struct tdx_sysinfo_tdmr_info, _member) @@ -339,6 +394,16 @@ static int get_tdx_tdmr_sysinfo(struct tdx_sysinfo_tdmr_info *tdmr_sysinfo) static int get_tdx_sysinfo(struct tdx_sysinfo *sysinfo) { + int ret; + + ret = get_tdx_module_info(&sysinfo->module_info); + if (ret) + return ret; + + ret = get_tdx_module_version(&sysinfo->module_version); + if (ret) + return ret; + return get_tdx_tdmr_sysinfo(&sysinfo->tdmr_info); } @@ -1121,6 +1186,8 @@ static int init_tdx_module(void) if (ret) return ret; + print_basic_sysinfo(&sysinfo); + /* * To keep things simple, assume that all TDX-protected memory * will come from the page allocator. Make sure all pages in the diff --git a/arch/x86/virt/vmx/tdx/tdx.h b/arch/x86/virt/vmx/tdx/tdx.h index 6b61dc67b0af..d80ec797fbf1 100644 --- a/arch/x86/virt/vmx/tdx/tdx.h +++ b/arch/x86/virt/vmx/tdx/tdx.h @@ -31,6 +31,15 @@ * * See Table "Global Scope Metadata", TDX module 1.5 ABI spec. */ +#define MD_FIELD_ID_SYS_ATTRIBUTES 0x0A00000200000000ULL +#define MD_FIELD_ID_TDX_FEATURES0 0x0A00000300000008ULL +#define MD_FIELD_ID_BUILD_DATE 0x8800000200000001ULL +#define MD_FIELD_ID_BUILD_NUM 0x8800000100000002ULL +#define MD_FIELD_ID_MINOR_VERSION 0x0800000100000003ULL +#define MD_FIELD_ID_MAJOR_VERSION 0x0800000100000004ULL +#define MD_FIELD_ID_UPDATE_VERSION 0x0800000100000005ULL +#define MD_FIELD_ID_INTERNAL_VERSION 0x0800000100000006ULL + #define MD_FIELD_ID_MAX_TDMRS 0x9100000100000008ULL #define MD_FIELD_ID_MAX_RESERVED_PER_TDMR 0x9100000100000009ULL #define MD_FIELD_ID_PAMT_4K_ENTRY_SIZE 0x9100000100000010ULL @@ -124,8 +133,28 @@ struct tdmr_info_list { * * Note not all metadata fields in each class are defined, only those * used by the kernel are. + * + * Also note the "bit definitions" are architectural. */ +/* Class "TDX Module Info" */ +struct tdx_sysinfo_module_info { + u32 sys_attributes; + u64 tdx_features0; +}; + +#define TDX_SYS_ATTR_DEBUG_MODULE 0x1 + +/* Class "TDX Module Version" */ +struct tdx_sysinfo_module_version { + u16 major; + u16 minor; + u16 update; + u16 internal; + u16 build_num; + u32 build_date; +}; + /* Class "TDMR Info" */ struct tdx_sysinfo_tdmr_info { u16 max_tdmrs; @@ -134,7 +163,9 @@ struct tdx_sysinfo_tdmr_info { }; struct tdx_sysinfo { - struct tdx_sysinfo_tdmr_info tdmr_info; + struct tdx_sysinfo_module_info module_info; + struct tdx_sysinfo_module_version module_version; + struct tdx_sysinfo_tdmr_info tdmr_info; }; #endif -- 2.43.2