From nobody Mon Feb 9 12:58:45 2026 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=1745334454; cv=none; d=zohomail.com; s=zohoarc; b=hYB7iOXK3zMxHnSI68RNm7cTQh3aksIp6NJlYGv2arkFzuwRqGnZ1leXx9/JTplTPqnhuSLt3X3kOEN/wQhuevg4pZvOQNFdkL85D5MP6wJylpL+VPm3+SfGC5dQw09xwV/or7fZmxzRolEfT22q5+kzySdbb1WJ7SmvaOKfDU8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1745334454; 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=zjfvm6tMPNPpoqe92b4S9vihWXD1gBOX5E2QXl7N77Y=; b=kzu0yiY2nW2Zi9IwnbW2xbL1oJy1/PF/gVsZEiIo99ZIIMZ3rAwiV5TUjQ5m4BVNAdSHOb66LtsGF1AXS4mHHyyxbJ/6th7miXTD3PIOGOXl3Pu6PgduMqRkwws5hsIcym+WRDx5lOBEQPRoXaHMPOH5gXw28xgF7GSL6MK3R64= 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 174533445494097.29433569147761; Tue, 22 Apr 2025 08:07:34 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.962757.1353909 (Exim 4.92) (envelope-from ) id 1u7FDK-0000Fa-08; Tue, 22 Apr 2025 15:07:10 +0000 Received: by outflank-mailman (output) from mailman id 962757.1353909; Tue, 22 Apr 2025 15:07:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1u7FDJ-0000FT-Tj; Tue, 22 Apr 2025 15:07:09 +0000 Received: by outflank-mailman (input) for mailman id 962757; Tue, 22 Apr 2025 15:07:08 +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 1u7FDI-0008SP-AM for xen-devel@lists.xenproject.org; Tue, 22 Apr 2025 15:07:08 +0000 Received: from 11.mo583.mail-out.ovh.net (11.mo583.mail-out.ovh.net [46.105.47.167]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 74a6e330-1f8b-11f0-9ffb-bf95429c2676; Tue, 22 Apr 2025 17:07:06 +0200 (CEST) Received: from director8.ghost.mail-out.ovh.net (unknown [10.108.17.23]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4ZhlvY6gTmz1Wvl for ; Tue, 22 Apr 2025 15:07:05 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-pjxff (unknown [10.110.118.174]) by director8.ghost.mail-out.ovh.net (Postfix) with ESMTPS id AEBDD1FE80; Tue, 22 Apr 2025 15:07:04 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.111]) by ghost-submission-5b5ff79f4f-pjxff with ESMTPSA id OXW0GJiwB2ixGAEA3arALQ (envelope-from ); Tue, 22 Apr 2025 15:07: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: 74a6e330-1f8b-11f0-9ffb-bf95429c2676 Authentication-Results: garm.ovh; auth=pass (GARM-111S005bd2e2365-bfb7-40b6-aafa-0791b63c51d7, 7E508E014E7E7C169EB13C6E22C3C4EBF1F0FDD7) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.181.178 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Lukasz Hawrylko , "Daniel P. Smith" , =?UTF-8?q?Mateusz=20M=C3=B3wka?= , trenchboot-devel@googlegroups.com Subject: [PATCH 01/21] x86/include/asm/intel_txt.h: constants and accessors for TXT registers and heap Date: Tue, 22 Apr 2025 18:06:35 +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: 12725202225531434140 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvgeegtdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpefhheefheduieelieekfffgfffgfedutdevleevvdfhfffgledvgfdtuddtheefieenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekuddrudejkedpfeejrdehledrudegvddrudduudenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehkeefmgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=zjfvm6tMPNPpoqe92b4S9vihWXD1gBOX5E2QXl7N77Y=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1745334426; v=1; b=RCQDK2olpwPZN4P76SfneliZU9W7Z5UedOIFN797GT0ejA2ps4nBfSjzWO1rerG/PPG0NMh/ Qlh5FW+uxQdWnd6vwYFQyhw0R5bZPYE4tW7w/5SLA47ew0WJeKwaveSa+fnQM1W9vdbB++fUWuL LMdCEsxZntepzbDc5HOwtxNORZU+U+8M1pGeez1EK8eVZWyeYdPMdnXPquh1qDdoD0ye9YKtM2k E+Ir47gbkI2B2nuSwJH8NyLLReVuVV+xIgXYucQqDS7ot4qM7/kDLdgYtV8DPmPTW7xdprGI0tc X57LLPgbPvttkVyOQnWY5tpouDLhHvoZoEIXS5sja09xw== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1745334455939019100 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel The file contains TXT register spaces base address, registers offsets, error codes and inline functions for accessing structures stored on TXT heap. Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/include/asm/intel_txt.h | 272 +++++++++++++++++++++++++++ xen/arch/x86/tboot.c | 20 +- 2 files changed, 274 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..2cc6eb5be9 --- /dev/null +++ b/xen/arch/x86/include/asm/intel_txt.h @@ -0,0 +1,272 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * 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 + +/* + * The same set of registers is exposed twice (with different permissions)= and + * they are allocated continuously with page alignment. + */ +#define NR_TXT_CONFIG_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 0xc0008001 +#define SLAUNCH_ERROR_TPM_INIT 0xc0008002 +#define SLAUNCH_ERROR_TPM_INVALID_LOG20 0xc0008003 +#define SLAUNCH_ERROR_TPM_LOGGING_FAILED 0xc0008004 +#define SLAUNCH_ERROR_REGION_STRADDLE_4GB 0xc0008005 +#define SLAUNCH_ERROR_TPM_EXTEND 0xc0008006 +#define SLAUNCH_ERROR_MTRR_INV_VCNT 0xc0008007 +#define SLAUNCH_ERROR_MTRR_INV_DEF_TYPE 0xc0008008 +#define SLAUNCH_ERROR_MTRR_INV_BASE 0xc0008009 +#define SLAUNCH_ERROR_MTRR_INV_MASK 0xc000800a +#define SLAUNCH_ERROR_MSR_INV_MISC_EN 0xc000800b +#define SLAUNCH_ERROR_INV_AP_INTERRUPT 0xc000800c +#define SLAUNCH_ERROR_INTEGER_OVERFLOW 0xc000800d +#define SLAUNCH_ERROR_HEAP_WALK 0xc000800e +#define SLAUNCH_ERROR_HEAP_MAP 0xc000800f +#define SLAUNCH_ERROR_REGION_ABOVE_4GB 0xc0008010 +#define SLAUNCH_ERROR_HEAP_INVALID_DMAR 0xc0008011 +#define SLAUNCH_ERROR_HEAP_DMAR_SIZE 0xc0008012 +#define SLAUNCH_ERROR_HEAP_DMAR_MAP 0xc0008013 +#define SLAUNCH_ERROR_HI_PMR_BASE 0xc0008014 +#define SLAUNCH_ERROR_HI_PMR_SIZE 0xc0008015 +#define SLAUNCH_ERROR_LO_PMR_BASE 0xc0008016 +#define SLAUNCH_ERROR_LO_PMR_SIZE 0xc0008017 +#define SLAUNCH_ERROR_LO_PMR_MLE 0xc0008018 +#define SLAUNCH_ERROR_INITRD_TOO_BIG 0xc0008019 +#define SLAUNCH_ERROR_HEAP_ZERO_OFFSET 0xc000801a +#define SLAUNCH_ERROR_WAKE_BLOCK_TOO_SMALL 0xc000801b +#define SLAUNCH_ERROR_MLE_BUFFER_OVERLAP 0xc000801c +#define SLAUNCH_ERROR_BUFFER_BEYOND_PMR 0xc000801d +#define SLAUNCH_ERROR_OS_SINIT_BAD_VERSION 0xc000801e +#define SLAUNCH_ERROR_EVENTLOG_MAP 0xc000801f +#define SLAUNCH_ERROR_TPM_NUMBER_ALGS 0xc0008020 +#define SLAUNCH_ERROR_TPM_UNKNOWN_DIGEST 0xc0008021 +#define SLAUNCH_ERROR_TPM_INVALID_EVENT 0xc0008022 + +#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 read_txt_reg(int reg_no) +{ + volatile uint64_t *reg =3D _txt(TXT_PRIV_CONFIG_REGS_BASE + reg_no); + return *reg; +} + +static inline void write_txt_reg(int reg_no, uint64_t val) +{ + volatile uint64_t *reg =3D _txt(TXT_PRIV_CONFIG_REGS_BASE + reg_no); + *reg =3D val; + /* This serves as TXT register barrier */ + (void)read_txt_reg(TXTCR_ESTS); +} + +static inline void txt_reset(uint32_t error) +{ + write_txt_reg(TXTCR_ERRORCODE, error); + write_txt_reg(TXTCR_CMD_NO_SECRETS, 1); + write_txt_reg(TXTCR_CMD_UNLOCK_MEM_CONFIG, 1); + write_txt_reg(TXTCR_CMD_RESET, 1); + while (1); +} + +/* + * 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 as follows: + * +------------------------------------+ + * | 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. + */ +static inline uint64_t txt_bios_data_size(void *heap) +{ + return *((uint64_t *)heap) - sizeof(uint64_t); +} + +static inline void *txt_bios_data_start(void *heap) +{ + return heap + sizeof(uint64_t); +} + +static inline uint64_t txt_os_mle_data_size(void *heap) +{ + return *((uint64_t *)(txt_bios_data_start(heap) + + txt_bios_data_size(heap))) - + sizeof(uint64_t); +} + +static inline void *txt_os_mle_data_start(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(void *heap) +{ + return *((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(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(void *heap) +{ + return *((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(void *heap) +{ + return txt_os_sinit_data_start(heap) + txt_os_sinit_data_size(heap) + + sizeof(uint64_t); +} + +#endif /* __ASSEMBLY__ */ diff --git a/xen/arch/x86/tboot.c b/xen/arch/x86/tboot.c index d5db60d335..f68354c374 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