Re: [PATCH v4] x86/efi: Correct ident mapping of efi old_map when kalsr enabled

From: Matt Fleming
Date: Thu May 25 2017 - 17:14:19 EST


On Thu, 18 May, at 02:39:30PM, Baoquan He wrote:
> For EFI with 'efi=old_map' kernel option specified, Kernel will panic
> when kaslr is enabled.
>
> The back trace is:
>
> BUG: unable to handle kernel paging request at 000000007febd57e
> IP: 0x7febd57e
> PGD 1025a067
> PUD 0
>
> Oops: 0010 [#1] SMP
> [ ... ]
> Call Trace:
> ? efi_call+0x58/0x90
> ? printk+0x58/0x6f
> efi_enter_virtual_mode+0x3c5/0x50d
> start_kernel+0x40f/0x4b8
> ? set_init_arg+0x55/0x55
> ? early_idt_handler_array+0x120/0x120
> x86_64_start_reservations+0x24/0x26
> x86_64_start_kernel+0x14c/0x16f
> start_cpu+0x14/0x14
>
> The root cause is the ident mapping is not built correctly in old_map case.
>
> For nokaslr kernel, PAGE_OFFSET is 0xffff880000000000 which is PGDIR_SIZE
> aligned. We can borrow the pud table from direct mapping safely. Given a
> physical address X, we have pud_index(X) == pud_index(__va(X)). However,
> for kaslr kernel, PAGE_OFFSET is PUD_SIZE aligned. For a given physical
> address X, pud_index(X) != pud_index(__va(X)). We can't only copy pgd entry
> from direct mapping to build ident mapping, instead need copy pud entry
> one by one from direct mapping.
>
> Fix it.
>
> Signed-off-by: Baoquan He <bhe@xxxxxxxxxx>
> Signed-off-by: Dave Young <dyoung@xxxxxxxxxx>
> Cc: Matt Fleming <matt@xxxxxxxxxxxxxxxxxxx>
> Cc: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>
> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Cc: Ingo Molnar <mingo@xxxxxxxxxx>
> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
> Cc: Thomas Garnier <thgarnie@xxxxxxxxxx>
> Cc: Kees Cook <keescook@xxxxxxxxxxxx>
> Cc: Russ Anderson <rja@xxxxxxx>
> Cc: Frank Ramsay <frank.ramsay@xxxxxxx>
> Cc: Borislav Petkov <bp@xxxxxxxxx>
> Cc: Bhupesh Sharma <bhsharma@xxxxxxxxxx>
> Cc: x86@xxxxxxxxxx
> Cc: linux-efi@xxxxxxxxxxxxxxx
> ---
> v3->v4:
> 1. Forget running scripts/checkpatch.pl to check patch, there are several
> code stype issue. Correct them in this version.
>
> v2->v3:
> 1. Rewrite code to copy pud entry one by one so that code can be understood
> better. Usually we only have less than 1TB or several TB memory, pud entry
> copy one by one won't impact efficiency.
>
> 2. Adding p4d page table handling.
>
> v1->v2:
> Change code and add description according to Thomas's suggestion as below:
>
> 1. Add checking if pud table is allocated successfully. If not just break
> the for loop.
>
> 2. Add code comment to explain how the 1:1 mapping is built in efi_call_phys_prolog
>
> 3. Other minor change
>
> arch/x86/platform/efi/efi_64.c | 70 +++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 62 insertions(+), 8 deletions(-)

Thanks, applied.