summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_memory.c
AgeCommit message (Collapse)Author
2019-06-14efi_loader: AllocatePages() must accept addr == 0Heinrich Schuchardt
It must be possible to allocate memory at address 0 with AllocatePages(). Move a NULL pointer check. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-10efi_loader: event signaling in ExitBootServicesHeinrich Schuchardt
ExitBootServices() has to stop timer related activity before calling the events of the EFI_EVENT_GROUP_EXIT_BOOT_SERVICES event group. But our current implementation was stopping all other events. All events have to observe the task priority level. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-06-04efi_loader: notify memory map changesHeinrich Schuchardt
When the memory map is changed signal events of the EFI_EVENT_GROUP_MEMORY_MAP_CHANGE event group. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12efi_loader: simplify efi_allocate_pages()Heinrich Schuchardt
Replace unnecessary control structures by using return statements. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12efi_loader: AllocateAdress error handlingHeinrich Schuchardt
If AllocatePages() is called with AllocateAddress, the UEFI spec requires to return EFI_NOT_FOUND in case the memory page does not exist. The UEFI SCT II 2017 spec additionally requires to return EFI_NOT_FOUND if the page is already allocated. Check that *Memory refers to an unallocated page. UEFI SCT II (2017): AllocatePages(), 5.1.2.1.9 - 5.1.2.1.10 Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12efi_loader: out of resources in AllocatePages()Heinrich Schuchardt
According to the UEFI AllocatePages() has to return EFI_OUT_OF_RESOURCES if sufficient memory is not available. Change the return value. UEFI SCT II (2017): 3.2.1 AllocatePages(), 5.1.2.1.8 Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-12efi_loader: check memory address before freeingHeinrich Schuchardt
When we call FreePages() we essentially add memory to our memory map. We shouldn't do this for memory that does not exit. Check if the memory that is to be freed via FreePages() or FreePool() is in our memory map and is not EFI_CONVENTIONAL_MEMORY. This check is mandated by the UEFI specification. Cf. UEFI SCT II (2017), 3.2.2 FreePages(), 5.1.2.1 - 5.1.2.2 Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-05-02efi_loader: FreePages() must fail with pages = 0Heinrich Schuchardt
The UEFI spec requires that freeing of pages fails if the number of pages to be freed is 'invalid'. Check that it is not zero. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-23efi_loader: check memory type in AllocatePages()Heinrich Schuchardt
The UEFI specification prescribes that AllocatePages() checks the memory type. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-12efi_loader: update virtual address in efi_mem_carve_outHeinrich Schuchardt
Handle virtual address in efi_mem_carve_out() function when a new region is created to avoid issue in EFI memory map. Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com> At boottime physical and virtual addressed have to be the same. This allowed to simplify the proposed logic. Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-07efi_loader: EFI_PRINT instead of debug for memory servicesHeinrich Schuchardt
For debug messages inside EFI API functions we should use the EFI_PRINT macro which gives us well aligned output like: EFI: Entry efi_allocate_pool_ext(4, 14, 000000007edd7718) EFI: efi_add_memory_map: 0x7dcfa000 0x1 4 yes EFI: Exit: efi_allocate_pool_ext: 0 Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-04-07efi_loader: sanity checks when freeing memoryHeinrich Schuchardt
Use a checksum to validate that efi_free_pool() is only called for memory allocated by efi_allocated_pool(). Add a plausibility check to efi_free_pages() checking that the address passed is page aligned. Update related function comments to match Sphinx style. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-03-20efi_loader: correct parameter size in efi_allocate_poolHeinrich Schuchardt
efi_allocate_pages() expects a (uint64_t *) pointer to pass the address of the assigned memory. If we pass the address of a pointer here, an illegal memory access occurs on 32bit systems. Fixes: 282a06cbcae8 ("efi_loader: Expose U-Boot addresses in memory map for sandbox") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
2019-02-13efi_loader: fix memory allocation on sandboxHeinrich Schuchardt
Commit 7b78d6438a2b ("efi_loader: Reserve unaccessible memory") introduced a comparison between RAM top and RAM start that was not known at the time when the patch of commit 49759743bf09 ("efi_loader: eliminate sandbox addresses") was written. The sandbox uses an address space that is only relevant in the sandbox context. We have to map ram_top from the sandbox address space to the physical address space before using it in the EFI subsystem. Fixes: 49759743bf09 ("efi_loader: eliminate sandbox addresses") Fixes: 7b78d6438a2b ("efi_loader: Reserve unaccessible memory") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02efi_loader: Align runtime section to 64kbAlexander Graf
The UEFI spec mandates that runtime sections are 64kb aligned to enable support for 64kb page size OSs. This patch ensures that we extend the runtime section to 64kb to be spec compliant. Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02efi_loader: macro efi_size_in_pages()Heinrich Schuchardt
When allocating EFI memory pages the size in bytes has to be converted to pages. Provide a macro efi_size_in_pages() for this conversion. Use it in the EFI subsystem and correct related comments. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02efi_loader: eliminate sandbox addressesHeinrich Schuchardt
Do not use the sandbox's virtual address space for the internal structures of the memory map. This way we can eliminate a whole lot of unnecessary conversions. The only conversion remaining is the one when adding known memory. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02efi_loader: Reserve unaccessible memoryAlexander Graf
On some systems, not all RAM may be usable within U-Boot. Maybe the memory maps are incomplete, maybe it's used as workaround for broken DMA. But whatever the reason may be, a platform can say that it does not wish to have its RAM accessed above a certain address by defining board_get_usable_ram_top(). In the efi_loader world, we ignored that hint, mostly because very few boards actually have real restrictions around this. So let's honor the board's wish to not access high addresses during boot time. The best way to do so is by indicating the respective pages as "allocated by firmware". That way, Operating Systems will still use the pages after boot, but before boot no allocation will use them. Reported-by: Baruch Siach <baruch@tkos.co.il> Signed-off-by: Alexander Graf <agraf@suse.de> Reviewed-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Tested-by: Baruch Siach <baruch@tkos.co.il>
2018-12-02efi_loader: correct efi_add_known_memory()Heinrich Schuchardt
If a memory bank is not EFI_PAGE_SIZE aligned efi_add_known_memory() the number of memory pages may be incorrectly calculated. We have to round up the start address and to round down the end address to determine which complete pages are provided by the memory bank. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-12-02efi_loader: Ensure memory allocations are page alignedAlexander Graf
When the max_addr parameter of efi_find_free_memory() is within bounds of an existing map and fits the reservation, we just return that address as allocation value. That breaks however if max_addr is not page aligned. So ensure that it always comes to us page aligned, simplifying the allocation logic. Without this, I've seen breakage where we were allocating pages at -1U (32bit) which fits into a region that spans beyond 0x100000000. In that case, we would return 0xffffffff as a valid memory allocation, although we usually do guarantee they are all page aligned. Fix this by aligning the max address argument always. Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23efi_loader: Merge memory map entriesAlexander Graf
We currently do not combine memory entries that are adjacent and have the same attributes. The problem with that is that our memory map can easily grow multiple hundreds of entries in a simple UEFI Shell environment. So let's make sure we always combine all entries to make the memory map as small as possible. That way every other piece of code that loops through it should also gain some nice speed ups. Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-23Revert "Revert "efi_loader: efi_allocate_pages is too restrictive""Stephen Warren
This reverts commit ccfc78b820e5e431c5bd73b072e7536a972e1710. Now that the underlying issue is fixed, we can revert the revert and hence restore the original EFI code. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-09-10Remove <inttypes.h> includes and PRI* usages in printf() entirelyMasahiro Yamada
In int-ll64.h, we always use the following typedefs: typedef unsigned int u32; typedef unsigned long uintptr_t; typedef unsigned long long u64; This does not need to match to the compiler's <inttypes.h>. Do not include it. The use of PRI* makes the code super-ugly. You can simply use "l" for printing uintptr_t, "ll" for u64, and no modifier for u32. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-08-21efi: Fix truncation of constant valueEugeniu Rosca
Starting with commit 867a6ac86dd8 ("efi: Add start-up library code"), sparse constantly complains about truncated constant value in efi.h: include/efi.h:176:35: warning: cast truncates bits from constant value (8000000000000000 becomes 0) This can get quite noisy, preventing real issues to be noticed: $ make defconfig *** Default configuration is based on 'sandbox_defconfig' $ make C=2 -j12 2>&1 | grep truncates | wc -l 441 After the patch is applied: $ make C=2 -j12 2>&1 | grep truncates | wc -l 0 $ sparse --version v0.5.2 Following the suggestion of Heinrich Schuchardt, instead of only fixing the root-cause, I replaced the whole enum of _SHIFT values by ULL defines. This matches both the UEFI 2.7 spec and the Linux kernel implementation. Some ELF size comparison before and after the patch (gcc 7.3.0): efi-x86_payload64_defconfig: text data bss dec hex filename 407174 29432 278676 715282 aea12 u-boot.old 407152 29464 278676 715292 aea1c u-boot.new -22 +32 0 +10 efi-x86_payload32_defconfig: text data bss dec hex filename 447075 30308 280076 757459 b8ed3 u-boot.old 447053 30340 280076 757469 b8edd u-boot.new -22 +32 0 +10 Fixes: 867a6ac86dd8 ("efi: Add start-up library code") Suggested-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Eugeniu Rosca <erosca@de.adit-jv.com> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-08-20efi_loader: avoid NULL dereference in efi_get_memory_map()Heinrich Schuchardt
We should only dereference parameter memory_map_size after checking that it is valid. Fixes: 8e835554b36b ("efi_loader: check parameters of GetMemoryMap") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-08-20Revert "efi_loader: efi_allocate_pages is too restrictive"Stephen Warren
This reverts commit aa909462d01866354f4cd4534db5f571c2cf1fbb. This change caused "dhcp filename" to crash the system on p2371-2180 (Jetson TX1), for example when running test/py. Reverting this change isn't optimal, but at least restores TX1 to a working state. In the future, we should: a) Fix whatever problem causes the crash with this patch applied. This needs further discussion, so isn't something we can immediately do. b) Undo the revert; re-apply the original patch to efi_allocate_pages. Signed-off-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25efi_loader: check map_key in ExitBootServicesHeinrich Schuchardt
The UEFI spec requires that the memory map key is checked in ExitBootServices(). Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25efi_loader: check parameters of GetMemoryMapHeinrich Schuchardt
Check the parameters of boottime service GetMemoryMap(). Return EFI_INVALID_PARAMETER where required by the UEFI spec. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25efi_loader: check parameters in memory allocationHeinrich Schuchardt
If no pointer is provided throw an error. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25efi_loader: Expose U-Boot addresses in memory map for sandboxAlexander Graf
We currently expose host addresses in the EFI memory map. That can be bad if we ever want to use sandbox to boot strap a real kernel, because then the kernel would fetch its memory table from our host virtual address map. But to make that use case work, we would need to have full control over the address space the EFI application sees. So let's expose only U-Boot addresses to the guest until we get to the point of allocation. EFI's allocation functions are fun - they can take U-Boot addresses as input values for hints and return host addresses as allocation results through the same uint64_t * parameter. So we need to be extra careful on what to pass in when. With this patch I am successfully able to run the efi selftest suite as well as grub.efi on aarch64. Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25efi: sandbox: Adjust memory usage for sandboxSimon Glass
With sandbox the U-Boot code is not mapped into the sandbox memory range so does not need to be excluded when allocating EFI memory. Update the EFI memory init code to take account of that. Signed-off-by: Simon Glass <sjg@chromium.org> [agraf: Remove map_sysmem() call and header reference] Signed-off-by: Alexander Graf <agraf@suse.de>
2018-07-25efi_loader: efi_allocate_pages is too restrictiveHeinrich Schuchardt
When running on the sandbox the stack is not necessarily at a higher memory address than the highest free memory. There is no reason why the checking of the highest memory address should be more restrictive for EFI_ALLOCATE_ANY_PAGES than for EFI_ALLOCATE_MAX_ADDRESS. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> [agraf: use -1ULL instead] Signed-off-by: Alexander Graf <agraf@suse.de>
2018-06-03efi_loader: efi_mem_carve_out should return s64Heinrich Schuchardt
efi_mem_carve_out() is used to remove memory pages from a mapping. As the number of pages to be removed is a 64bit type the return type should be 64bit too. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-06-03efi_loader: avoid anonymous constants for AllocatePagesHeinrich Schuchardt
Do not use anonymous constants when calling efi_allocage_pages. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-06-03efi_loader: remove unnecessary includeHeinrich Schuchardt
asm/global_data.h is already included via common.h. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-05-10SPDX: Convert a few files that were missed beforeTom Rini
As part of the main conversion a few files were missed. These files had additional whitespace after the '*' and before the SPDX tag and my previous regex was too strict. This time I did a grep for all SPDX tags and then filtered out anything that matched the correct styles. Fixes: 83d290c56fab ("SPDX: Convert all of our single license tags to Linux Kernel style") Reported-by: Heinrich Schuchardt <xypron.debian@gmx.de> Signed-off-by: Tom Rini <trini@konsulko.com>
2018-04-04efi: Correct header order in efi_memorySimon Glass
The headers are not in the correct order. Fix this. Also drop libfdt_env.h since it is not needed. Signed-off-by: Simon Glass <sjg@chromium.org> Rebased Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-04-04efi_loader: use constants in efi_allocate_pages()Heinrich Schuchardt
Using the existing predefined constants is less error prone and makes the code easier to read. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2018-03-05libfdt: move headers to <linux/libfdt.h> and <linux/libfdt_env.h>Masahiro Yamada
Thomas reported U-Boot failed to build host tools if libfdt-devel package is installed because tools include libfdt headers from /usr/include/ instead of using internal ones. This commit moves the header code: include/libfdt.h -> include/linux/libfdt.h include/libfdt_env.h -> include/linux/libfdt_env.h and replaces include directives: #include <libfdt.h> -> #include <linux/libfdt.h> #include <libfdt_env.h> -> #include <linux/libfdt_env.h> Reported-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-01-22efi_loader: add comments to memory functionsHeinrich Schuchardt
Add comments describing memory functions. Fix the formatting of a function declaration. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2017-12-01efi_loader: consistently use efi_uintn_t in boot servicesHeinrich Schuchardt
Consistenly use efi_uintn_t wherever the UEFI spec uses UINTN in boot services interfaces. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2017-09-20efi_loader: make pool allocations cacheline alignedRob Clark
This avoids printf() spam about file reads (such as loading an image) into unaligned buffers (and the associated memcpy()). And generally seems like a good idea. Signed-off-by: Rob Clark <robdclark@gmail.com> [agraf: use __aligned] Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-26efi_loader: fix bug in efi_get_memory_mapRob Clark
When booting shim -> fallback -> shim -> grub -> linux the memory map is a bit larger than the size linux passes in on the first call. But in the EFI_BUFFER_TOO_SMALL case we were not passing back the updated size to linux so it would loop forever. Signed-off-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-24efi_memory: return MapKeyxypron.glpk@gmx.de
efi_get_memory_map should set a defined value for map_key. We later can introduce the test against this value in efi_exit_boot_services as required by the UEFI standard. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-24efi_memory: do parameter checks firstxypron.glpk@gmx.de
The parameter checks should be done first. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2017-07-19efi_memory: avoid NULL dereference in efi_free_poolxypron.glpk@gmx.de
If efi_free_pool is called with argument NULL an illegal memory access occurs. So let's check the parameter on entry. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2017-03-14efi: Add a hook to allow adding memory mappingYork Sun
Instead of adding all memory banks, add a hook so individual SoC/board can has its own implementation. Signed-off-by: York Sun <york.sun@nxp.com> CC: Alexander Graf <agraf@suse.de> Reviewed-by: Alexander Graf <agraf@suse.de>
2016-10-18efi_loader: Do not leak memory when unlinking a mappingStefan Brüns
As soon as a mapping is unlinked from the list, there are no further references to it, so it should be freed. If it not unlinked, update the start address and length. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Reviewed-by: Alexander Graf <agraf@suse.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-18efi_loader: Keep memory mapping sorted when splitting an entryStefan Brüns
The code assumes sorted mappings in descending address order. When splitting a mapping, insert the new part next to the current mapping. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Reviewed-by: Alexander Graf <agraf@suse.de> Signed-off-by: Alexander Graf <agraf@suse.de>
2016-10-18efi_loader: Readd freed pages to memory poolStefan Brüns
Currently each allocation creates a new mapping. Readding the mapping as free memory (EFI_CONVENTIONAL_MEMORY) potentially allows to hand out an existing mapping, thus limiting the number of mapping descriptors in the memory map. Mitigates a problem with current (4.8rc7) linux kernels when doing an efi_get_memory map, resulting in an infinite loop. Space for the memory map is reserved with allocate_pool (implicitly creating a new mapping) and filled. If there is insufficient slack space (8 entries) in the map, the space is freed and a new round is started, with space for one more entry. As each round increases requirement and allocation by exactly one, there is never enough slack space. (At least 32 entries are allocated, so as long as there are less than 24 entries, there is enough slack). Earlier kernels reserved no slack, and did less allocations, so this problem was not visible. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Reviewed-by: Alexander Graf <agraf@suse.de> Signed-off-by: Alexander Graf <agraf@suse.de>