public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
	David Woodhouse <dwmw@amazon.co.uk>,
	Peter Zijlstra <peterz@infradead.org>,
	Michael Kelley <mikelley@microsoft.com>,
	Oleksandr Natalenko <oleksandr@natalenko.name>,
	Helge Deller <deller@gmx.de>,
	"Guilherme G . Piccoli" <gpiccoli@igalia.com>,
	Sasha Levin <sashal@kernel.org>,
	mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
	x86@kernel.org, usama.arif@bytedance.com, brgerst@gmail.com,
	jgross@suse.com, jpoimboe@kernel.org, thomas.lendacky@amd.com
Subject: [PATCH AUTOSEL 6.4 02/15] x86/smpboot: Implement a bit spinlock to protect the realmode stack
Date: Sun,  2 Jul 2023 15:40:07 -0400	[thread overview]
Message-ID: <20230702194020.1776895-2-sashal@kernel.org> (raw)
In-Reply-To: <20230702194020.1776895-1-sashal@kernel.org>

From: Thomas Gleixner <tglx@linutronix.de>

[ Upstream commit f6f1ae9128d2a080ecdd55f85e8a0ca3ed1d58eb ]

Parallel AP bringup requires that the APs can run fully parallel through
the early startup code including the real mode trampoline.

To prepare for this implement a bit-spinlock to serialize access to the
real mode stack so that parallel upcoming APs are not going to corrupt each
others stack while going through the real mode startup code.

Co-developed-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Michael Kelley <mikelley@microsoft.com>
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Tested-by: Helge Deller <deller@gmx.de> # parisc
Tested-by: Guilherme G. Piccoli <gpiccoli@igalia.com> # Steam Deck
Link: https://lore.kernel.org/r/20230512205257.355425551@linutronix.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/include/asm/realmode.h      |  3 +++
 arch/x86/kernel/head_64.S            | 12 ++++++++++++
 arch/x86/realmode/init.c             |  3 +++
 arch/x86/realmode/rm/trampoline_64.S | 23 ++++++++++++++++++-----
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
index f6a1737c77be2..87e5482acd0dc 100644
--- a/arch/x86/include/asm/realmode.h
+++ b/arch/x86/include/asm/realmode.h
@@ -52,6 +52,7 @@ struct trampoline_header {
 	u64 efer;
 	u32 cr4;
 	u32 flags;
+	u32 lock;
 #endif
 };
 
@@ -64,6 +65,8 @@ extern unsigned long initial_stack;
 extern unsigned long initial_vc_handler;
 #endif
 
+extern u32 *trampoline_lock;
+
 extern unsigned char real_mode_blob[];
 extern unsigned char real_mode_relocs[];
 
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 113c13376e512..6acf013c3a2c8 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -251,6 +251,16 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
 	movq	pcpu_hot + X86_current_task(%rdx), %rax
 	movq	TASK_threadsp(%rax), %rsp
 
+	/*
+	 * Now that this CPU is running on its own stack, drop the realmode
+	 * protection. For the boot CPU the pointer is NULL!
+	 */
+	movq	trampoline_lock(%rip), %rax
+	testq	%rax, %rax
+	jz	.Lsetup_gdt
+	movl	$0, (%rax)
+
+.Lsetup_gdt:
 	/*
 	 * We must switch to a new descriptor in kernel space for the GDT
 	 * because soon the kernel won't have access anymore to the userspace
@@ -433,6 +443,8 @@ SYM_DATA(initial_code,	.quad x86_64_start_kernel)
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 SYM_DATA(initial_vc_handler,	.quad handle_vc_boot_ghcb)
 #endif
+
+SYM_DATA(trampoline_lock, .quad 0);
 	__FINITDATA
 
 	__INIT
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index af565816d2ba6..788e5559549f3 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -154,6 +154,9 @@ static void __init setup_real_mode(void)
 
 	trampoline_header->flags = 0;
 
+	trampoline_lock = &trampoline_header->lock;
+	*trampoline_lock = 0;
+
 	trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
 
 	/* Map the real mode stub as virtual == physical */
diff --git a/arch/x86/realmode/rm/trampoline_64.S b/arch/x86/realmode/rm/trampoline_64.S
index e38d61d6562e4..4822ad2a5e898 100644
--- a/arch/x86/realmode/rm/trampoline_64.S
+++ b/arch/x86/realmode/rm/trampoline_64.S
@@ -37,6 +37,20 @@
 	.text
 	.code16
 
+.macro LOAD_REALMODE_ESP
+	/*
+	 * Make sure only one CPU fiddles with the realmode stack
+	 */
+.Llock_rm\@:
+        lock btsl       $0, tr_lock
+        jnc             2f
+        pause
+        jmp             .Llock_rm\@
+2:
+	# Setup stack
+	movl	$rm_stack_end, %esp
+.endm
+
 	.balign	PAGE_SIZE
 SYM_CODE_START(trampoline_start)
 	cli			# We should be safe anyway
@@ -49,8 +63,7 @@ SYM_CODE_START(trampoline_start)
 	mov	%ax, %es
 	mov	%ax, %ss
 
-	# Setup stack
-	movl	$rm_stack_end, %esp
+	LOAD_REALMODE_ESP
 
 	call	verify_cpu		# Verify the cpu supports long mode
 	testl   %eax, %eax		# Check for return code
@@ -93,8 +106,7 @@ SYM_CODE_START(sev_es_trampoline_start)
 	mov	%ax, %es
 	mov	%ax, %ss
 
-	# Setup stack
-	movl	$rm_stack_end, %esp
+	LOAD_REALMODE_ESP
 
 	jmp	.Lswitch_to_protected
 SYM_CODE_END(sev_es_trampoline_start)
@@ -177,7 +189,7 @@ SYM_CODE_START(pa_trampoline_compat)
 	 * In compatibility mode.  Prep ESP and DX for startup_32, then disable
 	 * paging and complete the switch to legacy 32-bit mode.
 	 */
-	movl	$rm_stack_end, %esp
+	LOAD_REALMODE_ESP
 	movw	$__KERNEL_DS, %dx
 
 	movl	$(CR0_STATE & ~X86_CR0_PG), %eax
@@ -241,6 +253,7 @@ SYM_DATA_START(trampoline_header)
 	SYM_DATA(tr_efer,		.space 8)
 	SYM_DATA(tr_cr4,		.space 4)
 	SYM_DATA(tr_flags,		.space 4)
+	SYM_DATA(tr_lock,		.space 4)
 SYM_DATA_END(trampoline_header)
 
 #include "trampoline_common.S"
-- 
2.39.2


  reply	other threads:[~2023-07-02 19:42 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-02 19:40 [PATCH AUTOSEL 6.4 01/15] cpu/hotplug: Reset task stack state in _cpu_up() Sasha Levin
2023-07-02 19:40 ` Sasha Levin [this message]
2023-07-03  9:19   ` [EXTERNAL] [PATCH AUTOSEL 6.4 02/15] x86/smpboot: Implement a bit spinlock to protect the realmode stack David Woodhouse
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 03/15] io_uring: annotate offset timeout races Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 04/15] x86/amd_nb: Add MI200 PCI IDs Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 05/15] debugobjects: Recheck debug_objects_enabled before reporting Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 06/15] nbd: Add the maximum limit of allocated index in nbd_dev_add Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 07/15] md: fix data corruption for raid456 when reshape restart while grow up Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 08/15] md/raid10: prevent soft lockup while flush writes Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 09/15] scsi: sg: fix blktrace debugfs entries leakage Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 10/15] blk-mq: fix NULL dereference on q->elevator in blk_mq_elv_switch_none Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 11/15] posix-timers: Ensure timer ID search-loop limit is valid Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 12/15] btrfs: add xxhash to fast checksum implementations Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 13/15] btrfs: don't check PageError in __extent_writepage Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 14/15] btrfs: abort transaction at update_ref_for_cow() when ref count is zero Sasha Levin
2023-07-02 19:40 ` [PATCH AUTOSEL 6.4 15/15] erofs: Fix detection of atomic context Sasha Levin
2023-07-03  9:17 ` [PATCH AUTOSEL 6.4 01/15] cpu/hotplug: Reset task stack state in _cpu_up() David Woodhouse

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230702194020.1776895-2-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=bp@alien8.de \
    --cc=brgerst@gmail.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=deller@gmx.de \
    --cc=dwmw@amazon.co.uk \
    --cc=gpiccoli@igalia.com \
    --cc=jgross@suse.com \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mikelley@microsoft.com \
    --cc=mingo@redhat.com \
    --cc=oleksandr@natalenko.name \
    --cc=peterz@infradead.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=usama.arif@bytedance.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox