[PATCH v2] efi/arm64: handle missing virtual mapping for UEFI System Table

Ard Biesheuvel ard.biesheuvel at linaro.org
Fri Jul 4 07:51:18 PDT 2014


(adding Catalin)

On 4 July 2014 16:42, Mark Salter <msalter at redhat.com> wrote:
> On Fri, 2014-07-04 at 12:16 +0200, Ard Biesheuvel wrote:
>> If we cannot resolve the virtual address of the UEFI System Table, its physical
>> offset must be missing from the virtual memory map, and there is really no point
>> in proceeding with installing the virtual memory map and the runtime services
>> dispatch table. So back out gracefully.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> ---
>>
>> v2:
>> - release mappings and free virtmap before bailing
>>
>>  arch/arm64/kernel/efi.c | 28 ++++++++++++++++++++++++++--
>>  1 file changed, 26 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
>> index 56c3327bbf79..23942158e0f8 100644
>> --- a/arch/arm64/kernel/efi.c
>> +++ b/arch/arm64/kernel/efi.c
>> @@ -416,11 +416,23 @@ static int __init arm64_enter_virtual_mode(void)
>>                       continue;
>>               if (remap_region(md, &virt_md))
>>                       ++count;
>> +             else
>> +                     goto err_unmap;
>
> How about:
>                 if (!remap_region(md, &virt_md))
>                         goto err_unmap;
>                 ++count;
>
>

Sure.

>>       }
>>
>>       efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table);
>> -     if (efi.systab)
>> -             set_bit(EFI_SYSTEM_TABLES, &efi.flags);
>> +     if (!efi.systab) {
>> +             /*
>> +              * If we have no virtual mapping for the System Table at this
>> +              * point, the memory map doesn't cover the physical offset where
>> +              * it resides. This means the System Table will be inaccessible
>> +              * to Runtime Services themselves once the virtual mapping is
>> +              * installed.
>> +              */
>> +             pr_err("Failed to remap EFI System Table -- buggy firmware?\n");
>> +             goto err_unmap;
>> +     }
>> +     set_bit(EFI_SYSTEM_TABLES, &efi.flags);
>>
>>       local_irq_save(flags);
>>       cpu_switch_mm(idmap_pg_dir, &init_mm);
>> @@ -453,5 +465,17 @@ static int __init arm64_enter_virtual_mode(void)
>>       set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
>>
>>       return 0;
>> +
>> +err_unmap:
>> +     /* unmap all mappings that succeeded: there are 'count' of those */
>> +     for_each_efi_memory_desc(&memmap, md) {
>> +             if (!(md->attribute & EFI_MEMORY_RUNTIME))
>> +                     continue;
>> +             if (!count--)
>> +                     break;
>> +             iounmap((__force void *)md->virt_addr);
>> +     }
>
> This is wrong. memmap still belongs to UEFI and hasn't been touched. The
> new mappings are in virtmap. So, it is even simpler:
>
>         /* unmap all mappings that succeeded: there are 'count' of those */
>         for (virt_md = virtmap; count; virt_md++, count--)
>                 iounmap((__force void __iomem *)virt_md->virt_addr);
>

Yes, you're right. Will respin.

-- 
Ard.



More information about the linux-arm-kernel mailing list