From nobody Sat Oct 4 23:47:53 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; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1759532063; cv=none; d=zohomail.com; s=zohoarc; b=kiliPd6ZFrcg0GdzVsK2M2o/7Ai1xjlCosdKf4LTMWuLkH7rvC+gVM8RsMVA4fmt74YAI8P6gff0lXnttN3kbDknHqaSxHHBIs4catA//y+0JshgxKkGMyaorG4/5iZLDuRJUpNq5DY1U5aBruE612Un9lYku1uOY0IunClnA80= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759532063; 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=ZB02FQCtZ7HQMg+a6BPzi5/pgcHeCMvxoE+tfd+QO6E=; b=mGRVh6l0BkeSHiDeLN/GaoNy7kPlIY265gcJMd8uQQNLfpBBUlkv68rl00uOu3VBUS4yUp2IYFWjZR1bYmZ5mZ1Mlu+MvQWEUYL2f7GTa3nXIYNebPuJbDbiT8ArePtQfe3HCgW3W9XCXxKLCBEAj5RX0ZMXrlmKB1m45XCUaNU= 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; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1759532063386454.884193092395; Fri, 3 Oct 2025 15:54:23 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1136903.1473416 (Exim 4.92) (envelope-from ) id 1v4of1-0007pI-RT; Fri, 03 Oct 2025 22:53:59 +0000 Received: by outflank-mailman (output) from mailman id 1136903.1473416; Fri, 03 Oct 2025 22:53:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1v4of1-0007mf-Il; Fri, 03 Oct 2025 22:53:59 +0000 Received: by outflank-mailman (input) for mailman id 1136903; Fri, 03 Oct 2025 22:53:57 +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 1v4oez-0004mF-P5 for xen-devel@lists.xenproject.org; Fri, 03 Oct 2025 22:53:57 +0000 Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [2a00:1450:4864:20::32e]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id d805581f-a0ab-11f0-9d14-b5c5bf9af7f9; Sat, 04 Oct 2025 00:53:57 +0200 (CEST) Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-46e326e4e99so20303505e9.1 for ; Fri, 03 Oct 2025 15:53:57 -0700 (PDT) Received: from localhost.localdomain (host-92-22-57-86.as13285.net. [92.22.57.86]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4255d8a6bbesm9616571f8f.12.2025.10.03.15.53.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Oct 2025 15:53:55 -0700 (PDT) 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: d805581f-a0ab-11f0-9d14-b5c5bf9af7f9 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1759532036; x=1760136836; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZB02FQCtZ7HQMg+a6BPzi5/pgcHeCMvxoE+tfd+QO6E=; b=Vo0xUkl5gAxFKKGtGhWUtuQIP6NXNAnYbLw6n28mueER/d8A7V35zwswXXwSSjocdA LNIiTFdhwDATzxhHtiGhiQuexf9wtVbzjLq7oPsO6fu1MHdB5aXhpZGT82Gw/Lo2wg7s 7DgJVLZhaz4k8RoaO5zhrFibpwBlkAARjonbM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759532036; x=1760136836; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZB02FQCtZ7HQMg+a6BPzi5/pgcHeCMvxoE+tfd+QO6E=; b=uL8BGYUfdOk0Xiood4nwK8N/LjV8Rb5+J6bk8bw95m+fBpcXTaGBJC1HPtfaan7pKT tsOnfEYKnwaN5GjFFVriSTnVR6kFHALVE1k0quWIothttKs7nhjzKKy61qpVR7XZrWG6 nN4STD5ZVAVSy8i5HEJGY83AOGz4dUzNJms/mT93J8DvrcX8v3X1uPBek2FIzfBiUF6X vZyw4SKOpFk+2Z0gbvZ1tScjgp9vNXA0f3TXCCsFpUPYHasw2mvOvu4prEJ99a1rzva4 2Qf5KcZ52CaiE2yXWFGacijI5GWct5AHWIh2/VOv69Prk5kxOagvLLAqbDQDQxrzxA11 Ma8A== X-Gm-Message-State: AOJu0YzsJUHdgcvsxcfiVRgQOfb+mY9i9F0so6YBZ3JfI9wc499Ffta4 ThE9sMZhb5gVFWLBhZ2M3yK8s6IZPEnMgbSVBv4Ol9DwEz2pMpLzsCeA8+gBewQv1ulqvrY9Nk5 c9uN7tnSNPA== X-Gm-Gg: ASbGncuZWeYHRUN+0lulCVdf5Hd/wltzQq4vtK9Tvp2YT4Y/KivVnm8xoM9jwWUJBvp LiPC2H7PDM3NVmDpgV5VYRt+cDiGvEXk6FWU5NYe10v+CibF+b87UiSq6z6gOxCSfhT4Io6Wb+/ JJdTMkq3jsxxrdX0zzIGVfg/2mLnPOjorNlZj+8FwYmhIj7aL46Xh0iyK0iTryd+6621NV1eQ31 uWkewOm6S8iTYBfnKYaAIgzRcQ9vdzLk82xKt2M9cCpkqsoJTwtIGVbunKbeExmF4zYh5FXO4Ak ML4tBSK8LzUljlRnDhOnH33/KoNdSw6NZ8BUCSmy/7vRkpmYOwJOcdZWkkAaAY0XfJeQsSbr6Bz bHrwZd3GzcudgLJC6Iik88hI7SEl+954M1CLW3iWD7CeN1joTP7Hu7BNx14opAG26DkPAw7hRYC ZpLYpbwO2KFHu1nLMPKdJ8JnIfQES/Ypk= X-Google-Smtp-Source: AGHT+IHDojY8NuOAkeDeOCm7hdMc7HP70ugcxmaKP4MOK/BXN/C9Zg+Cvz+hNWk+dwRPTfEr6AYdww== X-Received: by 2002:a5d:64e9:0:b0:3e7:6424:1b47 with SMTP id ffacd0b85a97d-42566c00d2fmr3521319f8f.6.1759532036300; Fri, 03 Oct 2025 15:53:56 -0700 (PDT) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH v3 13/22] x86/traps: Enable FRED when requested Date: Fri, 3 Oct 2025 23:53:25 +0100 Message-Id: <20251003225334.2123667-14-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20251003225334.2123667-1-andrew.cooper3@citrix.com> References: <20251003225334.2123667-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1759532064885116601 With the shadow stack and exception handling adjustements in place, we can = now activate FRED when appropriate. Note that opt_fred is still disabled by default. Introduce init_fred() to set up all the MSRs relevant for FRED. FRED uses MSR_STAR (entries from Ring3 only), and MSR_FRED_SSP_SL0 aliases MSR_PL0_SSP when CET-SS is active. Otherwise, they're all new MSRs. With init_fred() existing, load_system_tables() and legacy_syscall_init() should only be used when setting up IDT delivery. Insert ASSERT()s to this effect, and adjust the various *_init() functions to make this property tru= e. Per the documentation, percpu_early_traps_init() is responsible for switchi= ng off the boot GDT, which needs doing even in FRED mode. Finally, set CR4.FRED in traps_init()/percpu_early_traps_init(). Xen can now boot in FRED mode up until starting a PV guest, where it faults because IRET is not permitted to change privilege. Signed-off-by: Andrew Cooper --- CC: Jan Beulich CC: Roger Pau Monn=C3=A9 v3: * Fix poisoning of SL1 pointers. * Adjust bsp_traps_reinit(). It probably doesn't matter. v2: * Explain the lack of BUG_ON() * Posion SL1 In principle we can stop allocating the IDT and TSS for CPUs now, although I want to get shutdown and kexec working before making this optimisation, in case there's something I've overlooked. --- xen/arch/x86/include/asm/current.h | 3 ++ xen/arch/x86/include/asm/traps.h | 2 + xen/arch/x86/traps-setup.c | 83 ++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/include/asm/current.h b/xen/arch/x86/include/asm/= current.h index 62817e8476ec..6139980ab115 100644 --- a/xen/arch/x86/include/asm/current.h +++ b/xen/arch/x86/include/asm/current.h @@ -23,6 +23,9 @@ * 2 - NMI IST stack * 1 - #MC IST stack * 0 - IST Shadow Stacks (4x 1k, read-only) + * + * In FRED mode, #DB and NMI do not need special stacks, so their IST stac= ks + * are unused. */ =20 /* diff --git a/xen/arch/x86/include/asm/traps.h b/xen/arch/x86/include/asm/tr= aps.h index 73097e957d05..5d7504bc44d1 100644 --- a/xen/arch/x86/include/asm/traps.h +++ b/xen/arch/x86/include/asm/traps.h @@ -16,6 +16,8 @@ void traps_init(void); void bsp_traps_reinit(void); void percpu_traps_init(void); =20 +void nocall entry_FRED_R3(void); + extern unsigned int ler_msr; =20 const char *vector_name(unsigned int vec); diff --git a/xen/arch/x86/traps-setup.c b/xen/arch/x86/traps-setup.c index d77be8f83921..d937209ae606 100644 --- a/xen/arch/x86/traps-setup.c +++ b/xen/arch/x86/traps-setup.c @@ -59,6 +59,8 @@ static void load_system_tables(void) .limit =3D sizeof(bsp_idt) - 1, }; =20 + ASSERT(opt_fred =3D=3D 0); + /* * Set up the TSS. Warning - may be live, and the NMI/#MC must remain * valid on every instruction boundary. (Note: these are all @@ -191,6 +193,8 @@ static void legacy_syscall_init(void) unsigned char *stub_page; unsigned int offset; =20 + ASSERT(opt_fred =3D=3D 0); + /* No PV guests? No need to set up SYSCALL/SYSENTER infrastructure. */ if ( !IS_ENABLED(CONFIG_PV) ) return; @@ -268,6 +272,52 @@ static void __init init_ler(void) setup_force_cpu_cap(X86_FEATURE_XEN_LBR); } =20 +/* + * Set up all MSRs relevant for FRED event delivery. + * + * Xen does not use any of the optional config in MSR_FRED_CONFIG, so all = that + * is needed is the entrypoint. + * + * Because FRED always provides a good stack, NMI and #DB do not need any + * special treatment. Only #DF needs another stack level, and #MC for the + * offchance that Xen's main stack suffers an uncorrectable error. + * + * This makes Stack Level 1 unused, but we use #DB's stacks, and with the + * regular and shadow stacks reversed as posion to guarantee that any use + * escalates to #DF. + * + * FRED reuses MSR_STAR to provide the segment selector values to load on + * entry from Ring3. Entry from Ring0 leave %cs and %ss unmodified. + */ +static void init_fred(void) +{ + unsigned long stack_top =3D get_stack_bottom() & ~(STACK_SIZE - 1); + + ASSERT(opt_fred =3D=3D 1); + + wrmsrns(MSR_STAR, XEN_MSR_STAR); + wrmsrns(MSR_FRED_CONFIG, (unsigned long)entry_FRED_R3); + + /* + * MSR_FRED_RSP_* all come with an 64-byte alignment check, avoiding t= he + * need for an explicit BUG_ON(). + */ + wrmsrns(MSR_FRED_RSP_SL0, (unsigned long)(&get_cpu_info()->_fred + 1)); + wrmsrns(MSR_FRED_RSP_SL1, stack_top + (IST_DB * IST_SHSTK_SIZE)); /* P= oison */ + wrmsrns(MSR_FRED_RSP_SL2, stack_top + (1 + IST_MCE) * PAGE_SIZE); + wrmsrns(MSR_FRED_RSP_SL3, stack_top + (1 + IST_DF) * PAGE_SIZE); + wrmsrns(MSR_FRED_STK_LVLS, ((2UL << (X86_EXC_MC * 2)) | + (3UL << (X86_EXC_DF * 2)))); + + if ( cpu_has_xen_shstk ) + { + wrmsrns(MSR_FRED_SSP_SL0, stack_top + (PRIMARY_SHSTK_SLOT + 1) * P= AGE_SIZE); + wrmsrns(MSR_FRED_SSP_SL1, stack_top + (1 + IST_DB) * PAGE_SIZE); /= * Poison */ + wrmsrns(MSR_FRED_SSP_SL2, stack_top + (IST_MCE * IST_SHSTK_SIZE)); + wrmsrns(MSR_FRED_SSP_SL3, stack_top + (IST_DF * IST_SHSTK_SIZE)); + } +} + /* * Configure basic exception handling. This is prior to parsing the comma= nd * line or configuring a console, and needs to be as simple as possible. @@ -329,16 +379,20 @@ void __init traps_init(void) printk(XENLOG_INFO "Disabling PV32 due to FRED\n"); } #endif + + init_fred(); + set_in_cr4(X86_CR4_FRED); + setup_force_cpu_cap(X86_FEATURE_XEN_FRED); printk("Using FRED event delivery\n"); } else { + load_system_tables(); + printk("Using IDT event delivery\n"); } =20 - load_system_tables(); - init_ler(); =20 /* Cache {,compat_}gdt_l1e now that physically relocation is done. */ @@ -356,7 +410,11 @@ void __init traps_init(void) */ void __init bsp_traps_reinit(void) { - load_system_tables(); + if ( opt_fred ) + init_fred(); + else + load_system_tables(); + percpu_traps_init(); } =20 @@ -366,7 +424,8 @@ void __init bsp_traps_reinit(void) */ void percpu_traps_init(void) { - legacy_syscall_init(); + if ( !opt_fred ) + legacy_syscall_init(); =20 if ( cpu_has_xen_lbr ) wrmsrl(MSR_IA32_DEBUGCTLMSR, IA32_DEBUGCTLMSR_LBR); @@ -381,7 +440,21 @@ void percpu_traps_init(void) */ void asmlinkage percpu_early_traps_init(void) { - load_system_tables(); + if ( opt_fred ) + { + const seg_desc_t *gdt =3D this_cpu(gdt) - FIRST_RESERVED_GDT_ENTRY; + const struct desc_ptr gdtr =3D { + .base =3D (unsigned long)gdt, + .limit =3D LAST_RESERVED_GDT_BYTE, + }; + + lgdt(&gdtr); + + init_fred(); + write_cr4(read_cr4() | X86_CR4_FRED); + } + else + load_system_tables(); } =20 static void __init __maybe_unused build_assertions(void) --=20 2.39.5