Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1658669 > unrolled thread
| Started by | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| First post | 2017-06-06 13:40 +0200 |
| Last post | 2017-06-06 13:40 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[PATCHv7 00/14] x86: 5-level paging enabling for v4.13, Part 4 "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> - 2017-06-06 13:40 +0200
[PATCHv7 03/14] x86/boot/efi: Cleanup initialization of GDT entries "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> - 2017-06-06 13:40 +0200
[PATCHv7 06/14] x86/boot/compressed: Enable 5-level paging during decompression stage "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> - 2017-06-06 13:40 +0200
[PATCHv7 04/14] x86/boot/efi: Fix __KERNEL_CS definition of GDT entry on 64-bit configuration "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> - 2017-06-06 13:40 +0200
| From | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| Date | 2017-06-06 13:40 +0200 |
| Subject | [PATCHv7 00/14] x86: 5-level paging enabling for v4.13, Part 4 |
| Message-ID | <tPl05-8cX-3@gated-at.bofh.it> |
Here's updated version of the last bunch of of patches that brings initial
5-level paging enabling.
Please review and consider applying.
Changes since v6:
- Major rework 5-level paging enabling in decompression code to fix #GP when
bootloader enables long mode.
- Fix in sync_global_pgds() (Andrey Ryabinin);
- Couple Reviewed-by form Juergen Gross.
Kirill A. Shutemov (14):
x86/mm/gup: Switch GUP to the generic get_user_page_fast()
implementation
x86/asm: Fix comment in return_from_SYSCALL_64
x86/boot/efi: Cleanup initialization of GDT entries
x86/boot/efi: Fix __KERNEL_CS definition of GDT entry on 64-bit
configuration
x86/boot/efi: Define __KERNEL32_CS GDT on 64-bit configurations
x86/boot/compressed: Enable 5-level paging during decompression stage
x86/boot/64: Rewrite startup_64 in C
x86/boot/64: Rename init_level4_pgt and early_level4_pgt
x86/boot/64: Add support of additional page table level during early
boot
x86/mm: Add sync_global_pgds() for configuration with 5-level paging
x86/mm: Make kernel_physical_mapping_init() support 5-level paging
x86/mm: Add support for 5-level paging for KASLR
x86: Enable 5-level paging support
x86/mm: Allow to have userspace mappings above 47-bits
arch/arm/Kconfig | 2 +-
arch/arm64/Kconfig | 2 +-
arch/powerpc/Kconfig | 2 +-
arch/x86/Kconfig | 8 +
arch/x86/boot/compressed/eboot.c | 73 ++--
arch/x86/boot/compressed/head_64.S | 86 ++++-
arch/x86/entry/entry_64.S | 3 +-
arch/x86/include/asm/elf.h | 4 +-
arch/x86/include/asm/mmu_context.h | 12 -
arch/x86/include/asm/mpx.h | 9 +
arch/x86/include/asm/pgtable-3level.h | 47 +++
arch/x86/include/asm/pgtable.h | 55 ++-
arch/x86/include/asm/pgtable_64.h | 22 +-
arch/x86/include/asm/processor.h | 12 +-
arch/x86/include/uapi/asm/processor-flags.h | 2 +
arch/x86/kernel/espfix_64.c | 2 +-
arch/x86/kernel/head64.c | 143 +++++++-
arch/x86/kernel/head_64.S | 131 ++------
arch/x86/kernel/machine_kexec_64.c | 2 +-
arch/x86/kernel/sys_x86_64.c | 30 +-
arch/x86/mm/Makefile | 2 +-
arch/x86/mm/dump_pagetables.c | 2 +-
arch/x86/mm/gup.c | 496 ----------------------------
arch/x86/mm/hugetlbpage.c | 27 +-
arch/x86/mm/init_64.c | 108 +++++-
arch/x86/mm/kasan_init_64.c | 12 +-
arch/x86/mm/kaslr.c | 81 +++--
arch/x86/mm/mmap.c | 6 +-
arch/x86/mm/mpx.c | 33 +-
arch/x86/realmode/init.c | 2 +-
arch/x86/xen/Kconfig | 1 +
arch/x86/xen/mmu_pv.c | 16 +-
arch/x86/xen/xen-pvh.S | 2 +-
mm/Kconfig | 2 +-
mm/gup.c | 10 +-
35 files changed, 722 insertions(+), 725 deletions(-)
delete mode 100644 arch/x86/mm/gup.c
--
2.11.0
[toc] | [next] | [standalone]
| From | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| Date | 2017-06-06 13:40 +0200 |
| Subject | [PATCHv7 03/14] x86/boot/efi: Cleanup initialization of GDT entries |
| Message-ID | <tPl07-8cX-49@gated-at.bofh.it> |
| In reply to | #1658669 |
This is preparation for following patches without changing semantics of the
code.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
---
arch/x86/boot/compressed/eboot.c | 39 +++++++++++++++++++++------------------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index cbf4b87f55b9..1d5093d1f319 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1049,6 +1049,7 @@ struct boot_params *efi_main(struct efi_config *c,
/* The first GDT is a dummy and the second is unused. */
desc += 2;
+ /* __KERNEL_CS */
desc->limit0 = 0xffff;
desc->base0 = 0x0000;
desc->base1 = 0x0000;
@@ -1062,8 +1063,9 @@ struct boot_params *efi_main(struct efi_config *c,
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;
@@ -1077,24 +1079,25 @@ struct boot_params *efi_main(struct efi_config *c,
desc->d = SEG_OP_SIZE_32BIT;
desc->g = SEG_GRANULARITY_4KB;
desc->base2 = 0x00;
-
-#ifdef CONFIG_X86_64
- /* Task segment value */
desc++;
- desc->limit0 = 0x0000;
- desc->base0 = 0x0000;
- desc->base1 = 0x0000;
- desc->type = SEG_TYPE_TSS;
- desc->s = 0;
- desc->dpl = 0;
- desc->p = 1;
- desc->limit = 0x0;
- desc->avl = 0;
- desc->l = 0;
- desc->d = 0;
- desc->g = SEG_GRANULARITY_4KB;
- desc->base2 = 0x00;
-#endif /* CONFIG_X86_64 */
+
+ 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->limit = 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));
--
2.11.0
[toc] | [prev] | [next] | [standalone]
| From | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| Date | 2017-06-06 13:40 +0200 |
| Subject | [PATCHv7 06/14] x86/boot/compressed: Enable 5-level paging during decompression stage |
| Message-ID | <tPl07-8cX-45@gated-at.bofh.it> |
| In reply to | #1658669 |
We need to cover two basic cases: when bootloader left us in 32-bit mode and when bootloader enabled long mode. The patch implements unified codepath to enabled 5-level paging for both cases. It means case when we start in 32-bit mode, we first enable long mode with 4-level and then switch over to 5-level paging. Switching from 4-level to 5-level paging is not trivial. We cannot do it directly. Setting LA57 in long mode would trigger #GP. So we need to switch off long mode first and the then re-enable with 5-level paging. NOTE: The need of switching off long mode means we are in trouble if bootloader put us above 4G boundary. If bootloader wants to boot 5-level paging kernel, it has to put kernel below 4G or enable 5-level paging on it's own, so we could avoid the step. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> --- arch/x86/boot/compressed/head_64.S | 86 +++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index d2ae1f821e0c..fbf4c32d0b62 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -346,6 +346,48 @@ preferred_addr: /* Set up the stack */ leaq boot_stack_end(%rbx), %rsp +#ifdef CONFIG_X86_5LEVEL + /* Check if 5-level paging has already enabled */ + movq %cr4, %rax + testl $X86_CR4_LA57, %eax + jnz lvl5 + + /* + * At this point we are in long mode with 4-level paging enabled, + * but we want to enable 5-level paging. + * + * The problem is that we cannot do it directly. Setting LA57 in + * long mode would trigger #GP. So we need to switch off long mode + * first. + * + * NOTE: This is not going to work if bootloader put us above 4G + * limit. + * + * The first step is go into compatibility mode. + */ + + /* Clear additional page table */ + leaq lvl5_pgtable(%rbx), %rdi + xorq %rax, %rax + movq $(PAGE_SIZE/8), %rcx + rep stosq + + /* + * Setup current CR3 as the first and only entry in a new top level + * page table. + */ + movq %cr3, %rdi + leaq 0x7 (%rdi), %rax + movq %rax, lvl5_pgtable(%rbx) + + /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */ + pushq $__KERNEL32_CS + leaq compatible_mode(%rip), %rax + pushq %rax + lretq +lvl5: +#endif + /* Zero EFLAGS */ pushq $0 popfq @@ -429,6 +471,44 @@ relocated: jmp *%rax .code32 +#ifdef CONFIG_X86_5LEVEL +compatible_mode: + /* Setup data and stack segments */ + movl $__KERNEL_DS, %eax + movl %eax, %ds + movl %eax, %ss + + /* Disable paging */ + movl %cr0, %eax + btrl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + + /* Point CR3 to 5-level paging */ + leal lvl5_pgtable(%ebx), %eax + movl %eax, %cr3 + + /* Enable PAE and LA57 mode */ + movl %cr4, %eax + orl $(X86_CR4_PAE | X86_CR4_LA57), %eax + movl %eax, %cr4 + + /* Calculate address we are running at */ + call 1f +1: popl %edi + subl $1b, %edi + + /* Prepare stack for far return to Long Mode */ + pushl $__KERNEL_CS + leal lvl5(%edi), %eax + push %eax + + /* Enable paging back */ + movl $(X86_CR0_PG | X86_CR0_PE), %eax + movl %eax, %cr0 + + lret +#endif + no_longmode: /* This isn't an x86-64 CPU so hang */ 1: @@ -442,7 +522,7 @@ gdt: .word gdt_end - gdt .long gdt .word 0 - .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x00cf9a000000ffff /* __KERNEL32_CS */ .quad 0x00af9a000000ffff /* __KERNEL_CS */ .quad 0x00cf92000000ffff /* __KERNEL_DS */ .quad 0x0080890000000000 /* TS descriptor */ @@ -486,3 +566,7 @@ boot_stack_end: .balign 4096 pgtable: .fill BOOT_PGT_SIZE, 1, 0 +#ifdef CONFIG_X86_5LEVEL +lvl5_pgtable: + .fill PAGE_SIZE, 1, 0 +#endif -- 2.11.0
[toc] | [prev] | [next] | [standalone]
| From | "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> |
|---|---|
| Date | 2017-06-06 13:40 +0200 |
| Subject | [PATCHv7 04/14] x86/boot/efi: Fix __KERNEL_CS definition of GDT entry on 64-bit configuration |
| Message-ID | <tPl07-8cX-47@gated-at.bofh.it> |
| In reply to | #1658669 |
Define __KERNEL_CS GDT entry as long mode (.L=1, .D=0) on 64-bit
configuration.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
---
arch/x86/boot/compressed/eboot.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 1d5093d1f319..b75c20f779ea 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1059,8 +1059,13 @@ struct boot_params *efi_main(struct efi_config *c,
desc->p = 1;
desc->limit = 0xf;
desc->avl = 0;
- desc->l = 0;
- desc->d = SEG_OP_SIZE_32BIT;
+ 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++;
--
2.11.0
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web