]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming...
authorIngo Molnar <mingo@kernel.org>
Mon, 2 Mar 2015 13:18:57 +0000 (14:18 +0100)
committerIngo Molnar <mingo@kernel.org>
Mon, 2 Mar 2015 13:18:57 +0000 (14:18 +0100)
Pull EFI fixes from Matt Fleming:

" - Fix regression in DMI sysfs code for handling "End of Table" entry
    and a type bug that could lead to integer overflow. (Ivan Khoronzhuk)

  - Fix boundary checking in efi_high_alloc() which can lead to memory
    corruption in the EFI boot stubs. (Yinghai Lu)"

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
drivers/firmware/efi/libstub/efi-stub-helper.c

index 2fe195002021d079ec36515a7ebba4385c1f3600,c927bccd92bd168937777c4487a1a5b6b0f9a617..f07d4a67fa76b3a3cb542e31a24a093c6f7aff97
  
  static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
  
 +/*
 + * Allow the platform to override the allocation granularity: this allows
 + * systems that have the capability to run with a larger page size to deal
 + * with the allocations for initrd and fdt more efficiently.
 + */
 +#ifndef EFI_ALLOC_ALIGN
 +#define EFI_ALLOC_ALIGN               EFI_PAGE_SIZE
 +#endif
 +
  struct file_info {
        efi_file_handle_t *handle;
        u64 size;
@@@ -159,10 -150,10 +159,10 @@@ efi_status_t efi_high_alloc(efi_system_
         * a specific address.  We are doing page-based allocations,
         * so we must be aligned to a page.
         */
 -      if (align < EFI_PAGE_SIZE)
 -              align = EFI_PAGE_SIZE;
 +      if (align < EFI_ALLOC_ALIGN)
 +              align = EFI_ALLOC_ALIGN;
  
 -      nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
  again:
        for (i = 0; i < map_size / desc_size; i++) {
                efi_memory_desc_t *desc;
                start = desc->phys_addr;
                end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
  
-               if ((start + size) > end || (start + size) > max)
-                       continue;
-               if (end - size > max)
+               if (end > max)
                        end = max;
  
+               if ((start + size) > end)
+                       continue;
                if (round_down(end - size, align) < start)
                        continue;
  
@@@ -244,10 -235,10 +244,10 @@@ efi_status_t efi_low_alloc(efi_system_t
         * a specific address.  We are doing page-based allocations,
         * so we must be aligned to a page.
         */
 -      if (align < EFI_PAGE_SIZE)
 -              align = EFI_PAGE_SIZE;
 +      if (align < EFI_ALLOC_ALIGN)
 +              align = EFI_ALLOC_ALIGN;
  
 -      nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
        for (i = 0; i < map_size / desc_size; i++) {
                efi_memory_desc_t *desc;
                unsigned long m = (unsigned long)map;
@@@ -301,7 -292,7 +301,7 @@@ void efi_free(efi_system_table_t *sys_t
        if (!size)
                return;
  
 -      nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
        efi_call_early(free_pages, addr, nr_pages);
  }
  
@@@ -570,7 -561,7 +570,7 @@@ efi_status_t efi_relocate_kernel(efi_sy
         * to the preferred address.  If that fails, allocate as low
         * as possible while respecting the required alignment.
         */
 -      nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
 +      nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
        status = efi_call_early(allocate_pages,
                                EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
                                nr_pages, &efi_addr);