| From cb83cece57e1889109dd73ea08ee338668c9d1b8 Mon Sep 17 00:00:00 2001 |
| From: Ard Biesheuvel <ardb@kernel.org> |
| Date: Mon, 7 Aug 2023 18:27:11 +0200 |
| Subject: x86/decompressor: Pass pgtable address to trampoline directly |
| |
| From: Ard Biesheuvel <ardb@kernel.org> |
| |
| commit cb83cece57e1889109dd73ea08ee338668c9d1b8 upstream. |
| |
| The only remaining use of the trampoline address by the trampoline |
| itself is deriving the page table address from it, and this involves |
| adding an offset of 0x0. So simplify this, and pass the new CR3 value |
| directly. |
| |
| This makes the fact that the page table happens to be at the start of |
| the trampoline allocation an implementation detail of the caller. |
| |
| Signed-off-by: Ard Biesheuvel <ardb@kernel.org> |
| Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> |
| Link: https://lore.kernel.org/r/20230807162720.545787-15-ardb@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/boot/compressed/head_64.S | 8 ++++---- |
| arch/x86/boot/compressed/pgtable.h | 2 -- |
| arch/x86/boot/compressed/pgtable_64.c | 9 ++++----- |
| 3 files changed, 8 insertions(+), 11 deletions(-) |
| |
| --- a/arch/x86/boot/compressed/head_64.S |
| +++ b/arch/x86/boot/compressed/head_64.S |
| @@ -539,8 +539,9 @@ SYM_FUNC_END(.Lrelocated) |
| * running in 64-bit mode. |
| * |
| * Return address is at the top of the stack (might be above 4G). |
| - * The first argument (EDI) contains the 32-bit addressable base of the |
| - * trampoline memory. |
| + * The first argument (EDI) contains the address of the temporary PGD level |
| + * page table in 32-bit addressable memory which will be programmed into |
| + * register CR3. |
| */ |
| .section ".rodata", "a", @progbits |
| SYM_CODE_START(trampoline_32bit_src) |
| @@ -593,8 +594,7 @@ SYM_CODE_START(trampoline_32bit_src) |
| movl %eax, %cr0 |
| |
| /* Point CR3 to the trampoline's new top level page table */ |
| - leal TRAMPOLINE_32BIT_PGTABLE_OFFSET(%edi), %eax |
| - movl %eax, %cr3 |
| + movl %edi, %cr3 |
| |
| /* Set EFER.LME=1 as a precaution in case hypervsior pulls the rug */ |
| movl $MSR_EFER, %ecx |
| --- a/arch/x86/boot/compressed/pgtable.h |
| +++ b/arch/x86/boot/compressed/pgtable.h |
| @@ -3,8 +3,6 @@ |
| |
| #define TRAMPOLINE_32BIT_SIZE (2 * PAGE_SIZE) |
| |
| -#define TRAMPOLINE_32BIT_PGTABLE_OFFSET 0 |
| - |
| #define TRAMPOLINE_32BIT_CODE_OFFSET PAGE_SIZE |
| #define TRAMPOLINE_32BIT_CODE_SIZE 0xA0 |
| |
| --- a/arch/x86/boot/compressed/pgtable_64.c |
| +++ b/arch/x86/boot/compressed/pgtable_64.c |
| @@ -103,7 +103,7 @@ static unsigned long find_trampoline_pla |
| |
| asmlinkage void configure_5level_paging(struct boot_params *bp) |
| { |
| - void (*toggle_la57)(void *trampoline); |
| + void (*toggle_la57)(void *cr3); |
| bool l5_required = false; |
| |
| /* Initialize boot_params. Required for cmdline_find_option_bool(). */ |
| @@ -174,7 +174,7 @@ asmlinkage void configure_5level_paging( |
| * For 4- to 5-level paging transition, set up current CR3 as |
| * the first and the only entry in a new top-level page table. |
| */ |
| - trampoline_32bit[TRAMPOLINE_32BIT_PGTABLE_OFFSET] = __native_read_cr3() | _PAGE_TABLE_NOENC; |
| + *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; |
| } else { |
| unsigned long src; |
| |
| @@ -187,8 +187,7 @@ asmlinkage void configure_5level_paging( |
| * may be above 4G. |
| */ |
| src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; |
| - memcpy(trampoline_32bit + TRAMPOLINE_32BIT_PGTABLE_OFFSET / sizeof(unsigned long), |
| - (void *)src, PAGE_SIZE); |
| + memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); |
| } |
| |
| toggle_la57(trampoline_32bit); |
| @@ -198,7 +197,7 @@ void cleanup_trampoline(void *pgtable) |
| { |
| void *trampoline_pgtable; |
| |
| - trampoline_pgtable = trampoline_32bit + TRAMPOLINE_32BIT_PGTABLE_OFFSET / sizeof(unsigned long); |
| + trampoline_pgtable = trampoline_32bit; |
| |
| /* |
| * Move the top level page table out of trampoline memory, |