(cc'ing Laszlo)
On 23 July 2015 at 11:40, Haojian Zhuang haojian.zhuang@linaro.org wrote:
Hi all,
There's efi_low_alloc() in $KERNEL/drivers/firmware/efi/libstub/efi-stub-helper.c.
First of all, there are few Linux kernel folk on the UEFI list that you are cc'ing.
I have on question on the piece of code from efi_low_alloc().
/*
- Don't allocate at 0x0. It will confuse code that
- checks pointers against NULL. Skip the first 8
- bytes so we start at a nice even number.
*/ if (start == 0x0) start += 8;
Often, memory allocation functions return NULL if the allocation failed, and there is no way to distinguish failure from a successful allocation at 0x0. Also, the C standard does not allow a valid pointer to be 0x0, since 0x0 is reserved for the NULL pointer. This means that certain compiler optimizations may result in broken code if you [legally] dereference a pointer whose value happens to be 0x0.
In handle_kernel_image() of $KERNEL/arch/arm64/kernel/efi-stub.c, it's used to allocate memory to relocate kernel to (dram_base + TEXT_OFFSET). Because of the above code, kernel has to be relocated into (dram_base
- TEXT_OFFSET + SIZE_2M).
With the above code, I'll get the "Ignoring memory" message from linux kernel. If I remove it, I won't get the message any more.
Yes, this sucks. We are losing 2 megabytes of memory here, simply because the linear mapping starts at the base of the kernel image, and Linux currently has no way to use memory below the linear mapping. (see below)
[ 0.000000] efi: Getting EFI parameters from FDT: [ 0.000000] efi: System Table: 0x000000003da73f18 [ 0.000000] efi: MemMap Address: 0x0000000036d07618 [ 0.000000] efi: MemMap Size: 0x000004e0 [ 0.000000] efi: MemMap Desc. Size: 0x00000030 [ 0.000000] efi: MemMap Desc. Version: 0x00000001 [ 0.000000] EFI v2.40 by Linaro HiKey EFI Jun 28 2015 21:57:01 [ 0.000000] efi: [ 0.000000] Processing EFI memory map: [ 0.000000] 0x000000000000-0x000000000fff [Conventional Memory| | | | | |WB|WT|WC|UC] [ 0.000000] Ignoring memory block 0x0 - 0x1000 [ 0.000000] [ 0.000000] 0x000000001000-0x000000001fff [Loader Data | | | | | |WB|WT|WC|UC]
^^ this is an allocation that is done /after/ the allocation of the kernel image
[ 0.000000] Ignoring memory block 0x1000 - 0x2000 [ 0.000000] [ 0.000000] 0x000000002000-0x0000001fffff [Conventional Memory| | | | | |WB|WT|WC|UC] [ 0.000000] Ignoring memory range 0x2000 - 0x200000 [ 0.000000] [ 0.000000] 0x000000200000-0x000000e6bfff [Loader Data | | | | | |WB|WT|WC|UC]
^^^ this is the kernel mapping
So let's review the code again, we'll always check the return status value of efi_low_alloc() in kernel. Why do we need to avoid the 0x0 address? I think we could remove the piece of code.
Yes, perhaps it is a matter of redefining the return value of efi_low_alloc() so we can defer the failure handling to the caller.