All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@vger.kernel.org
Cc: Ard Biesheuvel <ardb@kernel.org>,
	Kevin Loughlin <kevinloughlin@google.com>,
	 Tom Lendacky <thomas.lendacky@amd.com>,
	Dionna Glaze <dionnaglaze@google.com>,
	 Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	 Dave Hansen <dave.hansen@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>,  Arnd Bergmann <arnd@arndb.de>,
	Nathan Chancellor <nathan@kernel.org>,
	 Nick Desaulniers <ndesaulniers@google.com>,
	Justin Stitt <justinstitt@google.com>,
	 Kees Cook <keescook@chromium.org>,
	Brian Gerst <brgerst@gmail.com>,
	linux-arch@vger.kernel.org,  llvm@lists.linux.dev
Subject: [PATCH v4 01/11] x86/startup_64: Simplify global variable accesses in GDT/IDT programming
Date: Tue, 13 Feb 2024 13:41:45 +0100	[thread overview]
Message-ID: <20240213124143.1484862-14-ardb+git@google.com> (raw)
In-Reply-To: <20240213124143.1484862-13-ardb+git@google.com>

From: Ard Biesheuvel <ardb@kernel.org>

There are two code paths in the startup code to program an IDT: one that
runs from the 1:1 mapping and one that runs from the virtual kernel
mapping. Currently, these are strictly separate because fixup_pointer()
is used on the 1:1 path, which will produce the wrong value when used
while executing from the virtual kernel mapping.

Switch to RIP_REL_REF() so that the two code paths can be merged. Also,
move the GDT and IDT descriptors to the stack so that they can be
referenced directly, rather than via RIP_REL_REF().

Rename startup_64_setup_env() to startup_64_setup_gdt_idt() while at it,
to make the call from assembler self-documenting.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/include/asm/setup.h |  2 +-
 arch/x86/kernel/head64.c     | 56 +++++++-------------
 arch/x86/kernel/head_64.S    |  4 +-
 3 files changed, 22 insertions(+), 40 deletions(-)

diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 5c83729c8e71..e61e68d71cba 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -48,7 +48,7 @@ extern unsigned long saved_video_mode;
 extern void reserve_standard_io_resources(void);
 extern void i386_reserve_resources(void);
 extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp);
-extern void startup_64_setup_env(unsigned long physbase);
+extern void startup_64_setup_gdt_idt(void);
 extern void early_setup_idt(void);
 extern void __init do_early_exception(struct pt_regs *regs, int trapnr);
 
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index dc0956067944..9d7f12829f2d 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -22,6 +22,7 @@
 #include <linux/cc_platform.h>
 #include <linux/pgtable.h>
 
+#include <asm/asm.h>
 #include <asm/processor.h>
 #include <asm/proto.h>
 #include <asm/smp.h>
@@ -76,15 +77,6 @@ static struct desc_struct startup_gdt[GDT_ENTRIES] __initdata = {
 	[GDT_ENTRY_KERNEL_DS]           = GDT_ENTRY_INIT(DESC_DATA64, 0, 0xfffff),
 };
 
-/*
- * Address needs to be set at runtime because it references the startup_gdt
- * while the kernel still uses a direct mapping.
- */
-static struct desc_ptr startup_gdt_descr __initdata = {
-	.size = sizeof(startup_gdt)-1,
-	.address = 0,
-};
-
 static void __head *fixup_pointer(void *ptr, unsigned long physaddr)
 {
 	return ptr - (void *)_text + (void *)physaddr;
@@ -569,12 +561,7 @@ void __init __noreturn x86_64_start_reservations(char *real_mode_data)
  */
 static gate_desc bringup_idt_table[NUM_EXCEPTION_VECTORS] __page_aligned_data;
 
-static struct desc_ptr bringup_idt_descr = {
-	.size		= (NUM_EXCEPTION_VECTORS * sizeof(gate_desc)) - 1,
-	.address	= 0, /* Set at runtime */
-};
-
-static void set_bringup_idt_handler(gate_desc *idt, int n, void *handler)
+static void __head set_bringup_idt_handler(gate_desc *idt, int n, void *handler)
 {
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 	struct idt_data data;
@@ -586,45 +573,42 @@ static void set_bringup_idt_handler(gate_desc *idt, int n, void *handler)
 #endif
 }
 
-/* This runs while still in the direct mapping */
-static void __head startup_64_load_idt(unsigned long physbase)
+/* This may run while still in the direct mapping */
+static void __head startup_64_load_idt(void *handler)
 {
-	struct desc_ptr *desc = fixup_pointer(&bringup_idt_descr, physbase);
-	gate_desc *idt = fixup_pointer(bringup_idt_table, physbase);
-
-
-	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
-		void *handler;
+	struct desc_ptr desc = {
+		.address	= (unsigned long)&RIP_REL_REF(bringup_idt_table),
+		.size		= sizeof(bringup_idt_table) - 1,
+	};
+	gate_desc *idt = (gate_desc *)desc.address;
 
+	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))
 		/* VMM Communication Exception */
-		handler = fixup_pointer(vc_no_ghcb, physbase);
 		set_bringup_idt_handler(idt, X86_TRAP_VC, handler);
-	}
 
-	desc->address = (unsigned long)idt;
-	native_load_idt(desc);
+	native_load_idt(&desc);
 }
 
 /* This is used when running on kernel addresses */
 void early_setup_idt(void)
 {
-	/* VMM Communication Exception */
-	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) {
+	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))
 		setup_ghcb();
-		set_bringup_idt_handler(bringup_idt_table, X86_TRAP_VC, vc_boot_ghcb);
-	}
 
-	bringup_idt_descr.address = (unsigned long)bringup_idt_table;
-	native_load_idt(&bringup_idt_descr);
+	startup_64_load_idt(vc_boot_ghcb);
 }
 
 /*
  * Setup boot CPU state needed before kernel switches to virtual addresses.
  */
-void __head startup_64_setup_env(unsigned long physbase)
+void __head startup_64_setup_gdt_idt(void)
 {
+	struct desc_ptr startup_gdt_descr = {
+		.address	= (unsigned long)&RIP_REL_REF(startup_gdt),
+		.size		= sizeof(startup_gdt) - 1,
+	};
+
 	/* Load GDT */
-	startup_gdt_descr.address = (unsigned long)fixup_pointer(startup_gdt, physbase);
 	native_load_gdt(&startup_gdt_descr);
 
 	/* New GDT is live - reload data segment registers */
@@ -632,5 +616,5 @@ void __head startup_64_setup_env(unsigned long physbase)
 		     "movl %%eax, %%ss\n"
 		     "movl %%eax, %%es\n" : : "a"(__KERNEL_DS) : "memory");
 
-	startup_64_load_idt(physbase);
+	startup_64_load_idt(&RIP_REL_REF(vc_no_ghcb));
 }
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index d4918d03efb4..3cac98c61066 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -68,8 +68,6 @@ SYM_CODE_START_NOALIGN(startup_64)
 	/* Set up the stack for verify_cpu() */
 	leaq	(__end_init_task - PTREGS_SIZE)(%rip), %rsp
 
-	leaq	_text(%rip), %rdi
-
 	/* Setup GSBASE to allow stack canary access for C code */
 	movl	$MSR_GS_BASE, %ecx
 	leaq	INIT_PER_CPU_VAR(fixed_percpu_data)(%rip), %rdx
@@ -77,7 +75,7 @@ SYM_CODE_START_NOALIGN(startup_64)
 	shrq	$32,  %rdx
 	wrmsr
 
-	call	startup_64_setup_env
+	call	startup_64_setup_gdt_idt
 
 	/* Now switch to __KERNEL_CS so IRET works reliably */
 	pushq	$__KERNEL_CS
-- 
2.43.0.687.g38aa6559b0-goog


  reply	other threads:[~2024-02-13 12:42 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-13 12:41 [PATCH v4 00/11] x86: Confine early 1:1 mapped startup code Ard Biesheuvel
2024-02-13 12:41 ` Ard Biesheuvel [this message]
2024-02-13 20:05   ` [PATCH v4 01/11] x86/startup_64: Simplify global variable accesses in GDT/IDT programming Borislav Petkov
2024-02-13 21:53     ` Ard Biesheuvel
2024-02-14  7:28       ` Ard Biesheuvel
2024-02-15 13:52         ` Borislav Petkov
2024-02-13 12:41 ` [PATCH v4 02/11] x86/startup_64: Replace pointer fixups with RIP-relative references Ard Biesheuvel
2024-02-17 12:51   ` Borislav Petkov
2024-02-17 13:58     ` Ard Biesheuvel
2024-02-17 16:10       ` Ard Biesheuvel
2024-02-19  9:55         ` Borislav Petkov
2024-02-19 10:45           ` Ard Biesheuvel
2024-02-19 10:01       ` Borislav Petkov
2024-02-19 10:47         ` Ard Biesheuvel
2024-02-13 12:41 ` [PATCH v4 03/11] x86/startup_64: Simplify CR4 handling in startup code Ard Biesheuvel
2024-02-19 10:32   ` Borislav Petkov
2024-02-13 12:41 ` [PATCH v4 04/11] x86/startup_64: Defer assignment of 5-level paging global variables Ard Biesheuvel
2024-02-20 18:45   ` Borislav Petkov
2024-02-20 23:33     ` Ard Biesheuvel
2024-02-21 10:09       ` Borislav Petkov
2024-02-21 10:20         ` Ard Biesheuvel
2024-02-21 11:12           ` Borislav Petkov
2024-02-21 11:21             ` Ard Biesheuvel
2024-02-21 11:23               ` Borislav Petkov
2024-02-13 12:41 ` [PATCH v4 05/11] x86/startup_64: Simplify calculation of initial page table address Ard Biesheuvel
2024-02-13 12:41 ` [PATCH v4 06/11] x86/startup_64: Simplify virtual switch on primary boot Ard Biesheuvel
2024-02-13 12:41 ` [PATCH v4 07/11] efi/libstub: Add generic support for parsing mem_encrypt= Ard Biesheuvel
2024-02-19 17:00   ` Tom Lendacky
2024-02-19 17:06     ` Ard Biesheuvel
2024-02-20 19:28       ` Tom Lendacky
2024-02-13 12:41 ` [PATCH v4 08/11] x86/boot: Move mem_encrypt= parsing to the decompressor Ard Biesheuvel
2024-02-13 12:41 ` [PATCH v4 09/11] x86/sme: Move early SME kernel encryption handling into .head.text Ard Biesheuvel
2024-02-13 12:41 ` [PATCH v4 10/11] x86/sev: Move early startup code into .head.text section Ard Biesheuvel
2024-02-13 12:41 ` [PATCH v4 11/11] x86/startup_64: Drop global variables keeping track of LA57 state Ard Biesheuvel
2024-02-14 15:24   ` Brian Gerst
2024-02-14 15:44     ` Ard Biesheuvel
2024-02-14 20:25       ` Brian Gerst

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=20240213124143.1484862-14-ardb+git@google.com \
    --to=ardb+git@google.com \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=bp@alien8.de \
    --cc=brgerst@gmail.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dionnaglaze@google.com \
    --cc=justinstitt@google.com \
    --cc=keescook@chromium.org \
    --cc=kevinloughlin@google.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.