From: Arvind Sankar <nivedita@alum.mit.edu>
To: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
"H. Peter Anvin" <hpa@zytor.com>,
Ard Biesheuvel <ardb@kernel.org>
Cc: linux-efi@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 5/7] efi/x86: Remove GDT setup from efi_main
Date: Sun, 2 Feb 2020 12:13:51 -0500 [thread overview]
Message-ID: <20200202171353.3736319-6-nivedita@alum.mit.edu> (raw)
In-Reply-To: <20200202171353.3736319-1-nivedita@alum.mit.edu>
The 64-bit kernel will already load a GDT in startup_64, which is the
next function to execute after return from efi_main.
Add GDT setup code to the 32-bit kernel's startup_32 as well. Doing it
in the head code has the advantage that we can avoid potentially
corrupting the GDT during copy/decompression. This also removes
dependence on having a specific GDT layout setup by the bootloader.
Both startup_32 and startup_64 now clear interrupts on entry, so we can
remove that from efi_main as well.
Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
---
arch/x86/boot/compressed/eboot.c | 103 -----------------------------
arch/x86/boot/compressed/head_32.S | 40 +++++++++--
2 files changed, 34 insertions(+), 109 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 287393d725f0..c92fe0b75cec 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -712,10 +712,8 @@ struct boot_params *efi_main(efi_handle_t handle,
efi_system_table_t *sys_table_arg,
struct boot_params *boot_params)
{
- struct desc_ptr *gdt = NULL;
struct setup_header *hdr = &boot_params->hdr;
efi_status_t status;
- struct desc_struct *desc;
unsigned long cmdline_paddr;
sys_table = sys_table_arg;
@@ -753,20 +751,6 @@ struct boot_params *efi_main(efi_handle_t handle,
setup_quirks(boot_params);
- status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*gdt),
- (void **)&gdt);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to allocate memory for 'gdt' structure\n");
- goto fail;
- }
-
- gdt->size = 0x800;
- status = efi_low_alloc(gdt->size, 8, (unsigned long *)&gdt->address);
- if (status != EFI_SUCCESS) {
- efi_printk("Failed to allocate memory for 'gdt'\n");
- goto fail;
- }
-
/*
* If the kernel isn't already loaded at the preferred load
* address, relocate it.
@@ -793,93 +777,6 @@ struct boot_params *efi_main(efi_handle_t handle,
goto fail;
}
- memset((char *)gdt->address, 0x0, gdt->size);
- desc = (struct desc_struct *)gdt->address;
-
- /* The first GDT is a dummy. */
- desc++;
-
- if (IS_ENABLED(CONFIG_X86_64)) {
- /* __KERNEL32_CS */
- desc->limit0 = 0xffff;
- desc->base0 = 0x0000;
- desc->base1 = 0x0000;
- desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
- desc->s = DESC_TYPE_CODE_DATA;
- desc->dpl = 0;
- desc->p = 1;
- desc->limit1 = 0xf;
- desc->avl = 0;
- desc->l = 0;
- desc->d = SEG_OP_SIZE_32BIT;
- desc->g = SEG_GRANULARITY_4KB;
- desc->base2 = 0x00;
-
- desc++;
- } else {
- /* Second entry is unused on 32-bit */
- desc++;
- }
-
- /* __KERNEL_CS */
- desc->limit0 = 0xffff;
- desc->base0 = 0x0000;
- desc->base1 = 0x0000;
- desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
- desc->s = DESC_TYPE_CODE_DATA;
- desc->dpl = 0;
- desc->p = 1;
- desc->limit1 = 0xf;
- desc->avl = 0;
-
- if (IS_ENABLED(CONFIG_X86_64)) {
- desc->l = 1;
- desc->d = 0;
- } else {
- desc->l = 0;
- desc->d = SEG_OP_SIZE_32BIT;
- }
- desc->g = SEG_GRANULARITY_4KB;
- desc->base2 = 0x00;
- desc++;
-
- /* __KERNEL_DS */
- desc->limit0 = 0xffff;
- desc->base0 = 0x0000;
- desc->base1 = 0x0000;
- desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
- desc->s = DESC_TYPE_CODE_DATA;
- desc->dpl = 0;
- desc->p = 1;
- desc->limit1 = 0xf;
- desc->avl = 0;
- desc->l = 0;
- desc->d = SEG_OP_SIZE_32BIT;
- desc->g = SEG_GRANULARITY_4KB;
- desc->base2 = 0x00;
- desc++;
-
- if (IS_ENABLED(CONFIG_X86_64)) {
- /* Task segment value */
- desc->limit0 = 0x0000;
- desc->base0 = 0x0000;
- desc->base1 = 0x0000;
- desc->type = SEG_TYPE_TSS;
- desc->s = 0;
- desc->dpl = 0;
- desc->p = 1;
- desc->limit1 = 0x0;
- desc->avl = 0;
- desc->l = 0;
- desc->d = 0;
- desc->g = SEG_GRANULARITY_4KB;
- desc->base2 = 0x00;
- desc++;
- }
-
- asm volatile("cli");
- asm volatile ("lgdt %0" : : "m" (*gdt));
-
return boot_params;
fail:
efi_printk("efi_main() failed!\n");
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index cb2cb91fce45..356060c5332c 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -64,12 +64,6 @@
SYM_FUNC_START(startup_32)
cld
cli
- movl $__BOOT_DS, %eax
- movl %eax, %ds
- movl %eax, %es
- movl %eax, %fs
- movl %eax, %gs
- movl %eax, %ss
/*
* Calculate the delta between where we were compiled to run
@@ -84,6 +78,19 @@ SYM_FUNC_START(startup_32)
1: popl %ebp
subl $1b, %ebp
+ /* Load new GDT */
+ leal gdt(%ebp), %eax
+ movl %eax, 2(%eax)
+ lgdt (%eax)
+
+ /* Load segment registers with our descriptors */
+ movl $__BOOT_DS, %eax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movl %eax, %ss
+
/*
* %ebp contains the address we are loaded at by the boot loader and %ebx
* contains the address where we should move the kernel image temporarily
@@ -129,6 +136,16 @@ SYM_FUNC_START(startup_32)
cld
popl %esi
+ /*
+ * The GDT may get overwritten either during the copy we just did or
+ * during extract_kernel below. To avoid any issues, repoint the GDTR
+ * to the new copy of the GDT. EAX still contains the previously
+ * calculated relocation offset of init_size - _end.
+ */
+ leal gdt(%ebx), %edx
+ addl %eax, 2(%edx)
+ lgdt (%edx)
+
/*
* Jump to the relocated address.
*/
@@ -201,6 +218,17 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
jmp *%eax
SYM_FUNC_END(.Lrelocated)
+ .data
+ .balign 8
+SYM_DATA_START_LOCAL(gdt)
+ .word gdt_end - gdt - 1
+ .long 0
+ .word 0
+ .quad 0x0000000000000000 /* Reserved */
+ .quad 0x00cf9a000000ffff /* __KERNEL_CS */
+ .quad 0x00cf92000000ffff /* __KERNEL_DS */
+SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
+
/*
* Stack and heap for uncompression
*/
--
2.24.1
next prev parent reply other threads:[~2020-02-02 17:14 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-30 20:04 [PATCH 0/8] Remove 64-bit GDT setup in efi_main + doc fixes Arvind Sankar
2020-01-30 20:04 ` [PATCH 1/8] efi/x86: Use C wrapper instead of inline assembly Arvind Sankar
2020-01-30 20:04 ` [PATCH 2/8] efi/x86: Allocate the GDT pointer on the stack Arvind Sankar
2020-01-30 20:04 ` [PATCH 3/8] efi/x86: Factor GDT setup code into a function Arvind Sankar
2020-01-30 20:04 ` [PATCH 4/8] efi/x86: Only setup the GDT for 32-bit kernel Arvind Sankar
2020-01-30 20:04 ` [PATCH 5/8] efi/x86: Allocate only the required 32 bytes for the GDT Arvind Sankar
2020-01-30 20:04 ` [PATCH 6/8] efi/x86: Change __KERNEL_{CS,DS} to __BOOT_{CS,DS} Arvind Sankar
2020-01-30 20:04 ` [PATCH 7/8] Documentation/x86/boot: Clarify segment requirements for EFI handover Arvind Sankar
2020-01-31 19:24 ` Arvind Sankar
2020-01-30 20:04 ` [PATCH 8/8] Documentation/x86/boot: Correct segment requirements for 64-bit boot Arvind Sankar
2020-01-31 8:42 ` [PATCH 0/8] Remove 64-bit GDT setup in efi_main + doc fixes Ard Biesheuvel
2020-01-31 9:31 ` Ard Biesheuvel
2020-01-31 19:10 ` Arvind Sankar
2020-02-02 17:13 ` [PATCH v2 0/7] x86/efi,boot: GDT handling cleanup/fixes Arvind Sankar
2020-02-02 17:13 ` [PATCH v2 1/7] x86/boot: Remove KEEP_SEGMENTS support Arvind Sankar
2020-02-02 17:13 ` [PATCH v2 2/7] efi/x86: Don't depend on firmware GDT layout Arvind Sankar
2020-02-02 17:54 ` Ard Biesheuvel
2020-02-02 18:18 ` Arvind Sankar
2020-02-02 17:13 ` [PATCH v2 3/7] x86/boot: Reload GDTR after copying to the end of the buffer Arvind Sankar
2020-02-02 17:13 ` [PATCH v2 4/7] x86/boot: Clear direction and interrupt flags in startup_64 Arvind Sankar
2020-02-02 17:13 ` Arvind Sankar [this message]
2020-02-02 17:13 ` [PATCH v2 6/7] x86/boot: GDT limit value should be size - 1 Arvind Sankar
2020-02-02 17:13 ` [PATCH v2 7/7] x86/boot: Micro-optimize GDT loading instructions Arvind Sankar
2020-02-02 18:01 ` [PATCH v2 0/7] x86/efi,boot: GDT handling cleanup/fixes Ard Biesheuvel
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=20200202171353.3736319-6-nivedita@alum.mit.edu \
--to=nivedita@alum.mit.edu \
--cc=ardb@kernel.org \
--cc=bp@alien8.de \
--cc=hpa@zytor.com \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--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;
as well as URLs for NNTP newsgroup(s).