Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp210324rdb; Tue, 5 Dec 2023 03:23:52 -0800 (PST) X-Google-Smtp-Source: AGHT+IFsluQtGNrmcxim5nWi/tSyYgtWiacX8LrFBeeUkOW2f2yXCYbhnG5pQgcM+1jXtV8EYwU/ X-Received: by 2002:a05:6a21:3386:b0:18f:97c:4f38 with SMTP id yy6-20020a056a21338600b0018f097c4f38mr3282793pzb.68.1701775432182; Tue, 05 Dec 2023 03:23:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701775432; cv=none; d=google.com; s=arc-20160816; b=03skeKo4P1NOX7osaUAi1UjtxZC2TG0rF/diQgF+rVLFSfWX6KBhTcj30QC2F3jorz +3wpxgw8/Kokz+SXetq4jaZ/m+RV/9cHEx5q+WbxgeQrRJO8rDYjkPwzvT2lFq5RV8Cd HrHks/tM24BLe0BVV8EuBYALWegm/Kz1enqcgua4MNtzxfhY0xxZVic2GpbNMsTkgXGy mDIP4R9r4e9lqxFTfTQ/NiUnycZJN1nS+vuFhGyo1dPYZIEeV3wcgHtaPJPQCTmSgbGW GPBezIgfieEWAMbz59vSZa6A1XLXeZHR8c2dozZIBSoFlCuLVM/sY4Yc+VJs5/vt0B4W dX6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=eijNUFi22BRvA0Sf8lLBLYPdkET1vlTspIR8SWm8f64=; fh=uCCWEUVpLc/xDP/D3WvGY/BxHU9d0NQYu/T71GEsNmA=; b=hMg3oMq8Ptu/jFde7GlROdXiQHiXx0FZRUfQMcX+KQw4AiAC+KSItgd0MVYE2uvp2X 2C2hmxo8Pfu2wWk7V6mgNiUEHpD2sJVFK/KhsJfO9TFCGjMXrjBpTlTlqjWXyIZsWDqR 2c3jio6H7i2iAp9EBhsoQQK50+fsujn9Q/2dKwBdboweticyWln0VWB6pKvqdmgsCw1w 9r3CgVJRoVaDPDj5z2mIOTDcXFnSCk8cwiB9BJBJnV38Hc05Q+ZG/kfgVfa1vHNsRRH9 2E6RanL7tWjjZVPbG7WZU3hg56BjSmJjjk2CZVHETlvqLitbb51p1PBp7sKBMyu7DgiY atjw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=ez7Sozwr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id p3-20020a17090a930300b002864c15489dsi8218378pjo.173.2023.12.05.03.23.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 03:23:52 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=ez7Sozwr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id CABCA80C245E; Tue, 5 Dec 2023 03:23:50 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442363AbjLELXT (ORCPT + 99 others); Tue, 5 Dec 2023 06:23:19 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442104AbjLELVz (ORCPT ); Tue, 5 Dec 2023 06:21:55 -0500 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A577F9A; Tue, 5 Dec 2023 03:21:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701775298; x=1733311298; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hUnJXd4Og3bi9hMQPhy7/57sMPohL9ggwF5nLer6ATE=; b=ez7SozwrQ0xyUHZhi698J8930S41b5SMBVmvFfwB0AsbgjLmt90vWNQr D8fwCzVK47GLD987hgXyD1g2mCu6ma0PbLmU04wCbhzOrXU3sMaHQ7rpa 2TmKshPfhDYKuyCRZa67EQhQ2Nxxi+dnCU2pT1o+8vCRAoFbAxulsYy6Z y5kP/nzNF30v+N4YfOBrwMPKTiV/bLgK5Cx21/+sFgyUNi099I/HxAu6O pt9ccW4KdB7/1wB5+vkoT7feVSijxpHRLsZ4KItocc+v2nrMVpEUb56Ho FZ44fhOSxpFDf+NgH1c2kxI53JBRFEEHxrfB0CGldVfJ6OmAqBtcDFiH/ Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="942741" X-IronPort-AV: E=Sophos;i="6.04,252,1695711600"; d="scan'208";a="942741" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Dec 2023 03:21:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="1018193019" X-IronPort-AV: E=Sophos;i="6.04,252,1695711600"; d="scan'208";a="1018193019" Received: from unknown (HELO fred..) ([172.25.112.68]) by fmsmga006.fm.intel.com with ESMTP; 05 Dec 2023 03:21:26 -0800 From: Xin Li To: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-edac@vger.kernel.org, linux-hyperv@vger.kernel.org, kvm@vger.kernel.org, xen-devel@lists.xenproject.org Cc: tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, luto@kernel.org, pbonzini@redhat.com, seanjc@google.com, peterz@infradead.org, jgross@suse.com, ravi.v.shankar@intel.com, mhiramat@kernel.org, andrew.cooper3@citrix.com, jiangshanlai@gmail.com, nik.borisov@suse.com, shan.kang@intel.com Subject: [PATCH v13 34/35] x86/fred: Add FRED initialization functions Date: Tue, 5 Dec 2023 02:50:23 -0800 Message-ID: <20231205105030.8698-35-xin3.li@intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231205105030.8698-1-xin3.li@intel.com> References: <20231205105030.8698-1-xin3.li@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Tue, 05 Dec 2023 03:23:51 -0800 (PST) From: "H. Peter Anvin (Intel)" Add cpu_init_fred_exceptions() to: - Set FRED entrypoints for events happening in ring 0 and 3. - Specify the stack level for IRQs occurred ring 0. - Specify dedicated event stacks for #DB/NMI/#MCE/#DF. - Enable FRED and invalidtes IDT. - Force 32-bit system calls to use "int $0x80" only. Add fred_complete_exception_setup() to: - Initialize system_vectors as done for IDT systems. - Set unused sysvec_table entries to fred_handle_spurious_interrupt(). Signed-off-by: H. Peter Anvin (Intel) Tested-by: Shan Kang Co-developed-by: Xin Li Signed-off-by: Xin Li --- Changes since v9: * Set unused sysvec table entries to fred_handle_spurious_interrupt() in fred_complete_exception_setup() (Thomas Gleixner). Changes since v5: * Add a comment for FRED stack level settings (Lai Jiangshan). * Define NMI/#DB/#MCE/#DF stack levels using macros. --- arch/x86/entry/entry_fred.c | 21 +++++++++++++ arch/x86/include/asm/fred.h | 5 ++++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/fred.c | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 arch/x86/kernel/fred.c diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c index 3e33a4ab4624..abe66d65fa2d 100644 --- a/arch/x86/entry/entry_fred.c +++ b/arch/x86/entry/entry_fred.c @@ -140,6 +140,27 @@ void __init fred_install_sysvec(unsigned int sysvec, idtentry_t handler) sysvec_table[sysvec - FIRST_SYSTEM_VECTOR] = handler; } +static noinstr void fred_handle_spurious_interrupt(struct pt_regs *regs) +{ + spurious_interrupt(regs, regs->fred_ss.vector); +} + +void __init fred_complete_exception_setup(void) +{ + unsigned int vector; + + for (vector = 0; vector < FIRST_EXTERNAL_VECTOR; vector++) + set_bit(vector, system_vectors); + + for (vector = 0; vector < NR_SYSTEM_VECTORS; vector++) { + if (sysvec_table[vector]) + set_bit(vector + FIRST_SYSTEM_VECTOR, system_vectors); + else + sysvec_table[vector] = fred_handle_spurious_interrupt; + } + fred_setup_done = true; +} + static noinstr void fred_extint(struct pt_regs *regs) { unsigned int vector = regs->fred_ss.vector; diff --git a/arch/x86/include/asm/fred.h b/arch/x86/include/asm/fred.h index 2fa9f34e5c95..e86c7ba32435 100644 --- a/arch/x86/include/asm/fred.h +++ b/arch/x86/include/asm/fred.h @@ -83,8 +83,13 @@ static __always_inline void fred_entry_from_kvm(unsigned int type, unsigned int asm_fred_entry_from_kvm(ss); } +void cpu_init_fred_exceptions(void); +void fred_complete_exception_setup(void); + #else /* CONFIG_X86_FRED */ static __always_inline unsigned long fred_event_data(struct pt_regs *regs) { return 0; } +static inline void cpu_init_fred_exceptions(void) { } +static inline void fred_complete_exception_setup(void) { } static __always_inline void fred_entry_from_kvm(unsigned int type, unsigned int vector) { } #endif /* CONFIG_X86_FRED */ #endif /* !__ASSEMBLY__ */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0000325ab98f..0dcbfc1a4c41 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -48,6 +48,7 @@ obj-y += platform-quirks.o obj-y += process_$(BITS).o signal.o signal_$(BITS).o obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o dumpstack.o nmi.o +obj-$(CONFIG_X86_FRED) += fred.o obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o obj-$(CONFIG_X86_KERNEL_IBT) += ibt_selftest.o obj-y += setup.o x86_init.o i8259.o irqinit.o diff --git a/arch/x86/kernel/fred.c b/arch/x86/kernel/fred.c new file mode 100644 index 000000000000..4bcd8791ad96 --- /dev/null +++ b/arch/x86/kernel/fred.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include + +#include +#include +#include +#include + +/* #DB in the kernel would imply the use of a kernel debugger. */ +#define FRED_DB_STACK_LEVEL 1UL +#define FRED_NMI_STACK_LEVEL 2UL +#define FRED_MC_STACK_LEVEL 2UL +/* + * #DF is the highest level because a #DF means "something went wrong + * *while delivering an exception*." The number of cases for which that + * can happen with FRED is drastically reduced and basically amounts to + * "the stack you pointed me to is broken." Thus, always change stacks + * on #DF, which means it should be at the highest level. + */ +#define FRED_DF_STACK_LEVEL 3UL + +#define FRED_STKLVL(vector, lvl) ((lvl) << (2 * (vector))) + +void cpu_init_fred_exceptions(void) +{ + /* When FRED is enabled by default, remove this log message */ + pr_info("Initialize FRED on CPU%d\n", smp_processor_id()); + + wrmsrl(MSR_IA32_FRED_CONFIG, + /* Reserve for CALL emulation */ + FRED_CONFIG_REDZONE | + FRED_CONFIG_INT_STKLVL(0) | + FRED_CONFIG_ENTRYPOINT(asm_fred_entrypoint_user)); + + /* + * The purpose of separate stacks for NMI, #DB and #MC *in the kernel* + * (remember that user space faults are always taken on stack level 0) + * is to avoid overflowing the kernel stack. + */ + wrmsrl(MSR_IA32_FRED_STKLVLS, + FRED_STKLVL(X86_TRAP_DB, FRED_DB_STACK_LEVEL) | + FRED_STKLVL(X86_TRAP_NMI, FRED_NMI_STACK_LEVEL) | + FRED_STKLVL(X86_TRAP_MC, FRED_MC_STACK_LEVEL) | + FRED_STKLVL(X86_TRAP_DF, FRED_DF_STACK_LEVEL)); + + /* The FRED equivalents to IST stacks... */ + wrmsrl(MSR_IA32_FRED_RSP1, __this_cpu_ist_top_va(DB)); + wrmsrl(MSR_IA32_FRED_RSP2, __this_cpu_ist_top_va(NMI)); + wrmsrl(MSR_IA32_FRED_RSP3, __this_cpu_ist_top_va(DF)); + + /* Enable FRED */ + cr4_set_bits(X86_CR4_FRED); + /* Any further IDT use is a bug */ + idt_invalidate(); + + /* Use int $0x80 for 32-bit system calls in FRED mode */ + setup_clear_cpu_cap(X86_FEATURE_SYSENTER32); + setup_clear_cpu_cap(X86_FEATURE_SYSCALL32); +} -- 2.43.0