From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611144; cv=none; d=zohomail.com; s=zohoarc; b=gVGo/pzFJYC1QGyXhyK13sbQgBIkCeuu62SQoq+SuDnBzDcYmjFlT0Urcd9BfQ3ISb5xY1x4xl3s5gCmroyHe0/7VsoEqRHvJrDiHURkaP3OXI3uWqX7o7/dFKO1QLdrPGhcWr0zcSJTLTDwzXTchGBwi1AahAyk53VD9RFaGCA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611144; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=75kgFmRc/GJ3HdcYtM6U8h8g3LZajEoRkGd+0twV0e8=; b=LAE7G9OO6Lcna+0FwnKjnbIV+kTf+RY+iFnrx3bJFLuRDh8rV6hsd+omW9+lDZuOK3N1wZt5p5DUVzx6X2vBQatV4CYd4Zfe8BSLhnm9uVEvmyNShazsfQhnjkMR9BgzEhe/urERyJxCOtNOW6cY8myHyQeBB/HempOuZOXPPVg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611144633768.6371331942037; Fri, 30 May 2025 06:19:04 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000930.1381112 (Exim 4.92) (envelope-from ) id 1uKzd6-0008NQ-9T; Fri, 30 May 2025 13:18:36 +0000 Received: by outflank-mailman (output) from mailman id 1000930.1381112; Fri, 30 May 2025 13:18:36 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzd6-0008Md-4W; Fri, 30 May 2025 13:18:36 +0000 Received: by outflank-mailman (input) for mailman id 1000930; Fri, 30 May 2025 13:18:35 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzd4-0008Jy-Rh for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:34 +0000 Received: from 3.mo576.mail-out.ovh.net (3.mo576.mail-out.ovh.net [188.165.52.203]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 9630bd2a-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:33 +0200 (CEST) Received: from director1.ghost.mail-out.ovh.net (unknown [10.108.2.206]) by mo576.mail-out.ovh.net (Postfix) with ESMTP id 4b83hn1Cptz31p0 for ; Fri, 30 May 2025 13:18:33 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-dfc6s (unknown [10.111.182.37]) by director1.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 7AFD4C43FE; Fri, 30 May 2025 13:18:31 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.113]) by ghost-submission-5b5ff79f4f-dfc6s with ESMTPSA id NlKHBCewOWhVigEAelGN8Q (envelope-from ); Fri, 30 May 2025 13:18:31 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9630bd2a-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-113S00710e8f645-8c55-4142-8ae5-6e1c6e47b73d, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Lukasz Hawrylko , =?UTF-8?q?Mateusz=20M=C3=B3wka?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 01/22] x86/include/asm/intel-txt.h: constants and accessors for TXT registers and heap Date: Fri, 30 May 2025 16:17:43 +0300 Message-ID: <5da8e6c9fd2d986cd99be35774b850584e4a43ee.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12693395550816285852 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduvdculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepheevieeivdejkeehueetgeeivddvfeeiueetvedtfffgjeekffekveefudfgleeunecuffhomhgrihhnpehinhhtvghlrdgtohhmnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduudefnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheejiegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=75kgFmRc/GJ3HdcYtM6U8h8g3LZajEoRkGd+0twV0e8=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611113; v=1; b=i5JJKazbMG38IlrUj/MuXJQvWOSDYDjr/lh9LoOanwsaUknGGW5bhsaaJlZv/+ggvvP0473p f7gq0XqJ8FjrhOD+qt5fX1Lpx4hSUCcuXhSQ6tKhjCVvtEnbJxG2TPsvjj4p5UFV+7Dn974+CFR YtaDJBVVQsedIyoa2yqeNZJ8IZYfZpwFl0Ela83itbte74cV+HFVA44Kijejqg753TPenLOmwAW T1l6tLnpNuRc9cthMkGZZJ1OzWwLUrQtZ4mM9tBbiBhvcEWvJ6Hj3YTpzdZCpkHgjAIPkegj9jn 6mn2q3DLaxEqy3dSejjZnhkf0rbcTYBW9/NYxYFWOZFOA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611146176116600 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel The file contains base address of TXT register spaces, offsets of registers within them, error codes and inline functions for accessing structures stored on TXT heap. xen/arch/x86/tboot.c is updated to use definitions from this new header instead of duplicating them. The change in tboot_protect_mem_regions() there is caused by going from NR_TXT_CONFIG_PAGES to TXT_CONFIG_SPACE_SIZE which avoids multiplying number of pages by page size on every use. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/include/asm/intel-txt.h | 297 +++++++++++++++++++++++++++ xen/arch/x86/tboot.c | 20 +- 2 files changed, 299 insertions(+), 18 deletions(-) create mode 100644 xen/arch/x86/include/asm/intel-txt.h diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h new file mode 100644 index 0000000000..cc2d312f4d --- /dev/null +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -0,0 +1,297 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Intel TXT is an implementation of DRTM in CPUs made by Intel (although = CPU + * alone isn't enough, chipset must support TXT as well). + * + * Overview: + * https://www.intel.com/content/www/us/en/support/articles/000025873/pr= ocessors.html + * Software Development Guide (SDG): + * https://www.intel.com/content/www/us/en/content-details/315168/ + */ + +#ifndef X86_INTEL_TXT_H +#define X86_INTEL_TXT_H + +/* + * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_B= ASE) + */ +#define TXT_PUB_CONFIG_REGS_BASE 0xfed30000U +#define TXT_PRIV_CONFIG_REGS_BASE 0xfed20000U + +/* + * The same set of registers is exposed twice (with different permissions)= and + * they are allocated continuously with page alignment. + */ +#define TXT_CONFIG_SPACE_SIZE \ + (TXT_PUB_CONFIG_REGS_BASE - TXT_PRIV_CONFIG_REGS_BASE) + +/* Offsets from pub/priv config space. */ +#define TXTCR_STS 0x0000 +#define TXTCR_ESTS 0x0008 +#define TXTCR_ERRORCODE 0x0030 +#define TXTCR_CMD_RESET 0x0038 +#define TXTCR_CMD_CLOSE_PRIVATE 0x0048 +#define TXTCR_DIDVID 0x0110 +#define TXTCR_VER_EMIF 0x0200 +#define TXTCR_CMD_UNLOCK_MEM_CONFIG 0x0218 +#define TXTCR_SINIT_BASE 0x0270 +#define TXTCR_SINIT_SIZE 0x0278 +#define TXTCR_MLE_JOIN 0x0290 +#define TXTCR_HEAP_BASE 0x0300 +#define TXTCR_HEAP_SIZE 0x0308 +#define TXTCR_SCRATCHPAD 0x0378 +#define TXTCR_CMD_OPEN_LOCALITY1 0x0380 +#define TXTCR_CMD_CLOSE_LOCALITY1 0x0388 +#define TXTCR_CMD_OPEN_LOCALITY2 0x0390 +#define TXTCR_CMD_CLOSE_LOCALITY2 0x0398 +#define TXTCR_CMD_SECRETS 0x08e0 +#define TXTCR_CMD_NO_SECRETS 0x08e8 +#define TXTCR_E2STS 0x08f0 + +/* + * Secure Launch Defined Error Codes used in MLE-initiated TXT resets. + * + * TXT Specification + * Appendix I ACM Error Codes + */ +#define SLAUNCH_ERROR_GENERIC 0xc0008001U +#define SLAUNCH_ERROR_TPM_INIT 0xc0008002U +#define SLAUNCH_ERROR_TPM_INVALID_LOG20 0xc0008003U +#define SLAUNCH_ERROR_TPM_LOGGING_FAILED 0xc0008004U +#define SLAUNCH_ERROR_REGION_STRADDLE_4GB 0xc0008005U +#define SLAUNCH_ERROR_TPM_EXTEND 0xc0008006U +#define SLAUNCH_ERROR_MTRR_INV_VCNT 0xc0008007U +#define SLAUNCH_ERROR_MTRR_INV_DEF_TYPE 0xc0008008U +#define SLAUNCH_ERROR_MTRR_INV_BASE 0xc0008009U +#define SLAUNCH_ERROR_MTRR_INV_MASK 0xc000800aU +#define SLAUNCH_ERROR_MSR_INV_MISC_EN 0xc000800bU +#define SLAUNCH_ERROR_INV_AP_INTERRUPT 0xc000800cU +#define SLAUNCH_ERROR_INTEGER_OVERFLOW 0xc000800dU +#define SLAUNCH_ERROR_HEAP_WALK 0xc000800eU +#define SLAUNCH_ERROR_HEAP_MAP 0xc000800fU +#define SLAUNCH_ERROR_REGION_ABOVE_4GB 0xc0008010U +#define SLAUNCH_ERROR_HEAP_INVALID_DMAR 0xc0008011U +#define SLAUNCH_ERROR_HEAP_DMAR_SIZE 0xc0008012U +#define SLAUNCH_ERROR_HEAP_DMAR_MAP 0xc0008013U +#define SLAUNCH_ERROR_HI_PMR_BASE 0xc0008014U +#define SLAUNCH_ERROR_HI_PMR_SIZE 0xc0008015U +#define SLAUNCH_ERROR_LO_PMR_BASE 0xc0008016U +#define SLAUNCH_ERROR_LO_PMR_SIZE 0xc0008017U +#define SLAUNCH_ERROR_LO_PMR_MLE 0xc0008018U +#define SLAUNCH_ERROR_INITRD_TOO_BIG 0xc0008019U +#define SLAUNCH_ERROR_HEAP_ZERO_OFFSET 0xc000801aU +#define SLAUNCH_ERROR_WAKE_BLOCK_TOO_SMALL 0xc000801bU +#define SLAUNCH_ERROR_MLE_BUFFER_OVERLAP 0xc000801cU +#define SLAUNCH_ERROR_BUFFER_BEYOND_PMR 0xc000801dU +#define SLAUNCH_ERROR_OS_SINIT_BAD_VERSION 0xc000801eU +#define SLAUNCH_ERROR_EVENTLOG_MAP 0xc000801fU +#define SLAUNCH_ERROR_TPM_NUMBER_ALGS 0xc0008020U +#define SLAUNCH_ERROR_TPM_UNKNOWN_DIGEST 0xc0008021U +#define SLAUNCH_ERROR_TPM_INVALID_EVENT 0xc0008022U + +#define SLAUNCH_BOOTLOADER_MAGIC 0x4c534254 + +#ifndef __ASSEMBLY__ + +/* Need to differentiate between pre- and post paging enabled. */ +#ifdef __EARLY_SLAUNCH__ +#include +#define _txt(x) _p(x) +#else +#include +#include // __va() +#define _txt(x) __va(x) +#endif + +/* + * Always use private space as some of registers are either read-only or n= ot + * present in public space. + */ +static inline uint64_t txt_read(unsigned int reg_no) +{ + volatile uint64_t *reg =3D _txt(TXT_PRIV_CONFIG_REGS_BASE + reg_no); + return *reg; +} + +static inline void txt_write(unsigned int reg_no, uint64_t val) +{ + volatile uint64_t *reg =3D _txt(TXT_PRIV_CONFIG_REGS_BASE + reg_no); + *reg =3D val; +} + +static inline void noreturn txt_reset(uint32_t error) +{ + txt_write(TXTCR_ERRORCODE, error); + txt_write(TXTCR_CMD_NO_SECRETS, 1); + txt_write(TXTCR_CMD_UNLOCK_MEM_CONFIG, 1); + /* + * This serves as TXT register barrier after writing to + * TXTCR_CMD_UNLOCK_MEM_CONFIG. Must be done to ensure that any future + * chipset operations see the write. + */ + (void)txt_read(TXTCR_ESTS); + txt_write(TXTCR_CMD_RESET, 1); + unreachable(); +} + +/* + * Secure Launch defined OS/MLE TXT Heap table + */ +struct txt_os_mle_data { + uint32_t version; + uint32_t reserved; + uint64_t slrt; + uint64_t txt_info; + uint32_t ap_wake_block; + uint32_t ap_wake_block_size; + uint8_t mle_scratch[64]; +} __packed; + +/* + * TXT specification defined BIOS data TXT Heap table + */ +struct txt_bios_data { + uint32_t version; /* Currently 5 for TPM 1.2 and 6 for TPM 2.0 */ + uint32_t bios_sinit_size; + uint64_t reserved1; + uint64_t reserved2; + uint32_t num_logical_procs; + /* Versions >=3D 3 && < 5 */ + uint32_t sinit_flags; + /* Versions >=3D 5 with updates in version 6 */ + uint32_t mle_flags; + /* Versions >=3D 4 */ + /* Ext Data Elements */ +} __packed; + +/* + * TXT specification defined OS/SINIT TXT Heap table + */ +struct txt_os_sinit_data { + uint32_t version; /* Currently 6 for TPM 1.2 and 7 for TPM 2.0 */ + uint32_t flags; /* Reserved in version 6 */ + uint64_t mle_ptab; + uint64_t mle_size; + uint64_t mle_hdr_base; + uint64_t vtd_pmr_lo_base; + uint64_t vtd_pmr_lo_size; + uint64_t vtd_pmr_hi_base; + uint64_t vtd_pmr_hi_size; + uint64_t lcp_po_base; + uint64_t lcp_po_size; + uint32_t capabilities; + /* Version =3D 5 */ + uint64_t efi_rsdt_ptr; /* RSD*P* in versions >=3D 6 */ + /* Versions >=3D 6 */ + /* Ext Data Elements */ +} __packed; + +/* + * TXT specification defined SINIT/MLE TXT Heap table + */ +struct txt_sinit_mle_data { + uint32_t version; /* Current values are 6 through 9 */ + /* Versions <=3D 8, fields until lcp_policy_control must be 0 for >=3D= 9 */ + uint8_t bios_acm_id[20]; + uint32_t edx_senter_flags; + uint64_t mseg_valid; + uint8_t sinit_hash[20]; + uint8_t mle_hash[20]; + uint8_t stm_hash[20]; + uint8_t lcp_policy_hash[20]; + uint32_t lcp_policy_control; + /* Versions >=3D 7 */ + uint32_t rlp_wakeup_addr; + uint32_t reserved; + uint32_t num_of_sinit_mdrs; + uint32_t sinit_mdrs_table_offset; + uint32_t sinit_vtd_dmar_table_size; + uint32_t sinit_vtd_dmar_table_offset; + /* Versions >=3D 8 */ + uint32_t processor_scrtm_status; + /* Versions >=3D 9 */ + /* Ext Data Elements */ +} __packed; + +/* + * Functions to extract data from the Intel TXT Heap Memory. + * + * The layout of the heap is dictated by TXT. It's a set of variable-sized + * tables that appear in pre-defined order: + * + * +------------------------------------+ + * | Size of Bios Data table (uint64_t) | + * +------------------------------------+ + * | Bios Data table | + * +------------------------------------+ + * | Size of OS MLE table (uint64_t) | + * +------------------------------------+ + * | OS MLE table | + * +-------------------------------- + + * | Size of OS SINIT table (uint64_t) | + * +------------------------------------+ + * | OS SINIT table | + * +------------------------------------+ + * | Size of SINIT MLE table (uint64_t) | + * +------------------------------------+ + * | SINIT MLE table | + * +------------------------------------+ + * + * NOTE: the table size fields include the 8 byte size field itself. + * + * NOTE: despite SDG mentioning 8-byte alignment, at least some BIOS ACM m= odules + * were observed to violate this requirement for Bios Data table, so= not + * enforcing any alignment. + */ +static inline uint64_t txt_bios_data_size(const void *heap) +{ + return *(const uint64_t *)heap - sizeof(uint64_t); +} + +static inline void *txt_bios_data_start(const void *heap) +{ + return (void *)heap + sizeof(uint64_t); +} + +static inline uint64_t txt_os_mle_data_size(const void *heap) +{ + return *(const uint64_t *)(txt_bios_data_start(heap) + + txt_bios_data_size(heap)) - + sizeof(uint64_t); +} + +static inline void *txt_os_mle_data_start(const void *heap) +{ + return txt_bios_data_start(heap) + txt_bios_data_size(heap) + + sizeof(uint64_t); +} + +static inline uint64_t txt_os_sinit_data_size(const void *heap) +{ + return *(const uint64_t *)(txt_os_mle_data_start(heap) + + txt_os_mle_data_size(heap)) - + sizeof(uint64_t); +} + +static inline void *txt_os_sinit_data_start(const void *heap) +{ + return txt_os_mle_data_start(heap) + txt_os_mle_data_size(heap) + + sizeof(uint64_t); +} + +static inline uint64_t txt_sinit_mle_data_size(const void *heap) +{ + return *(const uint64_t *)(txt_os_sinit_data_start(heap) + + txt_os_sinit_data_size(heap)) - + sizeof(uint64_t); +} + +static inline void *txt_sinit_mle_data_start(const void *heap) +{ + return txt_os_sinit_data_start(heap) + txt_os_sinit_data_size(heap) + + sizeof(uint64_t); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* X86_INTEL_TXT_H */ diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c index d5db60d335..8a573d8c79 100644 --- a/xen/arch/x86/tboot.c +++ b/xen/arch/x86/tboot.c @@ -15,6 +15,7 @@ #include #include #include +#include =20 #include =20 @@ -35,23 +36,6 @@ static uint64_t __initdata sinit_base, __initdata sinit_= size; =20 static bool __ro_after_init is_vtd; =20 -/* - * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_B= ASE) - */ - -#define TXT_PUB_CONFIG_REGS_BASE 0xfed30000 -#define TXT_PRIV_CONFIG_REGS_BASE 0xfed20000 - -/* # pages for each config regs space - used by fixmap */ -#define NR_TXT_CONFIG_PAGES ((TXT_PUB_CONFIG_REGS_BASE - = \ - TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT) - -/* offsets from pub/priv config space */ -#define TXTCR_SINIT_BASE 0x0270 -#define TXTCR_SINIT_SIZE 0x0278 -#define TXTCR_HEAP_BASE 0x0300 -#define TXTCR_HEAP_SIZE 0x0308 - #define SHA1_SIZE 20 typedef uint8_t sha1_hash_t[SHA1_SIZE]; =20 @@ -409,7 +393,7 @@ int __init tboot_protect_mem_regions(void) =20 /* TXT Private Space */ rc =3D e820_change_range_type(&e820, TXT_PRIV_CONFIG_REGS_BASE, - TXT_PRIV_CONFIG_REGS_BASE + NR_TXT_CONFIG_PAGES * PAGE_SI= ZE, + TXT_PRIV_CONFIG_REGS_BASE + NR_TXT_CONFIG_SIZE, E820_RESERVED, E820_UNUSABLE); if ( !rc ) return 0; --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611143; cv=none; d=zohomail.com; s=zohoarc; b=neVQRBlabuiV9Ufm692kF/tXFd50HCgySq5q1tCMEtXM4fAirO6wgv9yCINpgh6AIQsxPPdshLIDMex8BrVVpHUT3PO/4bc1zM5ZB41voKPU2E0E2ZWOyYXHmC/jdOmkAe0qEM7BbGJVSHhqVb1lC+KwTRKd9z7+Jnn1gDZOhOc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611143; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Jmq1hGKvknlCNJrEv6nB4vNlHz9UuOh2SDBrEluwy9Y=; b=lRt6dArKbFg0IoQ0yWlGTF1rolTNjBXt2DoRUS3DyWfe0e1XxgOye3DWFCHrPcMq2doKWS75ZIvmc4Khm5seYsHS8lqhiYLJCF3hIIbwaTD4a1FAOgyUd1O86L3BcXwu1ffvEBkFDdiFkqm5jxwPGA4120BdkKZQN7GholqMd38= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611143096115.8690969485965; Fri, 30 May 2025 06:19:03 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000931.1381126 (Exim 4.92) (envelope-from ) id 1uKzd8-0000Kn-Hw; Fri, 30 May 2025 13:18:38 +0000 Received: by outflank-mailman (output) from mailman id 1000931.1381126; Fri, 30 May 2025 13:18:38 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzd8-0000Ke-Ej; Fri, 30 May 2025 13:18:38 +0000 Received: by outflank-mailman (input) for mailman id 1000931; Fri, 30 May 2025 13:18:37 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzd7-0008Jy-7W for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:37 +0000 Received: from 10.mo582.mail-out.ovh.net (10.mo582.mail-out.ovh.net [87.98.157.236]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 97d11f80-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:36 +0200 (CEST) Received: from director7.ghost.mail-out.ovh.net (unknown [10.109.148.22]) by mo582.mail-out.ovh.net (Postfix) with ESMTP id 4b83hr09ljz1gVw for ; Fri, 30 May 2025 13:18:35 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-595tn (unknown [10.110.101.93]) by director7.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 1A05CC01C6; Fri, 30 May 2025 13:18:34 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.106]) by ghost-submission-5b5ff79f4f-595tn with ESMTPSA id 1uY5MCqwOWhrxwAAeVbzSg (envelope-from ); Fri, 30 May 2025 13:18:34 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 97d11f80-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-106R0066e9729c4-54b1-40e5-9241-747dee88eacc, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 02/22] include/xen/slr-table.h: Secure Launch Resource Table definitions Date: Fri, 30 May 2025 16:17:44 +0300 Message-ID: <49517f41e112720bdd2b76e8eb3d9b1064671f60.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12694239977603183772 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepjefgfeelteetueelfefgffehtdelkeegtddvtedukeduleelgfekgfetudegudelnecuffhomhgrihhnpehtrhgvnhgthhgsohhothdrohhrghenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddruddtieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehkedvmgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=Jmq1hGKvknlCNJrEv6nB4vNlHz9UuOh2SDBrEluwy9Y=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611116; v=1; b=e26ZF95PgWF4+7aMi7/mBgm4xjARf2OhwuiuZQCep1WSMldNSh+xSIBqxfk2vdCHeCwQdV5P q/pLTgmRuG2BkTjF1ulrtzKDc8yL753BSY9n++z3MPzUUo5wgZSy4D1ZiwcXl8ivnEQywFLZ3Un Tbe4rzfuefjPyu8B/7PeyF1RTpteEi0Rwiax39JsgzLo+3ENTXP6C4JSB//k6TNrXB4AX4eCotp 6Jv3fBZSRvOAegMNEMKEYuI/Xqad+iv6IMK3NvMuEeCQIb1PIvhIHyU709eRa8NBIqeL1t+pxno 4G4jOK3bN4pe145Y4XAVyag2V/ngZCyyffehrMU68Ctpw== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611144056116600 Content-Type: text/plain; charset="utf-8" The file provides constants, structures and several helper functions for parsing SLRT. The data described by the structures is passed to Xen by a bootloader which initiated DRTM. Signed-off-by: Daniel P. Smith Signed-off-by: Ross Philipson Signed-off-by: Sergii Dmytruk --- xen/include/xen/slr-table.h | 276 ++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 xen/include/xen/slr-table.h diff --git a/xen/include/xen/slr-table.h b/xen/include/xen/slr-table.h new file mode 100644 index 0000000000..fb36d06fa8 --- /dev/null +++ b/xen/include/xen/slr-table.h @@ -0,0 +1,276 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Copyright (c) 2025 Apertus Solutions, LLC + * Copyright (c) 2025 Oracle and/or its affiliates. + * Copyright (c) 2025 3mdeb Sp. z o.o + * + * Secure Launch Resource Table definitions. This table is passed to Xen= by + * a bootloader and contains information about pre-DRTM state necessary to + * restore hardware configuration, where to find TPM event log, how to ca= ll + * back into the bootloader (for EFI case) and what needs to be measured = by + * Xen. In other words, this is similar to MBI in Multiboot Specificatio= n. + * + * Specification: + * https://trenchboot.org/specifications/Secure_Launch/ + */ + +#ifndef XEN_SLR_TABLE_H +#define XEN_SLR_TABLE_H + +#include + +#define UEFI_SLR_TABLE_GUID \ + { 0x877a9b2aU, 0x0385, 0x45d1, { 0xa0, 0x34, 0x9d, 0xac, 0x9c, 0x9e, 0= x56, 0x5f } } + +/* SLR table header values */ +#define SLR_TABLE_MAGIC 0x4452544d +#define SLR_TABLE_REVISION 1 + +/* Current revisions for the policy and UEFI config */ +#define SLR_POLICY_REVISION 1 +#define SLR_UEFI_CONFIG_REVISION 1 + +/* SLR defined architectures */ +#define SLR_INTEL_TXT 1 +#define SLR_AMD_SKINIT 2 + +/* SLR defined bootloaders */ +#define SLR_BOOTLOADER_INVALID 0 +#define SLR_BOOTLOADER_GRUB 1 + +/* Log formats */ +#define SLR_DRTM_TPM12_LOG 1 +#define SLR_DRTM_TPM20_LOG 2 + +/* DRTM Policy Entry Flags */ +#define SLR_POLICY_FLAG_MEASURED 0x1 +#define SLR_POLICY_IMPLICIT_SIZE 0x2 + +/* Array Lengths */ +#define TPM_EVENT_INFO_LENGTH 32 +#define TXT_VARIABLE_MTRRS_LENGTH 32 + +/* Tags */ +#define SLR_ENTRY_INVALID 0x0000 +#define SLR_ENTRY_DL_INFO 0x0001 +#define SLR_ENTRY_LOG_INFO 0x0002 +#define SLR_ENTRY_DRTM_POLICY 0x0003 +#define SLR_ENTRY_INTEL_INFO 0x0004 +#define SLR_ENTRY_AMD_INFO 0x0005 +#define SLR_ENTRY_ARM_INFO 0x0006 +#define SLR_ENTRY_UEFI_INFO 0x0007 +#define SLR_ENTRY_UEFI_CONFIG 0x0008 +#define SLR_ENTRY_END 0xffff + +/* Entity Types */ +#define SLR_ET_UNSPECIFIED 0x0000 +#define SLR_ET_SLRT 0x0001 +#define SLR_ET_BOOT_PARAMS 0x0002 +#define SLR_ET_SETUP_DATA 0x0003 +#define SLR_ET_CMDLINE 0x0004 +#define SLR_ET_UEFI_MEMMAP 0x0005 +#define SLR_ET_RAMDISK 0x0006 +#define SLR_ET_MULTIBOOT2_INFO 0x0007 +#define SLR_ET_MULTIBOOT2_MODULE 0x0008 +#define SLR_ET_TXT_OS2MLE 0x0010 +#define SLR_ET_UNUSED 0xffff + +/* + * Primary SLR Table Header + */ +struct slr_table +{ + uint32_t magic; + uint16_t revision; + uint16_t architecture; + uint32_t size; + uint32_t max_size; + /* entries[] */ +} __packed; + +/* + * Common SLRT Table Header + */ +struct slr_entry_hdr +{ + uint32_t tag; + uint32_t size; +} __packed; + +/* + * Boot loader context + */ +struct slr_bl_context +{ + uint16_t bootloader; + uint16_t reserved[3]; + uint64_t context; +} __packed; + +/* + * Prototype of a function pointed to by slr_entry_dl_info::dl_handler. + */ +typedef void (*dl_handler_func)(struct slr_bl_context *bl_context); + +/* + * DRTM Dynamic Launch Configuration + */ +struct slr_entry_dl_info +{ + struct slr_entry_hdr hdr; + uint64_t dce_size; + uint64_t dce_base; + uint64_t dlme_size; + uint64_t dlme_base; + uint64_t dlme_entry; + struct slr_bl_context bl_context; + uint64_t dl_handler; +} __packed; + +/* + * TPM Log Information + */ +struct slr_entry_log_info +{ + struct slr_entry_hdr hdr; + uint16_t format; + uint16_t reserved; + uint32_t size; + uint64_t addr; +} __packed; + +/* + * DRTM Measurement Entry + */ +struct slr_policy_entry +{ + uint16_t pcr; + uint16_t entity_type; + uint16_t flags; + uint16_t reserved; + uint64_t size; + uint64_t entity; + char evt_info[TPM_EVENT_INFO_LENGTH]; +} __packed; + +/* + * DRTM Measurement Policy + */ +struct slr_entry_policy +{ + struct slr_entry_hdr hdr; + uint16_t reserved[2]; + uint16_t revision; + uint16_t nr_entries; + struct slr_policy_entry policy_entries[]; +} __packed; + +/* + * Secure Launch defined MTRR saving structures + */ +struct slr_txt_mtrr_pair +{ + uint64_t mtrr_physbase; + uint64_t mtrr_physmask; +} __packed; + +struct slr_txt_mtrr_state +{ + uint64_t default_mem_type; + uint64_t mtrr_vcnt; + struct slr_txt_mtrr_pair mtrr_pair[TXT_VARIABLE_MTRRS_LENGTH]; +} __packed; + +/* + * Intel TXT Info table + */ +struct slr_entry_intel_info +{ + struct slr_entry_hdr hdr; + uint64_t boot_params_base; + uint64_t txt_heap; + uint64_t saved_misc_enable_msr; + struct slr_txt_mtrr_state saved_bsp_mtrrs; +} __packed; + +/* + * AMD SKINIT Info table + */ +struct slr_entry_amd_info +{ + struct slr_entry_hdr hdr; + uint64_t next; + uint32_t type; + uint32_t len; + uint64_t slrt_size; + uint64_t slrt_base; + uint64_t boot_params_base; + uint16_t psp_version; + uint16_t reserved[3]; +} __packed; + +/* + * UEFI config measurement entry + */ +struct slr_uefi_cfg_entry +{ + uint16_t pcr; + uint16_t reserved; + uint32_t size; + uint64_t cfg; /* address or value */ + char evt_info[TPM_EVENT_INFO_LENGTH]; +} __packed; + +struct slr_entry_uefi_config +{ + struct slr_entry_hdr hdr; + uint16_t reserved[2]; + uint16_t revision; + uint16_t nr_entries; + struct slr_uefi_cfg_entry uefi_cfg_entries[]; +} __packed; + +static inline const void * +slr_end_of_entries(const struct slr_table *table) +{ + return (const void *)table + table->size; +} + +static inline const struct slr_entry_hdr * +slr_next_entry(const struct slr_table *table, const struct slr_entry_hdr *= curr) +{ + const struct slr_entry_hdr *next =3D (void *)curr + curr->size; + + if ( (void *)next + sizeof(*next) > slr_end_of_entries(table) ) + return NULL; + if ( next->tag =3D=3D SLR_ENTRY_END ) + return NULL; + if ( (void *)next + next->size > slr_end_of_entries(table) ) + return NULL; + + return next; +} + +static inline const struct slr_entry_hdr * +slr_next_entry_by_tag(const struct slr_table *table, + const struct slr_entry_hdr *entry, + uint16_t tag) +{ + if ( !entry ) /* Start from the beginning */ + entry =3D (void *)table + sizeof(*table); + + for ( ; ; ) + { + if ( entry->tag =3D=3D tag ) + return entry; + + entry =3D slr_next_entry(table, entry); + if ( !entry ) + return NULL; + } + + return NULL; +} + +#endif /* XEN_SLR_TABLE_H */ --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611150; cv=none; d=zohomail.com; s=zohoarc; b=EG88C96bOaK3qNxljgmme66vJAAIWqKcmTOxO+uA1tY2DI+bKljy+2whXw5SrQs48ay1Y4aNriZyEb0g3nCJQhVQqTIjdceOEffCH66WVsthw8nnIWTGm2bDYzmptr1UjVzrRyPwIiK7QaIJH6GFKG6tXxgAz9tWDrRC54NnWEg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611150; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=REsQ4rGltjGtDGspVocQv2/Sf60+XBS+U8hI4FuZ0Cs=; b=XCluh+hGNfL05gzRpP7Sa7OiL1/qdnGya0roWQ6WNaiSg9G8/syXSAFjbWh5EUsiKkHPwb8BxYNv2ngibgzy+LFxSHsidFSvk/O5Q1fefQ5yQH1LaC48dkZQMGrZJ2vYX88IEo7FY1DKOezgetIeynXs/5TGkPGfa+jS5qkHjyc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611150623217.59993860994769; Fri, 30 May 2025 06:19:10 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000932.1381135 (Exim 4.92) (envelope-from ) id 1uKzdA-0000a3-ON; Fri, 30 May 2025 13:18:40 +0000 Received: by outflank-mailman (output) from mailman id 1000932.1381135; Fri, 30 May 2025 13:18:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdA-0000Zw-Lg; Fri, 30 May 2025 13:18:40 +0000 Received: by outflank-mailman (input) for mailman id 1000932; Fri, 30 May 2025 13:18:40 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdA-0008Jy-3F for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:40 +0000 Received: from 10.mo575.mail-out.ovh.net (10.mo575.mail-out.ovh.net [46.105.79.203]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 998debce-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:39 +0200 (CEST) Received: from director11.ghost.mail-out.ovh.net (unknown [10.109.148.22]) by mo575.mail-out.ovh.net (Postfix) with ESMTP id 4b83ht5zchz289h for ; Fri, 30 May 2025 13:18:38 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-m2hqt (unknown [10.110.118.244]) by director11.ghost.mail-out.ovh.net (Postfix) with ESMTPS id A20CDC61DA; Fri, 30 May 2025 13:18:37 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.101]) by ghost-submission-5b5ff79f4f-m2hqt with ESMTPSA id 8EEPHi2wOWjlBgAAzgKK1w (envelope-from ); Fri, 30 May 2025 13:18:37 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 998debce-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-101G00483e32f39-353f-424e-a8fc-ffe6f4f47263, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , trenchboot-devel@googlegroups.com Subject: [PATCH v3 03/22] x86/boot: add MLE header and Secure Launch entry point Date: Fri, 30 May 2025 16:17:45 +0300 Message-ID: <916c87847457552583f1defb1aced37ea3ff58df.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12695084403030340764 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepkedugeefudeigeduieejleelkeefvddvhfehheevhfdukeejieefgedtudevhedtnecuffhomhgrihhnpehhvggrugdrshgsnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrddutddunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheejhegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=REsQ4rGltjGtDGspVocQv2/Sf60+XBS+U8hI4FuZ0Cs=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611118; v=1; b=AJwlGqENjuhLsTTl6afFnjmyNEklFCTYMEsMItvkax4JAE++9kXAudWVUE0Lebmf1/Q1s0rS WheNkVDW2KggJSxITVxdTJWi2n27BBlyEQSqAhaoUu6t/iplLrw/lY3nhRpwBroHZ11kqBDa5IE lyNLfF4RMGmsosWhP2nkjIVmjxJAd8LmlYdn8M8HAz2zAXqDS6IHLBOJjiSkamNhjC09ZTp6tD0 nm0Qt1yJ4o/tQMf9uPyhH3jBFlVivGM2j5EEvkQnRnjrEQILOxOaoaobsGn/kJTco71kouDgWaB zSJsx4SufdBqMVBfzVUn0miVYgdF5G2S2LPDGSWYFf2pw== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611151895116600 Content-Type: text/plain; charset="utf-8" From: Kacper Stojek Signed-off-by: Kacper Stojek Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- docs/hypervisor-guide/x86/how-xen-boots.rst | 5 ++ xen/arch/x86/boot/head.S | 53 +++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/docs/hypervisor-guide/x86/how-xen-boots.rst b/docs/hypervisor-= guide/x86/how-xen-boots.rst index 8b3229005c..050fe9c61f 100644 --- a/docs/hypervisor-guide/x86/how-xen-boots.rst +++ b/docs/hypervisor-guide/x86/how-xen-boots.rst @@ -55,6 +55,11 @@ If ``CONFIG_PVH_GUEST`` was selected at build time, an E= lf note is included which indicates the ability to use the PVH boot protocol, and registers ``__pvh_start`` as the entrypoint, entered in 32bit mode. =20 +A combination of Multiboot 2 and MLE headers is used to implement DRTM for +legacy (BIOS) boot. The separate entry point is used mainly to differentia= te +from other kinds of boots. It moves a magic number to EAX before jumping i= nto +common startup code. + =20 xen.gz ~~~~~~ diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 77bb7a9e21..a69107bd81 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,25 @@ multiboot2_header: .size multiboot2_header, . - multiboot2_header .type multiboot2_header, @object =20 + .balign 16 +mle_header: + .long 0x9082ac5a /* UUID0 */ + .long 0x74a7476f /* UUID1 */ + .long 0xa2555c0f /* UUID2 */ + .long 0x42b651cb /* UUID3 */ + .long 0x00000034 /* MLE header size */ + .long 0x00020002 /* MLE version 2.2 */ + .long (slaunch_stub_entry - start) /* Linear entry point of MLE= (SINIT virt. address) */ + .long 0x00000000 /* First valid page of MLE */ + .long 0x00000000 /* Offset within binary of first byte of MLE */ + .long (_end - start) /* Offset within binary of last byte + 1 o= f MLE */ + .long 0x00000723 /* Bit vector of MLE-supported capabilities */ + .long 0x00000000 /* Starting linear address of command line (un= used) */ + .long 0x00000000 /* Ending linear address of command line (unus= ed) */ + + .size mle_header, .-mle_header + .type mle_header, @object + .section .init.rodata, "a", @progbits =20 .Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!" @@ -332,6 +352,38 @@ cs32_switch: /* Jump to earlier loaded address. */ jmp *%edi =20 + /* + * Entry point for TrenchBoot Secure Launch on Intel TXT platforms. + * + * CPU is in 32b protected mode with paging disabled. On entry: + * - %ebx =3D %eip =3D MLE entry point, + * - stack pointer is undefined, + * - CS is flat 4GB code segment, + * - DS, ES, SS, FS and GS are undefined according to TXT SDG, but= this + * would make it impossible to initialize GDTR, because GDT base= must + * be relocated in the descriptor, which requires write access t= hat + * CS doesn't provide. Instead we have to assume that DS is set = by + * SINIT ACM as flat 4GB data segment. + * + * Additional restrictions: + * - some MSRs are partially cleared, among them IA32_MISC_ENABLE,= so + * some capabilities might be reported as disabled even if they = are + * supported by CPU + * - interrupts (including NMIs and SMIs) are disabled and must be + * enabled later + * - trying to enter real mode results in reset + * - APs must be brought up by MONITOR or GETSEC[WAKEUP], dependin= g on + * which is supported by a given SINIT ACM + */ +slaunch_stub_entry: + /* Calculate the load base address. */ + mov %ebx, %esi + sub $sym_offs(slaunch_stub_entry), %esi + + /* Mark Secure Launch boot protocol and jump to common entry. */ + mov $SLAUNCH_BOOTLOADER_MAGIC, %eax + jmp .Lset_stack + #ifdef CONFIG_PVH_GUEST ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long sym_offs(__pvh_start)) =20 @@ -371,6 +423,7 @@ __start: /* Restore the clobbered field. */ mov %edx, (%ebx) =20 +.Lset_stack: /* Set up stack. */ lea STACK_SIZE - CPUINFO_sizeof + sym_esi(cpu0_stack), %esp =20 --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611144; cv=none; d=zohomail.com; s=zohoarc; b=ZzvAFaVdihZubDiUJdMASYPl1yPR67lZR0WKChHGWj0eFxgYnJMXdokJM8vCfM7eFndWsRkQf2WhroupHFgZuSCfp8kMDmWJMC4O+U4Xibl3qR+HU6zDQsBVvYpzbn9gj5wX/JbNIA+q2VBFSMlkFVAzYkvA9shwsDdpqHRA2xs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611144; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GvKdVlecLh2PmzTm3hSectebiIzksYZuaxKe05SsphE=; b=DjqBxQqFeRei6ozfiDQ2bH7dMHxF23YAUcJh35M6ADBkQX8kUKUIJFMfFNvFkLHRVH9YR8Rtxu4MHI86j9+HLMGUsxQz+eHM79vgWPWLnefkDMfmr4SjUSJznzuef+ErxoxVcYl0uSWdPqtlobWw17qKpb1REXar2bGJx2GP3/o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611144119366.74169832871473; Fri, 30 May 2025 06:19:04 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000934.1381146 (Exim 4.92) (envelope-from ) id 1uKzdG-0000uI-2Q; Fri, 30 May 2025 13:18:46 +0000 Received: by outflank-mailman (output) from mailman id 1000934.1381146; Fri, 30 May 2025 13:18:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdF-0000u4-Uz; Fri, 30 May 2025 13:18:45 +0000 Received: by outflank-mailman (input) for mailman id 1000934; Fri, 30 May 2025 13:18:44 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdE-0000ql-Fr for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:44 +0000 Received: from 3.mo575.mail-out.ovh.net (3.mo575.mail-out.ovh.net [46.105.58.60]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9b4d507d-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:18:42 +0200 (CEST) Received: from director2.ghost.mail-out.ovh.net (unknown [10.108.2.206]) by mo575.mail-out.ovh.net (Postfix) with ESMTP id 4b83hx5zZRz28B8 for ; Fri, 30 May 2025 13:18:41 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-2djnr (unknown [10.111.174.16]) by director2.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 9CD20C3BB2; Fri, 30 May 2025 13:18:40 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.107]) by ghost-submission-5b5ff79f4f-2djnr with ESMTPSA id B0t9EzCwOWhgJgAAIK2ldA (envelope-from ); Fri, 30 May 2025 13:18:40 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9b4d507d-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-107S001d1b71519-d27e-408c-8523-b9c0e2d47a6d, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 04/22] x86/boot/slaunch-early: implement early initialization Date: Fri, 30 May 2025 16:17:46 +0300 Message-ID: <16a544876163afece619d50f80869aaacc9c797c.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12695928826315977884 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepffejgfduveektedugeeuiefhtdfhjefgieelkeeugfeggedtgeevheefheeffeeunecuffhomhgrihhnpegsrghsvgdrmhgrphdphhgvrggurdhssgenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddruddtjeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehjeehmgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=GvKdVlecLh2PmzTm3hSectebiIzksYZuaxKe05SsphE=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611121; v=1; b=YWF4HxQni853VwJ2/M7u7AJUwzUCW2rBUmmo7Iil0Sb4T6MHZdZcw+7Cdx9bGPsaHT9sRnBf iKX3omW9+HJ4/rCPVZdIcPc6in7tDPmWlRrzwDBjLRMJFGpU74UwIXTt4P5cUciJ+es+am0T0Rd JIDga3+IqfphDU98v6vXoNkMyi7E0pS+ioytkxiVt+gTga1fEcZE9zF+lyCgvBrR7NZy69qv5OD 84hP29LLpnp69wfRFOGetK/fy0vAu0XW7VvDBE8dd3Dfx9Y2jTbHXRt1rJgHvjBKiBMOeitzg48 I/QBz1ndITA+URa6BbRvKpdpDMTUMKZKEvCJACaq/n6rA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611146102116600 Content-Type: text/plain; charset="utf-8" Make head.S invoke a C function to retrieve MBI and SLRT addresses in a platform-specific way. This is also the place to perform sanity checks of DRTM. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/Makefile | 1 + xen/arch/x86/boot/Makefile | 5 +++- xen/arch/x86/boot/head.S | 43 ++++++++++++++++++++++++++++ xen/arch/x86/boot/slaunch-early.c | 41 ++++++++++++++++++++++++++ xen/arch/x86/include/asm/intel-txt.h | 16 +++++++++++ xen/arch/x86/include/asm/slaunch.h | 26 +++++++++++++++++ xen/arch/x86/slaunch.c | 27 +++++++++++++++++ 7 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 xen/arch/x86/boot/slaunch-early.c create mode 100644 xen/arch/x86/include/asm/slaunch.h create mode 100644 xen/arch/x86/slaunch.c diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index ce724a9daa..aa20eb42b5 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_COMPAT) +=3D x86_64/physdev.o obj-$(CONFIG_X86_PSR) +=3D psr.o obj-y +=3D setup.o obj-y +=3D shutdown.o +obj-y +=3D slaunch.o obj-y +=3D smp.o obj-y +=3D smpboot.o obj-y +=3D spec_ctrl.o diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index ff0d61d7ac..5471b966dd 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -5,6 +5,7 @@ obj-bin-y +=3D $(obj64) obj32 :=3D cmdline.32.o obj32 +=3D reloc.32.o obj32 +=3D reloc-trampoline.32.o +obj32 +=3D slaunch-early.32.o =20 obj64 :=3D reloc-trampoline.o =20 @@ -28,6 +29,8 @@ $(obj32): XEN_CFLAGS :=3D $(CFLAGS_x86_32) -fpic $(obj)/%.32.o: $(src)/%.c FORCE $(call if_changed_rule,cc_o_c) =20 +$(obj)/slaunch-early.32.o: XEN_CFLAGS +=3D -D__EARLY_SLAUNCH__ + orphan-handling-$(call ld-option,--orphan-handling=3Derror) :=3D --orphan-= handling=3Derror LDFLAGS_DIRECT-$(call ld-option,--warn-rwx-segments) :=3D --no-warn-rwx-se= gments LDFLAGS_DIRECT +=3D $(LDFLAGS_DIRECT-y) @@ -81,7 +84,7 @@ cmd_combine =3D \ --bin1 $(obj)/built-in-32.base.bin \ --bin2 $(obj)/built-in-32.offset.bin \ --map $(obj)/built-in-32.base.map \ - --exports cmdline_parse_early,reloc,reloc_trampoline32 \ + --exports cmdline_parse_early,reloc,reloc_trampoline32,sla= unch_early_init \ --output $@ =20 targets +=3D built-in-32.S diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index a69107bd81..b4cf423c80 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -472,6 +472,10 @@ __start: /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value= . */ xor %edx,%edx =20 + /* Check for TrenchBoot slaunch bootloader. */ + cmp $SLAUNCH_BOOTLOADER_MAGIC, %eax + je .Lslaunch_proto + /* Check for Multiboot2 bootloader. */ cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax je .Lmultiboot2_proto @@ -487,6 +491,45 @@ __start: cmovnz MB_mem_lower(%ebx),%edx jmp trampoline_bios_setup =20 +.Lslaunch_proto: + /* + * Upon reaching here, CPU state mostly matches the one setup by t= he + * bootloader with ESP, ESI and EDX being clobbered above. + */ + + /* Save information that TrenchBoot slaunch was used. */ + movb $1, sym_esi(slaunch_active) + + /* + * Prepare space for output parameter of slaunch_early_init(), whi= ch is + * a structure of two uint32_t fields. + */ + sub $8, %esp + + push %esp /* pointer to output stru= cture */ + lea sym_offs(__2M_rwdata_end), %ecx /* end of target image */ + lea sym_offs(_start), %edx /* target base address */ + mov %esi, %eax /* load base address */ + /* + * slaunch_early_init(load/eax, tgt/edx, tgt_end/ecx, ret/stk) usi= ng + * fastcall calling convention. + */ + call slaunch_early_init + add $4, %esp /* pop the fourth paramet= er */ + + /* Move outputs of slaunch_early_init() from stack into registers.= */ + pop %eax /* physical MBI address */ + pop %edx /* physical SLRT address */ + + /* Save physical address of SLRT for C code. */ + mov %edx, sym_esi(slaunch_slrt) + + /* Store MBI address in EBX where MB2 code expects it. */ + mov %eax, %ebx + + /* Move magic number expected by Multiboot 2 to EAX and fall throu= gh. */ + movl $MULTIBOOT2_BOOTLOADER_MAGIC, %eax + .Lmultiboot2_proto: /* Skip Multiboot2 information fixed part. */ lea (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx diff --git a/xen/arch/x86/boot/slaunch-early.c b/xen/arch/x86/boot/slaunch-= early.c new file mode 100644 index 0000000000..c9d364bcd5 --- /dev/null +++ b/xen/arch/x86/boot/slaunch-early.c @@ -0,0 +1,41 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved. + */ + +#include +#include +#include + +struct early_init_results +{ + uint32_t mbi_pa; + uint32_t slrt_pa; +} __packed; + +void asmlinkage slaunch_early_init(uint32_t load_base_addr, + uint32_t tgt_base_addr, + uint32_t tgt_end_addr, + struct early_init_results *result) +{ + void *txt_heap; + const struct txt_os_mle_data *os_mle; + const struct slr_table *slrt; + const struct slr_entry_intel_info *intel_info; + + txt_heap =3D txt_init(); + os_mle =3D txt_os_mle_data_start(txt_heap); + + result->slrt_pa =3D os_mle->slrt; + result->mbi_pa =3D 0; + + slrt =3D (const struct slr_table *)(uintptr_t)os_mle->slrt; + + intel_info =3D (const struct slr_entry_intel_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO); + if ( intel_info =3D=3D NULL || intel_info->hdr.size !=3D sizeof(*intel= _info) ) + return; + + result->mbi_pa =3D intel_info->boot_params_base; +} diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index cc2d312f4d..7658457e9d 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -292,6 +292,22 @@ static inline void *txt_sinit_mle_data_start(const voi= d *heap) sizeof(uint64_t); } =20 +static inline void *txt_init(void) +{ + void *txt_heap; + + /* Clear the TXT error register for a clean start of the day. */ + txt_write(TXTCR_ERRORCODE, 0); + + txt_heap =3D _p(txt_read(TXTCR_HEAP_BASE)); + + if ( txt_os_mle_data_size(txt_heap) < sizeof(struct txt_os_mle_data) || + txt_os_sinit_data_size(txt_heap) < sizeof(struct txt_os_sinit_dat= a) ) + txt_reset(SLAUNCH_ERROR_GENERIC); + + return txt_heap; +} + #endif /* __ASSEMBLY__ */ =20 #endif /* X86_INTEL_TXT_H */ diff --git a/xen/arch/x86/include/asm/slaunch.h b/xen/arch/x86/include/asm/= slaunch.h new file mode 100644 index 0000000000..df42defd92 --- /dev/null +++ b/xen/arch/x86/include/asm/slaunch.h @@ -0,0 +1,26 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved. + */ + +#ifndef X86_SLAUNCH_H +#define X86_SLAUNCH_H + +#include + +/* Indicates an active Secure Launch boot. */ +extern bool slaunch_active; + +/* + * Holds physical address of SLRT. Use slaunch_get_slrt() to access SLRT + * instead of mapping where this points to. + */ +extern uint32_t slaunch_slrt; + +/* + * Retrieves pointer to SLRT. Checks table's validity and maps it as nece= ssary. + */ +struct slr_table *slaunch_get_slrt(void); + +#endif /* X86_SLAUNCH_H */ diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c new file mode 100644 index 0000000000..a3e6ab8d71 --- /dev/null +++ b/xen/arch/x86/slaunch.c @@ -0,0 +1,27 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved. + */ + +#include +#include +#include +#include +#include + +/* + * These variables are assigned to by the code near Xen's entry point. + * + * slaunch_active is not __initdata to allow checking for an active Secure + * Launch boot. + */ +bool slaunch_active; +uint32_t __initdata slaunch_slrt; /* physical address */ + +/* Using slaunch_active in head.S assumes it's a single byte in size, so e= nforce + * this assumption. */ +static void __maybe_unused compile_time_checks(void) +{ + BUILD_BUG_ON(sizeof(slaunch_active) !=3D 1); +} --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611152; cv=none; d=zohomail.com; s=zohoarc; b=ewY+XGinE9w6RgpVZPBeAvEV7/1Y9i4R1chb/OnKGRLKaWx5sM3NwfO74RurgfR7DdKsZRcHksbowvy8covvb3vSRersKmRrqPxwqr8Rbvjx4SNBVct9/QLL6oNLc2TQVEVClyhnmlposQZoaPq4uciHrI7JiRk+r8rrmniROu8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611152; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Ze8+L6G+0Rc7+4Bq+m7/6vFCoR62w3qclGgLacvIoZA=; b=mxYUmo1i2htgI9v4sQtTs5MYcD7xZqk0+9o8bomGnj7R+VyqQJd0e4G6D+FMSE+RfUhiMSNXkuuy9aBg9Mt+lqandB/FrztVOuX0s8KqWWXuM4mmGTHZPpGRoGIKdDY+otQWx7uGdcoOKR97n2rUg2MdT2liNuRGBrsAXcMpmv4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611152142366.7503177071293; Fri, 30 May 2025 06:19:12 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000936.1381155 (Exim 4.92) (envelope-from ) id 1uKzdI-0001CW-E4; Fri, 30 May 2025 13:18:48 +0000 Received: by outflank-mailman (output) from mailman id 1000936.1381155; Fri, 30 May 2025 13:18:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdI-0001CJ-Ad; Fri, 30 May 2025 13:18:48 +0000 Received: by outflank-mailman (input) for mailman id 1000936; Fri, 30 May 2025 13:18:47 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdG-0000ql-U2 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:46 +0000 Received: from 10.mo583.mail-out.ovh.net (10.mo583.mail-out.ovh.net [46.105.52.148]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9d18b53d-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:18:45 +0200 (CEST) Received: from director5.ghost.mail-out.ovh.net (unknown [10.109.176.202]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4b83j06CYsz1kgY for ; Fri, 30 May 2025 13:18:44 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-r8s5j (unknown [10.110.168.204]) by director5.ghost.mail-out.ovh.net (Postfix) with ESMTPS id B94B4100223; Fri, 30 May 2025 13:18:43 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.111]) by ghost-submission-5b5ff79f4f-r8s5j with ESMTPSA id rs9PIzOwOWjQtgAAgydd6Q (envelope-from ); Fri, 30 May 2025 13:18:43 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9d18b53d-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-111S0054675508b-6510-4009-9374-a7b742f4e717, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 05/22] x86/boot/slaunch-early: early TXT checks and boot data retrieval Date: Fri, 30 May 2025 16:17:47 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12696773251544298652 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduuddunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekfegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=Ze8+L6G+0Rc7+4Bq+m7/6vFCoR62w3qclGgLacvIoZA=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611124; v=1; b=eHQo6MMWNilw9KMr/5ps9HwV90sMmmQb4iCsqFYY6RaZIbnl6BYqwYk2ch/L+oVHP4Cs+DGj BRDKLlcBdEXL0aviHBoLHwJ5XRo+yzbyPAMzQvYCcz1tTH9xMgOh5L0xB+OWP2A8pHAyCYKM4M9 yEIJzoYaZWZH90ES0jz39TDIYF0uayV6RK2cU/oBe9o4DnAsvqvukBd4Jbtv0J9CijBkyNsqphN +uYQHoJE5TLiETBh3xa7cCZwUjKHdEAGfOk9yy5IdF0Y9tyEUj1dOpW4LlEAnS1yCeh8MrJkxDM N82/v94/hsyo4IMycSoccIQppINRE479nyELIOzOG3XjA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611154204116600 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel The tests validate that important parts of memory are protected against DMA attacks, including Xen and MBI. Modules can be tested later, when it is possible to report issues to a user before invoking TXT reset. TPM event log validation is temporarily disabled due to an issue with its allocation by bootloader (GRUB) which will need to be modified to address this. Ultimately event log will also have to be validated early as it is used immediately after these tests to hold MBI measurements. See larger comment in txt_verify_pmr_ranges(). Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/boot/slaunch-early.c | 6 ++ xen/arch/x86/include/asm/intel-txt.h | 112 +++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/xen/arch/x86/boot/slaunch-early.c b/xen/arch/x86/boot/slaunch-= early.c index c9d364bcd5..662144e42f 100644 --- a/xen/arch/x86/boot/slaunch-early.c +++ b/xen/arch/x86/boot/slaunch-early.c @@ -22,10 +22,13 @@ void asmlinkage slaunch_early_init(uint32_t load_base_a= ddr, void *txt_heap; const struct txt_os_mle_data *os_mle; const struct slr_table *slrt; + const struct txt_os_sinit_data *os_sinit; const struct slr_entry_intel_info *intel_info; + uint32_t size =3D tgt_end_addr - tgt_base_addr; =20 txt_heap =3D txt_init(); os_mle =3D txt_os_mle_data_start(txt_heap); + os_sinit =3D txt_os_sinit_data_start(txt_heap); =20 result->slrt_pa =3D os_mle->slrt; result->mbi_pa =3D 0; @@ -38,4 +41,7 @@ void asmlinkage slaunch_early_init(uint32_t load_base_add= r, return; =20 result->mbi_pa =3D intel_info->boot_params_base; + + txt_verify_pmr_ranges(os_mle, os_sinit, intel_info, + load_base_addr, tgt_base_addr, size); } diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index 7658457e9d..122b4293ea 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -93,6 +93,8 @@ =20 #ifndef __ASSEMBLY__ =20 +#include + /* Need to differentiate between pre- and post paging enabled. */ #ifdef __EARLY_SLAUNCH__ #include @@ -308,6 +310,116 @@ static inline void *txt_init(void) return txt_heap; } =20 +static inline int is_in_pmr(const struct txt_os_sinit_data *os_sinit, + uint64_t base, uint32_t size, int check_high) +{ + /* Check for size overflow. */ + if ( base + size < base ) + txt_reset(SLAUNCH_ERROR_INTEGER_OVERFLOW); + + /* Low range always starts at 0, so its size is also end address. */ + if ( base >=3D os_sinit->vtd_pmr_lo_base && + base + size <=3D os_sinit->vtd_pmr_lo_size ) + return 1; + + if ( check_high && os_sinit->vtd_pmr_hi_size !=3D 0 ) + { + if ( os_sinit->vtd_pmr_hi_base + os_sinit->vtd_pmr_hi_size < + os_sinit->vtd_pmr_hi_size ) + txt_reset(SLAUNCH_ERROR_INTEGER_OVERFLOW); + if ( base >=3D os_sinit->vtd_pmr_hi_base && + base + size <=3D os_sinit->vtd_pmr_hi_base + + os_sinit->vtd_pmr_hi_size ) + return 1; + } + + return 0; +} + +static inline void txt_verify_pmr_ranges( + const struct txt_os_mle_data *os_mle, + const struct txt_os_sinit_data *os_sinit, + const struct slr_entry_intel_info *info, + uint32_t load_base_addr, + uint32_t tgt_base_addr, + uint32_t xen_size) +{ + int check_high_pmr =3D 0; + + /* Verify the value of the low PMR base. It should always be 0. */ + if ( os_sinit->vtd_pmr_lo_base !=3D 0 ) + txt_reset(SLAUNCH_ERROR_LO_PMR_BASE); + + /* + * Low PMR size should not be 0 on current platforms. There is an ongo= ing + * transition to TPR-based DMA protection instead of PMR-based; this i= s not + * yet supported by the code. + */ + if ( os_sinit->vtd_pmr_lo_size =3D=3D 0 ) + txt_reset(SLAUNCH_ERROR_LO_PMR_SIZE); + + /* Check if regions overlap. Treat regions with no hole between as err= or. */ + if ( os_sinit->vtd_pmr_hi_size !=3D 0 && + os_sinit->vtd_pmr_hi_base <=3D os_sinit->vtd_pmr_lo_size ) + txt_reset(SLAUNCH_ERROR_HI_PMR_BASE); + + /* All regions accessed by 32b code must be below 4G. */ + if ( os_sinit->vtd_pmr_hi_base + os_sinit->vtd_pmr_hi_size <=3D + 0x100000000ULL ) + check_high_pmr =3D 1; + + /* + * ACM checks that TXT heap and MLE memory is protected against DMA. W= e have + * to check if MBI and whole Xen memory is protected. The latter is do= ne in + * case bootloader failed to set whole image as MLE and to make sure t= hat + * both pre- and post-relocation code is protected. + */ + + /* Check if all of Xen before relocation is covered by PMR. */ + if ( !is_in_pmr(os_sinit, load_base_addr, xen_size, check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_LO_PMR_MLE); + + /* Check if all of Xen after relocation is covered by PMR. */ + if ( load_base_addr !=3D tgt_base_addr && + !is_in_pmr(os_sinit, tgt_base_addr, xen_size, check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_LO_PMR_MLE); + + /* + * If present, check that MBI is covered by PMR. MBI starts with 'uint= 32_t + * total_size'. + */ + if ( info->boot_params_base !=3D 0 && + !is_in_pmr(os_sinit, info->boot_params_base, + *(uint32_t *)(uintptr_t)info->boot_params_base, + check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_BUFFER_BEYOND_PMR); + + /* Check if TPM event log (if present) is covered by PMR. */ + /* + * FIXME: currently commented out as GRUB allocates it in a hole betwe= en + * PMR and reserved RAM, due to 2MB resolution of PMR. There are no ot= her + * easy-to-use DMA protection mechanisms that would allow to protect t= hat + * part of memory. TPR (TXT DMA Protection Range) gives 1MB resolution= , but + * it still wouldn't be enough. + * + * One possible solution would be for GRUB to allocate log at lower ad= dress, + * but this would further increase memory space fragmentation. Another + * option is to align PMR up instead of down, making PMR cover part of + * reserved region, but it is unclear what the consequences may be. + * + * In tboot this issue was resolved by reserving leftover chunks of me= mory + * in e820 and/or UEFI memory map. This is also a valid solution, but = would + * require more changes to GRUB than the ones listed above, as event l= og is + * allocated much earlier than PMRs. + */ + /* + if ( os_mle->evtlog_addr !=3D 0 && os_mle->evtlog_size !=3D 0 && + !is_in_pmr(os_sinit, os_mle->evtlog_addr, os_mle->evtlog_size, + check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_BUFFER_BEYOND_PMR); + */ +} + #endif /* __ASSEMBLY__ */ =20 #endif /* X86_INTEL_TXT_H */ --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611148; cv=none; d=zohomail.com; s=zohoarc; b=jwklsPWP9TNBqPdsCN8CWf8TLhjKYWWW6znemmIMHZvRwW3FpiICk1uO7wyi0t7yM+9RH/hOOhuhj4IaugP8KqsiqgcxNVzeqkwK81ow/qKPyVeicoypKcOVwmLtBKYI7XG8xzXnRR299EVIwO2Z43NCCygjRTFUD4i9Cso+bU4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611148; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Nf38lpeiCUvbLLteadUfdEVFOEAXLH0XFiAoqTSi818=; b=IslacUxn0MfhzdgwdY4ZEQO1ERqFfaAIHa0l/b6Eg2u+DekmKQy6CdAS0d+WRu+/4cUkNEW45ts7HcqhWyh4RiG8f4YjgniwlU/Shj9OM+WqZOORyEbr56mv+31ceW9hqLxa8tAr8/lxtCObfwQMi9Twx6kw0bcS5zR6SaoyBE0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611148027837.0535383056158; Fri, 30 May 2025 06:19:08 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000937.1381166 (Exim 4.92) (envelope-from ) id 1uKzdK-0001V4-Np; Fri, 30 May 2025 13:18:50 +0000 Received: by outflank-mailman (output) from mailman id 1000937.1381166; Fri, 30 May 2025 13:18:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdK-0001Us-Jg; Fri, 30 May 2025 13:18:50 +0000 Received: by outflank-mailman (input) for mailman id 1000937; Fri, 30 May 2025 13:18:49 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdI-0008Jy-UG for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:49 +0000 Received: from 4.mo576.mail-out.ovh.net (4.mo576.mail-out.ovh.net [46.105.42.102]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 9eb32284-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:48 +0200 (CEST) Received: from director1.ghost.mail-out.ovh.net (unknown [10.108.25.252]) by mo576.mail-out.ovh.net (Postfix) with ESMTP id 4b83j33X41z32V2 for ; Fri, 30 May 2025 13:18:47 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-r8cb6 (unknown [10.110.118.183]) by director1.ghost.mail-out.ovh.net (Postfix) with ESMTPS id BDA71C4523; Fri, 30 May 2025 13:18:46 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.114]) by ghost-submission-5b5ff79f4f-r8cb6 with ESMTPSA id HZerJTawOWi91goAdfCxkA (envelope-from ); Fri, 30 May 2025 13:18:46 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9eb32284-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-114S008955e152b-4069-4f80-bee0-b9936b0ef95e, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 06/22] xen/arch/x86: reserve TXT memory during Slaunch Date: Fri, 30 May 2025 16:17:48 +0300 Message-ID: <8d5ba2e7a0a8bd05bb9cdb89db3f15b831f7f4f7.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12697617674837472412 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduvdculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpeegkeffieeitdevkefhudegffevieeggfelgedvgeehffdtteehfeeuleeiudekvdenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddruddugeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehjeeimgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=Nf38lpeiCUvbLLteadUfdEVFOEAXLH0XFiAoqTSi818=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611127; v=1; b=dzUMtDoyKOU0Pn3wBrv6GNv6AvXgVZcONN70y/Fa52eEaV8APHKYIBZfRZ5P5cSR3XvmduBS FkRC7++v+5Q8edt/dfGfWy+TmCGS7wjH1RcLEpwFm1ib3WiLd70b+8cuYs2NitINj4DNfdhsdhM DX8PLEX0saHV9VEYrQFATBYf8j90PIRCq9f3Yo0ETW8HOKYk7XqTPXBduea4oFbT9x9iAEVxqop zQuv4MaDyjxzoFKIBh08xbe3i6gRfALEvPjejUfi3K2UGG8r60AB28d3KrDuAALMcFFrgoWvxa0 EWBbjQTNdb0eGBFaT1VCV0f9tqtTEQMwNzmLYNsKxkB/w== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611150274116600 From: Kacper Stojek TXT heap, SINIT and TXT private space are marked as reserved or unused in e820 to protect from unintended uses. Signed-off-by: Kacper Stojek Signed-off-by: Krystian Hebel Signed-off-by: Micha=C5=82 =C5=BBygowski Signed-off-by: Sergii Dmytruk --- xen/arch/x86/Makefile | 1 + xen/arch/x86/include/asm/intel-txt.h | 6 ++ xen/arch/x86/include/asm/mm.h | 3 + xen/arch/x86/include/asm/slaunch.h | 44 +++++++++++ xen/arch/x86/intel-txt.c | 113 +++++++++++++++++++++++++++ xen/arch/x86/setup.c | 10 ++- xen/arch/x86/slaunch.c | 98 ++++++++++++++++++++++- 7 files changed, 271 insertions(+), 4 deletions(-) create mode 100644 xen/arch/x86/intel-txt.c diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index aa20eb42b5..5788898166 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_GDBSX) +=3D gdbsx.o obj-y +=3D hypercall.o obj-y +=3D i387.o obj-y +=3D i8259.o +obj-y +=3D intel-txt.o obj-y +=3D io_apic.o obj-$(CONFIG_LIVEPATCH) +=3D livepatch.o obj-y +=3D msi.o diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index 122b4293ea..ad3c41d86c 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -420,6 +420,12 @@ static inline void txt_verify_pmr_ranges( */ } =20 +/* Prepares for accesses to TXT-specific memory. */ +void txt_map_mem_regions(void); + +/* Marks TXT-specific memory as used to avoid its corruption. */ +void txt_reserve_mem_regions(void); + #endif /* __ASSEMBLY__ */ =20 #endif /* X86_INTEL_TXT_H */ diff --git a/xen/arch/x86/include/asm/mm.h b/xen/arch/x86/include/asm/mm.h index d6e80db71c..91fa95cd90 100644 --- a/xen/arch/x86/include/asm/mm.h +++ b/xen/arch/x86/include/asm/mm.h @@ -106,6 +106,9 @@ #define _PGC_need_scrub _PGC_allocated #define PGC_need_scrub PGC_allocated =20 +/* How much of the directmap is prebuilt at compile time. */ +#define PREBUILT_MAP_LIMIT (1 << L2_PAGETABLE_SHIFT) + #ifndef CONFIG_BIGMEM /* * This definition is solely for the use in struct page_info (and diff --git a/xen/arch/x86/include/asm/slaunch.h b/xen/arch/x86/include/asm/= slaunch.h index df42defd92..7891d60035 100644 --- a/xen/arch/x86/include/asm/slaunch.h +++ b/xen/arch/x86/include/asm/slaunch.h @@ -7,6 +7,7 @@ #ifndef X86_SLAUNCH_H #define X86_SLAUNCH_H =20 +#include #include =20 /* Indicates an active Secure Launch boot. */ @@ -18,9 +19,52 @@ extern bool slaunch_active; */ extern uint32_t slaunch_slrt; =20 +/* + * evt_log is assigned a physical address and the caller must map it to + * virtual, if needed. + */ +static inline void find_evt_log(const struct slr_table *slrt, void **evt_l= og, + uint32_t *evt_log_size) +{ + const struct slr_entry_log_info *log_info; + + log_info =3D (const struct slr_entry_log_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_LOG_INFO); + if ( log_info !=3D NULL ) + { + *evt_log =3D _p(log_info->addr); + *evt_log_size =3D log_info->size; + } + else + { + *evt_log =3D NULL; + *evt_log_size =3D 0; + } +} + /* * Retrieves pointer to SLRT. Checks table's validity and maps it as nece= ssary. */ struct slr_table *slaunch_get_slrt(void); =20 +/* + * Prepares for accesses to essential data structures setup by boot enviro= nment. + */ +void slaunch_map_mem_regions(void); + +/* Marks regions of memory as used to avoid their corruption. */ +void slaunch_reserve_mem_regions(void); + +/* + * This helper function is used to map memory using L2 page tables by alig= ning + * mapped regions to 2MB. This way page allocator (which at this point isn= 't + * yet initialized) isn't needed for creating new L1 mappings. The function + * also checks and skips memory already mapped by the prebuilt tables. + * + * There is no unmap_l2() because the function is meant to be used by the = code + * that accesses DRTM-related memory soon after which Xen rebuilds memory = maps, + * effectively dropping all existing mappings. + */ +int slaunch_map_l2(unsigned long paddr, unsigned long size); + #endif /* X86_SLAUNCH_H */ diff --git a/xen/arch/x86/intel-txt.c b/xen/arch/x86/intel-txt.c new file mode 100644 index 0000000000..163383b262 --- /dev/null +++ b/xen/arch/x86/intel-txt.c @@ -0,0 +1,113 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include + +static uint64_t __initdata txt_heap_base, txt_heap_size; + +void __init txt_map_mem_regions(void) +{ + int rc; + + rc =3D slaunch_map_l2(TXT_PRIV_CONFIG_REGS_BASE, TXT_CONFIG_SPACE_SIZE= ); + BUG_ON(rc !=3D 0); + + txt_heap_base =3D txt_read(TXTCR_HEAP_BASE); + BUG_ON(txt_heap_base =3D=3D 0); + + txt_heap_size =3D txt_read(TXTCR_HEAP_SIZE); + BUG_ON(txt_heap_size =3D=3D 0); + + rc =3D slaunch_map_l2(txt_heap_base, txt_heap_size); + BUG_ON(rc !=3D 0); +} + +/* Mark RAM region as RESERVED if it isn't marked that way already. */ +static int __init mark_ram_as(struct e820map *map, uint64_t start, + uint64_t end, uint32_t type) +{ + unsigned int i; + uint32_t from_type =3D E820_RAM; + + for ( i =3D 0; i < map->nr_map; i++ ) + { + uint64_t rs =3D map->map[i].addr; + uint64_t re =3D rs + map->map[i].size; + + /* The entry includes the range. */ + if ( start >=3D rs && end <=3D re ) + break; + + /* The entry intersects the range. */ + if ( end > rs && start < re ) + { + /* Fatal failure. */ + return 0; + } + } + + /* + * If the range is not included by any entry and no entry intersects i= t, + * then it's not listed in the memory map. Consider this case as a su= ccess + * since we're only preventing RAM from being used and unlisted range = should + * not be used. + */ + if ( i =3D=3D map->nr_map ) + return 1; + + /* + * e820_change_range_type() fails if the range is already marked with = the + * desired type. Don't consider it an error if firmware has done it f= or us. + */ + if ( map->map[i].type =3D=3D type ) + return 1; + + /* E820_ACPI or E820_NVS are really unexpected, but others are fine. */ + if ( map->map[i].type =3D=3D E820_RESERVED || + map->map[i].type =3D=3D E820_UNUSABLE ) + from_type =3D map->map[i].type; + + return e820_change_range_type(map, start, end, from_type, type); +} + +void __init txt_reserve_mem_regions(void) +{ + int rc; + uint64_t sinit_base, sinit_size; + + /* TXT Heap */ + BUG_ON(txt_heap_base =3D=3D 0); + printk("SLAUNCH: reserving TXT heap (%#lx - %#lx)\n", txt_heap_base, + txt_heap_base + txt_heap_size); + rc =3D mark_ram_as(&e820_raw, txt_heap_base, txt_heap_base + txt_heap_= size, + E820_RESERVED); + BUG_ON(rc =3D=3D 0); + + sinit_base =3D txt_read(TXTCR_SINIT_BASE); + BUG_ON(sinit_base =3D=3D 0); + + sinit_size =3D txt_read(TXTCR_SINIT_SIZE); + BUG_ON(sinit_size =3D=3D 0); + + /* SINIT */ + printk("SLAUNCH: reserving SINIT memory (%#lx - %#lx)\n", sinit_base, + sinit_base + sinit_size); + rc =3D mark_ram_as(&e820_raw, sinit_base, sinit_base + sinit_size, + E820_RESERVED); + BUG_ON(rc =3D=3D 0); + + /* TXT Private Space */ + rc =3D mark_ram_as(&e820_raw, TXT_PRIV_CONFIG_REGS_BASE, + TXT_PRIV_CONFIG_REGS_BASE + TXT_CONFIG_SPACE_SIZE, + E820_UNUSABLE); + BUG_ON(rc =3D=3D 0); +} diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 1f5cb67bd0..e4638acd12 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -1087,9 +1088,6 @@ static struct domain *__init create_dom0(struct boot_= info *bi) return d; } =20 -/* How much of the directmap is prebuilt at compile time. */ -#define PREBUILT_MAP_LIMIT (1 << L2_PAGETABLE_SHIFT) - void asmlinkage __init noreturn __start_xen(void) { const char *memmap_type =3D NULL; @@ -1425,6 +1423,12 @@ void asmlinkage __init noreturn __start_xen(void) #endif } =20 + if ( slaunch_active ) + { + slaunch_map_mem_regions(); + slaunch_reserve_mem_regions(); + } + /* Sanitise the raw E820 map to produce a final clean version. */ max_page =3D raw_max_page =3D init_e820(memmap_type, &e820_raw); =20 diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c index a3e6ab8d71..ac3b43942b 100644 --- a/xen/arch/x86/slaunch.c +++ b/xen/arch/x86/slaunch.c @@ -7,14 +7,18 @@ #include #include #include +#include #include +#include +#include +#include #include =20 /* * These variables are assigned to by the code near Xen's entry point. * * slaunch_active is not __initdata to allow checking for an active Secure - * Launch boot. + * Launch boot at any point. */ bool slaunch_active; uint32_t __initdata slaunch_slrt; /* physical address */ @@ -25,3 +29,95 @@ static void __maybe_unused compile_time_checks(void) { BUILD_BUG_ON(sizeof(slaunch_active) !=3D 1); } + +struct slr_table *__init slaunch_get_slrt(void) +{ + static struct slr_table *slrt; + + if (slrt =3D=3D NULL) { + int rc; + + slrt =3D __va(slaunch_slrt); + + rc =3D slaunch_map_l2(slaunch_slrt, PAGE_SIZE); + BUG_ON(rc !=3D 0); + + if ( slrt->magic !=3D SLR_TABLE_MAGIC ) + panic("SLRT has invalid magic value: %#08x!\n", slrt->magic); + /* XXX: are newer revisions allowed? */ + if ( slrt->revision !=3D SLR_TABLE_REVISION ) + panic("SLRT is of unsupported revision: %#04x!\n", slrt->revis= ion); + if ( slrt->architecture !=3D SLR_INTEL_TXT ) + panic("SLRT is for unexpected architecture: %#04x!\n", + slrt->architecture); + if ( slrt->size > slrt->max_size ) + panic("SLRT is larger than its max size: %#08x > %#08x!\n", + slrt->size, slrt->max_size); + + if ( slrt->size > PAGE_SIZE ) + { + rc =3D slaunch_map_l2(slaunch_slrt, slrt->size); + BUG_ON(rc !=3D 0); + } + } + + return slrt; +} + +void __init slaunch_map_mem_regions(void) +{ + void *evt_log_addr; + uint32_t evt_log_size; + + /* Vendor-specific part. */ + txt_map_mem_regions(); + + find_evt_log(slaunch_get_slrt(), &evt_log_addr, &evt_log_size); + if ( evt_log_addr !=3D NULL ) + { + int rc =3D slaunch_map_l2((uintptr_t)evt_log_addr, evt_log_size); + BUG_ON(rc !=3D 0); + } +} + +void __init slaunch_reserve_mem_regions(void) +{ + int rc; + + void *evt_log_addr; + uint32_t evt_log_size; + + /* Vendor-specific part. */ + txt_reserve_mem_regions(); + + find_evt_log(slaunch_get_slrt(), &evt_log_addr, &evt_log_size); + if ( evt_log_addr !=3D NULL ) + { + printk("SLAUNCH: reserving event log (%#lx - %#lx)\n", + (uint64_t)evt_log_addr, + (uint64_t)evt_log_addr + evt_log_size); + rc =3D reserve_e820_ram(&e820_raw, (uint64_t)evt_log_addr, + (uint64_t)evt_log_addr + evt_log_size); + BUG_ON(rc =3D=3D 0); + } +} + +int __init slaunch_map_l2(unsigned long paddr, unsigned long size) +{ + unsigned long aligned_paddr =3D paddr & ~((1ULL << L2_PAGETABLE_SHIFT)= - 1); + unsigned long pages =3D ((paddr + size) - aligned_paddr); + pages =3D ROUNDUP(pages, 1ULL << L2_PAGETABLE_SHIFT) >> PAGE_SHIFT; + + if ( aligned_paddr + pages * PAGE_SIZE <=3D PREBUILT_MAP_LIMIT ) + return 0; + + if ( aligned_paddr < PREBUILT_MAP_LIMIT ) + { + pages -=3D (PREBUILT_MAP_LIMIT - aligned_paddr) >> PAGE_SHIFT; + aligned_paddr =3D PREBUILT_MAP_LIMIT; + } + + return map_pages_to_xen((uintptr_t)__va(aligned_paddr), + maddr_to_mfn(aligned_paddr), + pages, PAGE_HYPERVISOR); +} --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611151; cv=none; d=zohomail.com; s=zohoarc; b=TwlNxCjmFSKIJcWz7VBB01JJXgA9IVhdI3B5qcSS+ZimVUp454PKKh2xMavWnejTRHhVDmj/OtCAniYGz6sRKMsDzU5sXDpbG9KyhO67Lxg6W1leX/tvI9FnKoK8AV/D20GQyHlov3XqsltsGv8xR4WkYQF/+9eBAbmkGG71KZs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611151; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=p5/X8odYi3YN7N37QJCMftuc5hqSiV9vDM1ybqq3iiI=; b=HFgQSdWzdmqhitmSepYNEEdQ1R3WW1CjnJYSrKLcS6w8sssHL8nCpjnv4NweAqRN2YUR4WU6+MT5pTWAZHxLonpYu3iuHQ6BJ74itsrllqXLGKopVVTjtAazlpXrxB5uUOiOTo37vkWEx4t8CnmEex7DyHPeMybpqu0mQhzr5w8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611151529593.9224925204963; Fri, 30 May 2025 06:19:11 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000939.1381175 (Exim 4.92) (envelope-from ) id 1uKzdM-0001o3-UB; Fri, 30 May 2025 13:18:52 +0000 Received: by outflank-mailman (output) from mailman id 1000939.1381175; Fri, 30 May 2025 13:18:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdM-0001nr-R6; Fri, 30 May 2025 13:18:52 +0000 Received: by outflank-mailman (input) for mailman id 1000939; Fri, 30 May 2025 13:18:51 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdL-0008Jy-RY for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:51 +0000 Received: from 17.mo561.mail-out.ovh.net (17.mo561.mail-out.ovh.net [87.98.178.58]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id a0779712-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:50 +0200 (CEST) Received: from director9.ghost.mail-out.ovh.net (unknown [10.108.25.252]) by mo561.mail-out.ovh.net (Postfix) with ESMTP id 4b83j623d7z1TGn for ; Fri, 30 May 2025 13:18:50 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-kbk5q (unknown [10.110.164.164]) by director9.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 8FAE58498F; Fri, 30 May 2025 13:18:49 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.96]) by ghost-submission-5b5ff79f4f-kbk5q with ESMTPSA id Gn6JDjmwOWg+tAAARlXHSA (envelope-from ); Fri, 30 May 2025 13:18:49 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a0779712-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-96R001935d236c-c23a-46fa-83b9-c100e535bc6e, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 07/22] x86/mtrr: expose functions for pausing caching Date: Fri, 30 May 2025 16:17:49 +0300 Message-ID: <8d6e871f055c2456ab194e49bd470eafd04e454e.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12698462102722688156 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdelieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehiedumgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=p5/X8odYi3YN7N37QJCMftuc5hqSiV9vDM1ybqq3iiI=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611130; v=1; b=Aiqs0UheTfDL8AWg3gjFuTcW2oP2wzTA8ZmsvhoLDGbS1fV9zG+lGtq6QSzMu1DqiYV/1dh6 xwdDJJJ01w+6RDY+TPEb7KxNczTJvKigPVqC5Jnvoo6SWzN31hY8pYux59K1BMRjpQKImuGQhNK 4LxoTe+3dTFlwhrgjBCwRqgxb+X2gnCj/k2cXWD2t3P8HuE/IE+0G8SKuQRo3DIBZYMmY3BheuB 2wjeGk88cIRKdXiyQuGuQf5+THQBQx44Hjb30r7feVHX4lSl18WybfveM6RuqDFjcoYSoZlubDf UesS9HFaE2w+CdB4T/LIC+lzP8JCcaVlFFOkvXmARcu6A== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611153912116600 Content-Type: text/plain; charset="utf-8" This allows the functionality to be reused by other units that need to update MTRRs. This also gets rid of a static variable. Signed-off-by: Sergii Dmytruk --- xen/arch/x86/cpu/mtrr/generic.c | 51 ++++++++++++++++----------------- xen/arch/x86/include/asm/mtrr.h | 8 ++++++ 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/xen/arch/x86/cpu/mtrr/generic.c b/xen/arch/x86/cpu/mtrr/generi= c.c index c587e9140e..2a8dd1d8ff 100644 --- a/xen/arch/x86/cpu/mtrr/generic.c +++ b/xen/arch/x86/cpu/mtrr/generic.c @@ -396,9 +396,7 @@ static bool set_mtrr_var_ranges(unsigned int index, str= uct mtrr_var_range *vr) return changed; } =20 -static uint64_t deftype; - -static unsigned long set_mtrr_state(void) +static unsigned long set_mtrr_state(uint64_t *deftype) /* [SUMMARY] Set the MTRR state for this CPU. The MTRR state information to read. Some relevant CPU context. @@ -416,14 +414,12 @@ static unsigned long set_mtrr_state(void) if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) change_mask |=3D MTRR_CHANGE_MASK_FIXED; =20 - /* Set_mtrr_restore restores the old value of MTRRdefType, - so to set it we fiddle with the saved value */ - if ((deftype & 0xff) !=3D mtrr_state.def_type - || MASK_EXTR(deftype, MTRRdefType_E) !=3D mtrr_state.enabled - || MASK_EXTR(deftype, MTRRdefType_FE) !=3D mtrr_state.fixed_enabled) { - deftype =3D (deftype & ~0xcff) | mtrr_state.def_type | - MASK_INSR(mtrr_state.enabled, MTRRdefType_E) | - MASK_INSR(mtrr_state.fixed_enabled, MTRRdefType_FE); + if ((*deftype & 0xff) !=3D mtrr_state.def_type + || MASK_EXTR(*deftype, MTRRdefType_E) !=3D mtrr_state.enabled + || MASK_EXTR(*deftype, MTRRdefType_FE) !=3D mtrr_state.fixed_enabled)= { + *deftype =3D (*deftype & ~0xcff) | mtrr_state.def_type | + MASK_INSR(mtrr_state.enabled, MTRRdefType_E) | + MASK_INSR(mtrr_state.fixed_enabled, MTRRdefType_FE); change_mask |=3D MTRR_CHANGE_MASK_DEFTYPE; } =20 @@ -440,9 +436,10 @@ static DEFINE_SPINLOCK(set_atomicity_lock); * has been called. */ =20 -static bool prepare_set(void) +struct mtrr_pausing_state mtrr_pause_caching(void) { unsigned long cr4; + struct mtrr_pausing_state state; =20 /* Note that this is not ideal, since the cache is only flushed/disabled for this CPU while the MTRRs are changed, but changing this requires @@ -462,7 +459,9 @@ static bool prepare_set(void) alternative("wbinvd", "", X86_FEATURE_XEN_SELFSNOOP); =20 cr4 =3D read_cr4(); - if (cr4 & X86_CR4_PGE) + state.pge =3D cr4 & X86_CR4_PGE; + + if (state.pge) write_cr4(cr4 & ~X86_CR4_PGE); else if (use_invpcid) invpcid_flush_all(); @@ -470,27 +469,27 @@ static bool prepare_set(void) write_cr3(read_cr3()); =20 /* Save MTRR state */ - rdmsrl(MSR_MTRRdefType, deftype); + rdmsrl(MSR_MTRRdefType, state.def_type); =20 /* Disable MTRRs, and set the default type to uncached */ - mtrr_wrmsr(MSR_MTRRdefType, deftype & ~0xcff); + mtrr_wrmsr(MSR_MTRRdefType, state.def_type & ~0xcff); =20 /* Again, only flush caches if we have to. */ alternative("wbinvd", "", X86_FEATURE_XEN_SELFSNOOP); =20 - return cr4 & X86_CR4_PGE; + return state; } =20 -static void post_set(bool pge) +void mtrr_resume_caching(struct mtrr_pausing_state state) { /* Intel (P6) standard MTRRs */ - mtrr_wrmsr(MSR_MTRRdefType, deftype); + mtrr_wrmsr(MSR_MTRRdefType, state.def_type); =20 /* Enable caches */ write_cr0(read_cr0() & ~X86_CR0_CD); =20 /* Reenable CR4.PGE (also flushes the TLB) */ - if (pge) + if (state.pge) write_cr4(read_cr4() | X86_CR4_PGE); else if (use_invpcid) invpcid_flush_all(); @@ -504,15 +503,15 @@ void mtrr_set_all(void) { unsigned long mask, count; unsigned long flags; - bool pge; + struct mtrr_pausing_state pausing_state; =20 local_irq_save(flags); - pge =3D prepare_set(); + pausing_state =3D mtrr_pause_caching(); =20 /* Actually set the state */ - mask =3D set_mtrr_state(); + mask =3D set_mtrr_state(&pausing_state.def_type); =20 - post_set(pge); + mtrr_resume_caching(pausing_state); local_irq_restore(flags); =20 /* Use the atomic bitops to update the global mask */ @@ -537,12 +536,12 @@ void mtrr_set( { unsigned long flags; struct mtrr_var_range *vr; - bool pge; + struct mtrr_pausing_state pausing_state; =20 vr =3D &mtrr_state.var_ranges[reg]; =20 local_irq_save(flags); - pge =3D prepare_set(); + pausing_state =3D mtrr_pause_caching(); =20 if (size =3D=3D 0) { /* The invalid bit is kept in the mask, so we simply clear the @@ -563,7 +562,7 @@ void mtrr_set( mtrr_wrmsr(MSR_IA32_MTRR_PHYSMASK(reg), vr->mask); } =20 - post_set(pge); + mtrr_resume_caching(pausing_state); local_irq_restore(flags); } =20 diff --git a/xen/arch/x86/include/asm/mtrr.h b/xen/arch/x86/include/asm/mtr= r.h index 25d442659d..82ea427ba0 100644 --- a/xen/arch/x86/include/asm/mtrr.h +++ b/xen/arch/x86/include/asm/mtrr.h @@ -66,6 +66,14 @@ extern uint8_t pat_type_2_pte_flags(uint8_t pat_type); extern void mtrr_aps_sync_begin(void); extern void mtrr_aps_sync_end(void); =20 +struct mtrr_pausing_state { + bool pge; + uint64_t def_type; +}; + +extern struct mtrr_pausing_state mtrr_pause_caching(void); +extern void mtrr_resume_caching(struct mtrr_pausing_state state); + extern bool mtrr_var_range_msr_set(struct domain *d, struct mtrr_state *m, uint32_t msr, uint64_t msr_content); extern bool mtrr_fix_range_msr_set(struct domain *d, struct mtrr_state *m, --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611262; cv=none; d=zohomail.com; s=zohoarc; b=O+e7sERU2qFoCpKWKUwoRG6KIeV//4OPJsjCrDDXzRQClyopi689xRFjvNGywvYH1kV0gXW8gXS1Ej8Xm0Y06swMpGS1MeEdhNYdEYGslR7e7dm6AyZi/o7JOx1J8k863He8zCSB2P7IMF4qxdYI8Lw/aUYmNg3+jYeNv0xZ65Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611262; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wR1hVbpxxN9SQ0YmcXd59qUIZ1ZgOyrRB96NJpE74ts=; b=Cq4rmgIKwweNryJSJ2tOeF5aS9rReA4mK6LrSMWaEsmiE9ZIIMlqbKkpBNB7OnVXEPgNuottbzU9K8VUZhSGcVMODTnSqT6Jc3/EeReh5NT2/15zx/U1ZlCav0VNfI9rAts0yq/SG92+o0Ne/IkEA6eYp4DaYrSYaxzNjWJYk9Q= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611262506881.3152192413884; Fri, 30 May 2025 06:21:02 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000975.1381227 (Exim 4.92) (envelope-from ) id 1uKzfF-000730-GY; Fri, 30 May 2025 13:20:49 +0000 Received: by outflank-mailman (output) from mailman id 1000975.1381227; Fri, 30 May 2025 13:20:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzfF-00071l-BQ; Fri, 30 May 2025 13:20:49 +0000 Received: by outflank-mailman (input) for mailman id 1000975; Fri, 30 May 2025 13:20:48 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdO-0008Jy-S3 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:54 +0000 Received: from 7.mo582.mail-out.ovh.net (7.mo582.mail-out.ovh.net [46.105.59.196]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id a217e06e-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:53 +0200 (CEST) Received: from director6.ghost.mail-out.ovh.net (unknown [10.109.140.39]) by mo582.mail-out.ovh.net (Postfix) with ESMTP id 4b83j91wPNz1V3B for ; Fri, 30 May 2025 13:18:53 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-jf7jg (unknown [10.110.96.35]) by director6.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 2563980257; Fri, 30 May 2025 13:18:52 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.106]) by ghost-submission-5b5ff79f4f-jf7jg with ESMTPSA id W9soOzuwOWg3twAAMsIQHg (envelope-from ); Fri, 30 May 2025 13:18:52 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a217e06e-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-106R00679701ec5-0cea-4536-851d-f45d9eef6760, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 08/22] x86/slaunch: restore boot MTRRs after Intel TXT DRTM Date: Fri, 30 May 2025 16:17:50 +0300 Message-ID: <5b6b9bf165a4fd9444dc53848fb8faa2cea30781.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12699306524953392284 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpeegkeffieeitdevkefhudegffevieeggfelgedvgeehffdtteehfeeuleeiudekvdenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddruddtieenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehkedvmgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=wR1hVbpxxN9SQ0YmcXd59qUIZ1ZgOyrRB96NJpE74ts=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611133; v=1; b=PMvC/81ouczRL8OJeS1H4LvnV8SeaCAuNjd/xU5Yh7XEGSmZGOqtbxQJQGVoekhjaZjNWsy7 ywWqXeVEcu/tPro4xHpuUGEuwoHsS1fhuEISU57LwjwhqiyHLhphw8w4nmQtFsWoFXArUajhx24 vs6W6srHf1ZXBrCW7r5IqpJjdjyBGF0jDTa8qu+HDMSGyKj/+mFwwGDN/tx5mVa7/YGNOfWboPK gWLFyZ0/CENTGXGeGRpPVZbN8mw9lXP/S5OQHLrB7slBtHqPXCp+FgeJYh4AK0QSdOJc99osmah z2yWgMo/vIjX3KFbAdqV0r9dPcgbjAfNRiZNl3jNev+nQ== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611263647116600 From: Krystian Hebel In preparation for TXT SENTER call, GRUB had to modify MTRR settings to be UC for everything except SINIT ACM. Old values are restored from SLRT where they were saved by the bootloader. Signed-off-by: Krystian Hebel Signed-off-by: Micha=C5=82 =C5=BBygowski Signed-off-by: Sergii Dmytruk --- xen/arch/x86/e820.c | 5 ++ xen/arch/x86/include/asm/intel-txt.h | 3 ++ xen/arch/x86/intel-txt.c | 75 ++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index ca577c0bde..60f00e5259 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include =20 /* * opt_mem: Limit maximum address of physical RAM. @@ -442,6 +444,9 @@ static uint64_t __init mtrr_top_of_ram(void) ASSERT(paddr_bits); addr_mask =3D ((1ULL << paddr_bits) - 1) & PAGE_MASK; =20 + if ( slaunch_active ) + txt_restore_mtrrs(e820_verbose); + rdmsrl(MSR_MTRRcap, mtrr_cap); rdmsrl(MSR_MTRRdefType, mtrr_def); =20 diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index ad3c41d86c..0b0bdc1bb2 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -426,6 +426,9 @@ void txt_map_mem_regions(void); /* Marks TXT-specific memory as used to avoid its corruption. */ void txt_reserve_mem_regions(void); =20 +/* Restores original MTRR values saved by a bootloader before starting DRT= M. */ +void txt_restore_mtrrs(bool e820_verbose); + #endif /* __ASSEMBLY__ */ =20 #endif /* X86_INTEL_TXT_H */ diff --git a/xen/arch/x86/intel-txt.c b/xen/arch/x86/intel-txt.c index 163383b262..0c14d84486 100644 --- a/xen/arch/x86/intel-txt.c +++ b/xen/arch/x86/intel-txt.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include =20 static uint64_t __initdata txt_heap_base, txt_heap_size; @@ -111,3 +113,76 @@ void __init txt_reserve_mem_regions(void) E820_UNUSABLE); BUG_ON(rc =3D=3D 0); } + +void __init txt_restore_mtrrs(bool e820_verbose) +{ + struct slr_entry_intel_info *intel_info; + uint64_t mtrr_cap, mtrr_def, base, mask; + unsigned int i; + uint64_t def_type; + struct mtrr_pausing_state pausing_state; + + rdmsrl(MSR_MTRRcap, mtrr_cap); + rdmsrl(MSR_MTRRdefType, mtrr_def); + + if ( e820_verbose ) + { + printk("MTRRs set previously for SINIT ACM:\n"); + printk(" MTRR cap: %"PRIx64" type: %"PRIx64"\n", mtrr_cap, mtrr_de= f); + + for ( i =3D 0; i < (uint8_t)mtrr_cap; i++ ) + { + rdmsrl(MSR_IA32_MTRR_PHYSBASE(i), base); + rdmsrl(MSR_IA32_MTRR_PHYSMASK(i), mask); + + printk(" MTRR[%d]: base %"PRIx64" mask %"PRIx64"\n", + i, base, mask); + } + } + + intel_info =3D (struct slr_entry_intel_info *) + slr_next_entry_by_tag(slaunch_get_slrt(), NULL, SLR_ENTRY_INTEL_IN= FO); + + if ( (mtrr_cap & 0xFF) !=3D intel_info->saved_bsp_mtrrs.mtrr_vcnt ) + { + printk("Bootloader saved %ld MTRR values, but there should be %ld\= n", + intel_info->saved_bsp_mtrrs.mtrr_vcnt, mtrr_cap & 0xFF); + /* Choose the smaller one to be on the safe side. */ + mtrr_cap =3D (mtrr_cap & 0xFF) > intel_info->saved_bsp_mtrrs.mtrr_= vcnt ? + intel_info->saved_bsp_mtrrs.mtrr_vcnt : mtrr_cap; + } + + def_type =3D intel_info->saved_bsp_mtrrs.default_mem_type; + pausing_state =3D mtrr_pause_caching(); + + for ( i =3D 0; i < (uint8_t)mtrr_cap; i++ ) + { + base =3D intel_info->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physbase; + mask =3D intel_info->saved_bsp_mtrrs.mtrr_pair[i].mtrr_physmask; + wrmsrl(MSR_IA32_MTRR_PHYSBASE(i), base); + wrmsrl(MSR_IA32_MTRR_PHYSMASK(i), mask); + } + + pausing_state.def_type =3D def_type; + mtrr_resume_caching(pausing_state); + + if ( e820_verbose ) + { + printk("Restored MTRRs:\n"); /* Printed by caller, mtrr_top_of_ram= (). */ + + /* If MTRRs are not enabled or WB is not a default type, MTRRs won= 't be printed */ + if ( !test_bit(11, &def_type) || ((uint8_t)def_type =3D=3D X86_MT_= WB) ) + { + for ( i =3D 0; i < (uint8_t)mtrr_cap; i++ ) + { + rdmsrl(MSR_IA32_MTRR_PHYSBASE(i), base); + rdmsrl(MSR_IA32_MTRR_PHYSMASK(i), mask); + printk(" MTRR[%d]: base %"PRIx64" mask %"PRIx64"\n", + i, base, mask); + } + } + } + + /* Restore IA32_MISC_ENABLES */ + wrmsrl(MSR_IA32_MISC_ENABLE, intel_info->saved_misc_enable_msr); +} --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611172; cv=none; d=zohomail.com; s=zohoarc; b=X0X5gx/MN62rAnHV2/iC57OSHs952imSezme2LSCvNHDTsHYs9Zs8MRYZkAkwCKzYrc6DjeGzOu21UonMOw/cH4/QNU5/BpsMDqxxOpE7xWkSHszH7xvdDaTwV3jaiuhjQ8Osjsw2kXHFcMSBqQAixeVJO2YdsMM3oK6hccEuGE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611172; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=K3Dew7MrO0ilxuikP+BcmF7QZioZCbjXXYgwGcnqPdk=; b=RINvTTTdMhsAkQt1KMtGChUvxj8bWVhv8bKjvJ//eb9OxhgxVH1CJGnR3pb/UuFfErAJvTpuOOObW8o7Ap6B0QeCSWE64pgt+UbxdaMJ+5UFLVS9BjFXGp09+LSic33LNuC7prcEv4U43j8YW8oq1o/QjvDHP16cUJJk6Bnq4vM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 174861117261775.7052626556848; Fri, 30 May 2025 06:19:32 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000951.1381186 (Exim 4.92) (envelope-from ) id 1uKzdo-0003cu-BB; Fri, 30 May 2025 13:19:20 +0000 Received: by outflank-mailman (output) from mailman id 1000951.1381186; Fri, 30 May 2025 13:19:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdo-0003cn-7d; Fri, 30 May 2025 13:19:20 +0000 Received: by outflank-mailman (input) for mailman id 1000951; Fri, 30 May 2025 13:19:19 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdn-0003ZU-26 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:19 +0000 Received: from 10.mo582.mail-out.ovh.net (10.mo582.mail-out.ovh.net [87.98.157.236]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id a4170f4e-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:18:56 +0200 (CEST) Received: from director8.ghost.mail-out.ovh.net (unknown [10.109.140.35]) by mo582.mail-out.ovh.net (Postfix) with ESMTP id 4b83jD4Vjdz1SmT for ; Fri, 30 May 2025 13:18:56 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-9nq6m (unknown [10.108.42.28]) by director8.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 66338C0276; Fri, 30 May 2025 13:18:55 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.110]) by ghost-submission-5b5ff79f4f-9nq6m with ESMTPSA id w09eBz+wOWgo8QAAj53byA (envelope-from ); Fri, 30 May 2025 13:18:55 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a4170f4e-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-110S004e213af52-45b3-49a3-b1b6-7b97c322dceb, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , trenchboot-devel@googlegroups.com Subject: [PATCH v3 09/22] xen/lib: add implementation of SHA-1 Date: Fri, 30 May 2025 16:17:51 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12700150950728086684 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -110 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenfghrlhcuvffnffculddquddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepvedvgfeukeehhfevuddvheetudekkefggfeiveehvefhgfehgfffhffgvefhudejnecuffhomhgrihhnpehgihhthhhusgdrtghomhdpnhhishhtrdhgohhvnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduuddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekvdgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=K3Dew7MrO0ilxuikP+BcmF7QZioZCbjXXYgwGcnqPdk=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611136; v=1; b=PdZw+hQFIYx7PC+k/ctBqeINiD2mnpzbA1VGm6XEnnkFD1DSWdx+OLK7cPak4cye9xCHjy6V +6XvolUAOl1tfjKtITbQ2b3cfdvd9AnrfqF33F9jLU0tIbi6h3Rk4GhgD6fm0fp7/JTyp+/2HfR PCRXJPFAda9x0wOGO9NbWogP6WhKUep0f6FClfzLLizSiE0ymMy61DOFpdQXsR/zN/K7sg2aJec o3ZKpREmvB51N3TfXQLA0AiF6LZWc4f2wCUYd6lFYGhABQQ9y3FwnlbL51oeIDHy9Rc43FMPc1n GAAvjH9rHZYB0o92fMSWA5duwB7oPMbDAckHVz/RXnZXg== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611173995116600 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel The code comes from [1] and is licensed under GPL-2.0 license. The initial version was a combination of: - include/crypto/sha1.h - include/crypto/sha1_base.h - lib/crypto/sha1.c - crypto/sha1_generic.c Changes: - includes, formatting, naming - renames and splicing of some trivial functions that are called once - dropping of `int` return values (only zero was ever returned) - getting rid of references to `struct shash_desc` - getting rid of macros - getting rid of unnecessary function pointers - removing workaround for some old version of GCC [1]: https://github.com/torvalds/linux/tree/afdab700f65e14070d8ab92175544b1= c62b8bf03 Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk Acked-by: Jan Beulich --- xen/include/xen/sha1.h | 14 +++ xen/lib/Makefile | 1 + xen/lib/sha1.c | 190 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 xen/include/xen/sha1.h create mode 100644 xen/lib/sha1.c diff --git a/xen/include/xen/sha1.h b/xen/include/xen/sha1.h new file mode 100644 index 0000000000..909ca25a50 --- /dev/null +++ b/xen/include/xen/sha1.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * SHA1: https://csrc.nist.gov/pubs/fips/180-4/upd1/final + */ +#ifndef XEN_SHA1_H +#define XEN_SHA1_H + +#include + +#define SHA1_DIGEST_SIZE 20 + +void sha1_hash(uint8_t digest[SHA1_DIGEST_SIZE], const void *msg, size_t l= en); + +#endif /* XEN_SHA1_H */ diff --git a/xen/lib/Makefile b/xen/lib/Makefile index 5ccb1e5241..fd4b9ece63 100644 --- a/xen/lib/Makefile +++ b/xen/lib/Makefile @@ -17,6 +17,7 @@ lib-y +=3D memset.o lib-y +=3D muldiv64.o lib-y +=3D parse-size.o lib-y +=3D rbtree.o +lib-$(CONFIG_X86) +=3D sha1.o lib-$(CONFIG_X86) +=3D sha2-256.o lib-y +=3D sort.o lib-y +=3D strcasecmp.o diff --git a/xen/lib/sha1.c b/xen/lib/sha1.c new file mode 100644 index 0000000000..c25f0b9309 --- /dev/null +++ b/xen/lib/sha1.c @@ -0,0 +1,190 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * SHA1 routine optimized to do word accesses rather than byte accesses, + * and to avoid unnecessary copies into the context array. + * + * This was based on the git SHA1 implementation. + */ + +#include +#include +#include +#include +#include + +#define SHA1_BLOCK_SIZE 64 +#define SHA1_WORKSPACE_WORDS 16 +#define SHA1_WORKSPACE_MASK (SHA1_WORKSPACE_WORDS - 1) + +struct sha1_state { + uint64_t count; + uint32_t state[SHA1_DIGEST_SIZE / 4]; + uint8_t buffer[SHA1_BLOCK_SIZE]; +}; + +/* This "rolls" over the 512-bit array named w */ +#define W(i) w[(i) & SHA1_WORKSPACE_MASK] + +static uint32_t blend(const uint32_t w[SHA1_WORKSPACE_WORDS], size_t i) +{ + return rol32(W(i + 13) ^ W(i + 8) ^ W(i + 2) ^ W(i), 1); +} + +/** + * sha1_transform - single block SHA1 transform + * + * @digest: 160 bit digest to update + * @data: 512 bits of data to hash + * + * This function executes SHA-1's internal compression function. It updat= es the + * 160-bit internal state (@digest) with a single 512-bit data block (@dat= a). + */ +static void sha1_transform(uint32_t *digest, const uint8_t *data) +{ + uint32_t a, b, c, d, e, t; + uint32_t w[SHA1_WORKSPACE_WORDS]; + unsigned int i =3D 0; + + a =3D digest[0]; + b =3D digest[1]; + c =3D digest[2]; + d =3D digest[3]; + e =3D digest[4]; + + /* Round 1 - iterations 0-16 take their input from 'data' */ + for ( ; i < 16; ++i ) + { + t =3D get_unaligned_be32((uint32_t *)data + i); + W(i) =3D t; + e +=3D t + rol32(a, 5) + (((c ^ d) & b) ^ d) + 0x5a827999U; + b =3D ror32(b, 2); + t =3D e; e =3D d; d =3D c; c =3D b; b =3D a; a =3D t; + } + + /* Round 1 - tail. Input from 512-bit mixing array */ + for ( ; i < 20; ++i ) + { + t =3D blend(w, i); + W(i) =3D t; + e +=3D t + rol32(a, 5) + (((c ^ d) & b) ^ d) + 0x5a827999U; + b =3D ror32(b, 2); + t =3D e; e =3D d; d =3D c; c =3D b; b =3D a; a =3D t; + } + + /* Round 2 */ + for ( ; i < 40; ++i ) + { + t =3D blend(w, i); + W(i) =3D t; + e +=3D t + rol32(a, 5) + (b ^ c ^ d) + 0x6ed9eba1U; + b =3D ror32(b, 2); + t =3D e; e =3D d; d =3D c; c =3D b; b =3D a; a =3D t; + } + + /* Round 3 */ + for ( ; i < 60; ++i ) + { + t =3D blend(w, i); + W(i) =3D t; + e +=3D t + rol32(a, 5) + ((b & c) + (d & (b ^ c))) + 0x8f1bbcdcU; + b =3D ror32(b, 2); + t =3D e; e =3D d; d =3D c; c =3D b; b =3D a; a =3D t; + } + + /* Round 4 */ + for ( ; i < 80; ++i ) + { + t =3D blend(w, i); + W(i) =3D t; + e +=3D t + rol32(a, 5) + (b ^ c ^ d) + 0xca62c1d6U; + b =3D ror32(b, 2); + t =3D e; e =3D d; d =3D c; c =3D b; b =3D a; a =3D t; + } + + digest[0] +=3D a; + digest[1] +=3D b; + digest[2] +=3D c; + digest[3] +=3D d; + digest[4] +=3D e; +} + +static void sha1_init(struct sha1_state *sctx) +{ + sctx->state[0] =3D 0x67452301UL; + sctx->state[1] =3D 0xefcdab89UL; + sctx->state[2] =3D 0x98badcfeUL; + sctx->state[3] =3D 0x10325476UL; + sctx->state[4] =3D 0xc3d2e1f0UL; + sctx->count =3D 0; +} + +static void sha1_update(struct sha1_state *sctx, const uint8_t *msg, size_= t len) +{ + unsigned int partial =3D sctx->count % SHA1_BLOCK_SIZE; + + sctx->count +=3D len; + + if ( (partial + len) >=3D SHA1_BLOCK_SIZE ) + { + if ( partial ) + { + unsigned int rem =3D SHA1_BLOCK_SIZE - partial; + + /* Fill the partial block. */ + memcpy(sctx->buffer + partial, msg, rem); + msg +=3D rem; + len -=3D rem; + + sha1_transform(sctx->state, sctx->buffer); + } + + for ( ; len >=3D SHA1_BLOCK_SIZE; len -=3D SHA1_BLOCK_SIZE ) + { + sha1_transform(sctx->state, msg); + msg +=3D SHA1_BLOCK_SIZE; + } + partial =3D 0; + } + + /* Remaining data becomes partial. */ + memcpy(sctx->buffer + partial, msg, len); +} + +static void sha1_final(struct sha1_state *sctx, uint8_t out[SHA1_DIGEST_SI= ZE]) +{ + const int bit_offset =3D SHA1_BLOCK_SIZE - sizeof(__be64); + unsigned int partial =3D sctx->count % SHA1_BLOCK_SIZE; + + __be32 *digest =3D (__be32 *)out; + unsigned int i; + + /* Start padding */ + sctx->buffer[partial++] =3D 0x80; + + if ( partial > bit_offset ) + { + /* Need one extra block, so properly pad this one with zeroes */ + memset(sctx->buffer + partial, 0x0, SHA1_BLOCK_SIZE - partial); + sha1_transform(sctx->state, sctx->buffer); + partial =3D 0; + } + /* Pad up to the location of the bit count */ + memset(sctx->buffer + partial, 0x0, bit_offset - partial); + + /* Append the bit count */ + put_unaligned_be64(sctx->count << 3, &sctx->buffer[bit_offset]); + sha1_transform(sctx->state, sctx->buffer); + + /* Store state in digest */ + for ( i =3D 0; i < SHA1_DIGEST_SIZE / sizeof(__be32); i++ ) + put_unaligned_be32(sctx->state[i], &digest[i]); +} + +void sha1_hash(uint8_t digest[SHA1_DIGEST_SIZE], const void *msg, size_t l= en) +{ + struct sha1_state sctx; + + sha1_init(&sctx); + sha1_update(&sctx, msg, len); + sha1_final(&sctx, digest); +} --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611308; cv=none; d=zohomail.com; s=zohoarc; b=JtHo+S7+wyMsWXVHZiXLBbkGWvNXZsA+mw/COHeNMMLvQtPGZW+s/GOq8EGuLo5fV7HUIQLDx87yuv3qA5m8k9CTKnH1RWvfa+QZff31HFyh0aAqb+BkN89TtSIzHp75ujg9pHY+LkyECXuF115P3CnwgQ66mOUVBqFurflmrag= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611308; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=0x2mnB2zALc+h57HnIXgGV7sg4jfhRh/4OId+n19BXc=; b=kV6/xCTEoVZnAsga53+D+RTivbVxKdhpz8UZ55+iS82BIqVMAQkG3RavkYe3Mbv+vy+Qh62lLYghBn+T9MENYE9Cp3J6cY0yx6xqtPvuEfg019z7zc4nnHhaOPwaemRVOmqVrwLeqqaPooXX8mibVpaR4vA1CY431ZVZll6iGjc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611308917689.8151958851421; Fri, 30 May 2025 06:21:48 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1001009.1381277 (Exim 4.92) (envelope-from ) id 1uKzfz-0001TN-Tt; Fri, 30 May 2025 13:21:35 +0000 Received: by outflank-mailman (output) from mailman id 1001009.1381277; Fri, 30 May 2025 13:21:35 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzfz-0001TG-Ph; Fri, 30 May 2025 13:21:35 +0000 Received: by outflank-mailman (input) for mailman id 1001009; Fri, 30 May 2025 13:21:34 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdU-0008Jy-Pt for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:00 +0000 Received: from 2.mo576.mail-out.ovh.net (2.mo576.mail-out.ovh.net [178.33.251.80]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id a5afd443-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:18:59 +0200 (CEST) Received: from director4.ghost.mail-out.ovh.net (unknown [10.108.25.63]) by mo576.mail-out.ovh.net (Postfix) with ESMTP id 4b83jH2PX6z32tv for ; Fri, 30 May 2025 13:18:59 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-d5dtf (unknown [10.110.188.251]) by director4.ghost.mail-out.ovh.net (Postfix) with ESMTPS id A0261C5715; Fri, 30 May 2025 13:18:58 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.104]) by ghost-submission-5b5ff79f4f-d5dtf with ESMTPSA id TDFDHkKwOWiVuB4AAS47Dg (envelope-from ); Fri, 30 May 2025 13:18:58 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a5afd443-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-104R0052f59d384-b7d7-485b-afb3-3b2b0e54e04f, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 10/22] x86/tpm.c: code for early hashing and extending PCRs (for TPM1.2) Date: Fri, 30 May 2025 16:17:52 +0300 Message-ID: <0c249037eeda4809b565a55c6473bb21cdd0304e.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12700995376294179996 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduvdculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepffejgfduveektedugeeuiefhtdfhjefgieelkeeugfeggedtgeevheefheeffeeunecuffhomhgrihhnpegsrghsvgdrmhgrphdphhgvrggurdhssgenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddruddtgeenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehjeeimgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=0x2mnB2zALc+h57HnIXgGV7sg4jfhRh/4OId+n19BXc=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611139; v=1; b=LGc4CPtqUYlE2GZ7PtzAKsBx9oPJ8gHPfOTF9bvdEerNr6uutmqXG8r7pRyoR9xwuip2fVsr Cr+E1n4YUiXtoMxb/LXeW4f/PXOgDvwNT0I+hVpRT4I50mMEl340XR4hJWmJ+tJgcecvbrl5GF+ gVAbloSdUolRtKC8fWC50Rqz+GY6dFaKluWhFJrRqQOs4+M3vUn/0kVSPLhRDNqJ7GBqKYmDi8j BPtRw9jgwOAsiqvZ2tS6IU3uZS/9EfOPvAY35Hka6oxmkGSYoguuUBM2azQN5X1Yb1vdUxuTRUP wpefD5BZj7i5SeMc/ETKckDRRdAtXB6Npb2A90cDeCunA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611309934116600 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel This file is built twice: for early 32b mode without paging to measure MBI and for 64b code to measure dom0 kernel and initramfs. Since MBI is small, the first case uses TPM to do the hashing. Kernel and initramfs on the other hand are too big, sending them to the TPM would take multiple minutes. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/Makefile | 1 + xen/arch/x86/boot/Makefile | 7 +- xen/arch/x86/boot/head.S | 3 + xen/arch/x86/include/asm/slaunch.h | 14 + xen/arch/x86/include/asm/tpm.h | 19 ++ xen/arch/x86/slaunch.c | 7 +- xen/arch/x86/tpm.c | 437 +++++++++++++++++++++++++++++ 7 files changed, 486 insertions(+), 2 deletions(-) create mode 100644 xen/arch/x86/include/asm/tpm.h create mode 100644 xen/arch/x86/tpm.c diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 5788898166..2d008a5f52 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -66,6 +66,7 @@ obj-y +=3D spec_ctrl.o obj-y +=3D srat.o obj-y +=3D string.o obj-y +=3D time.o +obj-y +=3D tpm.o obj-y +=3D traps-setup.o obj-y +=3D traps.o obj-$(CONFIG_INTEL) +=3D tsx.o diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index 5471b966dd..55fbe155b6 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -6,6 +6,7 @@ obj32 :=3D cmdline.32.o obj32 +=3D reloc.32.o obj32 +=3D reloc-trampoline.32.o obj32 +=3D slaunch-early.32.o +obj32 +=3D tpm-early.32.o =20 obj64 :=3D reloc-trampoline.o =20 @@ -31,6 +32,10 @@ $(obj)/%.32.o: $(src)/%.c FORCE =20 $(obj)/slaunch-early.32.o: XEN_CFLAGS +=3D -D__EARLY_SLAUNCH__ =20 +$(obj)/tpm-early.32.o: XEN_CFLAGS +=3D -D__EARLY_SLAUNCH__ +$(obj)/tpm-early.32.o: $(src)/../tpm.c FORCE + $(call if_changed_rule,cc_o_c) + orphan-handling-$(call ld-option,--orphan-handling=3Derror) :=3D --orphan-= handling=3Derror LDFLAGS_DIRECT-$(call ld-option,--warn-rwx-segments) :=3D --no-warn-rwx-se= gments LDFLAGS_DIRECT +=3D $(LDFLAGS_DIRECT-y) @@ -84,7 +89,7 @@ cmd_combine =3D \ --bin1 $(obj)/built-in-32.base.bin \ --bin2 $(obj)/built-in-32.offset.bin \ --map $(obj)/built-in-32.base.map \ - --exports cmdline_parse_early,reloc,reloc_trampoline32,sla= unch_early_init \ + --exports cmdline_parse_early,reloc,reloc_trampoline32,sla= unch_early_init,tpm_extend_mbi \ --output $@ =20 targets +=3D built-in-32.S diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index b4cf423c80..9a272155e9 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -527,6 +527,9 @@ __start: /* Store MBI address in EBX where MB2 code expects it. */ mov %eax, %ebx =20 + /* tpm_extend_mbi(mbi/eax, slrt/edx) using fastcall. */ + call tpm_extend_mbi + /* Move magic number expected by Multiboot 2 to EAX and fall throu= gh. */ movl $MULTIBOOT2_BOOTLOADER_MAGIC, %eax =20 diff --git a/xen/arch/x86/include/asm/slaunch.h b/xen/arch/x86/include/asm/= slaunch.h index 7891d60035..3b38045864 100644 --- a/xen/arch/x86/include/asm/slaunch.h +++ b/xen/arch/x86/include/asm/slaunch.h @@ -10,6 +10,20 @@ #include #include =20 +#define DRTM_LOC 2 +#define DRTM_CODE_PCR 17 +#define DRTM_DATA_PCR 18 + +/* + * Secure Launch event log entry types. The TXT specification defines the = base + * event value as 0x400 for DRTM values, use it regardless of the DRTM for + * consistency. + */ +#define DLE_EVTYPE_BASE 0x400 +#define DLE_EVTYPE_SLAUNCH (DLE_EVTYPE_BASE + 0x102) +#define DLE_EVTYPE_SLAUNCH_START (DLE_EVTYPE_BASE + 0x103) +#define DLE_EVTYPE_SLAUNCH_END (DLE_EVTYPE_BASE + 0x104) + /* Indicates an active Secure Launch boot. */ extern bool slaunch_active; =20 diff --git a/xen/arch/x86/include/asm/tpm.h b/xen/arch/x86/include/asm/tpm.h new file mode 100644 index 0000000000..d1e791fc69 --- /dev/null +++ b/xen/arch/x86/include/asm/tpm.h @@ -0,0 +1,19 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved. + */ + +#ifndef X86_TPM_H +#define X86_TPM_H + +#include + +#define TPM_TIS_BASE 0xfed40000U +#define TPM_TIS_SIZE 0x00010000U + +void tpm_hash_extend(unsigned loc, unsigned pcr, const uint8_t *buf, + unsigned size, uint32_t type, const uint8_t *log_data, + unsigned log_data_size); + +#endif /* X86_TPM_H */ diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c index ac3b43942b..5f91fe5ad0 100644 --- a/xen/arch/x86/slaunch.c +++ b/xen/arch/x86/slaunch.c @@ -13,6 +13,7 @@ #include #include #include +#include =20 /* * These variables are assigned to by the code near Xen's entry point. @@ -66,16 +67,20 @@ struct slr_table *__init slaunch_get_slrt(void) =20 void __init slaunch_map_mem_regions(void) { + int rc; void *evt_log_addr; uint32_t evt_log_size; =20 + rc =3D slaunch_map_l2(TPM_TIS_BASE, TPM_TIS_SIZE); + BUG_ON(rc !=3D 0); + /* Vendor-specific part. */ txt_map_mem_regions(); =20 find_evt_log(slaunch_get_slrt(), &evt_log_addr, &evt_log_size); if ( evt_log_addr !=3D NULL ) { - int rc =3D slaunch_map_l2((uintptr_t)evt_log_addr, evt_log_size); + rc =3D slaunch_map_l2((uintptr_t)evt_log_addr, evt_log_size); BUG_ON(rc !=3D 0); } } diff --git a/xen/arch/x86/tpm.c b/xen/arch/x86/tpm.c new file mode 100644 index 0000000000..7fb19ce4fa --- /dev/null +++ b/xen/arch/x86/tpm.c @@ -0,0 +1,437 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (c) 2022-2025 3mdeb Sp. z o.o. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef __EARLY_SLAUNCH__ + +#ifdef __va +#error "__va defined in non-paged mode!" +#endif + +#define __va(x) _p(x) + +/* Implementation of slaunch_get_slrt() for early TPM code. */ +static uint32_t slrt_location; +struct slr_table *slaunch_get_slrt(void) +{ + return __va(slrt_location); +} + +/* + * The code is being compiled as a standalone binary without linking to any + * other part of Xen. Providing implementation of builtin functions in th= is + * case is necessary if compiler chooses to not use an inline builtin. + */ +void *(memcpy)(void *dest, const void *src, size_t n) +{ + const uint8_t *s =3D src; + uint8_t *d =3D dest; + + while ( n-- ) + *d++ =3D *s++; + + return dest; +} + +#else /* __EARLY_SLAUNCH__ */ + +#include +#include + +#endif /* __EARLY_SLAUNCH__ */ + +#define TPM_LOC_REG(loc, reg) (0x1000 * (loc) + (reg)) + +#define TPM_ACCESS_(x) TPM_LOC_REG(x, 0x00) +#define ACCESS_REQUEST_USE (1 << 1) +#define ACCESS_ACTIVE_LOCALITY (1 << 5) +#define TPM_INTF_CAPABILITY_(x) TPM_LOC_REG(x, 0x14) +#define INTF_VERSION_MASK 0x70000000 +#define TPM_STS_(x) TPM_LOC_REG(x, 0x18) +#define TPM_FAMILY_MASK 0x0C000000 +#define STS_DATA_AVAIL (1 << 4) +#define STS_TPM_GO (1 << 5) +#define STS_COMMAND_READY (1 << 6) +#define STS_VALID (1 << 7) +#define TPM_DATA_FIFO_(x) TPM_LOC_REG(x, 0x24) + +#define swap16(x) __builtin_bswap16(x) +#define swap32(x) __builtin_bswap32(x) + +static inline volatile uint32_t tis_read32(unsigned reg) +{ + return *(volatile uint32_t *)__va(TPM_TIS_BASE + reg); +} + +static inline volatile uint8_t tis_read8(unsigned reg) +{ + return *(volatile uint8_t *)__va(TPM_TIS_BASE + reg); +} + +static inline void tis_write8(unsigned reg, uint8_t val) +{ + *(volatile uint8_t *)__va(TPM_TIS_BASE + reg) =3D val; +} + +static inline void request_locality(unsigned loc) +{ + tis_write8(TPM_ACCESS_(loc), ACCESS_REQUEST_USE); + /* Check that locality was actually activated. */ + while ( (tis_read8(TPM_ACCESS_(loc)) & ACCESS_ACTIVE_LOCALITY) =3D=3D = 0 ); +} + +static inline void relinquish_locality(unsigned loc) +{ + tis_write8(TPM_ACCESS_(loc), ACCESS_ACTIVE_LOCALITY); +} + +static void send_cmd(unsigned loc, uint8_t *buf, unsigned i_size, + unsigned *o_size) +{ + /* + * Value of "data available" bit counts only when "valid" field is set= as + * well. + */ + const unsigned data_avail =3D STS_VALID | STS_DATA_AVAIL; + + unsigned i; + + /* Make sure TPM can accept a command. */ + if ( (tis_read8(TPM_STS_(loc)) & STS_COMMAND_READY) =3D=3D 0 ) + { + /* Abort current command. */ + tis_write8(TPM_STS_(loc), STS_COMMAND_READY); + /* Wait until TPM is ready for a new one. */ + while ( (tis_read8(TPM_STS_(loc)) & STS_COMMAND_READY) =3D=3D 0 ); + } + + for ( i =3D 0; i < i_size; i++ ) + tis_write8(TPM_DATA_FIFO_(loc), buf[i]); + + tis_write8(TPM_STS_(loc), STS_TPM_GO); + + /* Wait for the first byte of response. */ + while ( (tis_read8(TPM_STS_(loc)) & data_avail) !=3D data_avail); + + for ( i =3D 0; i < *o_size && tis_read8(TPM_STS_(loc)) & data_avail; i= ++ ) + buf[i] =3D tis_read8(TPM_DATA_FIFO_(loc)); + + if ( i < *o_size ) + *o_size =3D i; + + tis_write8(TPM_STS_(loc), STS_COMMAND_READY); +} + +static inline bool is_tpm12(void) +{ + /* + * If one of these conditions is true: + * - INTF_CAPABILITY_x.interfaceVersion is 0 (TIS <=3D 1.21) + * - INTF_CAPABILITY_x.interfaceVersion is 2 (TIS =3D=3D 1.3) + * - STS_x.tpmFamily is 0 + * we're dealing with TPM1.2. + */ + uint32_t intf_version =3D tis_read32(TPM_INTF_CAPABILITY_(0)) + & INTF_VERSION_MASK; + return (intf_version =3D=3D 0x00000000 || intf_version =3D=3D 0x200000= 00 || + (tis_read32(TPM_STS_(0)) & TPM_FAMILY_MASK) =3D=3D 0); +} + +/****************************** TPM1.2 specific **************************= *****/ +#define TPM_ORD_Extend 0x00000014 +#define TPM_ORD_SHA1Start 0x000000A0 +#define TPM_ORD_SHA1Update 0x000000A1 +#define TPM_ORD_SHA1CompleteExtend 0x000000A3 + +#define TPM_TAG_RQU_COMMAND 0x00C1 +#define TPM_TAG_RSP_COMMAND 0x00C4 + +/* All fields of following structs are big endian. */ +struct tpm_cmd_hdr { + uint16_t tag; + uint32_t paramSize; + uint32_t ordinal; +} __packed; + +struct tpm_rsp_hdr { + uint16_t tag; + uint32_t paramSize; + uint32_t returnCode; +} __packed; + +struct extend_cmd { + struct tpm_cmd_hdr h; + uint32_t pcrNum; + uint8_t inDigest[SHA1_DIGEST_SIZE]; +} __packed; + +struct extend_rsp { + struct tpm_rsp_hdr h; + uint8_t outDigest[SHA1_DIGEST_SIZE]; +} __packed; + +struct sha1_start_cmd { + struct tpm_cmd_hdr h; +} __packed; + +struct sha1_start_rsp { + struct tpm_rsp_hdr h; + uint32_t maxNumBytes; +} __packed; + +struct sha1_update_cmd { + struct tpm_cmd_hdr h; + uint32_t numBytes; /* Must be a multiple of 64 */ + uint8_t hashData[]; +} __packed; + +struct sha1_update_rsp { + struct tpm_rsp_hdr h; +} __packed; + +struct sha1_complete_extend_cmd { + struct tpm_cmd_hdr h; + uint32_t pcrNum; + uint32_t hashDataSize; /* 0-64, inclusive */ + uint8_t hashData[]; +} __packed; + +struct sha1_complete_extend_rsp { + struct tpm_rsp_hdr h; + uint8_t hashValue[SHA1_DIGEST_SIZE]; + uint8_t outDigest[SHA1_DIGEST_SIZE]; +} __packed; + +struct TPM12_PCREvent { + uint32_t PCRIndex; + uint32_t Type; + uint8_t Digest[SHA1_DIGEST_SIZE]; + uint32_t Size; + uint8_t Data[]; +}; + +struct txt_ev_log_container_12 { + char Signature[20]; /* "TXT Event Container", null-termina= ted */ + uint8_t Reserved[12]; + uint8_t ContainerVerMajor; + uint8_t ContainerVerMinor; + uint8_t PCREventVerMajor; + uint8_t PCREventVerMinor; + uint32_t ContainerSize; /* Allocated size */ + uint32_t PCREventsOffset; + uint32_t NextEventOffset; + struct TPM12_PCREvent PCREvents[]; +}; + +#ifdef __EARLY_SLAUNCH__ +/* + * TPM1.2 is required to support commands of up to 1101 bytes, vendors rar= ely + * go above that. Limit maximum size of block of data to be hashed to 1024. + */ +#define MAX_HASH_BLOCK 1024 +#define CMD_RSP_BUF_SIZE (sizeof(struct sha1_update_cmd) + MAX_HASH_BLO= CK) + +union cmd_rsp { + struct sha1_start_cmd start_c; + struct sha1_start_rsp start_r; + struct sha1_update_cmd update_c; + struct sha1_update_rsp update_r; + struct sha1_complete_extend_cmd finish_c; + struct sha1_complete_extend_rsp finish_r; + uint8_t buf[CMD_RSP_BUF_SIZE]; +}; + +/* Returns true on success. */ +static bool tpm12_hash_extend(unsigned loc, const uint8_t *buf, unsigned s= ize, + unsigned pcr, uint8_t *out_digest) +{ + union cmd_rsp cmd_rsp; + unsigned max_bytes =3D MAX_HASH_BLOCK; + unsigned o_size =3D sizeof(cmd_rsp); + bool success =3D false; + + request_locality(loc); + + cmd_rsp.start_c =3D (struct sha1_start_cmd) { + .h.tag =3D swap16(TPM_TAG_RQU_COMMAND), + .h.paramSize =3D swap32(sizeof(struct sha1_start_cmd)), + .h.ordinal =3D swap32(TPM_ORD_SHA1Start), + }; + + send_cmd(loc, cmd_rsp.buf, sizeof(struct sha1_start_cmd), &o_size); + if ( o_size < sizeof(struct sha1_start_rsp) ) + goto error; + + if ( max_bytes > swap32(cmd_rsp.start_r.maxNumBytes) ) + max_bytes =3D swap32(cmd_rsp.start_r.maxNumBytes); + + while ( size > 64 ) + { + if ( size < max_bytes ) + max_bytes =3D size & ~(64 - 1); + + o_size =3D sizeof(cmd_rsp); + + cmd_rsp.update_c =3D (struct sha1_update_cmd){ + .h.tag =3D swap16(TPM_TAG_RQU_COMMAND), + .h.paramSize =3D swap32(sizeof(struct sha1_update_cmd) + max_b= ytes), + .h.ordinal =3D swap32(TPM_ORD_SHA1Update), + .numBytes =3D swap32(max_bytes), + }; + memcpy(cmd_rsp.update_c.hashData, buf, max_bytes); + + send_cmd(loc, cmd_rsp.buf, sizeof(struct sha1_update_cmd) + max_by= tes, + &o_size); + if ( o_size < sizeof(struct sha1_update_rsp) ) + goto error; + + size -=3D max_bytes; + buf +=3D max_bytes; + } + + o_size =3D sizeof(cmd_rsp); + + cmd_rsp.finish_c =3D (struct sha1_complete_extend_cmd) { + .h.tag =3D swap16(TPM_TAG_RQU_COMMAND), + .h.paramSize =3D swap32(sizeof(struct sha1_complete_extend_cmd) + = size), + .h.ordinal =3D swap32(TPM_ORD_SHA1CompleteExtend), + .pcrNum =3D swap32(pcr), + .hashDataSize =3D swap32(size), + }; + memcpy(cmd_rsp.finish_c.hashData, buf, size); + + send_cmd(loc, cmd_rsp.buf, sizeof(struct sha1_complete_extend_cmd) + s= ize, + &o_size); + if ( o_size < sizeof(struct sha1_complete_extend_rsp) ) + goto error; + + if ( out_digest !=3D NULL ) + memcpy(out_digest, cmd_rsp.finish_r.hashValue, SHA1_DIGEST_SIZE); + + success =3D true; + +error: + relinquish_locality(loc); + return success; +} + +#else + +union cmd_rsp { + struct extend_cmd extend_c; + struct extend_rsp extend_r; +}; + +/* Returns true on success. */ +static bool tpm12_hash_extend(unsigned loc, const uint8_t *buf, unsigned s= ize, + unsigned pcr, uint8_t *out_digest) +{ + union cmd_rsp cmd_rsp; + unsigned o_size =3D sizeof(cmd_rsp); + + sha1_hash(out_digest, buf, size); + + request_locality(loc); + + cmd_rsp.extend_c =3D (struct extend_cmd) { + .h.tag =3D swap16(TPM_TAG_RQU_COMMAND), + .h.paramSize =3D swap32(sizeof(struct extend_cmd)), + .h.ordinal =3D swap32(TPM_ORD_Extend), + .pcrNum =3D swap32(pcr), + }; + + memcpy(cmd_rsp.extend_c.inDigest, out_digest, SHA1_DIGEST_SIZE); + + send_cmd(loc, (uint8_t *)&cmd_rsp, sizeof(struct extend_cmd), &o_size); + + relinquish_locality(loc); + + return (o_size >=3D sizeof(struct extend_rsp)); +} + +#endif /* __EARLY_SLAUNCH__ */ + +static void *create_log_event12(struct txt_ev_log_container_12 *evt_log, + uint32_t evt_log_size, uint32_t pcr, + uint32_t type, const uint8_t *data, + unsigned data_size) +{ + struct TPM12_PCREvent *new_entry; + + new_entry =3D (void *)(((uint8_t *)evt_log) + evt_log->NextEventOffset= ); + + /* + * Check if there is enough space left for new entry. + * Note: it is possible to introduce a gap in event log if entry with = big + * data_size is followed by another entry with smaller data. Maybe we = should + * cap the event log size in such case? + */ + if ( evt_log->NextEventOffset + sizeof(struct TPM12_PCREvent) + data_s= ize + > evt_log_size ) + return NULL; + + evt_log->NextEventOffset +=3D sizeof(struct TPM12_PCREvent) + data_siz= e; + + new_entry->PCRIndex =3D pcr; + new_entry->Type =3D type; + new_entry->Size =3D data_size; + + if ( data && data_size > 0 ) + memcpy(new_entry->Data, data, data_size); + + return new_entry->Digest; +} + +/************************** end of TPM1.2 specific ***********************= *****/ + +void tpm_hash_extend(unsigned loc, unsigned pcr, const uint8_t *buf, + unsigned size, uint32_t type, const uint8_t *log_data, + unsigned log_data_size) +{ + void *evt_log_addr; + uint32_t evt_log_size; + + find_evt_log(slaunch_get_slrt(), &evt_log_addr, &evt_log_size); + evt_log_addr =3D __va((uintptr_t)evt_log_addr); + + if ( is_tpm12() ) + { + uint8_t sha1_digest[SHA1_DIGEST_SIZE]; + + struct txt_ev_log_container_12 *evt_log =3D evt_log_addr; + void *entry_digest =3D create_log_event12(evt_log, evt_log_size, p= cr, + type, log_data, log_data_s= ize); + + /* We still need to write computed hash somewhere. */ + if ( entry_digest =3D=3D NULL ) + entry_digest =3D sha1_digest; + + if ( !tpm12_hash_extend(loc, buf, size, pcr, entry_digest) ) + { +#ifndef __EARLY_SLAUNCH__ + printk(XENLOG_ERR "Extending PCR%u failed\n", pcr); +#endif + } + } +} + +#ifdef __EARLY_SLAUNCH__ +void asmlinkage tpm_extend_mbi(uint32_t *mbi, uint32_t slrt_pa) +{ + /* Need this to implement slaunch_get_slrt() for early TPM code. */ + slrt_location =3D slrt_pa; + + /* MBI starts with uint32_t total_size. */ + tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, (uint8_t *)mbi, *mbi, + DLE_EVTYPE_SLAUNCH, NULL, 0); +} +#endif --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611185; cv=none; d=zohomail.com; s=zohoarc; b=KE45pLZ/IQTDS2zi5/GHyY/TZHHaU2jNE3cyYH2aH86vyfrK4S/tNGdaS40Aku0TuXkPwPlaiWXypbHKtb69aUAK+cItk95mlu+fop+vcbLl7M4sUy5PKIbPqzoWcUfbm49pWI74XnozPySCTkZdd66vPmVeFqWdOnV9nDUYILE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611185; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=vbZBG6/p+HYIHnA6JUFYr41EnuLF4cyFkDoUUxgDG/o=; b=n1+LOBEbGkF7dAPpoDGyaQemoDFQLFS2QOsg8lXIdaPM3TMPEs0cFXpi7DHxS8SKjDrv1/XkO8e8h2Sx5DBUCS6G2vb6+imEe9lp5UL2kc7jeAY3YKqr+GOoOIZEKg9NUl/8rlkWYcdl7nwV9ZlZbPIbuOOX9KsbgVH3jvbWbL8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611184978759.770463410284; Fri, 30 May 2025 06:19:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000958.1381216 (Exim 4.92) (envelope-from ) id 1uKzdu-0004Sx-3p; Fri, 30 May 2025 13:19:26 +0000 Received: by outflank-mailman (output) from mailman id 1000958.1381216; Fri, 30 May 2025 13:19:26 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdu-0004Sk-0k; Fri, 30 May 2025 13:19:26 +0000 Received: by outflank-mailman (input) for mailman id 1000958; Fri, 30 May 2025 13:19:25 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdt-0003ZU-2W for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:25 +0000 Received: from 7.mo583.mail-out.ovh.net (7.mo583.mail-out.ovh.net [178.32.124.100]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id a7afecb9-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:19:03 +0200 (CEST) Received: from director4.ghost.mail-out.ovh.net (unknown [10.109.140.215]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4b83jL3gKkz1kgt for ; Fri, 30 May 2025 13:19:02 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-hvgnt (unknown [10.111.174.63]) by director4.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 8B287C571F; Fri, 30 May 2025 13:19:01 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.102]) by ghost-submission-5b5ff79f4f-hvgnt with ESMTPSA id KNMyDUWwOWi4BgAANXmUfQ (envelope-from ); Fri, 30 May 2025 13:19:01 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a7afecb9-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-102R0041e3c7755-c10f-46ce-aaa4-685e3d70a9d1, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 11/22] x86/tpm.c: support extending PCRs of TPM2.0 Date: Fri, 30 May 2025 16:17:53 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12701839800321160348 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepvdfhhedukefhveeifefffedvfeejgeegkeeuhfegheejhefgieeikeejleeihfffnecuffhomhgrihhnpehuphgurghtvggptgdruggrthgrpdhfihhnihhshhgptgdruggrthgrnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrddutddvnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekfegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=vbZBG6/p+HYIHnA6JUFYr41EnuLF4cyFkDoUUxgDG/o=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611142; v=1; b=WffUb+f30ijaMQ62rKcvtD+Dk7yHxQDQsJuWrkyXV53kLPoCi4qPkRTzG24TXakjvoGEtC5Y 1+ud9PwQsPkczhAcrkJ7lN4SH6RWwnTlD5Y3M+lXSTjo51sRAU2wswbl8pAIXquXkqMWjE5qpm0 3gza46lK3AObNHXNReSmKdrC8WA/9GKjZVts3VYScuSHWzA+4CYcPUvf5B+xGrumuhzenlbXlnH qlZ/2nYJXoFN5HboGIK3/cDtv1+hiHHmiIXd9fCcsw+zHY9c1u/Q3Tj2TfV0kK/L+2rohhGr4Vm yRl11Bulo6we2us6yVoFiOFs3tpx6oqHr7lCpI4vMo3NQ== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611186234116600 Content-Type: text/plain; charset="utf-8" SHA1 and SHA256 are hard-coded here, but their support by the TPM is checked. Addition of event log for TPM2.0 will generalize the code further. Signed-off-by: Sergii Dmytruk --- xen/arch/x86/tpm.c | 464 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 452 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/tpm.c b/xen/arch/x86/tpm.c index 7fb19ce4fa..ed49fe3ccf 100644 --- a/xen/arch/x86/tpm.c +++ b/xen/arch/x86/tpm.c @@ -5,6 +5,7 @@ */ =20 #include +#include #include #include #include @@ -31,6 +32,15 @@ struct slr_table *slaunch_get_slrt(void) * other part of Xen. Providing implementation of builtin functions in th= is * case is necessary if compiler chooses to not use an inline builtin. */ +void *(memset)(void *s, int c, size_t n) +{ + uint8_t *d =3D s; + + while ( n-- ) + *d++ =3D c; + + return s; +} void *(memcpy)(void *dest, const void *src, size_t n) { const uint8_t *s =3D src; @@ -146,14 +156,15 @@ static inline bool is_tpm12(void) (tis_read32(TPM_STS_(0)) & TPM_FAMILY_MASK) =3D=3D 0); } =20 -/****************************** TPM1.2 specific **************************= *****/ -#define TPM_ORD_Extend 0x00000014 -#define TPM_ORD_SHA1Start 0x000000A0 -#define TPM_ORD_SHA1Update 0x000000A1 -#define TPM_ORD_SHA1CompleteExtend 0x000000A3 +/****************************** TPM1.2 & TPM2.0 **************************= *****/ =20 -#define TPM_TAG_RQU_COMMAND 0x00C1 -#define TPM_TAG_RSP_COMMAND 0x00C4 +/* + * TPM1.2 is required to support commands of up to 1101 bytes, vendors rar= ely + * go above that. Limit maximum size of block of data to be hashed to 1024. + * + * TPM2.0 should support hashing of at least 1024 bytes. + */ +#define MAX_HASH_BLOCK 1024 =20 /* All fields of following structs are big endian. */ struct tpm_cmd_hdr { @@ -168,6 +179,17 @@ struct tpm_rsp_hdr { uint32_t returnCode; } __packed; =20 +/****************************** TPM1.2 specific **************************= *****/ + +#define TPM_ORD_Extend 0x00000014 +#define TPM_ORD_SHA1Start 0x000000A0 +#define TPM_ORD_SHA1Update 0x000000A1 +#define TPM_ORD_SHA1CompleteExtend 0x000000A3 + +#define TPM_TAG_RQU_COMMAND 0x00C1 +#define TPM_TAG_RSP_COMMAND 0x00C4 + +/* All fields of following structs are big endian. */ struct extend_cmd { struct tpm_cmd_hdr h; uint32_t pcrNum; @@ -233,11 +255,6 @@ struct txt_ev_log_container_12 { }; =20 #ifdef __EARLY_SLAUNCH__ -/* - * TPM1.2 is required to support commands of up to 1101 bytes, vendors rar= ely - * go above that. Limit maximum size of block of data to be hashed to 1024. - */ -#define MAX_HASH_BLOCK 1024 #define CMD_RSP_BUF_SIZE (sizeof(struct sha1_update_cmd) + MAX_HASH_BLO= CK) =20 union cmd_rsp { @@ -393,6 +410,400 @@ static void *create_log_event12(struct txt_ev_log_con= tainer_12 *evt_log, =20 /************************** end of TPM1.2 specific ***********************= *****/ =20 +/****************************** TPM2.0 specific **************************= *****/ + +/* + * These constants are for TPM2.0 but don't have a distinct prefix to match + * names in the specification. + */ + +#define TPM_HT_PCR 0x00 + +#define TPM_RH_NULL 0x40000007 +#define TPM_RS_PW 0x40000009 + +#define HR_SHIFT 24 +#define HR_PCR (TPM_HT_PCR << HR_SHIFT) + +#define TPM_ST_NO_SESSIONS 0x8001 +#define TPM_ST_SESSIONS 0x8002 + +#define TPM_ALG_SHA1 0x0004 +#define TPM_ALG_SHA256 0x000b +#define TPM_ALG_NULL 0x0010 + +#define TPM2_PCR_Extend 0x00000182 +#define TPM2_PCR_HashSequenceStart 0x00000186 +#define TPM2_PCR_SequenceUpdate 0x0000015C +#define TPM2_PCR_EventSequenceComplete 0x00000185 + +#define PUT_BYTES(p, bytes, size) do { \ + memcpy((p), (bytes), (size)); \ + (p) +=3D (size); \ + } while ( 0 ) + +#define PUT_16BIT(p, data) do { \ + *(uint16_t *)(p) =3D swap16(data); \ + (p) +=3D 2; \ + } while ( 0 ) + +/* All fields of following structs are big endian. */ +struct tpm2_session_header { + uint32_t handle; + uint16_t nonceSize; + uint8_t nonce[0]; + uint8_t attrs; + uint16_t hmacSize; + uint8_t hmac[0]; +} __packed; + +struct tpm2_extend_cmd { + struct tpm_cmd_hdr h; + uint32_t pcrHandle; + uint32_t sessionHdrSize; + struct tpm2_session_header pcrSession; + uint32_t hashCount; + uint8_t hashes[0]; +} __packed; + +struct tpm2_extend_rsp { + struct tpm_rsp_hdr h; +} __packed; + +struct tpm2_sequence_start_cmd { + struct tpm_cmd_hdr h; + uint16_t hmacSize; + uint8_t hmac[0]; + uint16_t hashAlg; +} __packed; + +struct tpm2_sequence_start_rsp { + struct tpm_rsp_hdr h; + uint32_t sequenceHandle; +} __packed; + +struct tpm2_sequence_update_cmd { + struct tpm_cmd_hdr h; + uint32_t sequenceHandle; + uint32_t sessionHdrSize; + struct tpm2_session_header session; + uint16_t dataSize; + uint8_t data[0]; +} __packed; + +struct tpm2_sequence_update_rsp { + struct tpm_rsp_hdr h; +} __packed; + +struct tpm2_sequence_complete_cmd { + struct tpm_cmd_hdr h; + uint32_t pcrHandle; + uint32_t sequenceHandle; + uint32_t sessionHdrSize; + struct tpm2_session_header pcrSession; + struct tpm2_session_header sequenceSession; + uint16_t dataSize; + uint8_t data[0]; +} __packed; + +struct tpm2_sequence_complete_rsp { + struct tpm_rsp_hdr h; + uint32_t paramSize; + uint32_t hashCount; + uint8_t hashes[0]; + /* + * Each hash is represented as: + * struct { + * uint16_t hashAlg; + * uint8_t hash[size of hashAlg]; + * }; + */ +} __packed; + +/* + * These two structure are for convenience, they don't correspond to anyth= ing in + * any spec. + */ +struct tpm2_log_hash { + uint16_t alg; /* TPM_ALG_* */ + uint16_t size; + uint8_t *data; /* Non-owning reference to a buffer inside log entry. */ +}; +/* Should be more than enough for now and awhile in the future. */ +#define MAX_HASH_COUNT 8 +struct tpm2_log_hashes { + uint32_t count; + struct tpm2_log_hash hashes[MAX_HASH_COUNT]; +}; + +#ifdef __EARLY_SLAUNCH__ + +union tpm2_cmd_rsp { + uint8_t b[sizeof(struct tpm2_sequence_update_cmd) + MAX_HASH_BLOCK]; + struct tpm_cmd_hdr c; + struct tpm_rsp_hdr r; + struct tpm2_sequence_start_cmd start_c; + struct tpm2_sequence_start_rsp start_r; + struct tpm2_sequence_update_cmd update_c; + struct tpm2_sequence_update_rsp update_r; + struct tpm2_sequence_complete_cmd finish_c; + struct tpm2_sequence_complete_rsp finish_r; +}; + +static uint32_t tpm2_hash_extend(unsigned loc, const uint8_t *buf, + unsigned size, unsigned pcr, + struct tpm2_log_hashes *log_hashes) +{ + uint32_t seq_handle; + unsigned max_bytes =3D MAX_HASH_BLOCK; + + union tpm2_cmd_rsp cmd_rsp; + unsigned o_size; + unsigned i; + uint8_t *p; + uint32_t rc; + + cmd_rsp.start_c =3D (struct tpm2_sequence_start_cmd) { + .h.tag =3D swap16(TPM_ST_NO_SESSIONS), + .h.paramSize =3D swap32(sizeof(cmd_rsp.start_c)), + .h.ordinal =3D swap32(TPM2_PCR_HashSequenceStart), + .hashAlg =3D swap16(TPM_ALG_NULL), /* Compute all supported hashes= . */ + }; + + request_locality(loc); + + o_size =3D sizeof(cmd_rsp); + send_cmd(loc, cmd_rsp.b, swap32(cmd_rsp.c.paramSize), &o_size); + + if ( cmd_rsp.r.tag =3D=3D swap16(TPM_ST_NO_SESSIONS) && + cmd_rsp.r.paramSize =3D=3D swap32(10) ) + { + rc =3D swap32(cmd_rsp.r.returnCode); + if ( rc !=3D 0 ) + goto error; + } + + seq_handle =3D swap32(cmd_rsp.start_r.sequenceHandle); + + while ( size > 64 ) + { + if ( size < max_bytes ) + max_bytes =3D size & ~(64 - 1); + + cmd_rsp.update_c =3D (struct tpm2_sequence_update_cmd) { + .h.tag =3D swap16(TPM_ST_SESSIONS), + .h.paramSize =3D swap32(sizeof(cmd_rsp.update_c) + max_bytes), + .h.ordinal =3D swap32(TPM2_PCR_SequenceUpdate), + .sequenceHandle =3D swap32(seq_handle), + .sessionHdrSize =3D swap32(sizeof(struct tpm2_session_header)), + .session.handle =3D swap32(TPM_RS_PW), + .dataSize =3D swap16(max_bytes), + }; + + memcpy(cmd_rsp.update_c.data, buf, max_bytes); + + o_size =3D sizeof(cmd_rsp); + send_cmd(loc, cmd_rsp.b, swap32(cmd_rsp.c.paramSize), &o_size); + + if ( cmd_rsp.r.tag =3D=3D swap16(TPM_ST_NO_SESSIONS) && + cmd_rsp.r.paramSize =3D=3D swap32(10) ) + { + rc =3D swap32(cmd_rsp.r.returnCode); + if ( rc !=3D 0 ) + goto error; + } + + size -=3D max_bytes; + buf +=3D max_bytes; + } + + cmd_rsp.finish_c =3D (struct tpm2_sequence_complete_cmd) { + .h.tag =3D swap16(TPM_ST_SESSIONS), + .h.paramSize =3D swap32(sizeof(cmd_rsp.finish_c) + size), + .h.ordinal =3D swap32(TPM2_PCR_EventSequenceComplete), + .pcrHandle =3D swap32(HR_PCR + pcr), + .sequenceHandle =3D swap32(seq_handle), + .sessionHdrSize =3D swap32(sizeof(struct tpm2_session_header)*2), + .pcrSession.handle =3D swap32(TPM_RS_PW), + .sequenceSession.handle =3D swap32(TPM_RS_PW), + .dataSize =3D swap16(size), + }; + + memcpy(cmd_rsp.finish_c.data, buf, size); + + o_size =3D sizeof(cmd_rsp); + send_cmd(loc, cmd_rsp.b, swap32(cmd_rsp.c.paramSize), &o_size); + + if ( cmd_rsp.r.tag =3D=3D swap16(TPM_ST_NO_SESSIONS) && + cmd_rsp.r.paramSize =3D=3D swap32(10) ) + { + rc =3D swap32(cmd_rsp.r.returnCode); + if ( rc !=3D 0 ) + goto error; + } + + p =3D cmd_rsp.finish_r.hashes; + for ( i =3D 0; i < swap32(cmd_rsp.finish_r.hashCount); ++i ) + { + unsigned j; + uint16_t hash_type; + + hash_type =3D swap16(*(uint16_t *)p); + p +=3D sizeof(uint16_t); + + for ( j =3D 0; j < log_hashes->count; ++j ) + { + struct tpm2_log_hash *hash =3D &log_hashes->hashes[j]; + if ( hash->alg =3D=3D hash_type ) + { + memcpy(hash->data, p, hash->size); + p +=3D hash->size; + break; + } + } + + if ( j =3D=3D log_hashes->count ) + /* Can't continue parsing without knowing hash size. */ + break; + } + + rc =3D 0; + +error: + relinquish_locality(loc); + return rc; +} + +#else + +union tpm2_cmd_rsp { + /* Enough space for multiple hashes. */ + uint8_t b[sizeof(struct tpm2_extend_cmd) + 1024]; + struct tpm_cmd_hdr c; + struct tpm_rsp_hdr r; + struct tpm2_extend_cmd extend_c; + struct tpm2_extend_rsp extend_r; +}; + +static uint32_t tpm20_pcr_extend(unsigned loc, uint32_t pcr_handle, + const struct tpm2_log_hashes *log_hashes) +{ + union tpm2_cmd_rsp cmd_rsp; + unsigned o_size; + unsigned i; + uint8_t *p; + + cmd_rsp.extend_c =3D (struct tpm2_extend_cmd) { + .h.tag =3D swap16(TPM_ST_SESSIONS), + .h.ordinal =3D swap32(TPM2_PCR_Extend), + .pcrHandle =3D swap32(pcr_handle), + .sessionHdrSize =3D swap32(sizeof(struct tpm2_session_header)), + .pcrSession.handle =3D swap32(TPM_RS_PW), + .hashCount =3D swap32(log_hashes->count), + }; + + p =3D cmd_rsp.extend_c.hashes; + for ( i =3D 0; i < log_hashes->count; ++i ) + { + const struct tpm2_log_hash *hash =3D &log_hashes->hashes[i]; + + if ( p + sizeof(uint16_t) + hash->size > &cmd_rsp.b[sizeof(cmd_rsp= )] ) + { + printk(XENLOG_ERR "Hit TPM message size implementation limit: = %ld\n", + sizeof(cmd_rsp)); + return -1; + } + + *(uint16_t *)p =3D swap16(hash->alg); + p +=3D sizeof(uint16_t); + + memcpy(p, hash->data, hash->size); + p +=3D hash->size; + } + + /* Fill in command size (size of the whole buffer). */ + cmd_rsp.extend_c.h.paramSize =3D swap32(sizeof(cmd_rsp.extend_c) + + (p - cmd_rsp.extend_c.hashes)), + + o_size =3D sizeof(cmd_rsp); + send_cmd(loc, cmd_rsp.b, swap32(cmd_rsp.c.paramSize), &o_size); + + return swap32(cmd_rsp.r.returnCode); +} + +static bool tpm_supports_hash(unsigned loc, const struct tpm2_log_hash *ha= sh) +{ + uint32_t rc; + struct tpm2_log_hashes hashes =3D { + .count =3D 1, + .hashes[0] =3D *hash, + }; + + /* + * This is a valid way of checking hash support, using it to not imple= ment + * TPM2_GetCapability(). + */ + rc =3D tpm20_pcr_extend(loc, /*pcr_handle=3D*/TPM_RH_NULL, &hashes); + + return rc =3D=3D 0; +} + +static uint32_t tpm2_hash_extend(unsigned loc, const uint8_t *buf, + unsigned size, unsigned pcr, + const struct tpm2_log_hashes *log_hashes) +{ + uint32_t rc; + unsigned i; + struct tpm2_log_hashes supported_hashes =3D {0}; + + request_locality(loc); + + for ( i =3D 0; i < log_hashes->count; ++i ) + { + const struct tpm2_log_hash *hash =3D &log_hashes->hashes[i]; + if ( !tpm_supports_hash(loc, hash) ) + { + printk(XENLOG_WARNING "Skipped hash unsupported by TPM: %d\n", + hash->alg); + continue; + } + + if ( hash->alg =3D=3D TPM_ALG_SHA1 ) + { + sha1_hash(hash->data, buf, size); + } + else if ( hash->alg =3D=3D TPM_ALG_SHA256 ) + { + sha2_256_digest(hash->data, buf, size); + } + else + { + /* This is called "OneDigest" in TXT Software Development Guid= e. */ + memset(hash->data, 0, size); + hash->data[0] =3D 1; + } + + if ( supported_hashes.count =3D=3D MAX_HASH_COUNT ) + { + printk(XENLOG_ERR "Hit hash count implementation limit: %d\n", + MAX_HASH_COUNT); + return -1; + } + + supported_hashes.hashes[supported_hashes.count] =3D *hash; + ++supported_hashes.count; + } + + rc =3D tpm20_pcr_extend(loc, HR_PCR + pcr, &supported_hashes); + relinquish_locality(loc); + + return rc; +} + +#endif /* __EARLY_SLAUNCH__ */ + +/************************** end of TPM2.0 specific ***********************= *****/ + void tpm_hash_extend(unsigned loc, unsigned pcr, const uint8_t *buf, unsigned size, uint32_t type, const uint8_t *log_data, unsigned log_data_size) @@ -419,6 +830,35 @@ void tpm_hash_extend(unsigned loc, unsigned pcr, const= uint8_t *buf, { #ifndef __EARLY_SLAUNCH__ printk(XENLOG_ERR "Extending PCR%u failed\n", pcr); +#endif + } + } else { + uint8_t sha1_digest[SHA1_DIGEST_SIZE]; + uint8_t sha256_digest[SHA2_256_DIGEST_SIZE]; + uint32_t rc; + + struct tpm2_log_hashes log_hashes =3D { + .count =3D 2, + .hashes =3D { + { + .alg =3D TPM_ALG_SHA1, + .size =3D SHA1_DIGEST_SIZE, + .data =3D sha1_digest, + }, + { + .alg =3D TPM_ALG_SHA256, + .size =3D SHA2_256_DIGEST_SIZE, + .data =3D sha256_digest, + }, + }, + }; + + rc =3D tpm2_hash_extend(loc, buf, size, pcr, &log_hashes); + if ( rc !=3D 0 ) + { +#ifndef __EARLY_SLAUNCH__ + printk(XENLOG_ERR "Extending PCR%u failed with TPM error: 0x%0= 8x\n", + pcr, rc); #endif } } --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611266; cv=none; d=zohomail.com; s=zohoarc; b=NzvoTs2XifyfiVjK67JKECzJFOnZo/FhUUJIIv3ua3sNYqahyuNwOqtpON83VPveC52SlIJ0YyF7kutLiyAKqTlZSKRZlk3GFTDyPfjxgHa0OLihSDsI0lo/epobOOhW0DGax5M0F3hngSnzxDwxyBjKR8V5//PxR6E836082rA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611266; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=obSSiy8YAHm2T2PniWDCTzac2MGgksM6oibQ6iXFGMY=; b=lRq7YKHazM3wCRlZuKLhBv8jgje1URczNx8qGPbBI/hFKJnrasio4bDWyq/C7nbbaH52ZkWLFJaWNJRh07S/g4OrDWtpsIhd3rAe684k+Ju/GEwOsp9abw1ALPRAPhCVnGbZMb3+Sn9I+wDxfVMx1TgHNB8bjn6ygbwp8LcPVuQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611266617715.5593313013012; Fri, 30 May 2025 06:21:06 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000982.1381249 (Exim 4.92) (envelope-from ) id 1uKzfH-0007aC-Ct; Fri, 30 May 2025 13:20:51 +0000 Received: by outflank-mailman (output) from mailman id 1000982.1381249; Fri, 30 May 2025 13:20:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzfH-0007YY-7X; Fri, 30 May 2025 13:20:51 +0000 Received: by outflank-mailman (input) for mailman id 1000982; Fri, 30 May 2025 13:20:49 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdc-0008Jy-JQ for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:08 +0000 Received: from 9.mo561.mail-out.ovh.net (9.mo561.mail-out.ovh.net [87.98.184.141]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id a932ea8e-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:19:05 +0200 (CEST) Received: from director5.ghost.mail-out.ovh.net (unknown [10.109.176.180]) by mo561.mail-out.ovh.net (Postfix) with ESMTP id 4b83jP1cy2z1YFn for ; Fri, 30 May 2025 13:19:05 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-sqk4q (unknown [10.110.168.56]) by director5.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 77CA610022F; Fri, 30 May 2025 13:19:04 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.103]) by ghost-submission-5b5ff79f4f-sqk4q with ESMTPSA id nUD9EEiwOWgXJgAAZ+UDpg (envelope-from ); Fri, 30 May 2025 13:19:04 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a932ea8e-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-103G005baab5605-d08e-4e2c-a3be-21458a63de71, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 12/22] x86/hvm: check for VMX in SMX if Slaunch is active Date: Fri, 30 May 2025 16:17:54 +0300 Message-ID: <25de2a5ba43629cca33b96d20c77f19d64096242.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12702684225100625052 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpeegkeffieeitdevkefhudegffevieeggfelgedvgeehffdtteehfeeuleeiudekvdenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddruddtfeenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehiedumgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=obSSiy8YAHm2T2PniWDCTzac2MGgksM6oibQ6iXFGMY=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611145; v=1; b=KnQZv8WLUXETTFEQ2abZsscZIgP0ZcCLoZ2Bli4n4ItYmqdUYAtfwWaFuD8LUXd+noBHCgch ZZnTJEE8g0D8K29rvNOxbSAzyr3kRiv8PID4qEs+3GTNPyAYFM1Pf/nZVli6T9LcrzU8Dwf0Rtg DlUBSumOo/9zXJ8O5w1ZkDLOE37hDXDHwF1I9hjnyJFWKXEKX2p3UHGlnQpKPMENCZauT/vVVvo ipWZ5JZejWAaGhDPRe1wKMSXt6Mh5N4XNaT904xvPmLc7Cz+SATbivuvVoouG/pDWKmyn+jmhG1 muOgvoW7wFNDPiui0pgyw2jDMDUWfcWS6mtJJE8mMYCFw== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611267356116600 From: Micha=C5=82 =C5=BBygowski Check whther IA32_FEATURE_CONTROL has the proper bits enabled to run VMX in SMX when slaunch is active. Signed-off-by: Micha=C5=82 =C5=BBygowski Acked-by: Jan Beulich --- xen/arch/x86/hvm/vmx/vmcs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 57d49364db..835a6be75a 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -724,7 +725,7 @@ static int _vmx_cpu_up(bool bsp) bios_locked =3D !!(eax & IA32_FEATURE_CONTROL_LOCK); if ( bios_locked ) { - if ( !(eax & (tboot_in_measured_env() + if ( !(eax & (tboot_in_measured_env() || slaunch_active ? IA32_FEATURE_CONTROL_ENABLE_VMXON_INSIDE_SMX : IA32_FEATURE_CONTROL_ENABLE_VMXON_OUTSIDE_SMX)) ) { --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611260; cv=none; d=zohomail.com; s=zohoarc; b=RIQKjr2aWErE3aOapfuFiv+s7jWirJtQzDjR79ErL3GWWoB4J23YPmZnm1jsifZlwobXinRRU+UfRqFqthDbu9rG+F1K1w4W1ddteHhTizkp1Mc2k8Eo/MaszorVDWSOQLLUyHDd+s/qa6keAq+yLYc7bXKTZz3UEoEIsfkyrP8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611260; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ixLmPLThAstC9HSOCxNeT4qjU8C58Im4iR2Vxsanw3Y=; b=h2Tn9wjJI11y0Y5X65pwLR0X5xl4X5aEpWfXsnKnijSLv7u6cmlxSc6uf+7aw/zArMVXT3w9l1wQqaOnd5gKZYA9PAind8iyTkJiN5TzjngRANDPHyVqvnxvlfU5SSxkoqNXUMhy99hXQD5oiLar5gs6A9qHH0JlY1E08K3JkkQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611260455127.96922395776392; Fri, 30 May 2025 06:21:00 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000977.1381232 (Exim 4.92) (envelope-from ) id 1uKzfF-00074r-Qn; Fri, 30 May 2025 13:20:49 +0000 Received: by outflank-mailman (output) from mailman id 1000977.1381232; Fri, 30 May 2025 13:20:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzfF-00073z-IF; Fri, 30 May 2025 13:20:49 +0000 Received: by outflank-mailman (input) for mailman id 1000977; Fri, 30 May 2025 13:20:48 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdh-0008Jy-Jl for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:13 +0000 Received: from 3.mo583.mail-out.ovh.net (3.mo583.mail-out.ovh.net [46.105.40.108]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id ab069374-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:19:08 +0200 (CEST) Received: from director4.ghost.mail-out.ovh.net (unknown [10.109.140.215]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4b83jS26Cjz1gpb for ; Fri, 30 May 2025 13:19:08 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-sqj9x (unknown [10.110.113.35]) by director4.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 70D72C5715; Fri, 30 May 2025 13:19:07 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.106]) by ghost-submission-5b5ff79f4f-sqj9x with ESMTPSA id bshXCkuwOWj6JQAAPescrA (envelope-from ); Fri, 30 May 2025 13:19:07 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: ab069374-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-106R006d10a0eb1-598f-4895-b746-f3445aee3969, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 13/22] x86/tpm.c: implement event log for TPM2.0 Date: Fri, 30 May 2025 16:17:55 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12703528653124908188 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrddutdeinecuvehluhhsthgvrhfuihiivgepvdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekfegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=ixLmPLThAstC9HSOCxNeT4qjU8C58Im4iR2Vxsanw3Y=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611148; v=1; b=EPtTXt3tCy4mxfiCGuAMAj/aTQ5IkWPMwhIJJPJEuc+aoZA25rC0B9UjsKHZ4H5FAr4M+Z30 ufBRDnzwI781Wrnxfq6RhusSEsHWNUbaTH70b2RCXYfFs29V4RGtsNYOoHDwrx0olgZvBWaK8EE oP5lwrUTA3HnNPlpso5LN40kYO+aZH44Ess7BAtssJ1zCtVF6d3hZMpARDQePM48Lqx4uNeOAdx welO+/pnPQGkZmhUvj9s5JjmOnebt3WqpFF8g+/mOfpKwzYDOMpJWJCa3gnhI7orSNogV9SGOXY p6mECGTHhS5Uuxodpg9XTa3xm0sGFjOmyenoPYz9oSMAQ== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611261397116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Sergii Dmytruk --- xen/arch/x86/include/asm/intel-txt.h | 33 ++++++ xen/arch/x86/tpm.c | 169 ++++++++++++++++++++++----- 2 files changed, 175 insertions(+), 27 deletions(-) diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index 0b0bdc1bb2..de7f23d4ff 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -215,6 +215,39 @@ struct txt_sinit_mle_data { /* Ext Data Elements */ } __packed; =20 +/* Types of extended data. */ +#define TXT_HEAP_EXTDATA_TYPE_END 0 +#define TXT_HEAP_EXTDATA_TYPE_BIOS_SPEC_VER 1 +#define TXT_HEAP_EXTDATA_TYPE_ACM 2 +#define TXT_HEAP_EXTDATA_TYPE_STM 3 +#define TXT_HEAP_EXTDATA_TYPE_CUSTOM 4 +#define TXT_HEAP_EXTDATA_TYPE_MADT 6 +#define TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1 8 +#define TXT_HEAP_EXTDATA_TYPE_MCFG 9 +#define TXT_HEAP_EXTDATA_TYPE_TPR_REQ 13 +#define TXT_HEAP_EXTDATA_TYPE_DTPR 14 +#define TXT_HEAP_EXTDATA_TYPE_CEDT 15 + +/* + * Self-describing data structure that is used for extensions to TXT heap + * tables. + */ +struct txt_ext_data_element { + uint32_t type; /* One of TXT_HEAP_EXTDATA_TYPE_*. */ + uint32_t size; + uint8_t data[0]; /* size bytes. */ +} __packed; + +/* + * Extended data describing TPM 2.0 log. + */ +struct heap_event_log_pointer_element2_1 { + uint64_t physical_address; + uint32_t allocated_event_container_size; + uint32_t first_record_offset; + uint32_t next_record_offset; +} __packed; + /* * Functions to extract data from the Intel TXT Heap Memory. * diff --git a/xen/arch/x86/tpm.c b/xen/arch/x86/tpm.c index ed49fe3ccf..3c145fd3cc 100644 --- a/xen/arch/x86/tpm.c +++ b/xen/arch/x86/tpm.c @@ -536,6 +536,44 @@ struct tpm2_log_hashes { struct tpm2_log_hash hashes[MAX_HASH_COUNT]; }; =20 +struct tpm2_pcr_event_header { + uint32_t pcrIndex; + uint32_t eventType; + uint32_t digestCount; + uint8_t digests[0]; + /* + * Each hash is represented as: + * struct { + * uint16_t hashAlg; + * uint8_t hash[size of hashAlg]; + * }; + */ + /* uint32_t eventSize; */ + /* uint8_t event[0]; */ +} __packed; + +struct tpm2_digest_sizes { + uint16_t algId; + uint16_t digestSize; +} __packed; + +struct tpm2_spec_id_event { + uint32_t pcrIndex; + uint32_t eventType; + uint8_t digest[20]; + uint32_t eventSize; + uint8_t signature[16]; + uint32_t platformClass; + uint8_t specVersionMinor; + uint8_t specVersionMajor; + uint8_t specErrata; + uint8_t uintnSize; + uint32_t digestCount; + struct tpm2_digest_sizes digestSizes[0]; /* variable number of members= */ + /* uint8_t vendorInfoSize; */ + /* uint8_t vendorInfo[vendorInfoSize]; */ +} __packed; + #ifdef __EARLY_SLAUNCH__ =20 union tpm2_cmd_rsp { @@ -769,19 +807,11 @@ static uint32_t tpm2_hash_extend(unsigned loc, const = uint8_t *buf, } =20 if ( hash->alg =3D=3D TPM_ALG_SHA1 ) - { sha1_hash(hash->data, buf, size); - } else if ( hash->alg =3D=3D TPM_ALG_SHA256 ) - { sha2_256_digest(hash->data, buf, size); - } else - { - /* This is called "OneDigest" in TXT Software Development Guid= e. */ - memset(hash->data, 0, size); - hash->data[0] =3D 1; - } + /* create_log_event20() took care of initializing the digest. = */; =20 if ( supported_hashes.count =3D=3D MAX_HASH_COUNT ) { @@ -802,6 +832,102 @@ static uint32_t tpm2_hash_extend(unsigned loc, const = uint8_t *buf, =20 #endif /* __EARLY_SLAUNCH__ */ =20 +static struct heap_event_log_pointer_element2_1 *find_evt_log_ext_data(voi= d) +{ + struct txt_os_sinit_data *os_sinit; + struct txt_ext_data_element *ext_data; + + os_sinit =3D txt_os_sinit_data_start(__va(txt_read(TXTCR_HEAP_BASE))); + ext_data =3D (void *)((uint8_t *)os_sinit + sizeof(*os_sinit)); + + /* + * Find TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER2_1 which is necessary = to + * know where to put the next entry. + */ + while ( ext_data->type !=3D TXT_HEAP_EXTDATA_TYPE_END ) + { + if ( ext_data->type =3D=3D TXT_HEAP_EXTDATA_TYPE_EVENT_LOG_POINTER= 2_1 ) + break; + ext_data =3D (void *)&ext_data->data[ext_data->size]; + } + + if ( ext_data->type =3D=3D TXT_HEAP_EXTDATA_TYPE_END ) + return NULL; + + return (void *)&ext_data->data[0]; +} + +static struct tpm2_log_hashes +create_log_event20(struct tpm2_spec_id_event *evt_log, uint32_t evt_log_si= ze, + uint32_t pcr, uint32_t type, const uint8_t *data, + unsigned data_size) +{ + struct tpm2_log_hashes log_hashes =3D {0}; + + struct heap_event_log_pointer_element2_1 *log_ext_data; + struct tpm2_pcr_event_header *new_entry; + uint32_t entry_size; + unsigned i; + uint8_t *p; + + log_ext_data =3D find_evt_log_ext_data(); + if ( log_ext_data =3D=3D NULL ) + return log_hashes; + + entry_size =3D sizeof(*new_entry); + for ( i =3D 0; i < evt_log->digestCount; ++i ) + { + entry_size +=3D sizeof(uint16_t); /* hash type */ + entry_size +=3D evt_log->digestSizes[i].digestSize; + } + entry_size +=3D sizeof(uint32_t); /* data size field */ + entry_size +=3D data_size; + + /* + * Check if there is enough space left for new entry. + * Note: it is possible to introduce a gap in event log if entry with = big + * data_size is followed by another entry with smaller data. Maybe we = should + * cap the event log size in such case? + */ + if ( log_ext_data->next_record_offset + entry_size > evt_log_size ) + return log_hashes; + + new_entry =3D (void *)((uint8_t *)evt_log + log_ext_data->next_record_= offset); + log_ext_data->next_record_offset +=3D entry_size; + + new_entry->pcrIndex =3D pcr; + new_entry->eventType =3D type; + new_entry->digestCount =3D evt_log->digestCount; + + p =3D &new_entry->digests[0]; + for ( i =3D 0; i < evt_log->digestCount; ++i ) + { + uint16_t alg =3D evt_log->digestSizes[i].algId; + uint16_t size =3D evt_log->digestSizes[i].digestSize; + + *(uint16_t *)p =3D alg; + p +=3D sizeof(uint16_t); + + log_hashes.hashes[i].alg =3D alg; + log_hashes.hashes[i].size =3D size; + log_hashes.hashes[i].data =3D p; + p +=3D size; + + /* This is called "OneDigest" in TXT Software Development Guide. */ + memset(log_hashes.hashes[i].data, 0, size); + log_hashes.hashes[i].data[0] =3D 1; + } + log_hashes.count =3D evt_log->digestCount; + + *(uint32_t *)p =3D data_size; + p +=3D sizeof(uint32_t); + + if ( data && data_size > 0 ) + memcpy(p, data, data_size); + + return log_hashes; +} + /************************** end of TPM2.0 specific ***********************= *****/ =20 void tpm_hash_extend(unsigned loc, unsigned pcr, const uint8_t *buf, @@ -832,26 +958,15 @@ void tpm_hash_extend(unsigned loc, unsigned pcr, cons= t uint8_t *buf, printk(XENLOG_ERR "Extending PCR%u failed\n", pcr); #endif } - } else { - uint8_t sha1_digest[SHA1_DIGEST_SIZE]; - uint8_t sha256_digest[SHA2_256_DIGEST_SIZE]; + } + else + { uint32_t rc; =20 - struct tpm2_log_hashes log_hashes =3D { - .count =3D 2, - .hashes =3D { - { - .alg =3D TPM_ALG_SHA1, - .size =3D SHA1_DIGEST_SIZE, - .data =3D sha1_digest, - }, - { - .alg =3D TPM_ALG_SHA256, - .size =3D SHA2_256_DIGEST_SIZE, - .data =3D sha256_digest, - }, - }, - }; + struct tpm2_spec_id_event *evt_log =3D evt_log_addr; + struct tpm2_log_hashes log_hashes =3D + create_log_event20(evt_log, evt_log_size, pcr, type, log_data, + log_data_size); =20 rc =3D tpm2_hash_extend(loc, buf, size, pcr, &log_hashes); if ( rc !=3D 0 ) --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611176; cv=none; d=zohomail.com; s=zohoarc; b=FsvEmp+4SXWajb3c7ynwkgHLsGKsLfLy5I3eKwwYaloR19X3EcF8zxlitlNjhgyyuBE39kgUPS8Iss7QtVwcVqf84EDbL0HcEMbaHshmirXcNSprNJgLwmJzhuVTkH1fxoOlAQyT+BdKyPuITIMrHt5zJ/ANUiN+p2kStX/KDxo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611176; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ez/L2d75KfUHpHUpt0ebohb99nk9msXfBgDhtfciYEI=; b=ZoX8l6vOIueoJ0jiLjfs7LBug5+VVml/k1njm+zY3kGyBddvYtGMWndvf/DWQVVItNTzNOS1pKTv4wNINsp+N0SLgiZuIeHh9JBWglpeCc1DvnJnWH5N7+ZZhw3s5Kl62jQbtlp9fTEyfYie2fq4lIdXehd0/Rvw810rO89MTkw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611176948700.8943297124482; Fri, 30 May 2025 06:19:36 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000952.1381196 (Exim 4.92) (envelope-from ) id 1uKzdp-0003sX-HG; Fri, 30 May 2025 13:19:21 +0000 Received: by outflank-mailman (output) from mailman id 1000952.1381196; Fri, 30 May 2025 13:19:21 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdp-0003sM-EF; Fri, 30 May 2025 13:19:21 +0000 Received: by outflank-mailman (input) for mailman id 1000952; Fri, 30 May 2025 13:19:20 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdo-0003ZU-28 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:20 +0000 Received: from 2.mo582.mail-out.ovh.net (2.mo582.mail-out.ovh.net [46.105.76.65]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id acbbac5f-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:19:11 +0200 (CEST) Received: from director8.ghost.mail-out.ovh.net (unknown [10.109.176.180]) by mo582.mail-out.ovh.net (Postfix) with ESMTP id 4b83jW1B83z1YBR for ; Fri, 30 May 2025 13:19:11 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-sqt8x (unknown [10.108.42.198]) by director8.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 7555FC0286; Fri, 30 May 2025 13:19:10 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.110]) by ghost-submission-5b5ff79f4f-sqt8x with ESMTPSA id +3vSCk6wOWjKxgAAsdTabg (envelope-from ); Fri, 30 May 2025 13:19:10 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: acbbac5f-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-110S004aa21ae74-13c6-44dd-aa83-995d3ec55e96, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 14/22] x86/boot: choose AP stack based on APIC ID Date: Fri, 30 May 2025 16:17:56 +0300 Message-ID: <16a5438f73a026d4db1a5340f599d4839c74fcc6.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12704373077045261468 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepveelieehudellefgleegieevteegudfhhefffefghfeltdevhfelvdfgkeefhfeunecuffhomhgrihhnpehhvggrugdrshgspdhtrhgrmhhpohhlihhnvgdrshgspdigkeeipgeigedrshgsnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduuddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekvdgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=ez/L2d75KfUHpHUpt0ebohb99nk9msXfBgDhtfciYEI=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611151; v=1; b=fi1gQgNbRQp0Yg5FRfZNGxUVBwnr6X0Ko8aZAbamWXVf53GH80iAa1FSdeDs3hGeZZtA2Xqf AKTBKxOEnQ+BppxveurAbKecRBTlhfAwskWw5MKwiwx1lKfBmVVu7jL8dvKB0kBpxes1TlhwMHw BTN4lfsJO+/8z28AfZguSZX7FYNKKvzOWmzgojHVDsKCcP3e1IpgzckxYR2vE6lnb1Fjg++XMTh /XZHFlekMFJxskCLj2QlHAt63YEV56osLIQoWRXDBFsKI2hIF+SEhFtuN0Egyws0ylrBeP6D0IX VwGJb2KBdWChpiDnooCKYFV4vO1UeuXMZppTKlFFo4NFQ== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611178439116600 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel This is made as the first step of making parallel AP bring-up possible. It should be enough for pre-C code. Parallel AP bring-up is necessary because TXT by design releases all APs at once. In addition to that it reduces number of IPIs (and more importantly, delays between them) required to start all logical processors. This results in significant reduction of boot time, even when DRTM is not used, with performance gain growing with the number of logical CPUs. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/boot/head.S | 1 + xen/arch/x86/boot/trampoline.S | 21 +++++++++++++++++++++ xen/arch/x86/boot/x86_64.S | 28 +++++++++++++++++++++++++++- xen/arch/x86/include/asm/apicdef.h | 4 ++++ xen/arch/x86/include/asm/msr-index.h | 3 +++ xen/arch/x86/setup.c | 7 +++++++ 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 9a272155e9..7376fa85d5 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -8,6 +8,7 @@ #include #include #include +#include #include #include =20 diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index a92e399fbe..ed593acc46 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -71,6 +71,27 @@ trampoline_protmode_entry: mov $X86_CR4_PAE,%ecx mov %ecx,%cr4 =20 + /* + * Get APIC ID while we're in non-paged mode. Start by checking if + * x2APIC is enabled. + */ + mov $MSR_APIC_BASE, %ecx + rdmsr + test $APIC_BASE_EXTD, %eax + jnz .Lx2apic + + /* Not x2APIC, read from MMIO */ + and $APIC_BASE_ADDR_MASK, %eax + mov APIC_ID(%eax), %esp + shr $24, %esp + jmp 1f + +.Lx2apic: + mov $(MSR_X2APIC_FIRST + (APIC_ID >> MSR_X2APIC_SHIFT)), %ecx + rdmsr + mov %eax, %esp +1: + /* Load pagetable base register. */ mov $sym_offs(idle_pg_table),%eax add bootsym_rel(trampoline_xen_phys_start,4,%eax) diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 08ae97e261..ac33576d8f 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -15,7 +15,33 @@ ENTRY(__high_start) mov $XEN_MINIMAL_CR4,%rcx mov %rcx,%cr4 =20 - mov stack_start(%rip),%rsp + test %ebx,%ebx + cmovz stack_start(%rip), %rsp + jz .L_stack_set + + /* APs only: get stack base from APIC ID saved in %esp. */ + mov $-1, %rax + lea x86_cpu_to_apicid(%rip), %rcx +1: + add $1, %rax + cmp $NR_CPUS, %eax + jb 2f + hlt +2: + cmp %esp, (%rcx, %rax, 4) + jne 1b + + /* %eax is now Xen CPU index. */ + lea stack_base(%rip), %rcx + mov (%rcx, %rax, 8), %rsp + + test %rsp,%rsp + jnz 1f + hlt +1: + add $(STACK_SIZE - CPUINFO_sizeof), %rsp + +.L_stack_set: =20 /* Reset EFLAGS (subsumes CLI and CLD). */ pushq $0 diff --git a/xen/arch/x86/include/asm/apicdef.h b/xen/arch/x86/include/asm/= apicdef.h index 63dab01dde..e093a2aa3c 100644 --- a/xen/arch/x86/include/asm/apicdef.h +++ b/xen/arch/x86/include/asm/apicdef.h @@ -121,6 +121,10 @@ =20 #define MAX_IO_APICS 128 =20 +#ifndef __ASSEMBLY__ + extern bool x2apic_enabled; =20 +#endif /* !__ASSEMBLY__ */ + #endif diff --git a/xen/arch/x86/include/asm/msr-index.h b/xen/arch/x86/include/as= m/msr-index.h index 6f2c3147e3..73be38da17 100644 --- a/xen/arch/x86/include/asm/msr-index.h +++ b/xen/arch/x86/include/asm/msr-index.h @@ -172,6 +172,9 @@ #define MSR_X2APIC_FIRST 0x00000800 #define MSR_X2APIC_LAST 0x000008ff =20 +/* MSR offset can be obtained by shifting MMIO offset this number of bits = to the right. */ +#define MSR_X2APIC_SHIFT 4 + #define MSR_X2APIC_TPR 0x00000808 #define MSR_X2APIC_PPR 0x0000080a #define MSR_X2APIC_EOI 0x0000080b diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index e4638acd12..87e4693a11 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -2097,6 +2097,7 @@ void asmlinkage __init noreturn __start_xen(void) */ if ( !pv_shim ) { + /* Separate loop to make parallel AP bringup possible. */ for_each_present_cpu ( i ) { /* Set up cpu_to_node[]. */ @@ -2104,6 +2105,12 @@ void asmlinkage __init noreturn __start_xen(void) /* Set up node_to_cpumask based on cpu_to_node[]. */ numa_add_cpu(i); =20 + if ( stack_base[i] =3D=3D NULL ) + stack_base[i] =3D cpu_alloc_stack(i); + } + + for_each_present_cpu ( i ) + { if ( (park_offline_cpus || num_online_cpus() < max_cpus) && !cpu_online(i) ) { --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611176; cv=none; d=zohomail.com; s=zohoarc; b=h75xiMe4AmM55dz1b9+URAav8qQIPmQ4Hhdyd5czFICY0PNwwggU1DX+q5Fx2qORR0dsm8aULoIAvIurfv7XTkcuWyOH+s9/mXIY7bbE20+0TWS2d+L1teWYgcwd0s+jti4z406Hry5F1jeCzF0BlmSj5muSnfiQNT0AwqwzqTM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611176; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gr1rPrDMI12BQGKfWWI47H6s2RO9Y2JqlRCdgepLO2s=; b=EXSEIXr0uQLNebP1T4Y5E+j6KkLYqFwlihyKwNpLv+AfaKNBGSozdFs6xjR4x7xdXtVeKiXffiL2exAaolbTd4w714e/jwsw7l27nyPCayP0n2XWcPbplUwMPzujG+5YDL4YMycbx/WrWCSPoEdFEKIgLqkdXGjPpmfgjBifPAU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611176899238.32884386587114; Fri, 30 May 2025 06:19:36 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000953.1381206 (Exim 4.92) (envelope-from ) id 1uKzdq-00048k-Nm; Fri, 30 May 2025 13:19:22 +0000 Received: by outflank-mailman (output) from mailman id 1000953.1381206; Fri, 30 May 2025 13:19:22 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdq-00048X-Kk; Fri, 30 May 2025 13:19:22 +0000 Received: by outflank-mailman (input) for mailman id 1000953; Fri, 30 May 2025 13:19:21 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdp-0003ZU-28 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:21 +0000 Received: from 11.mo581.mail-out.ovh.net (11.mo581.mail-out.ovh.net [87.98.173.157]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id aec1e352-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:19:14 +0200 (CEST) Received: from director8.ghost.mail-out.ovh.net (unknown [10.109.176.180]) by mo581.mail-out.ovh.net (Postfix) with ESMTP id 4b83jZ30WQz1Yxh for ; Fri, 30 May 2025 13:19:14 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-5d8n2 (unknown [10.111.174.164]) by director8.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 39E9EC024C; Fri, 30 May 2025 13:19:13 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.111]) by ghost-submission-5b5ff79f4f-5d8n2 with ESMTPSA id pQ4+OFCwOWjaBgAA4lxFtg (envelope-from ); Fri, 30 May 2025 13:19:13 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: aec1e352-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-111S0054b49fc25-ab36-4bb2-9224-4168f55b003f, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 15/22] x86/smpboot.c: TXT AP bringup Date: Fri, 30 May 2025 16:17:57 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12705217499186640028 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepgeeguedvvdettdetvedujeejiedtfefhteekgeegffffleefiedvffduledtiefhnecuffhomhgrihhnpehtrhgrmhhpohhlihhnvgdrshgsnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduuddunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekudgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=gr1rPrDMI12BQGKfWWI47H6s2RO9Y2JqlRCdgepLO2s=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611154; v=1; b=Vxf6RhrwCxqkvQJezXfDi2WLBdjKF6Twig33138h07zBOd5pvSHlqX3Fx6o+3aiUz3pe2lKs hAzCw74Gd9pI83+NTYGfqnTHm4D4BymoNxlep9zsdNXq7p4E+Ju6eYBuJJqdZCtL3lgzpfaZF0g 9hRMn9rlql/gx+HxQXyn3qzCIiIeNZC2BJ4tP2C6KT0m6BNWJvQ7hY/bkqgNDowuSTrx9A4mbfS bZt8VHBB++H75Xttax3p+88L/IturEkeut4bwmm6vLOpgqK6PAvaa5z+t6lzo0ylnQxxvLi/npz MREedbh55kw5YYFb/nFrPQAMfF2qT0439iIkrisfGBoRg== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611178239116600 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel On Intel TXT, APs are started in one of two ways, depending on ACM which reports it in its information table. In both cases, all APs are started simultaneously after BSP requests them to do so. Two possible ways are: - GETSEC[WAKEUP] instruction, - MONITOR address. GETSEC[WAKEUP] requires versions >=3D 7 of SINIT to MLE Data, but there is no clear mapping of that version with regard to processor family and it's not known which CPUs actually use it. It could have been designed for TXT support on CPUs that lack MONITOR/MWAIT, because GETSEC[WAKEUP] seems to be more complicated, in software and hardware alike. This patch implements only MONITOR approach, GETSEC[WAKEUP] support will be added later once more details and means of testing are available and if there is a practical need for it. With this patch, every AP goes through assembly part, and only when in start_secondary() in C they re-enter MONITOR/MWAIT iff they are not the AP that was asked to boot. The same address is reused for simplicity, and on next wakeup call APs don't have to go through assembly part again (GDT, paging, stack setting). Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/boot/trampoline.S | 19 ++++++++- xen/arch/x86/include/asm/intel-txt.h | 6 +++ xen/arch/x86/include/asm/processor.h | 1 + xen/arch/x86/smpboot.c | 63 ++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S index ed593acc46..8cd9881828 100644 --- a/xen/arch/x86/boot/trampoline.S +++ b/xen/arch/x86/boot/trampoline.S @@ -58,6 +58,16 @@ GLOBAL(entry_SIPI16) ljmpl $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6) =20 .code32 +GLOBAL(txt_ap_entry) + /* + * APs enter here in protected mode without paging. GDT is set in = JOIN + * structure, it points to trampoline_gdt. Interrupts are disabled= by + * TXT (including NMI and SMI), so IDT doesn't matter at this poin= t. + * The only missing point is telling that we are AP by saving non-= zero + * value in EBX. + */ + mov $1, %ebx + trampoline_protmode_entry: /* Set up a few descriptors: on entry only CS is guaranteed good. = */ mov $BOOT_DS,%eax @@ -143,7 +153,7 @@ start64: .word 0 idt_48: .word 0, 0, 0 # base =3D limit =3D 0 =20 -trampoline_gdt: +GLOBAL(trampoline_gdt) .word 0 /* 0x0000: unused (reused for GDTR) */ gdt_48: .word .Ltrampoline_gdt_end - trampoline_gdt - 1 @@ -154,6 +164,13 @@ gdt_48: .quad 0x00cf93000000ffff /* 0x0018: ring 0 data */ .quad 0x00009b000000ffff /* 0x0020: real-mode code @ BOOT_TRAMPO= LINE */ .quad 0x000093000000ffff /* 0x0028: real-mode data @ BOOT_TRAMPO= LINE */ + /* + * Intel TXT requires these two in exact order. This isn't compati= ble + * with order required by syscall, so we have duplicated entries... + * If order ever changes, update selector numbers in asm/intel-txt= .h. + */ + .quad 0x00cf9b000000ffff /* 0x0030: ring 0 code, 32-bit mode */ + .quad 0x00cf93000000ffff /* 0x0038: ring 0 data */ .Ltrampoline_gdt_end: =20 /* Relocations for trampoline Real Mode segments. */ diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index de7f23d4ff..c032ebb2e1 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -91,6 +91,9 @@ =20 #define SLAUNCH_BOOTLOADER_MAGIC 0x4c534254 =20 +#define TXT_AP_BOOT_CS 0x0030 +#define TXT_AP_BOOT_DS 0x0038 + #ifndef __ASSEMBLY__ =20 #include @@ -105,6 +108,9 @@ #define _txt(x) __va(x) #endif =20 +extern char txt_ap_entry[]; +extern uint32_t trampoline_gdt[]; + /* * Always use private space as some of registers are either read-only or n= ot * present in public space. diff --git a/xen/arch/x86/include/asm/processor.h b/xen/arch/x86/include/as= m/processor.h index 96b9bf5f5e..20c85eb2f3 100644 --- a/xen/arch/x86/include/asm/processor.h +++ b/xen/arch/x86/include/asm/processor.h @@ -466,6 +466,7 @@ void set_in_pb_opt_ctrl(uint32_t mask, uint32_t val); enum ap_boot_method { AP_BOOT_NORMAL, AP_BOOT_SKINIT, + AP_BOOT_TXT, }; extern enum ap_boot_method ap_boot_method; =20 diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index a90caf45a5..74a7cbe23b 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -321,6 +323,29 @@ void asmlinkage start_secondary(void) struct cpu_info *info =3D get_cpu_info(); unsigned int cpu =3D smp_processor_id(); =20 + if ( ap_boot_method =3D=3D AP_BOOT_TXT ) { + uint64_t misc_enable; + uint32_t my_apicid; + struct txt_sinit_mle_data *sinit_mle =3D + txt_sinit_mle_data_start(__va(txt_read(TXTCR_HEAP_BASE))); + + /* TXT released us with MONITOR disabled in IA32_MISC_ENABLE. */ + rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); + wrmsrl(MSR_IA32_MISC_ENABLE, + misc_enable | MSR_IA32_MISC_ENABLE_MONITOR_ENABLE); + + /* get_apic_id() reads from x2APIC if it thinks it is enabled. */ + x2apic_ap_setup(); + my_apicid =3D get_apic_id(); + + while ( my_apicid !=3D x86_cpu_to_apicid[cpu] ) { + asm volatile ("monitor; xor %0,%0; mwait" + :: "a"(__va(sinit_mle->rlp_wakeup_addr)), "c"(0), + "d"(0) : "memory"); + cpu =3D smp_processor_id(); + } + } + /* Critical region without IDT or TSS. Any fault is deadly! */ =20 set_current(idle_vcpu[cpu]); @@ -418,6 +443,28 @@ void asmlinkage start_secondary(void) startup_cpu_idle_loop(); } =20 +static int wake_aps_in_txt(void) +{ + struct txt_sinit_mle_data *sinit_mle =3D + txt_sinit_mle_data_start(__va(txt_read(TXTCR_HEAP_BASE))); + uint32_t *wakeup_addr =3D __va(sinit_mle->rlp_wakeup_addr); + + uint32_t join[4] =3D { + trampoline_gdt[1], /* GDT limit */ + bootsym_phys(trampoline_gdt), /* GDT base */ + TXT_AP_BOOT_CS, /* CS selector, DS =3D CS+8 */ + bootsym_phys(txt_ap_entry) /* EIP */ + }; + + txt_write(TXTCR_MLE_JOIN, __pa(join)); + + smp_mb(); + + *wakeup_addr =3D 1; + + return 0; +} + static int wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) { unsigned long send_status =3D 0, accept_status =3D 0; @@ -440,6 +487,9 @@ static int wakeup_secondary_cpu(int phys_apicid, unsign= ed long start_eip) if ( tboot_in_measured_env() && !tboot_wake_ap(phys_apicid, start_eip)= ) return 0; =20 + if ( ap_boot_method =3D=3D AP_BOOT_TXT ) + return wake_aps_in_txt(); + /* * Be paranoid about clearing APIC errors. */ @@ -1147,6 +1197,13 @@ static struct notifier_block cpu_smpboot_nfb =3D { =20 void __init smp_prepare_cpus(void) { + /* + * If the platform is performing a Secure Launch via TXT, secondary + * CPUs (APs) will need to be woken up in a TXT-specific way. + */ + if ( slaunch_active && boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_INTE= L ) + ap_boot_method =3D AP_BOOT_TXT; + register_cpu_notifier(&cpu_smpboot_nfb); =20 mtrr_aps_sync_begin(); @@ -1424,6 +1481,12 @@ void __init smp_cpus_done(void) =20 mtrr_save_state(); mtrr_aps_sync_end(); + + /* + * After the initial startup the DRTM-specific method for booting APs + * should not longer be used unless DRTM sequence is started again. + */ + ap_boot_method =3D AP_BOOT_NORMAL; } =20 void __init smp_intr_init(void) --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611281; cv=none; d=zohomail.com; s=zohoarc; b=M5x/FeJt/izHDokyFvUqTE/u8tWFEBQCGEkgxHVQQHsA2rgRmKgNgB0CMQlTBkMnC2qLPNr8LxDXiz7dc12lZmy8d7qxdVkW8BdoX+bJhBArc4k6mwpa+VkORaZ72AndVTSLI5InpV1JXJaJyDwjy5Weh8A78/KlNM683QKjoLw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611281; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=m5usq3QTRGIaGl8YW2FD4N9j9KXlGN9QTdRCtYRkM1M=; b=QkCoRH0awSQz7jr8GhObLwe85ylALV0oeNtjDcil12dO4gPrT5R/CzYFm8Xekd+7OwgT4EJ452WXjtGKbM/iYhc0zHLiD42wU/G0esbUMWhM2k5xUeP4yL0uCxzt4JYZCYETx1MyWfek31wyJ8EFkanw384VQDcfGRe8UOMKqOo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611281024769.9251836463533; Fri, 30 May 2025 06:21:21 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000995.1381266 (Exim 4.92) (envelope-from ) id 1uKzfb-0000Ww-KT; Fri, 30 May 2025 13:21:11 +0000 Received: by outflank-mailman (output) from mailman id 1000995.1381266; Fri, 30 May 2025 13:21:11 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzfb-0000Wn-HB; Fri, 30 May 2025 13:21:11 +0000 Received: by outflank-mailman (input) for mailman id 1000995; Fri, 30 May 2025 13:21:10 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzds-0008Jy-Lg for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:24 +0000 Received: from 5.mo561.mail-out.ovh.net (5.mo561.mail-out.ovh.net [87.98.178.36]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b0b6fdb1-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:19:18 +0200 (CEST) Received: from director7.ghost.mail-out.ovh.net (unknown [10.108.25.131]) by mo561.mail-out.ovh.net (Postfix) with ESMTP id 4b83jd4fctz1fvP for ; Fri, 30 May 2025 13:19:17 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-ptgrr (unknown [10.108.54.144]) by director7.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 80185C06D1; Fri, 30 May 2025 13:19:16 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.113]) by ghost-submission-5b5ff79f4f-ptgrr with ESMTPSA id xqfoDFSwOWio8AAA2loDpw (envelope-from ); Fri, 30 May 2025 13:19:16 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b0b6fdb1-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-113S0074fb95b9e-83ce-4588-b545-b055bf4ee8c1, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 16/22] x86/slaunch: process DRTM policy Date: Fri, 30 May 2025 16:17:58 +0300 Message-ID: <8cce3c111a2dceaf4fcf33f8f8d5632a321dfacd.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12706061926178534556 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduudefnecuvehluhhsthgvrhfuihiivgepfeenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheeiudgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=m5usq3QTRGIaGl8YW2FD4N9j9KXlGN9QTdRCtYRkM1M=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611157; v=1; b=E5NhPU9p90IfaVvoT6SCTtwm+E5O7xwUynvNJGN/aTYeDda9yZuC1frlOZ4jK62wXEFs043A Q+3NN+066PwwZGBFGvqKJHFfRouBIZFmE8mqi3CWY5qZyaxQCR2R1+b0zxJaGGZ4FPFdtkMLa/E dmiV+CjH12++6/sy39BzRxehL7w2ePC8lBtRgc5l9CEmCXzNQhHyMFP9Rgt4WRagUMYDPjLqVze SM7qQ1H05Ysl0rwM8a04FCtpASNORnBo5wVkQK0xQWVTVlCe/h2wSKajQVJCtnt59J80Y5GXkgq QybDRXXD2/WYM77ZNtCt2CokZOP017ej0GRTUTKSXTuYA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611281643116600 Content-Type: text/plain; charset="utf-8" Go through entires in the DRTM policy of SLRT to hash and extend data that they describe into corresponding PCRs. Addresses are being zeroed on measuring platform-specific data to prevent measurements from changing when the only thing that has changed is an address. Addresses can vary due to bootloader, firmware or user doing something differently or just if GRUB gets bigger in size due to inclusion of more modules and ends up offsetting newly allocated memory. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/include/asm/slaunch.h | 14 ++ xen/arch/x86/setup.c | 15 ++ xen/arch/x86/slaunch.c | 213 +++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) diff --git a/xen/arch/x86/include/asm/slaunch.h b/xen/arch/x86/include/asm/= slaunch.h index 3b38045864..62ba41d56e 100644 --- a/xen/arch/x86/include/asm/slaunch.h +++ b/xen/arch/x86/include/asm/slaunch.h @@ -24,6 +24,8 @@ #define DLE_EVTYPE_SLAUNCH_START (DLE_EVTYPE_BASE + 0x103) #define DLE_EVTYPE_SLAUNCH_END (DLE_EVTYPE_BASE + 0x104) =20 +struct boot_info; + /* Indicates an active Secure Launch boot. */ extern bool slaunch_active; =20 @@ -69,6 +71,18 @@ void slaunch_map_mem_regions(void); /* Marks regions of memory as used to avoid their corruption. */ void slaunch_reserve_mem_regions(void); =20 +/* Measures essential parts of SLR table before making use of them. */ +void slaunch_measure_slrt(void); + +/* + * Takes measurements of DRTM policy entries except for MBI and SLRT which + * should have been measured by the time this is called. Also performs san= ity + * checks of the policy and panics on failure. In particular, the function + * verifies that DRTM is consistent with modules obtained from MultibootIn= fo + * (MBI) and written to struct boot_info in setup.c. + */ +void slaunch_process_drtm_policy(const struct boot_info *bi); + /* * This helper function is used to map memory using L2 page tables by alig= ning * mapped regions to 2MB. This way page allocator (which at this point isn= 't diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 87e4693a11..063ac49b8a 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1426,6 +1426,13 @@ void asmlinkage __init noreturn __start_xen(void) if ( slaunch_active ) { slaunch_map_mem_regions(); + + /* + * SLRT needs to be measured here because it is used by init_e820(= ), the + * rest is measured slightly below by slaunch_process_drtm_policy(= ). + */ + slaunch_measure_slrt(); + slaunch_reserve_mem_regions(); } =20 @@ -1447,6 +1454,14 @@ void asmlinkage __init noreturn __start_xen(void) /* Create a temporary copy of the E820 map. */ memcpy(&boot_e820, &e820, sizeof(e820)); =20 + /* + * Process all yet unmeasured DRTM entries after E820 initialization t= o not + * do this while memory is uncached (too slow). This must also happen = before + * modules are relocated or used. + */ + if ( slaunch_active ) + slaunch_process_drtm_policy(bi); + /* Early kexec reservation (explicit static start address). */ nr_pages =3D 0; for ( i =3D 0; i < e820.nr_map; i++ ) diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c index 5f91fe5ad0..2390d0a3f3 100644 --- a/xen/arch/x86/slaunch.c +++ b/xen/arch/x86/slaunch.c @@ -9,9 +9,11 @@ #include #include #include +#include #include #include #include +#include #include #include =20 @@ -107,6 +109,217 @@ void __init slaunch_reserve_mem_regions(void) } } =20 +void __init slaunch_measure_slrt(void) +{ + struct slr_table *slrt =3D slaunch_get_slrt(); + + if ( slrt->revision =3D=3D 1 ) + { + /* + * In revision one of the SLRT, only platform-specific info table = is + * measured. + */ + struct slr_entry_intel_info tmp; + struct slr_entry_intel_info *entry; + + entry =3D (struct slr_entry_intel_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO); + if ( entry =3D=3D NULL ) + panic("SLRT is missing Intel-specific information!\n"); + + tmp =3D *entry; + tmp.boot_params_base =3D 0; + tmp.txt_heap =3D 0; + + tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, (uint8_t *)&tmp, + sizeof(tmp), DLE_EVTYPE_SLAUNCH, NULL, 0); + } + else + { + /* + * slaunch_get_slrt() checks that the revision is valid, so we mus= t not get + * here unless the code is wrong. + */ + panic("Unhandled SLRT revision: %d!\n", slrt->revision); + } +} + +static const struct slr_entry_policy *__init +slr_get_policy(const struct slr_table *slrt) +{ + struct slr_entry_policy *policy; + + policy =3D (struct slr_entry_policy *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DRTM_POLICY); + if (policy =3D=3D NULL) + panic("SLRT is missing DRTM policy!\n"); + + /* XXX: are newer revisions allowed? */ + if ( policy->revision !=3D SLR_POLICY_REVISION ) + panic("DRTM policy in SLRT is of unsupported revision: %#04x!\n", + slrt->revision); + + return policy; +} + +static void __init +check_slrt_policy_entry(struct slr_policy_entry *policy_entry, + int idx, + const struct slr_table *slrt) +{ + if ( policy_entry->entity_type !=3D SLR_ET_SLRT ) + panic("Expected DRTM policy entry #%d to describe SLRT, got %#04x!= \n", + idx, policy_entry->entity_type); + if ( policy_entry->pcr !=3D DRTM_DATA_PCR ) + panic("SLRT was measured to PCR-%d instead of PCR-%d!\n", DRTM_DAT= A_PCR, + policy_entry->pcr); + if ( policy_entry->entity !=3D (uint64_t)__pa(slrt) ) + panic("SLRT address (%#08lx) differs from its DRTM entry (%#08lx)\= n", + __pa(slrt), policy_entry->entity); +} + +/* Returns number of policy entries that were already measured. */ +static unsigned int __init +check_drtm_policy(const struct slr_table *slrt, + const struct slr_entry_policy *policy, + struct slr_policy_entry *policy_entry, + const struct boot_info *bi) +{ + uint32_t i; + uint32_t num_mod_entries; + + if ( policy->nr_entries < 2 ) + panic("DRTM policy in SLRT contains less than 2 entries (%d)!\n", + policy->nr_entries); + + /* + * MBI policy entry must be the first one, so that measuring order mat= ches + * policy order. + */ + if ( policy_entry[0].entity_type !=3D SLR_ET_MULTIBOOT2_INFO ) + panic("First entry of DRTM policy in SLRT is not MBI: %#04x!\n", + policy_entry[0].entity_type); + if ( policy_entry[0].pcr !=3D DRTM_DATA_PCR ) + panic("MBI was measured to %d instead of %d PCR!\n", DRTM_DATA_PCR, + policy_entry[0].pcr); + + /* SLRT policy entry must be the second one. */ + check_slrt_policy_entry(&policy_entry[1], 1, slrt); + + for ( i =3D 0; i < bi->nr_modules; i++ ) + { + uint16_t j; + const struct boot_module *mod =3D &bi->mods[i]; + + if (mod->relocated || mod->released) + { + panic("Multiboot module \"%s\" (at %d) was consumed before mea= surement\n", + (const char *)__va(mod->cmdline_pa), i); + } + + for ( j =3D 2; j < policy->nr_entries; j++ ) + { + if ( policy_entry[j].entity_type !=3D SLR_ET_MULTIBOOT2_MODULE= ) + continue; + + if ( policy_entry[j].entity =3D=3D mod->start && + policy_entry[j].size =3D=3D mod->size ) + break; + } + + if ( j >=3D policy->nr_entries ) + { + panic("Couldn't find Multiboot module \"%s\" (at %d) in DRTM o= f Secure Launch\n", + (const char *)__va(mod->cmdline_pa), i); + } + } + + num_mod_entries =3D 0; + for ( i =3D 0; i < policy->nr_entries; i++ ) + { + if ( policy_entry[i].entity_type =3D=3D SLR_ET_MULTIBOOT2_MODULE ) + num_mod_entries++; + } + + if ( bi->nr_modules !=3D num_mod_entries ) + { + panic("Unexpected number of Multiboot modules: %d instead of %d\n", + (int)bi->nr_modules, (int)num_mod_entries); + } + + /* + * MBI was measured in tpm_extend_mbi(). + * SLRT was measured in tpm_measure_slrt(). + */ + return 2; +} + +void __init slaunch_process_drtm_policy(const struct boot_info *bi) +{ + const struct slr_table *slrt; + const struct slr_entry_policy *policy; + struct slr_policy_entry *policy_entry; + uint16_t i; + unsigned int measured; + + slrt =3D slaunch_get_slrt(); + + policy =3D slr_get_policy(slrt); + policy_entry =3D (void *)policy + sizeof(*policy); + + measured =3D check_drtm_policy(slrt, policy, policy_entry, bi); + for ( i =3D 0; i < measured; i++ ) + policy_entry[i].flags |=3D SLR_POLICY_FLAG_MEASURED; + + for ( i =3D measured; i < policy->nr_entries; i++ ) + { + int rc; + uint64_t start =3D policy_entry[i].entity; + uint64_t size =3D policy_entry[i].size; + + /* No already measured entries are expected here. */ + if ( policy_entry[i].flags & SLR_POLICY_FLAG_MEASURED ) + panic("DRTM entry at %d was measured out of order!\n", i); + + switch ( policy_entry[i].entity_type ) + { + case SLR_ET_MULTIBOOT2_INFO: + panic("Duplicated MBI entry in DRTM of Secure Launch at %d\n",= i); + case SLR_ET_SLRT: + panic("Duplicated SLRT entry in DRTM of Secure Launch at %d\n"= , i); + + case SLR_ET_UNSPECIFIED: + case SLR_ET_BOOT_PARAMS: + case SLR_ET_SETUP_DATA: + case SLR_ET_CMDLINE: + case SLR_ET_UEFI_MEMMAP: + case SLR_ET_RAMDISK: + case SLR_ET_MULTIBOOT2_MODULE: + case SLR_ET_TXT_OS2MLE: + /* Measure this entry below. */ + break; + + case SLR_ET_UNUSED: + /* Skip this entry. */ + continue; + } + + if ( policy_entry[i].flags & SLR_POLICY_IMPLICIT_SIZE ) + panic("Unexpected implicitly-sized DRTM entry of Secure Launch= at %d (type %d, info: %s)\n", + i, policy_entry[i].entity_type, policy_entry[i].evt_info= ); + + rc =3D slaunch_map_l2(start, size); + BUG_ON(rc !=3D 0); + + tpm_hash_extend(DRTM_LOC, policy_entry[i].pcr, __va(start), size, + DLE_EVTYPE_SLAUNCH, (uint8_t *)policy_entry[i].evt= _info, + strnlen(policy_entry[i].evt_info, + TPM_EVENT_INFO_LENGTH)); + + policy_entry[i].flags |=3D SLR_POLICY_FLAG_MEASURED; + } +} + int __init slaunch_map_l2(unsigned long paddr, unsigned long size) { unsigned long aligned_paddr =3D paddr & ~((1ULL << L2_PAGETABLE_SHIFT)= - 1); --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611412; cv=none; d=zohomail.com; s=zohoarc; b=gOl6ZZR/nTCWp6HCuH85ODOyZVT5OEAyFWE6ygWeBYOiJKiKEQesq0ei9JIFuUrk++fY3zc1eJqDNhpGRdk1oklSFu9DIIXznFK9WDQkBF+wAtzYu2DxttWGW1xnCGQsovzhFwCTzGUrJJzpjFBdoSTctPFP7PZ30HXBFd1VmDo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611412; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GDql3BTKkItj9wJ+5Y5x33V6WArPQmOVJIP++1bnZvg=; b=JpNjUlBhZck9ak47X/RxTzU0wLEKBKp/YRHs+b/gXXtzxITVQM5Mv9gDCBoStnc/p3dii+S7LaTdm0uFcgjYfMQ9G5MYk7/0HzfPPOWfKMskG+6IbHqIKfbzv+mGKAXVZtMNE++zSUnYVDv3EIQJpBMFKSSJX5kAN0PYQ1m5lYk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611412377131.94252190637792; Fri, 30 May 2025 06:23:32 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1001061.1381316 (Exim 4.92) (envelope-from ) id 1uKzhg-0004cE-6U; Fri, 30 May 2025 13:23:20 +0000 Received: by outflank-mailman (output) from mailman id 1001061.1381316; Fri, 30 May 2025 13:23:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzhg-0004c7-3g; Fri, 30 May 2025 13:23:20 +0000 Received: by outflank-mailman (input) for mailman id 1001061; Fri, 30 May 2025 13:23:18 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdt-0008Jy-Lj for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:25 +0000 Received: from 14.mo550.mail-out.ovh.net (14.mo550.mail-out.ovh.net [178.32.97.215]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b22512b8-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:19:20 +0200 (CEST) Received: from director7.ghost.mail-out.ovh.net (unknown [10.109.148.49]) by mo550.mail-out.ovh.net (Postfix) with ESMTP id 4b83jh1WJ5z1lvF for ; Fri, 30 May 2025 13:19:20 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-595tn (unknown [10.110.113.13]) by director7.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 8AD7EC06E0; Fri, 30 May 2025 13:19:19 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.114]) by ghost-submission-5b5ff79f4f-595tn with ESMTPSA id TNHOGFewOWjNxwAAeVbzSg (envelope-from ); Fri, 30 May 2025 13:19:19 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b22512b8-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-114S00895dc382f-a550-4f6b-b404-f0cac4229ca3, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v3 17/22] x86/acpi: disallow S3 on Secure Launch boot Date: Fri, 30 May 2025 16:17:59 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12706906350127527068 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduudegnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheehtdgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=GDql3BTKkItj9wJ+5Y5x33V6WArPQmOVJIP++1bnZvg=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611160; v=1; b=VisO5To8RRu8TC0ZFsf9Gfi3F2pq+oFPXbyOfsoWBWec/iz+gmWk7FcqiZOMnht0TmDHwhsM 7q2T2kZdE6di2acc+rnLeFMqRDkERQkYfH4TXf2qgTCHjlVc+DlnGrMrMYxhVpuPAVguxXVr1KN CjWepru+WVBQx7iYx0gH0pgSkbmPCYs7Z7ctKQAGTw4ecgA/rmdty8DXK+BRufHQi4G6q0zHPmD 30mYab7ia4SbIesn6X/Dv8A0V3CJXc+h+oOUVbNFaD1yGMnZqKt9/TRdY60507zBLPEuOhMtxMs QAGODC0YsBg2Fyhh7oqap0w91NxL5DYa1zU/54bEM4AhA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611413370116600 Content-Type: text/plain; charset="utf-8" Secure Launch won't initiate DRTM on S3 resume (the code for starting DRTM is not part of Xen), so abort a request to perform S3 suspend to not lose the state of DRTM PCRs. Signed-off-by: Sergii Dmytruk --- xen/arch/x86/acpi/power.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xen/arch/x86/acpi/power.c b/xen/arch/x86/acpi/power.c index 448aa9f3a7..6a53c6718c 100644 --- a/xen/arch/x86/acpi/power.c +++ b/xen/arch/x86/acpi/power.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -356,6 +357,13 @@ int acpi_enter_sleep(const struct xenpf_enter_acpi_sle= ep *sleep) PAGE_SIZE - acpi_sinfo.vector_width / 8)) ) return -EOPNOTSUPP; =20 + /* Secure Launch won't initiate DRTM on S3 resume, so abort S3 suspend= . */ + if ( sleep->sleep_state =3D=3D ACPI_STATE_S3 && slaunch_active ) + { + printk(XENLOG_INFO "SLAUNCH: refusing switching into ACPI S3 state= .\n"); + return -EPERM; + } + if ( sleep->flags & XENPF_ACPI_SLEEP_EXTENDED ) { if ( !acpi_sinfo.sleep_control.address || --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611329; cv=none; d=zohomail.com; s=zohoarc; b=C7seMIi2V0LV5Gjm3EIZIv3FidZDfy/BdmRiptrwg7WPSbdtbqDS6+3tLf2zxVvCMnXoUz20qDdD4m0g3LCTDURlLCbFjvBeVWuOty72qY8NgOc3wKtHiarsDFiZUuml0JducDs1YnE6Vj/6etVlOPpuLNSyusluVaghswBu0lA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611329; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=6b/MBAdcX7V7P2Nt96V761xn41jitI/g+aKn4sKLesI=; b=kXiBjzEwBbuhFCEZ6jr6XznT8g1svVbabE7Vam5MpsLFo+suCMPgjdXLyteAWgoEEK0OTkWK3iLDbK2Pm5DA4GjulxnVCIWDsPQ+opPJhkN9W3IVm+oDkBG54WUTTegD0CXV1jMRVQqN0tfxrrItVoidobUZw5qqYpC5/bTDhag= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611329015741.0144020084191; Fri, 30 May 2025 06:22:09 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1001022.1381296 (Exim 4.92) (envelope-from ) id 1uKzgK-0002Pd-Ha; Fri, 30 May 2025 13:21:56 +0000 Received: by outflank-mailman (output) from mailman id 1001022.1381296; Fri, 30 May 2025 13:21:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzgK-0002PW-EI; Fri, 30 May 2025 13:21:56 +0000 Received: by outflank-mailman (input) for mailman id 1001022; Fri, 30 May 2025 13:21:56 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdu-0008Jy-Lm for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:26 +0000 Received: from 5.mo583.mail-out.ovh.net (5.mo583.mail-out.ovh.net [87.98.173.103]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b3afa57d-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:19:23 +0200 (CEST) Received: from director4.ghost.mail-out.ovh.net (unknown [10.108.25.4]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4b83jk5Jg2z1kgy for ; Fri, 30 May 2025 13:19:22 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-7mj9p (unknown [10.110.168.40]) by director4.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 0E7EFC57BA; Fri, 30 May 2025 13:19:21 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.104]) by ghost-submission-5b5ff79f4f-7mj9p with ESMTPSA id lFyANFmwOWgz4wAAMDjBXw (envelope-from ); Fri, 30 May 2025 13:19:21 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b3afa57d-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-104R00545eb1c88-6e30-4b42-870d-eb4a1160ce4c, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 18/22] x86/boot/slaunch-early: find MBI and SLRT on AMD Date: Fri, 30 May 2025 16:18:00 +0300 Message-ID: <7272ac988ae672f0a05486775e805a9513e86950.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12707469300486354076 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepkedugeefudeigeduieejleelkeefvddvhfehheevhfdukeejieefgedtudevhedtnecuffhomhgrihhnpehhvggrugdrshgsnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrddutdegnecuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekfegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=6b/MBAdcX7V7P2Nt96V761xn41jitI/g+aKn4sKLesI=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611162; v=1; b=RLVB/6EW7AX63X7XuboL0LJKFS1pB903Pl9pBA8I+sF6xEp+DiyWfHfvyC28iGPCi9fXbnNN dPlLSd5sfq7yAmN/Nan4hJvHqsa/Pk1vGJAtYyf5EkoQ5xI7wGsTCKUwGcuy5Ic0VH2PwOYsDwe +JoaPDGFketeAwhzz15C04F5uyP3q8jsxBrr0xqtWQNDMEzVCAKBq4N9ZVJcolGKzvwTq1qDSR/ JfpsOLV1YhXJ3dwlw97i+yH09bkHxmuqFLhV4iC+2Gy8wiRO9/f0uF0JAHb6h9MrKgGaarSyp6v JC0TN191+SlBGDM5dHDW+1bC6q7regUIvkGz3hK/9RrGw== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611330475116600 Content-Type: text/plain; charset="utf-8" Use slr_entry_amd_info::boot_params_base on AMD with SKINIT to get MBI location. Another thing of interest is the location of SLRT which is bootloader's data after SKL. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/boot/head.S | 38 ++++++++++++++++---- xen/arch/x86/boot/slaunch-early.c | 58 +++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 7376fa85d5..66e1a21033 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -354,10 +354,12 @@ cs32_switch: jmp *%edi =20 /* - * Entry point for TrenchBoot Secure Launch on Intel TXT platforms. + * Entry point for TrenchBoot Secure Launch, common for Intel TXT = and + * AMD Secure Startup, but state is slightly different. * + * On Intel: * CPU is in 32b protected mode with paging disabled. On entry: - * - %ebx =3D %eip =3D MLE entry point, + * - %ebx =3D %eip =3D this entry point, * - stack pointer is undefined, * - CS is flat 4GB code segment, * - DS, ES, SS, FS and GS are undefined according to TXT SDG, but= this @@ -375,13 +377,34 @@ cs32_switch: * - trying to enter real mode results in reset * - APs must be brought up by MONITOR or GETSEC[WAKEUP], dependin= g on * which is supported by a given SINIT ACM + * + * On AMD (as implemented by TrenchBoot's SKL): + * CPU is in 32b protected mode with paging disabled. On entry: + * - %ebx =3D %eip =3D this entry point, + * - %ebp holds base address of SKL + * - stack pointer is treated as undefined for parity with TXT, + * - CS is flat 4GB code segment, + * - DS, ES, SS are flat 4GB data segments, but treated as undefin= ed for + * parity with TXT. + * + * Additional restrictions: + * - interrupts (including NMIs and SMIs) are disabled and must be + * enabled later + * - APs must be brought up by SIPI without an INIT */ slaunch_stub_entry: /* Calculate the load base address. */ mov %ebx, %esi sub $sym_offs(slaunch_stub_entry), %esi =20 - /* Mark Secure Launch boot protocol and jump to common entry. */ + /* On AMD, %ebp holds the base address of SLB, save it for later. = */ + mov %ebp, %ebx + + /* + * Mark Secure Launch boot protocol and jump to common entry. Note= that + * all general purpose registers except %ebx and %esi are clobbered + * between here and .Lslaunch_proto. + */ mov $SLAUNCH_BOOTLOADER_MAGIC, %eax jmp .Lset_stack =20 @@ -508,15 +531,18 @@ __start: sub $8, %esp =20 push %esp /* pointer to output stru= cture */ + push %ebx /* Slaunch parameter on A= MD */ lea sym_offs(__2M_rwdata_end), %ecx /* end of target image */ lea sym_offs(_start), %edx /* target base address */ mov %esi, %eax /* load base address */ /* - * slaunch_early_init(load/eax, tgt/edx, tgt_end/ecx, ret/stk) usi= ng - * fastcall calling convention. + * slaunch_early_init(load/eax, tgt/edx, tgt_end/ecx, + * slaunch/stk, ret/stk) + * + * Uses fastcall calling convention. */ call slaunch_early_init - add $4, %esp /* pop the fourth paramet= er */ + add $8, %esp /* pop last two parameter= s */ =20 /* Move outputs of slaunch_early_init() from stack into registers.= */ pop %eax /* physical MBI address */ diff --git a/xen/arch/x86/boot/slaunch-early.c b/xen/arch/x86/boot/slaunch-= early.c index 662144e42f..ac4c294e61 100644 --- a/xen/arch/x86/boot/slaunch-early.c +++ b/xen/arch/x86/boot/slaunch-early.c @@ -7,6 +7,20 @@ #include #include #include +#include + +/* + * The AMD-defined structure layout for the SLB. The last two fields are + * SL-specific. + */ +struct skinit_sl_header +{ + uint16_t skl_entry_point; + uint16_t length; + uint8_t reserved[62]; + uint16_t skl_info_offset; + uint16_t bootloader_data_offset; +} __packed; =20 struct early_init_results { @@ -14,9 +28,25 @@ struct early_init_results uint32_t slrt_pa; } __packed; =20 +static bool is_intel_cpu(void) +{ + /* + * asm/processor.h can't be included in early code, which means neither + * cpuid() function nor boot_cpu_data can be used here. + */ + uint32_t eax, ebx, ecx, edx; + asm volatile ( "cpuid" + : "=3Da" (eax), "=3Db" (ebx), "=3Dc" (ecx), "=3Dd" (edx) + : "0" (0), "c" (0) ); + return ebx =3D=3D X86_VENDOR_INTEL_EBX + && ecx =3D=3D X86_VENDOR_INTEL_ECX + && edx =3D=3D X86_VENDOR_INTEL_EDX; +} + void asmlinkage slaunch_early_init(uint32_t load_base_addr, uint32_t tgt_base_addr, uint32_t tgt_end_addr, + uint32_t slaunch_param, struct early_init_results *result) { void *txt_heap; @@ -26,6 +56,34 @@ void asmlinkage slaunch_early_init(uint32_t load_base_ad= dr, const struct slr_entry_intel_info *intel_info; uint32_t size =3D tgt_end_addr - tgt_base_addr; =20 + if ( !is_intel_cpu() ) + { + /* + * Not an Intel CPU. Currently the only other option is AMD with S= KINIT + * and secure-kernel-loader (SKL). + */ + const struct slr_entry_amd_info *amd_info; + const struct skinit_sl_header *sl_header =3D (void *)slaunch_param; + + /* + * slaunch_param holds a physical address of SLB. + * Bootloader's data is SLRT. + */ + result->slrt_pa =3D slaunch_param + sl_header->bootloader_data_off= set; + result->mbi_pa =3D 0; + + slrt =3D (struct slr_table *)(uintptr_t)result->slrt_pa; + + amd_info =3D (const struct slr_entry_amd_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_AMD_INFO); + /* Basic checks only, SKL checked and consumed the rest. */ + if ( amd_info =3D=3D NULL || amd_info->hdr.size !=3D sizeof(*amd_i= nfo) ) + return; + + result->mbi_pa =3D amd_info->boot_params_base; + return; + } + txt_heap =3D txt_init(); os_mle =3D txt_os_mle_data_start(txt_heap); os_sinit =3D txt_os_sinit_data_start(txt_heap); --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611412; cv=none; d=zohomail.com; s=zohoarc; b=ml50gC0zQmet79PqrZ6ek+JCcv0XO2uDtuCTpC4F3uSMZwHQZ2HSfj75HmupACoAWW8DMSPEmcKlUQhQ33kHL/+qh7rJSN8r94czVc72WLWgwE8AI/a/rqdgNm3S/kiICKUO3qa324dmfQlZeaYk6ysSGVGpIV1cBUA95KChSoM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611412; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wzJGPzWI7lL37VfLBh9g3OqTx3SpBQMv+io19vUhKSI=; b=IiBOLyvjam/qIon2hyEMo0ww++fmCyquDZvoD+Z4GM6OUE6My/OkzukFtr0501dujf6UmKjqBuUNbplLrjM/tMnKa/rapa2PbbMsnEVQpvqm6tCwQ33vYBrqiBnd+YhbZv77bfoRXHCx4tjpodTbbPKkUINcRMGS8+1qfM2jJL4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611412152410.75092449098986; Fri, 30 May 2025 06:23:32 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1001065.1381321 (Exim 4.92) (envelope-from ) id 1uKzhg-0004f5-Eg; Fri, 30 May 2025 13:23:20 +0000 Received: by outflank-mailman (output) from mailman id 1001065.1381321; Fri, 30 May 2025 13:23:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzhg-0004e0-9g; Fri, 30 May 2025 13:23:20 +0000 Received: by outflank-mailman (input) for mailman id 1001065; Fri, 30 May 2025 13:23:19 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKze4-0003ZU-3h for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:36 +0000 Received: from 2.mo582.mail-out.ovh.net (2.mo582.mail-out.ovh.net [46.105.76.65]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id b64ceedc-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:19:27 +0200 (CEST) Received: from director3.ghost.mail-out.ovh.net (unknown [10.109.148.49]) by mo582.mail-out.ovh.net (Postfix) with ESMTP id 4b83jq0y11z1dJf for ; Fri, 30 May 2025 13:19:27 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-xc6mh (unknown [10.110.168.219]) by director3.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 1E5BEC3326; Fri, 30 May 2025 13:19:24 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.105]) by ghost-submission-5b5ff79f4f-xc6mh with ESMTPSA id fw8bLlywOWiZtgAAiTdl2Q (envelope-from ); Fri, 30 May 2025 13:19:24 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b64ceedc-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-105G0063501688f-cd43-4a5e-8213-abcfdd892099, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 19/22] x86/slaunch: support AMD SKINIT Date: Fri, 30 May 2025 16:18:01 +0300 Message-ID: <20c2380bd920fea3009f6e5ae2d3011b0a3fe431.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12708876676210341020 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrddutdehnecuvehluhhsthgvrhfuihiivgepgeenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekvdgmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=wzJGPzWI7lL37VfLBh9g3OqTx3SpBQMv+io19vUhKSI=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611167; v=1; b=P1yuXhTV2FhzHLEx6qizEKIvBbFXbXU4JRWkbqxJS/2eGtvmfU26yFqGaPeyj610TYhb7s+m PmsQhcwSeVILCgvJCBSqDPy8dGGwJHBMAfXvzzaFpuXMmXkKbiDXchthBgvant6fxQFncNRPxh0 T5cKJP8sJrYArt0u7/ic6a6ycwsGSM18LBoEQbwn/GfhKdcNkrASz5HPyC8cL4FPbLg1KcLIb2S FTPAppTrI5jjrWmsJpogzKzS3+B05KQEFAFGeyMeINre6lPOtLNZNqpw1T4UDmuLEXWZN/37duy xpakrVFG70Qw0cTC7N1/rabPQMDshFS9JLzB3/iK42FLA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611413343116600 Content-Type: text/plain; charset="utf-8" This mostly involves not running Intel-specific code when on AMD. There are only a few new AMD-specific implementation details: - finding SLB start and size and then mapping and reserving it in e820 - managing offset for adding the next TPM log entry (TXT-compatible data prepared by SKL is stored inside of vendor data field within TCG header) Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/e820.c | 2 +- xen/arch/x86/slaunch.c | 90 ++++++++++++++++++++++++++++++++++-------- xen/arch/x86/tpm.c | 68 ++++++++++++++++++++++++++++++- 3 files changed, 141 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index 60f00e5259..cf13ab269a 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -444,7 +444,7 @@ static uint64_t __init mtrr_top_of_ram(void) ASSERT(paddr_bits); addr_mask =3D ((1ULL << paddr_bits) - 1) & PAGE_MASK; =20 - if ( slaunch_active ) + if ( slaunch_active && boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_INTE= L ) txt_restore_mtrrs(e820_verbose); =20 rdmsrl(MSR_MTRRcap, mtrr_cap); diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c index 2390d0a3f3..58a0de910d 100644 --- a/xen/arch/x86/slaunch.c +++ b/xen/arch/x86/slaunch.c @@ -17,6 +17,10 @@ #include #include =20 +/* SLB is 64k, 64k-aligned */ +#define SKINIT_SLB_SIZE 0x10000 +#define SKINIT_SLB_ALIGN 0x10000 + /* * These variables are assigned to by the code near Xen's entry point. * @@ -39,6 +43,8 @@ struct slr_table *__init slaunch_get_slrt(void) =20 if (slrt =3D=3D NULL) { int rc; + bool intel_cpu =3D (boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_INT= EL); + uint16_t slrt_architecture =3D intel_cpu ? SLR_INTEL_TXT : SLR_AMD= _SKINIT; =20 slrt =3D __va(slaunch_slrt); =20 @@ -50,9 +56,9 @@ struct slr_table *__init slaunch_get_slrt(void) /* XXX: are newer revisions allowed? */ if ( slrt->revision !=3D SLR_TABLE_REVISION ) panic("SLRT is of unsupported revision: %#04x!\n", slrt->revis= ion); - if ( slrt->architecture !=3D SLR_INTEL_TXT ) - panic("SLRT is for unexpected architecture: %#04x!\n", - slrt->architecture); + if ( slrt->architecture !=3D slrt_architecture ) + panic("SLRT is for unexpected architecture: %#04x !=3D %#04x!\= n", + slrt->architecture, slrt_architecture); if ( slrt->size > slrt->max_size ) panic("SLRT is larger than its max size: %#08x > %#08x!\n", slrt->size, slrt->max_size); @@ -67,6 +73,23 @@ struct slr_table *__init slaunch_get_slrt(void) return slrt; } =20 +static uint32_t __init get_slb_start(void) +{ + /* + * The runtime computation relies on size being a power of 2 and equal= to + * alignment. Make sure these assumptions hold. + */ + BUILD_BUG_ON(SKINIT_SLB_SIZE !=3D SKINIT_SLB_ALIGN); + BUILD_BUG_ON(SKINIT_SLB_SIZE =3D=3D 0); + BUILD_BUG_ON((SKINIT_SLB_SIZE & (SKINIT_SLB_SIZE - 1)) !=3D 0); + + /* + * Rounding any address within SLB down to alignment gives SLB base and + * SLRT is inside SLB on AMD. + */ + return slaunch_slrt & ~(SKINIT_SLB_SIZE - 1); +} + void __init slaunch_map_mem_regions(void) { int rc; @@ -77,7 +100,10 @@ void __init slaunch_map_mem_regions(void) BUG_ON(rc !=3D 0); =20 /* Vendor-specific part. */ - txt_map_mem_regions(); + if ( boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_INTEL ) + txt_map_mem_regions(); + else if ( boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_AMD ) + slaunch_map_l2(get_slb_start(), SKINIT_SLB_SIZE); =20 find_evt_log(slaunch_get_slrt(), &evt_log_addr, &evt_log_size); if ( evt_log_addr !=3D NULL ) @@ -95,7 +121,18 @@ void __init slaunch_reserve_mem_regions(void) uint32_t evt_log_size; =20 /* Vendor-specific part. */ - txt_reserve_mem_regions(); + if ( boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_INTEL ) + { + txt_reserve_mem_regions(); + } + else if ( boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_AMD ) + { + uint64_t slb_start =3D get_slb_start(); + uint64_t slb_end =3D slb_start + SKINIT_SLB_SIZE; + printk("SLAUNCH: reserving SLB (%#lx - %#lx)\n", slb_start, slb_en= d); + rc =3D reserve_e820_ram(&e820_raw, slb_start, slb_end); + BUG_ON(rc =3D=3D 0); + } =20 find_evt_log(slaunch_get_slrt(), &evt_log_addr, &evt_log_size); if ( evt_log_addr !=3D NULL ) @@ -119,20 +156,41 @@ void __init slaunch_measure_slrt(void) * In revision one of the SLRT, only platform-specific info table = is * measured. */ - struct slr_entry_intel_info tmp; - struct slr_entry_intel_info *entry; + if ( boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_INTEL ) + { + struct slr_entry_intel_info tmp; + struct slr_entry_intel_info *entry; + + entry =3D (struct slr_entry_intel_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO); + if ( entry =3D=3D NULL ) + panic("SLRT is missing Intel-specific information!\n"); =20 - entry =3D (struct slr_entry_intel_info *) - slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO); - if ( entry =3D=3D NULL ) - panic("SLRT is missing Intel-specific information!\n"); + tmp =3D *entry; + tmp.boot_params_base =3D 0; + tmp.txt_heap =3D 0; =20 - tmp =3D *entry; - tmp.boot_params_base =3D 0; - tmp.txt_heap =3D 0; + tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, (uint8_t *)&tmp, + sizeof(tmp), DLE_EVTYPE_SLAUNCH, NULL, 0); + } + else if ( boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_AMD ) + { + struct slr_entry_amd_info tmp; + struct slr_entry_amd_info *entry; + + entry =3D (struct slr_entry_amd_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_AMD_INFO); + if ( entry =3D=3D NULL ) + panic("SLRT is missing AMD-specific information!\n"); =20 - tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, (uint8_t *)&tmp, - sizeof(tmp), DLE_EVTYPE_SLAUNCH, NULL, 0); + tmp =3D *entry; + tmp.next =3D 0; + tmp.slrt_base =3D 0; + tmp.boot_params_base =3D 0; + + tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, (uint8_t *)&tmp, + sizeof(tmp), DLE_EVTYPE_SLAUNCH, NULL, 0); + } } else { diff --git a/xen/arch/x86/tpm.c b/xen/arch/x86/tpm.c index 3c145fd3cc..77f910a8c9 100644 --- a/xen/arch/x86/tpm.c +++ b/xen/arch/x86/tpm.c @@ -11,6 +11,7 @@ #include #include #include +#include =20 #ifdef __EARLY_SLAUNCH__ =20 @@ -52,11 +53,31 @@ void *(memcpy)(void *dest, const void *src, size_t n) return dest; } =20 +static bool is_amd_cpu(void) +{ + /* + * asm/processor.h can't be included in early code, which means neither + * cpuid() function nor boot_cpu_data can be used here. + */ + uint32_t eax, ebx, ecx, edx; + asm volatile ( "cpuid" + : "=3Da" (eax), "=3Db" (ebx), "=3Dc" (ecx), "=3Dd" (edx) + : "0" (0), "c" (0) ); + return ebx =3D=3D X86_VENDOR_AMD_EBX + && ecx =3D=3D X86_VENDOR_AMD_ECX + && edx =3D=3D X86_VENDOR_AMD_EDX; +} + #else /* __EARLY_SLAUNCH__ */ =20 #include #include =20 +static bool is_amd_cpu(void) +{ + return boot_cpu_data.x86_vendor =3D=3D X86_VENDOR_AMD; +} + #endif /* __EARLY_SLAUNCH__ */ =20 #define TPM_LOC_REG(loc, reg) (0x1000 * (loc) + (reg)) @@ -241,6 +262,21 @@ struct TPM12_PCREvent { uint8_t Data[]; }; =20 +struct tpm1_spec_id_event { + uint32_t pcrIndex; + uint32_t eventType; + uint8_t digest[20]; + uint32_t eventSize; + uint8_t signature[16]; + uint32_t platformClass; + uint8_t specVersionMinor; + uint8_t specVersionMajor; + uint8_t specErrata; + uint8_t uintnSize; + uint8_t vendorInfoSize; + uint8_t vendorInfo[0]; /* variable number of members */ +} __packed; + struct txt_ev_log_container_12 { char Signature[20]; /* "TXT Event Container", null-termina= ted */ uint8_t Reserved[12]; @@ -384,6 +420,16 @@ static void *create_log_event12(struct txt_ev_log_cont= ainer_12 *evt_log, { struct TPM12_PCREvent *new_entry; =20 + if ( is_amd_cpu() ) + { + /* + * On AMD, TXT-compatible structure is stored as vendor data of + * TCG-defined event log header. + */ + struct tpm1_spec_id_event *spec_id =3D (void *)evt_log; + evt_log =3D (struct txt_ev_log_container_12 *)&spec_id->vendorInfo= [0]; + } + new_entry =3D (void *)(((uint8_t *)evt_log) + evt_log->NextEventOffset= ); =20 /* @@ -832,11 +878,29 @@ static uint32_t tpm2_hash_extend(unsigned loc, const = uint8_t *buf, =20 #endif /* __EARLY_SLAUNCH__ */ =20 -static struct heap_event_log_pointer_element2_1 *find_evt_log_ext_data(voi= d) +static struct heap_event_log_pointer_element2_1 * +find_evt_log_ext_data(struct tpm2_spec_id_event *evt_log) { struct txt_os_sinit_data *os_sinit; struct txt_ext_data_element *ext_data; =20 + if ( is_amd_cpu() ) + { + /* + * Event log pointer is defined by TXT specification, but + * secure-kernel-loader provides a compatible structure in vendor = data + * of the log. + */ + const uint8_t *data_size =3D + (void *)&evt_log->digestSizes[evt_log->digestCount]; + + if ( *data_size !=3D sizeof(struct heap_event_log_pointer_element2= _1) ) + return NULL; + + /* Vendor data directly follows one-byte size. */ + return (void *)(data_size + 1); + } + os_sinit =3D txt_os_sinit_data_start(__va(txt_read(TXTCR_HEAP_BASE))); ext_data =3D (void *)((uint8_t *)os_sinit + sizeof(*os_sinit)); =20 @@ -870,7 +934,7 @@ create_log_event20(struct tpm2_spec_id_event *evt_log, = uint32_t evt_log_size, unsigned i; uint8_t *p; =20 - log_ext_data =3D find_evt_log_ext_data(); + log_ext_data =3D find_evt_log_ext_data(evt_log); if ( log_ext_data =3D=3D NULL ) return log_hashes; =20 --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611310; cv=none; d=zohomail.com; s=zohoarc; b=VlkZoee2gFfufmIYgDuH3K7Z4yaOU+hsIFggjUTp8ZWewB1+otwLWVtw5xpqlFfD0F84yoJdpZk9Knm08kxcfCvUI5WoeszRYUp+NPeufQLpaUv80YasiCLetrPj7urz3cQQTqIfef6xkcVi3WV08kbPUfUEG7a3ZsYdgIHeXgk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611310; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Drr6FWlQScmF8BWhc//AZ198parzbtjMM3aMJ+vfK8U=; b=HgkEiil8j4a6rGIbqdf47igv9na9Cns09oRQqxqi3TXmsAX7ruihzn+DDl3hiYBGR7+u69ni1z6VIj1b33chmDl+Lv1CWx7qgOmToc96gNQgcvdlGEPnsA/2eAPW5290CUjuDtZMrpS8a5tI18hekIZcC28AzeJwNtVHFCxT6wo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611310684375.6320708405792; Fri, 30 May 2025 06:21:50 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1001013.1381286 (Exim 4.92) (envelope-from ) id 1uKzg5-0001q7-9o; Fri, 30 May 2025 13:21:41 +0000 Received: by outflank-mailman (output) from mailman id 1001013.1381286; Fri, 30 May 2025 13:21:41 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzg5-0001px-6k; Fri, 30 May 2025 13:21:41 +0000 Received: by outflank-mailman (input) for mailman id 1001013; Fri, 30 May 2025 13:21:40 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKze1-0008Jy-F1 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:33 +0000 Received: from 7.mo575.mail-out.ovh.net (7.mo575.mail-out.ovh.net [46.105.63.230]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id b91584a4-3d58-11f0-a2ff-13f23c93f187; Fri, 30 May 2025 15:19:32 +0200 (CEST) Received: from director10.ghost.mail-out.ovh.net (unknown [10.108.2.235]) by mo575.mail-out.ovh.net (Postfix) with ESMTP id 4b83jv5LP9z264Q for ; Fri, 30 May 2025 13:19:31 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-nc6qk (unknown [10.110.188.144]) by director10.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 79E51C4832; Fri, 30 May 2025 13:19:29 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.100]) by ghost-submission-5b5ff79f4f-nc6qk with ESMTPSA id nnzwCmGwOWjeQzsACj9Bag (envelope-from ); Fri, 30 May 2025 13:19:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: b91584a4-3d58-11f0-a2ff-13f23c93f187 Authentication-Results: garm.ovh; auth=pass (GARM-100R003bd8ebc15-fda5-48b5-885e-5e7d68c13e5c, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Nicola Vetrini , Doug Goldstein , "Daniel P. Smith" , =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 20/22] x86/slaunch: support EFI boot Date: Fri, 30 May 2025 16:18:02 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12710002576057283740 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhepleelkeekhfeikeeifeekgfethfdvheekfedvffetfefgveelleekkedvgeekuddvnecuffhomhgrihhnpehhvggrugdrshgspdigkeeipgeigedrshgsnecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrddutddtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheejhegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=Drr6FWlQScmF8BWhc//AZ198parzbtjMM3aMJ+vfK8U=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611171; v=1; b=dmbjUHDx3MRM9pDuWhCkzBUZKK+IgSP1BCpk7hMPevMMYhgXmrGgQ77SrpvMRpf+fyw0pqzS g5SViFyNQkVWI9/yz16arc2X6q3Up1U7NjGS4pn7WTVY85qJ3cbWhFY4i2PtAuNGdocc2n4PRrS g28ZM+4mD8WBT13kY4mY515za9+i17OniNy7dhAGFOSBXGOxotrAzVem/lq658kws03kTQvn+CB 5YJXgXqPyemtyX76zJr401uvo8Di9Xx6pYl+QKHwK5DFuT6+VZnzlUQLJvH85oyru+j+K4dH8vR SNlqhgpwZB0RDQyjy+IA1JBbq1qpDg0QWwEO4KhVABvVA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611312236116600 Content-Type: text/plain; charset="utf-8" When running on an EFI-enabled system, Xen needs to have access to Boot Services in order to initialize itself properly and reach a state in which a dom0 kernel can operate without issues. This means that DRTM must be started in the middle of Xen's initialization process. This effect is achieved via a callback into a TrenchBoot-enabled bootloader (GRUB) which is responsible for initiating DRTM and continuing Xen's initialization process. The latter is done by branching in Slaunch entry point on a flag to switch back into long mode before calling the same function which Xen would execute as the next step without DRTM. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- .gitignore | 1 + .../eclair_analysis/ECLAIR/out_of_scope.ecl | 1 + docs/hypervisor-guide/x86/how-xen-boots.rst | 10 +- xen/arch/x86/Makefile | 9 +- xen/arch/x86/boot/head.S | 124 +++++++++++++++++ xen/arch/x86/boot/x86_64.S | 14 +- xen/arch/x86/efi/efi-boot.h | 88 +++++++++++- xen/arch/x86/efi/fixmlehdr.c | 127 ++++++++++++++++++ xen/arch/x86/slaunch.c | 74 +++++++++- xen/common/efi/boot.c | 4 + xen/common/efi/runtime.c | 1 + xen/include/xen/efi.h | 1 + 12 files changed, 441 insertions(+), 13 deletions(-) create mode 100644 xen/arch/x86/efi/fixmlehdr.c diff --git a/.gitignore b/.gitignore index 4a4e206804..707e839ea8 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,7 @@ xen/.xen.elf32 xen/System.map xen/arch/x86/efi.lds xen/arch/x86/efi/check.efi +xen/arch/x86/efi/fixmlehdr xen/arch/x86/efi/mkreloc xen/arch/x86/include/asm/asm-macros.h xen/arch/*/xen.lds diff --git a/automation/eclair_analysis/ECLAIR/out_of_scope.ecl b/automatio= n/eclair_analysis/ECLAIR/out_of_scope.ecl index 9bcec4c69d..a09cf5442c 100644 --- a/automation/eclair_analysis/ECLAIR/out_of_scope.ecl +++ b/automation/eclair_analysis/ECLAIR/out_of_scope.ecl @@ -19,6 +19,7 @@ =20 -doc_begin=3D"Build tools are out of scope." -file_tag+=3D{out_of_scope_tools,"^xen/tools/.*$"} +-file_tag+=3D{out_of_scope_tools,"^xen/arch/x86/efi/fixmlehdr\\.c$"} -file_tag+=3D{out_of_scope_tools,"^xen/arch/x86/efi/mkreloc\\.c$"} -file_tag+=3D{out_of_scope_tools,"^xen/arch/x86/boot/mkelf32\\.c$"} -doc_end diff --git a/docs/hypervisor-guide/x86/how-xen-boots.rst b/docs/hypervisor-= guide/x86/how-xen-boots.rst index 050fe9c61f..63f81a8198 100644 --- a/docs/hypervisor-guide/x86/how-xen-boots.rst +++ b/docs/hypervisor-guide/x86/how-xen-boots.rst @@ -55,10 +55,12 @@ If ``CONFIG_PVH_GUEST`` was selected at build time, an = Elf note is included which indicates the ability to use the PVH boot protocol, and registers ``__pvh_start`` as the entrypoint, entered in 32bit mode. =20 -A combination of Multiboot 2 and MLE headers is used to implement DRTM for -legacy (BIOS) boot. The separate entry point is used mainly to differentia= te -from other kinds of boots. It moves a magic number to EAX before jumping i= nto -common startup code. +A combination of Multiboot 2 and MLE headers is used to implement DRTM. The +separate entry point is used mainly to differentiate from other kinds of b= oots. +For a legacy (BIOS) boot, it moves a magic number to EAX before jumping in= to +common startup code. For a EFI boot, it resumes execution of Xen.efi whic= h was +paused by handing control to a part of a bootloader responsible for initia= ting +DRTM sequence. =20 =20 xen.gz diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 2d008a5f52..aab98c003f 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -89,6 +89,7 @@ extra-y +=3D xen.lds =20 hostprogs-y +=3D boot/mkelf32 hostprogs-y +=3D efi/mkreloc +hostprogs-y +=3D efi/fixmlehdr =20 $(obj)/efi/mkreloc: HOSTCFLAGS +=3D -I$(srctree)/include =20 @@ -140,6 +141,10 @@ $(TARGET): $(TARGET)-syms $(efi-y) $(obj)/boot/mkelf32 =20 CFLAGS-$(XEN_BUILD_EFI) +=3D -DXEN_BUILD_EFI =20 +ifeq ($(XEN_BUILD_EFI),y) +XEN_AFLAGS +=3D -DXEN_BUILD_EFI +endif + $(TARGET)-syms: $(objtree)/prelink.o $(obj)/xen.lds $(LD) $(XEN_LDFLAGS) -T $(obj)/xen.lds $< $(build_id_linker) \ $(objtree)/common/symbols-dummy.o -o $(dot-target).0 @@ -209,7 +214,7 @@ note_file_option ?=3D $(note_file) =20 extra-$(XEN_BUILD_PE) +=3D efi.lds ifeq ($(XEN_BUILD_PE),y) -$(TARGET).efi: $(objtree)/prelink.o $(note_file) $(obj)/efi.lds $(obj)/efi= /relocs-dummy.o $(obj)/efi/mkreloc +$(TARGET).efi: $(objtree)/prelink.o $(note_file) $(obj)/efi.lds $(obj)/efi= /relocs-dummy.o $(obj)/efi/mkreloc $(obj)/efi/fixmlehdr ifeq ($(CONFIG_DEBUG_INFO),y) $(if $(filter --strip-debug,$(EFI_LDFLAGS)),echo,:) "Will strip debug inf= o from $(@F)" endif @@ -236,6 +241,8 @@ endif $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T $(obj)/efi.lds $< \ $(dot-target).1r.o $(dot-target).1s.o $(orphan-handling-y) \ $(note_file_option) -o $@ + # take image offset into account + $(obj)/efi/fixmlehdr $@ $(XEN_IMG_OFFSET) $(NM) -pa --format=3Dsysv $@ \ | $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \ > $@.map diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 66e1a21033..5ec2a272a9 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -397,6 +397,12 @@ slaunch_stub_entry: mov %ebx, %esi sub $sym_offs(slaunch_stub_entry), %esi =20 +#ifdef XEN_BUILD_EFI + /* If the flag is already set, then Xen should continue execution.= */ + cmpb $0, sym_esi(slaunch_active) + jne slaunch_efi_jumpback +#endif + /* On AMD, %ebp holds the base address of SLB, save it for later. = */ mov %ebp, %ebx =20 @@ -836,6 +842,124 @@ trampoline_setup: /* Jump into the relocated trampoline. */ lret =20 +#ifdef XEN_BUILD_EFI + + /* + * The state matches that of slaunch_stub_entry above, but with %e= si + * already initialized. + */ +slaunch_efi_jumpback: + lea STACK_SIZE - CPUINFO_sizeof + sym_esi(cpu0_stack), %esp + + /* Prepare gdt and segments. */ + add %esi, sym_esi(gdt_boot_base) + lgdt sym_esi(gdt_boot_descr) + + mov $BOOT_DS, %ecx + mov %ecx, %ds + mov %ecx, %es + mov %ecx, %ss + + push $BOOT_CS32 + lea sym_esi(.Lgdt_is_set),%edx + push %edx + lret +.Lgdt_is_set: + + /* + * Stash TSC as above because it was zeroed on jumping into bootlo= ader + * to not interfere with measurements. + */ + rdtsc + mov %eax, sym_esi(boot_tsc_stamp) + mov %edx, 4 + sym_esi(boot_tsc_stamp) + + /* + * Clear the pagetables before the use. We are loaded below 4GiB a= nd + * this avoids the need for writing to higher dword of each entry. + * Additionally, this ensures those dwords are actually zero and t= he + * mappings aren't manipulated from outside. + */ + lea sym_esi(bootmap_start), %edi + lea sym_esi(bootmap_end), %ecx + sub %edi, %ecx + xor %eax, %eax + shr $2, %ecx + rep stosl + + /* 1x L1 page, 512 entries mapping total of 2M. */ + lea sym_esi(l1_bootmap), %edi + mov $512, %ecx + mov $(__PAGE_HYPERVISOR + 512 * PAGE_SIZE), %edx +.Lfill_l1_identmap: + sub $PAGE_SIZE, %edx + /* Loop runs for ecx=3D[512..1] for entries [511..0], hence -8. */ + mov %edx, -8(%edi,%ecx,8) + loop .Lfill_l1_identmap + + /* 4x L2 pages, each page mapping 1G of RAM. */ + lea sym_esi(l2_bootmap), %edi + /* 1st entry points to L1. */ + lea (sym_offs(l1_bootmap) + __PAGE_HYPERVISOR)(%esi), %edx + mov %edx, (%edi) + /* Other entries are 2MB pages. */ + mov $(4 * 512 - 1), %ecx + /* + * Value below should be 4GB + flags, which wouldn't fit in 32b + * register. To avoid warning from the assembler, 4GB is skipped h= ere. + * Substitution in first iteration makes the value roll over and p= oint + * to 4GB - 2MB + flags. + */ + mov $(_PAGE_PSE + __PAGE_HYPERVISOR), %edx +.Lfill_l2_identmap: + sub $(1 << L2_PAGETABLE_SHIFT), %edx + /* Loop runs for ecx=3D[2047..1] for entries [2047..1]. */ + mov %edx, (%edi,%ecx,8) + loop .Lfill_l2_identmap + + /* 1x L3 page, mapping the 4x L2 pages. */ + lea sym_esi(l3_bootmap), %edi + mov $4, %ecx + lea (sym_offs(l2_bootmap) + 4 * PAGE_SIZE + __PAGE_HYPERVISOR)= (%esi), %edx +.Lfill_l3_identmap: + sub $PAGE_SIZE, %edx + /* Loop runs for ecx=3D[4..1] for entries [3..0], hence -8. */ + mov %edx, -8(%edi,%ecx,8) + loop .Lfill_l3_identmap + + /* 1x L4 page, mapping the L3 page. */ + lea (sym_offs(l3_bootmap) + __PAGE_HYPERVISOR)(%esi), %edx + mov %edx, sym_esi(l4_bootmap) + + /* Restore CR4, PAE must be enabled before IA-32e mode */ + mov %cr4, %ecx + or $X86_CR4_PAE, %ecx + mov %ecx, %cr4 + + /* Load PML4 table location into PT base register */ + lea sym_esi(l4_bootmap), %eax + mov %eax, %cr3 + + /* Enable IA-32e mode and paging */ + mov $MSR_EFER, %ecx + rdmsr + or $EFER_LME >> 8, %ah + wrmsr + + mov %cr0, %eax + or $X86_CR0_PG | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP, %eax + mov %eax, %cr0 + + /* Now in IA-32e compatibility mode, use lret to jump to 64b mode = */ + lea sym_esi(start_xen_from_efi), %ecx + push $BOOT_CS64 + push %ecx + lret + +.global start_xen_from_efi + +#endif /* XEN_BUILD_EFI */ + ENTRY(trampoline_start) #include "trampoline.S" ENTRY(trampoline_end) diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index ac33576d8f..67896f5fe5 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -221,14 +221,22 @@ GLOBAL(__page_tables_end) /* Init pagetables. Enough page directories to map into 4GB. */ .section .init.data, "aw", @progbits =20 -DATA_LOCAL(l1_bootmap, PAGE_SIZE) +bootmap_start: + +DATA_LOCAL(l1_bootmap, PAGE_SIZE) /* 1x L1 page, mapping 2M of RAM. */ .fill L1_PAGETABLE_ENTRIES, 8, 0 END(l1_bootmap) =20 -DATA(l2_bootmap, PAGE_SIZE) +DATA(l2_bootmap, PAGE_SIZE) /* 4x L2 pages, each mapping 1G of RAM. */ .fill 4 * L2_PAGETABLE_ENTRIES, 8, 0 END(l2_bootmap) =20 -DATA(l3_bootmap, PAGE_SIZE) +DATA(l3_bootmap, PAGE_SIZE) /* 1x L3 page, mapping the 4x L2 pages. */ .fill L3_PAGETABLE_ENTRIES, 8, 0 END(l3_bootmap) + +DATA_LOCAL(l4_bootmap, PAGE_SIZE) /* 1x L4 page, mapping the L3 page. */ + .fill L4_PAGETABLE_ENTRIES, 8, 0 +END(l4_bootmap) + +bootmap_end: diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index 0ecf4ca53f..7533e2f12a 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -9,6 +9,12 @@ =20 #include =20 +/* + * Tell to access TXT registers without address translat= ion + * which has not yet been set up. + */ +#define __EARLY_SLAUNCH__ + #include #include #include @@ -17,8 +23,11 @@ #include #include #include +#include +#include =20 static struct file __initdata ucode; +static uint64_t __initdata xen_image_size; static multiboot_info_t __initdata mbi =3D { .flags =3D MBI_MODULES | MBI_LOADERNAME }; @@ -234,10 +243,29 @@ static void __init efi_arch_pre_exit_boot(void) } } =20 -static void __init noreturn efi_arch_post_exit_boot(void) +void __init asmlinkage noreturn start_xen_from_efi(void) { u64 cr4 =3D XEN_MINIMAL_CR4 & ~X86_CR4_PGE, efer; =20 + if ( slaunch_active ) + { + struct slr_table *slrt =3D (struct slr_table *)efi.slr; + struct slr_entry_intel_info *intel_info; + + intel_info =3D (struct slr_entry_intel_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_INTEL_INFO); + if ( intel_info !=3D NULL ) + { + void *txt_heap =3D txt_init(); + struct txt_os_mle_data *os_mle =3D txt_os_mle_data_start(txt_h= eap); + struct txt_os_sinit_data *os_sinit =3D + txt_os_sinit_data_start(txt_heap); + + txt_verify_pmr_ranges(os_mle, os_sinit, intel_info, xen_phys_s= tart, + xen_phys_start, xen_image_size); + } + } + efi_arch_relocate_image(__XEN_VIRT_START - xen_phys_start); memcpy(_p(trampoline_phys), trampoline_start, cfg.size); =20 @@ -283,6 +311,63 @@ static void __init noreturn efi_arch_post_exit_boot(vo= id) unreachable(); } =20 +static void __init attempt_secure_launch(void) +{ + struct slr_table *slrt; + struct slr_entry_dl_info *dlinfo; + dl_handler_func handler_callback; + + /* The presence of this table indicates a Secure Launch boot. */ + slrt =3D (struct slr_table *)efi.slr; + if ( efi.slr =3D=3D EFI_INVALID_TABLE_ADDR || slrt->magic !=3D SLR_TAB= LE_MAGIC || + slrt->revision !=3D SLR_TABLE_REVISION ) + return; + + /* Avoid calls into firmware after DRTM. */ + __clear_bit(EFI_RS, &efi_flags); + + /* + * Make measurements less sensitive to hardware-specific details. + * + * Intentionally leaving efi_ct and efi_num_ct intact. + */ + efi_ih =3D NULL; + efi_bs =3D NULL; + efi_bs_revision =3D 0; + efi_rs =3D NULL; + efi_version =3D 0; + efi_fw_vendor =3D NULL; + efi_fw_revision =3D 0; + StdOut =3D NULL; + StdErr =3D NULL; + boot_tsc_stamp =3D 0; + + slaunch_active =3D true; + slaunch_slrt =3D efi.slr; + + /* Jump through DL stub to initiate Secure Launch. */ + dlinfo =3D (struct slr_entry_dl_info *) + slr_next_entry_by_tag(slrt, NULL, SLR_ENTRY_DL_INFO); + + handler_callback =3D (dl_handler_func)dlinfo->dl_handler; + handler_callback(&dlinfo->bl_context); + + unreachable(); +} + +static void __init noreturn efi_arch_post_exit_boot(void) +{ + /* + * If Secure Launch happens, attempt_secure_launch() doesn't return and + * start_xen_from_efi() is invoked after DRTM has been initiated. + * Otherwise, attempt_secure_launch() returns and execution continues = as + * usual. + */ + attempt_secure_launch(); + + start_xen_from_efi(); +} + static void __init efi_arch_cfg_file_early(const EFI_LOADED_IMAGE *image, EFI_FILE_HANDLE dir_handle, const char *section) @@ -779,6 +864,7 @@ static void __init efi_arch_halt(void) static void __init efi_arch_load_addr_check(const EFI_LOADED_IMAGE *loaded= _image) { xen_phys_start =3D (UINTN)loaded_image->ImageBase; + xen_image_size =3D loaded_image->ImageSize; if ( (xen_phys_start + loaded_image->ImageSize - 1) >> 32 ) blexit(L"Xen must be loaded below 4Gb."); if ( xen_phys_start & ((1 << L2_PAGETABLE_SHIFT) - 1) ) diff --git a/xen/arch/x86/efi/fixmlehdr.c b/xen/arch/x86/efi/fixmlehdr.c new file mode 100644 index 0000000000..60a91c6b73 --- /dev/null +++ b/xen/arch/x86/efi/fixmlehdr.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include + +/* + * Depending on the toolchain and its configuration the header can end up = quite + * far from the start of the file. + */ +#define PREFIX_SIZE (8*1024) + +struct mle_header +{ + uint8_t uuid[16]; + uint32_t header_len; + uint32_t version; + uint32_t entry_point; + uint32_t first_valid_page; + uint32_t mle_start; + uint32_t mle_end; + uint32_t capabilities; + uint32_t cmdline_start; + uint32_t cmdline_end; +} __attribute__ ((packed)); + +static const uint8_t MLE_HEADER_UUID[] =3D { + 0x5a, 0xac, 0x82, 0x90, 0x6f, 0x47, 0xa7, 0x74, + 0x0f, 0x5c, 0x55, 0xa2, 0xcb, 0x51, 0xb6, 0x42 +}; + +int main(int argc, char *argv[]) +{ + FILE *fp; + struct mle_header header; + int i; + char *end_ptr; + long long correction; + const char *file_path; + + if ( argc !=3D 3 ) + { + fprintf(stderr, "Usage: %s \n", argv[0= ]); + return 1; + } + + correction =3D strtoll(argv[2], &end_ptr, 0); + if ( *end_ptr !=3D '\0' ) + { + fprintf(stderr, "Failed to parse '%s' as a number\n", argv[2]); + return 1; + } + if ( correction < INT32_MIN ) + { + fprintf(stderr, "Correction '%s' is too small\n", argv[2]); + return 1; + } + if ( correction > INT32_MAX ) + { + fprintf(stderr, "Correction '%s' is too large\n", argv[2]); + return 1; + } + + file_path =3D argv[1]; + + fp =3D fopen(file_path, "r+"); + if ( fp =3D=3D NULL ) + { + fprintf(stderr, "Failed to open %s\n", file_path); + return 1; + } + + for ( i =3D 0; i < PREFIX_SIZE; i +=3D 16 ) + { + uint8_t bytes[16]; + + if ( fread(bytes, sizeof(bytes), 1, fp) !=3D 1 ) + { + fprintf(stderr, "Failed to find MLE header in %s\n", file_path= ); + goto fail; + } + + if ( memcmp(bytes, MLE_HEADER_UUID, 16) =3D=3D 0 ) + { + break; + } + } + + if ( i >=3D PREFIX_SIZE ) + { + fprintf(stderr, "Failed to find MLE header in %s\n", file_path); + goto fail; + } + + if ( fseek(fp, -16, SEEK_CUR) ) + { + fprintf(stderr, "Failed to seek back to MLE header in %s\n", file_= path); + goto fail; + } + + if ( fread(&header, sizeof(header), 1, fp) !=3D 1 ) + { + fprintf(stderr, "Failed to read MLE header from %s\n", file_path); + goto fail; + } + + if ( fseek(fp, -(int)sizeof(header), SEEK_CUR) ) + { + fprintf(stderr, "Failed to seek back again to MLE header in %s\n", + file_path); + goto fail; + } + + header.entry_point +=3D correction; + + if ( fwrite(&header, sizeof(header), 1, fp) !=3D 1 ) + { + fprintf(stderr, "Failed to write MLE header in %s\n", file_path); + goto fail; + } + + fclose(fp); + return 0; + +fail: + fclose(fp); + return 1; +} diff --git a/xen/arch/x86/slaunch.c b/xen/arch/x86/slaunch.c index 58a0de910d..89e78f498d 100644 --- a/xen/arch/x86/slaunch.c +++ b/xen/arch/x86/slaunch.c @@ -5,6 +5,7 @@ */ =20 #include +#include #include #include #include @@ -245,10 +246,23 @@ check_drtm_policy(const struct slr_table *slrt, { uint32_t i; uint32_t num_mod_entries; + int min_entries; =20 - if ( policy->nr_entries < 2 ) - panic("DRTM policy in SLRT contains less than 2 entries (%d)!\n", - policy->nr_entries); + min_entries =3D efi_enabled(EFI_BOOT) ? 1 : 2; + if ( policy->nr_entries < min_entries ) + { + panic("DRTM policy in SLRT contains less than %d entries (%d)!\n", + min_entries, policy->nr_entries); + } + + if ( efi_enabled(EFI_BOOT) ) + { + check_slrt_policy_entry(&policy_entry[0], 0, slrt); + /* SLRT was measured in tpm_measure_slrt(). */ + return 1; + } + + /* This must be legacy MultiBoot2 boot. */ =20 /* * MBI policy entry must be the first one, so that measuring order mat= ches @@ -317,6 +331,7 @@ void __init slaunch_process_drtm_policy(const struct bo= ot_info *bi) const struct slr_table *slrt; const struct slr_entry_policy *policy; struct slr_policy_entry *policy_entry; + int rc; uint16_t i; unsigned int measured; =20 @@ -331,7 +346,6 @@ void __init slaunch_process_drtm_policy(const struct bo= ot_info *bi) =20 for ( i =3D measured; i < policy->nr_entries; i++ ) { - int rc; uint64_t start =3D policy_entry[i].entity; uint64_t size =3D policy_entry[i].size; =20 @@ -376,6 +390,58 @@ void __init slaunch_process_drtm_policy(const struct b= oot_info *bi) =20 policy_entry[i].flags |=3D SLR_POLICY_FLAG_MEASURED; } + + /* + * On x86 EFI platforms Xen reads its command-line options and kernel/= initrd + * from configuration files (several can be chained). Bootloader can't= know + * contents of the configuration beforehand without parsing it, so the= re + * will be no corresponding policy entries. Instead, measure command-l= ine + * and all modules here. + */ + if ( efi_enabled(EFI_BOOT) ) + { +#define LOG_DATA(str) (uint8_t *)(str), (sizeof(str) - 1) + + tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, + (const uint8_t *)bi->cmdline, strlen(bi->cmdline), + DLE_EVTYPE_SLAUNCH, LOG_DATA("Xen's command line")= ); + + for ( i =3D 0; i < bi->nr_modules; i++ ) + { + const struct boot_module *mod =3D &bi->mods[i]; + + paddr_t string =3D mod->cmdline_pa; + paddr_t start =3D mod->start; + size_t size =3D mod->size; + + if ( mod->relocated || mod->released ) + { + panic("A module \"%s\" (#%d) was consumed before measureme= nt\n", + (const char *)__va(string), i); + } + + /* + * Measuring module's name separately because module's command= -line + * parameters are appended to its name when present. + * + * 2 MiB is minimally mapped size and it should more than suff= ice. + */ + rc =3D slaunch_map_l2(string, 2 * 1024 * 1024); + BUG_ON(rc !=3D 0); + + tpm_hash_extend(DRTM_LOC, DRTM_DATA_PCR, + __va(string), strlen(__va(string)), + DLE_EVTYPE_SLAUNCH, LOG_DATA("MB module string= ")); + + rc =3D slaunch_map_l2(start, size); + BUG_ON(rc !=3D 0); + + tpm_hash_extend(DRTM_LOC, DRTM_CODE_PCR, __va(start), size, + DLE_EVTYPE_SLAUNCH, LOG_DATA("MB module")); + } + +#undef LOG_DATA + } } =20 int __init slaunch_map_l2(unsigned long paddr, unsigned long size) diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index e39fbc3529..35501ee4de 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -19,6 +19,7 @@ #if EFI_PAGE_SIZE !=3D PAGE_SIZE # error Cannot use xen/pfn.h here! #endif +#include #include #include #ifdef CONFIG_X86 @@ -1004,6 +1005,7 @@ static void __init efi_tables(void) static EFI_GUID __initdata mps_guid =3D MPS_TABLE_GUID; static EFI_GUID __initdata smbios_guid =3D SMBIOS_TABLE_GUID; static EFI_GUID __initdata smbios3_guid =3D SMBIOS3_TABLE_GUID; + static EFI_GUID __initdata slr_guid =3D UEFI_SLR_TABLE_GUID; =20 if ( match_guid(&acpi2_guid, &efi_ct[i].VendorGuid) ) efi.acpi20 =3D (unsigned long)efi_ct[i].VendorTable; @@ -1015,6 +1017,8 @@ static void __init efi_tables(void) efi.smbios =3D (unsigned long)efi_ct[i].VendorTable; if ( match_guid(&smbios3_guid, &efi_ct[i].VendorGuid) ) efi.smbios3 =3D (unsigned long)efi_ct[i].VendorTable; + if ( match_guid(&slr_guid, &efi_ct[i].VendorGuid) ) + efi.slr =3D (unsigned long)efi_ct[i].VendorTable; if ( match_guid(&esrt_guid, &efi_ct[i].VendorGuid) ) esrt =3D (UINTN)efi_ct[i].VendorTable; } diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c index 7e1fce291d..e1b339f162 100644 --- a/xen/common/efi/runtime.c +++ b/xen/common/efi/runtime.c @@ -70,6 +70,7 @@ struct efi __read_mostly efi =3D { .mps =3D EFI_INVALID_TABLE_ADDR, .smbios =3D EFI_INVALID_TABLE_ADDR, .smbios3 =3D EFI_INVALID_TABLE_ADDR, + .slr =3D EFI_INVALID_TABLE_ADDR, }; =20 const struct efi_pci_rom *__read_mostly efi_pci_roms; diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h index 160804e294..614dfce66a 100644 --- a/xen/include/xen/efi.h +++ b/xen/include/xen/efi.h @@ -19,6 +19,7 @@ struct efi { unsigned long acpi20; /* ACPI table (ACPI 2.0) */ unsigned long smbios; /* SM BIOS table */ unsigned long smbios3; /* SMBIOS v3 table */ + unsigned long slr; /* SLR table */ }; =20 extern struct efi efi; --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611264; cv=none; d=zohomail.com; s=zohoarc; b=ICIPpaoECWZFBYqap1ZYZ65GEi6YvaoUXswfyJWSVY7xq387w49F6MC9JDBlwcj1bZqUFw9C+nMvqoNxlHP5btA08Br4+LJ/Pl8DcS51I5we46JNqbbWD2+drspigQ6UnztqUk/wn3/nS+fvKWtJNr4AVgJSCqPCq3xx/PyLigs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611264; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ms5Oz9mARFyw7F3TkgqehvFJRD2s1RQlx2UtDwBUcCc=; b=nMIXM+UjTHWIGdv1rMkOsO4v7nR1jnw0q9IPwWevdN/X5k/aBzOMsSV3Cw1GEo1Bv+u1eAXzQaLbBVWNUiHhlCWexuZo/r7MdNjetHNhCk3SWUBMPCzN8fBeyFc6BMkTvnjYLaM1reLwGB1WBMecJk+6nzAWFFEzJn94iHDguFQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1748611264170113.86995100573938; Fri, 30 May 2025 06:21:04 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000979.1381245 (Exim 4.92) (envelope-from ) id 1uKzfH-0007X9-3s; Fri, 30 May 2025 13:20:51 +0000 Received: by outflank-mailman (output) from mailman id 1000979.1381245; Fri, 30 May 2025 13:20:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzfH-0007X2-0X; Fri, 30 May 2025 13:20:51 +0000 Received: by outflank-mailman (input) for mailman id 1000979; Fri, 30 May 2025 13:20:48 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKze7-0003ZU-3j for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:39 +0000 Received: from 4.mo576.mail-out.ovh.net (4.mo576.mail-out.ovh.net [46.105.42.102]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id baae0b70-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:19:34 +0200 (CEST) Received: from director3.ghost.mail-out.ovh.net (unknown [10.108.9.150]) by mo576.mail-out.ovh.net (Postfix) with ESMTP id 4b83jy44vXz33bG for ; Fri, 30 May 2025 13:19:34 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-7mj9p (unknown [10.110.178.161]) by director3.ghost.mail-out.ovh.net (Postfix) with ESMTPS id C68EDC3334; Fri, 30 May 2025 13:19:33 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.98]) by ghost-submission-5b5ff79f4f-7mj9p with ESMTPSA id 3lLgJWWwOWhE4wAAMDjBXw (envelope-from ); Fri, 30 May 2025 13:19:33 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: baae0b70-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-98R0024bd3e58b-6ef2-461f-a919-a86e5b2b2194, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , "Daniel P. Smith" , Ross Philipson , trenchboot-devel@googlegroups.com Subject: [PATCH v3 21/22] x86/cpu: report SMX, TXT and SKINIT capabilities Date: Fri, 30 May 2025 16:18:03 +0300 Message-ID: <6fb0f217027fc323d3c23e94bb99bc56e06f9763.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12710847002492581020 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduvdculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfgggtgfesthekredtredtjeenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpeegkeffieeitdevkefhudegffevieeggfelgedvgeehffdtteehfeeuleeiudekvdenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekgedrvddvuddpfeejrdehledrudegvddrleeknecuvehluhhsthgvrhfuihiivgepgeenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheejiegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=ms5Oz9mARFyw7F3TkgqehvFJRD2s1RQlx2UtDwBUcCc=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611174; v=1; b=C6XLwEEbnykxW5WCFW8jHLZp64xfpb5SRpRsUQdRMVjN7TEmRlNs7QoW1amRsHyG+KqO7z3+ oAXEKrwNcCfSw7IPy9V4jWynYKJ1FaJghakTlgHaxZiQaVIZw77iZMv2SXQVdrUZ24esqF2TBoB gfOUHnlIIbWihbhi80t+CODpnGw1dIV+b9GRnAlvHRXEeoduVU/MqBtXIWil2F5GcP+OkyQIt4t CwbeliALJ8PQFIUwWNeGRLzuNQygt9L40ou5byjwcpQqPHgq1/YuoaCHWoRMBA5IKrErppAYUPc zU8mMFm75oMVQ9XhinXvi0aPSsDbnH42lis7PmUMrV2yA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611265311116600 From: Micha=C5=82 =C5=BBygowski Report TXT capabilities so that dom0 can query the Intel TXT or AMD SKINIT support information using xl dmesg. Signed-off-by: Micha=C5=82 =C5=BBygowski Signed-off-by: Sergii Dmytruk --- xen/arch/x86/cpu/amd.c | 16 ++++++++++ xen/arch/x86/cpu/cpu.h | 1 + xen/arch/x86/cpu/hygon.c | 1 + xen/arch/x86/cpu/intel.c | 46 ++++++++++++++++++++++++++++ xen/arch/x86/include/asm/intel-txt.h | 5 +++ 5 files changed, 69 insertions(+) diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c index 27ae167808..e630a0bb2a 100644 --- a/xen/arch/x86/cpu/amd.c +++ b/xen/arch/x86/cpu/amd.c @@ -688,6 +688,21 @@ void amd_log_freq(const struct cpuinfo_x86 *c) #undef FREQ } =20 +void amd_log_skinit(const struct cpuinfo_x86 *c) +{ + /* + * Run only on BSP and not during resume to report the capability only= once. + */ + if ( system_state !=3D SYS_STATE_resume && smp_processor_id() ) + return; + + printk("CPU: SKINIT capability "); + if ( !test_bit(X86_FEATURE_SKINIT, &boot_cpu_data.x86_capability) ) + printk("not supported\n"); + else + printk("supported\n"); +} + void cf_check early_init_amd(struct cpuinfo_x86 *c) { if (c =3D=3D &boot_cpu_data) @@ -1337,6 +1352,7 @@ static void cf_check init_amd(struct cpuinfo_x86 *c) check_syscfg_dram_mod_en(); =20 amd_log_freq(c); + amd_log_skinit(c); } =20 const struct cpu_dev __initconst_cf_clobber amd_cpu_dev =3D { diff --git a/xen/arch/x86/cpu/cpu.h b/xen/arch/x86/cpu/cpu.h index cbb434f3a2..94132394aa 100644 --- a/xen/arch/x86/cpu/cpu.h +++ b/xen/arch/x86/cpu/cpu.h @@ -24,6 +24,7 @@ extern bool detect_extended_topology(struct cpuinfo_x86 *= c); =20 void cf_check early_init_amd(struct cpuinfo_x86 *c); void amd_log_freq(const struct cpuinfo_x86 *c); +void amd_log_skinit(const struct cpuinfo_x86 *c); void amd_init_lfence(struct cpuinfo_x86 *c); void amd_init_ssbd(const struct cpuinfo_x86 *c); void amd_init_spectral_chicken(void); diff --git a/xen/arch/x86/cpu/hygon.c b/xen/arch/x86/cpu/hygon.c index f7508cc8fc..6ebb8b5fab 100644 --- a/xen/arch/x86/cpu/hygon.c +++ b/xen/arch/x86/cpu/hygon.c @@ -85,6 +85,7 @@ static void cf_check init_hygon(struct cpuinfo_x86 *c) } =20 amd_log_freq(c); + amd_log_skinit(c); } =20 const struct cpu_dev __initconst_cf_clobber hygon_cpu_dev =3D { diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c index ef9368167a..ed9cdd064f 100644 --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -14,6 +14,7 @@ #include #include #include +#include =20 #include "cpu.h" =20 @@ -633,6 +634,49 @@ static void init_intel_perf(struct cpuinfo_x86 *c) } } =20 +/* + * Print out the SMX and TXT capabilties, so that dom0 can determine if the + * system is DRTM-capable. + */ +static void intel_log_smx_txt(void) +{ + unsigned long cr4_val, getsec_caps; + + /* + * Run only on BSP and not during resume to report the capability only= once. + */ + if ( system_state !=3D SYS_STATE_resume && smp_processor_id() ) + return; + + printk("CPU: SMX capability "); + if ( !test_bit(X86_FEATURE_SMX, &boot_cpu_data.x86_capability) ) + { + printk("not supported\n"); + return; + } + printk("supported\n"); + + /* Can't run GETSEC without VMX and SMX */ + if ( !test_bit(X86_FEATURE_VMX, &boot_cpu_data.x86_capability) ) + return; + + cr4_val =3D read_cr4(); + if ( !(cr4_val & X86_CR4_SMXE) ) + write_cr4(cr4_val | X86_CR4_SMXE); + + asm volatile ("getsec\n" + : "=3Da" (getsec_caps) + : "a" (GETSEC_CAPABILITIES), "b" (0) :); + + if ( getsec_caps & GETSEC_CAP_TXT_CHIPSET ) + printk("Chipset supports TXT\n"); + else + printk("Chipset does not support TXT\n"); + + if ( !(cr4_val & X86_CR4_SMXE) ) + write_cr4(cr4_val & ~X86_CR4_SMXE); +} + static void cf_check init_intel(struct cpuinfo_x86 *c) { /* Detect the extended topology information if available */ @@ -647,6 +691,8 @@ static void cf_check init_intel(struct cpuinfo_x86 *c) detect_ht(c); } =20 + intel_log_smx_txt(); + /* Work around errata */ Intel_errata_workarounds(c); =20 diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index c032ebb2e1..af388ade02 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -94,6 +94,11 @@ #define TXT_AP_BOOT_CS 0x0030 #define TXT_AP_BOOT_DS 0x0038 =20 +/* EAX value for GETSEC leaf functions. Intel SDM: GETSEC[CAPABILITIES] */ +#define GETSEC_CAPABILITIES 0 +/* Intel SDM: GETSEC Capability Result Encoding */ +#define GETSEC_CAP_TXT_CHIPSET 1 + #ifndef __ASSEMBLY__ =20 #include --=20 2.49.0 From nobody Fri Oct 31 09:32:50 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1748611333; cv=none; d=zohomail.com; s=zohoarc; b=BGxSLJ7Gz97hjSPjBRjm67QufrIwRE91yzRTaV/DYOd8f+hxPTwvb1mJLZqpe0tAOW/hQ/xgy58RnzHBk4+qrCyenA5KXX9oJb6efNfiraeUq7JMrfGqkXP4AtnSjgSFQ/9CwUgNDk0qgcROgUmUaoMhr4fyVSHirMMh41PXgMM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611333; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=lkr/y2WetCt+mF/LprSnrtNgrDqTmRaZK+50RlJ14fY=; b=IwZjy49qZn0w06dc6snK++vCITXj2pP8k1SzV98hCVc6ItpW6Ll8G0fcpn6AIfY+1OFw0pI4ZsBO5O5NklOnHfCZidZa3Xi/Ps4BxOJKK0qO9l+GwcXBssj4XF9kDaeNVKU3Bkq+6m0rr603QqsEoXNIQJw55fodBDm01+/JR30= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 174861133390679.92600674273172; Fri, 30 May 2025 06:22:13 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1001025.1381306 (Exim 4.92) (envelope-from ) id 1uKzgR-0002yT-Sr; Fri, 30 May 2025 13:22:03 +0000 Received: by outflank-mailman (output) from mailman id 1001025.1381306; Fri, 30 May 2025 13:22:03 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzgR-0002yM-Q0; Fri, 30 May 2025 13:22:03 +0000 Received: by outflank-mailman (input) for mailman id 1001025; Fri, 30 May 2025 13:22:02 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKze9-0003ZU-3n for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:19:41 +0000 Received: from 13.mo583.mail-out.ovh.net (13.mo583.mail-out.ovh.net [87.98.182.191]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id bca85697-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:19:38 +0200 (CEST) Received: from director11.ghost.mail-out.ovh.net (unknown [10.108.17.88]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4b83k15sPTz1khX for ; Fri, 30 May 2025 13:19:37 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-nz9zm (unknown [10.108.42.21]) by director11.ghost.mail-out.ovh.net (Postfix) with ESMTPS id BCE5DC2659; Fri, 30 May 2025 13:19:36 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.95]) by ghost-submission-5b5ff79f4f-nz9zm with ESMTPSA id w/UMHGiwOWi8HAgAWBo3Rw (envelope-from ); Fri, 30 May 2025 13:19:36 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: bca85697-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-95G001fe63952f-1568-4af4-bba7-78aaf58620e7, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , trenchboot-devel@googlegroups.com Subject: [PATCH v3 22/22] MAINTAINERS: add a section for TrenchBoot Slaunch Date: Fri, 30 May 2025 16:18:04 +0300 Message-ID: <113264e01d44acfe2af59cf220fe7124ab49b9e4.1748611041.git.sergii.dmytruk@3mdeb.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 12711691424670921884 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdelheenucevlhhushhtvghrufhiiigvpeefnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehkeefmgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=lkr/y2WetCt+mF/LprSnrtNgrDqTmRaZK+50RlJ14fY=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611177; v=1; b=Qj8nEN04nWAX/lCMM0PYYSItWTnqFv6X+uS/dBFXXu+N/lXoWi849ayCOI8STFzhUPkuiMdh HmcifkPc0oUzP6THKQsImSddJ3BbAjivl3bBYqP6KF/LRFKx3aCPa/NzB47Qcg1MKY9OIXhLmwb usHB+fQu8X5iAjcT4iYyVkmjCnlMkkuNForfsFnQhZiiRKe/Ny2qY7t93EEreTWJv/wgDolFMAx PvPxy2PIG4Y11Ru1hqiME1Vmhxi3e+gtdCPv8Gpdl8ug0Q26O4vKNxgs56C7BUF0A7pHosEjs7I BLHtDd7vESx5b5uG9dPKOPilSMPao7W8jIjw4y/PKS06g== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611336197116600 Content-Type: text/plain; charset="utf-8" Signed-off-by: Sergii Dmytruk --- MAINTAINERS | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index c11b82eca9..5b1e67401a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -542,6 +542,21 @@ F: */configure F: */*.ac F: tools/ =20 +TRENCHBOOT SECURE LAUNCH +M: Daniel P. Smith +R: Ross Philipson +R: Sergii Dmytruk +S: Supported +F: xen/arch/x86/boot/slaunch-early.c +F: xen/arch/x86/efi/fixmlehdr.c +F: xen/arch/x86/include/asm/intel-txt.h +F: xen/arch/x86/include/asm/slaunch.h +F: xen/arch/x86/include/asm/tpm.h +F: xen/arch/x86/intel-txt.c +F: xen/arch/x86/slaunch.c +F: xen/arch/x86/tpm.c +F: xen/include/xen/slr-table.h + VM EVENT, MEM ACCESS and MONITOR M: Tamas K Lengyel R: Alexandru Isaila --=20 2.49.0