From patchwork Thu Sep 14 04:48:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Xin3" X-Patchwork-Id: 139500 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp258518vqi; Thu, 14 Sep 2023 03:53:39 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEAIhTQwlBpSRcvd1QLN7WS9pmNzk8oonxO9zDlQVdQZetmGWQuV2VdlKE31aEacY2CV4iy X-Received: by 2002:a17:902:da92:b0:1bb:b226:52b1 with SMTP id j18-20020a170902da9200b001bbb22652b1mr5746423plx.17.1694688819457; Thu, 14 Sep 2023 03:53:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694688819; cv=none; d=google.com; s=arc-20160816; b=yYZylS0POfQBfUu9i7ja6IYNKM/KuPn7FFwoNkzSKmBHF4MaL9EMxF9A0pMY28ihKr yTDrJrzHoPQdMuMz0wlLflL156VPhTe91LjRI+fo78/ucuw6PTvrfDeAGFFTuFA7FN2S rgcduyfDLR7cUhHkfqjF3SVsiiMdw4oMbd2vqzRnFy/x8mlA+9gnvLM2jXw7DKq6CRPZ ybdkVtOXGM8rilkINWa2MnnsVMP4JZwfSQCBrZLAp4bqudq2IpIgcNmor2M6GF4bdIuv qUJKUP/8crXRvqgIPChkgwL/ADAKnKLjlHumdjY6TnhSuGOfpbC4U7VwT0KfGDT4JVWD yueg== 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=GRF5wBRj/zC+WEC8qjp3589gpuKF0RuoG3nxP7Y+qdc=; fh=jqCbnajAXgJ+s7A1aA7DOHJD13/+EpD442pw8d+Ofss=; b=jHYMRkNVvxe9dh1i75HxbNp+HArr0j9DYZ6RHpMelxvNbmRMKuEoGYg1kPgObR4zJa DvONqbkyA1o1p0s5kAv15g8aD4kmcBytonlHccN8LH3JT89vvvKuiXmCVfL5e+NNDu8h 1P5WvgG6ZzlBynzae/RGbO6buJIFN2gY+vedZw+MNCWzZA/B+cCIC/loVRnsFYDTxeEW xynyk7ObWtwQbFGmstgP9urlczwn/b3iotgaz1DnE8FGHi5xwJsxflNyyNHPWbLDiOfK //fFkr5IN+0KIn9kw5fYS3yK87dEBWciKGNteWjcMaylic09Ek9HX8NldtT6xljvPoGH VJaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=R5bbsZAM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 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 groat.vger.email (groat.vger.email. [2620:137:e000::3:5]) by mx.google.com with ESMTPS id a7-20020a170902b58700b001bd9ae2a3dfsi1383991pls.237.2023.09.14.03.53.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Sep 2023 03:53:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 as permitted sender) client-ip=2620:137:e000::3:5; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=R5bbsZAM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:5 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 groat.vger.email (Postfix) with ESMTP id B0B4C824631A; Wed, 13 Sep 2023 22:21:56 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235890AbjINFVO (ORCPT + 35 others); Thu, 14 Sep 2023 01:21:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235668AbjINFUK (ORCPT ); Thu, 14 Sep 2023 01:20:10 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 49F052681; Wed, 13 Sep 2023 22:19:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694668768; x=1726204768; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oAURox5d3DpugMW7F8/nDRZuIjZAXrI53V5n3V05JaY=; b=R5bbsZAMbaSVWWfaY8eQtTCgn2QRM6lA9doXlheyDlTRT8Mgtg74tAgl 3/fS47hLSvJia6NBuJOh9T+QDKYjCHbLprlvD01csojLNLZWZYrTgM8cq 4fRlRwuVbvi16AxU2daRdn5c/fkj/h/OXyAnD8dDxWk+EygOIHR5OLBEb u9yKW3SnLCIXdFH6Lcl96ikRq6jMu6g9Yx5GV6E4gRdS6Fplcjx6D37jY GsBQaKY3j0ZhINVMi9ltD8bAXU1oAuXdqm2BZV0sf8OY0hkA8YMhNe2Lt 86afIAHXNq1/s+M/JE7X9YIJx797xoDQyPP2/rQm3tXAfr7DRZmfEvCrt g==; X-IronPort-AV: E=McAfee;i="6600,9927,10832"; a="382661549" X-IronPort-AV: E=Sophos;i="6.02,145,1688454000"; d="scan'208";a="382661549" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2023 22:17:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10832"; a="779488850" X-IronPort-AV: E=Sophos;i="6.02,145,1688454000"; d="scan'208";a="779488850" Received: from unknown (HELO fred..) ([172.25.112.68]) by orsmga001.jf.intel.com with ESMTP; 13 Sep 2023 22:17:48 -0700 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 Subject: [PATCH v10 37/38] x86/fred: Add FRED initialization functions Date: Wed, 13 Sep 2023 21:48:04 -0700 Message-Id: <20230914044805.301390-38-xin3.li@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230914044805.301390-1-xin3.li@intel.com> References: <20230914044805.301390-1-xin3.li@intel.com> MIME-Version: 1.0 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 (groat.vger.email [0.0.0.0]); Wed, 13 Sep 2023 22:21:56 -0700 (PDT) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777010023339743759 X-GMAIL-MSGID: 1777010023339743759 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) Co-developed-by: Xin Li Tested-by: Shan Kang 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 f8774611af80..7d507f59315d 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 3269a0e23d3a..8dfdae4111bb 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -47,6 +47,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); +}