From nobody Tue Feb 10 03:04:34 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=1745334459; cv=none; d=zohomail.com; s=zohoarc; b=BNPiLj1n1tjwhRT+72BdyAuUYcBHI+zkDNSOZISz+hmh652UaBr5g2Mf1YaTSWE8La24zUY7sPSZqxTjJ8vVl7eTgK2LOnCgBXxy7Lg+xq2UUgIgFlKUC22MsDw6R1nh8iURDkWNU7kKjIpf0ARe3/Ut31ztBA5Vu0VZoU2C+t4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1745334459; 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=sDqAgp/M0rnx3UyLlpBLSL73Y4pMrP7a5rwyrX+6GX8=; b=HUNHATAhI8Y1P4s5jkcDiYG85l/ztDrYZavZR6FtlbMbmfWCptRTy7+OA/FHckGRIghFQmq7ceI65IzrjiJgARM0J4PTRCxGsH8KV6SBqeo/TBix+qJ2sgHiPEqn/R7eyhxufLobSkO/lZtIPjpfCOIzQItmALmS8uGmBCHaK5g= 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 1745334459894729.8220440306484; Tue, 22 Apr 2025 08:07:39 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.962761.1353949 (Exim 4.92) (envelope-from ) id 1u7FDW-0001RV-A7; Tue, 22 Apr 2025 15:07:22 +0000 Received: by outflank-mailman (output) from mailman id 962761.1353949; Tue, 22 Apr 2025 15:07: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 1u7FDW-0001RM-6J; Tue, 22 Apr 2025 15:07:22 +0000 Received: by outflank-mailman (input) for mailman id 962761; Tue, 22 Apr 2025 15:07: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 1u7FDU-0008SP-8g for xen-devel@lists.xenproject.org; Tue, 22 Apr 2025 15:07:20 +0000 Received: from 7.mo561.mail-out.ovh.net (7.mo561.mail-out.ovh.net [46.105.57.200]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 7bd5597b-1f8b-11f0-9ffb-bf95429c2676; Tue, 22 Apr 2025 17:07:18 +0200 (CEST) Received: from director6.ghost.mail-out.ovh.net (unknown [10.109.148.7]) by mo561.mail-out.ovh.net (Postfix) with ESMTP id 4Zhlvp1ZgRz1bl7 for ; Tue, 22 Apr 2025 15:07:18 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-2rjjd (unknown [10.110.96.65]) by director6.ghost.mail-out.ovh.net (Postfix) with ESMTPS id 7D1F31FECD; Tue, 22 Apr 2025 15:07:17 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.109]) by ghost-submission-5b5ff79f4f-2rjjd with ESMTPSA id LdyRDaWwB2htQAEAITd0qQ (envelope-from ); Tue, 22 Apr 2025 15:07:17 +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: 7bd5597b-1f8b-11f0-9ffb-bf95429c2676 Authentication-Results: garm.ovh; auth=pass (GARM-109S003a3e5d368-64c5-4915-82bc-18f6a6b58197, 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?= , trenchboot-devel@googlegroups.com Subject: [PATCH 05/21] x86/boot/slaunch_early: early TXT checks and boot data retrieval Date: Tue, 22 Apr 2025 18:06:39 +0300 Message-ID: <86c2de54e0ebcd1632b921c56858cc77eba51ee1.1745172094.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: 12728861399315887260 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgddvgeegtdehucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpefhheefheduieelieekfffgfffgfedutdevleevvdfhfffgledvgfdtuddtheefieenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekuddrudejkedpfeejrdehledrudegvddruddtleenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehiedumgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=sDqAgp/M0rnx3UyLlpBLSL73Y4pMrP7a5rwyrX+6GX8=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1745334438; v=1; b=Zuu/Of5ekkE/TpMsCupV07C79TRv0Y+ECiG3wE2Tn188knJG6/3dQHIdUr3k8aGZ49d24LhE apO9r32EhL8IhIA5bYTgdjlDZ2SkqBik7e11/noVBmGyhjmaejzqSNmZVZbxnr52eaQEfHtQz7Z lNHxT5lO3PVllnrhc1xwirbqSPsc4st9hOeQlCb/AKgx57s+loVoqotajp9lwKbUcLB2E+Y1880 pA4bpxf4uX/vjWSP4yrDKrok4G/OGDYCl2Z+FG118lioYHOqmAPQDzmBR4l3vlCGjUGkCgf/CVa IjJOS/us1lUhu7ukKvMKNIKrgigivggJIs/hNMQgzEyxQ== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1745334460393019000 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 | 111 +++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/xen/arch/x86/boot/slaunch_early.c b/xen/arch/x86/boot/slaunch_= early.c index 177267248f..af8aa29ae0 100644 --- a/xen/arch/x86/boot/slaunch_early.c +++ b/xen/arch/x86/boot/slaunch_early.c @@ -22,10 +22,13 @@ void slaunch_early_init(uint32_t load_base_addr, void *txt_heap; struct txt_os_mle_data *os_mle; struct slr_table *slrt; + struct txt_os_sinit_data *os_sinit; 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 slaunch_early_init(uint32_t load_base_addr, 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 b973640c56..7170baf6fb 100644 --- a/xen/arch/x86/include/asm/intel_txt.h +++ b/xen/arch/x86/include/asm/intel_txt.h @@ -81,6 +81,8 @@ =20 #ifndef __ASSEMBLY__ =20 +#include + /* Need to differentiate between pre- and post paging enabled. */ #ifdef __EARLY_SLAUNCH__ #include @@ -285,4 +287,113 @@ static inline void *txt_init(void) return txt_heap; } =20 +static inline int is_in_pmr(struct txt_os_sinit_data *os_sinit, uint64_t b= ase, + 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(struct txt_os_mle_data *os_mle, + struct txt_os_sinit_data *os_sini= t, + 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 2.49.0