diff mbox

efi/libstub/fdt: Standardize the names of EFI stub parameters

Message ID 55F6886D.1090900@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shannon Zhao Sept. 14, 2015, 8:42 a.m. UTC
On 2015/9/11 23:45, Daniel Kiper wrote:
> On Fri, Sep 11, 2015 at 03:30:15PM +0200, Ard Biesheuvel wrote:
>> On 11 September 2015 at 15:14, Stefano Stabellini
>> <stefano.stabellini@eu.citrix.com> wrote:
>>> On Fri, 11 Sep 2015, Daniel Kiper wrote:
>>>> On Thu, Sep 10, 2015 at 05:23:02PM +0100, Mark Rutland wrote:
>>>>>>> C) When you could go:
>>>>>>>
>>>>>>>    DT -> Discover Xen -> Xen-specific stuff -> Xen-specific EFI/ACPI discovery
>>>>>>
>>>>>> I take you mean discovering Xen with the usual Xen hypervisor node on
>>>>>> device tree. I think that C) is a good option actually. I like it. Not
>>>>>> sure why we didn't think about this earlier. Is there anything EFI or
>>>>>> ACPI which is needed before Xen support is discovered by
>>>>>> arch/arm64/kernel/setup.c:setup_arch -> xen_early_init()?
>>>>>
>>>>> Currently lots (including the memory map). With the stuff to support
>>>>> SPCR, the ACPI discovery would be moved before xen_early_init().
>>>>>
>>>>>> If not, we could just go for this. A lot of complexity would go away.
>>>>>
>>>>> I suspect this would still be fairly complex, but would at least prevent
>>>>> the Xen-specific EFI handling from adversely affecting the native case.
>>>>>
>>>>>>> D) If you want to be generic:
>>>>>>>    EFI -> EFI application -> EFI tables -> ACPI tables -> Xen-specific stuff
>>>>>>>           \------------------------------------------/
>>>>>>>            (virtualize these, provide shims to Dom0, but handle
>>>>>>>             everything in Xen itself)
>>>>>>
>>>>>> I think that this is good in theory but could turn out to be a lot of
>>>>>> work in practice. We could probably virtualize the RuntimeServices but
>>>>>> the BootServices are troublesome.
>>>>>
>>>>> What's troublesome with the boot services?
>>>>>
>>>>> What can't be simulated?
>>>>
>>>> How do you want to access bare metal EFI boot services from dom0 if they
>>>> were shutdown long time ago before loading dom0 image? What do you need
>>>> from EFI boot services in dom0?
>>>
>>> That's right. Trying to emulate BootServices after the real
>>> ExitBootServices has already been called seems like a very bad plan.
>>>
>>> I think that whatever interface we come up with, would need to be past
>>> ExitBootServices.
>>
>> It feels like this discussion is going in circles.
>>
>> When we discussed this six months ago, we already concluded that,
>> since UEFI is the only specified way that the presence of ACPI is
>> advertised on an ARM system, we need to emulate UEFI to some extent.
>>
>> So we need the EFI system table to expose the UEFI configuration table
>> that carries the ACPI root pointer.
>>
>> Since ACPI support also relies on the UEFI memory map (I think?), we
>> need that as well.
>>
>> These two items are exactly what we pass via the UEFI DT properties,
>> so we should indeed promote the current de-facto binding to a proper
>> binding, and renaming the properties makes sense in that context.
>>
>> I agree that this should also include a description of the expected
>> state of the firmware, i.e., that ExitBootServices() has been called,
>> and that the memory map has been populated with virtual address, which
>> have been installed using SetVirtualAddressMap() if they differ from
>> the physical addresses. (The current implementation on the kernel side
>> is perfectly capable of dealing with a 1:1 mapping).
>>
>> Beyond that, there is no point in pretending to be a full UEFI
>> implementation, imo. Boot services are not required, nor are runtime
>> services (only the current EFI init code on arm needs to be modified
>> to deal with a NULL runtime services pointer)
> 
> Taking into account above I think that you have most of the code in place.
> Please take a look at linux/arch/x86/xen/efi.c, linux/drivers/acpi/osl.c
> and linux/drivers/xen/efi.c (maybe somewhere else). In general you should
> create ARM version of xen_efi_init() (x86 version you can find in
> linux/drivers/xen/efi.c; it is very simple thing), maybe add some
> code in a few places and voila.
> 

It only needs to apply following patch to fix a bug in Linux kernel when
mapping EFI_MEMORY_RUNTIME memory.

Author: Shannon Zhao <shannon.zhao@linaro.org>
Date:   Thu Aug 20 14:54:58 2015 +0800

    arm64/efi: Fix a bug when no EFI_MEMORY_RUNTIME memory found

    Currently if the attribute type of all the EFI Memory Descriptors are
    not EFI_MEMORY_RUNTIME, efi_virtmap_init will return true. But at this
    case, it expect false as there are no EFI memory for RUNTIME. Fix it by
    introducing a status to show whether it finds EFI_MEMORY_RUNTIME.

    Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>

Comments

Ard Biesheuvel Sept. 14, 2015, 9:09 a.m. UTC | #1
On 14 September 2015 at 10:42, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
[..]

>
> It only needs to apply following patch to fix a bug in Linux kernel when
> mapping EFI_MEMORY_RUNTIME memory.
>

Could you explain why you think efi_virtmap_init() should fail if
there are no EFI_MEMORY_RUNTIME regions?

The absence of such regions is allowed by the spec, so
efi_virtmap_init() is correct imo to return success.

If you are trying to work around the issue where Xen does not expose
any Runtime Services regions, there is simply no way to do that and be
still UEFI compliant. I have suggested before that we should perhaps
tolerate this anyway, by considering the case where the EFI System
Table has a NULL runtime services pointer. But rigging
efi_virtmap_init() like this is really not the way to achieve that.
Shannon Zhao Sept. 14, 2015, 9:31 a.m. UTC | #2
On 2015/9/14 17:09, Ard Biesheuvel wrote:
> On 14 September 2015 at 10:42, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
> [..]
> 
>>
>> It only needs to apply following patch to fix a bug in Linux kernel when
>> mapping EFI_MEMORY_RUNTIME memory.
>>
> 
> Could you explain why you think efi_virtmap_init() should fail if
> there are no EFI_MEMORY_RUNTIME regions?
> 

My understanding is that if there are no EFI_MEMORY_RUNTIME regions, it
means we can't use runtime services and should not set the bit
EFI_RUNTIME_SERVICES of efi.flags. But if efi_virtmap_init() return
true, the bit will be set.

> The absence of such regions is allowed by the spec, so
> efi_virtmap_init() is correct imo to return success.
> 
Sorry, not well know about the spec. Could you point out where the spec
says this?

> If you are trying to work around the issue where Xen does not expose
> any Runtime Services regions, there is simply no way to do that and be
> still UEFI compliant. I have suggested before that we should perhaps
> tolerate this anyway, by considering the case where the EFI System
> Table has a NULL runtime services pointer. But rigging
> efi_virtmap_init() like this is really not the way to achieve that.
>
Ard Biesheuvel Sept. 14, 2015, 9:36 a.m. UTC | #3
(snip some cc's)

On 14 September 2015 at 11:31, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
>
>
> On 2015/9/14 17:09, Ard Biesheuvel wrote:
>> On 14 September 2015 at 10:42, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
>> [..]
>>
>>>
>>> It only needs to apply following patch to fix a bug in Linux kernel when
>>> mapping EFI_MEMORY_RUNTIME memory.
>>>
>>
>> Could you explain why you think efi_virtmap_init() should fail if
>> there are no EFI_MEMORY_RUNTIME regions?
>>
>
> My understanding is that if there are no EFI_MEMORY_RUNTIME regions, it
> means we can't use runtime services and should not set the bit
> EFI_RUNTIME_SERVICES of efi.flags. But if efi_virtmap_init() return
> true, the bit will be set.
>

As I said, if you don't want the EFI_RUNTIME_SERVICES bit to be set
for other reasons, don't rig efi_virtmap_init() to return false when
it shouldn't.

>> The absence of such regions is allowed by the spec, so
>> efi_virtmap_init() is correct imo to return success.
>>
> Sorry, not well know about the spec. Could you point out where the spec
> says this?
>

Well, I think it doesn't work that way. You are claiming that a memory
map without at least one EFI_MEMORY_RUNTIME constitutes an error
condition, so the burden is on you to provide a reference to the spec
that says you must have at least one such region.
Jan Beulich Sept. 14, 2015, 10:39 a.m. UTC | #4
>>> On 14.09.15 at 11:36, <ard.biesheuvel@linaro.org> wrote:
> On 14 September 2015 at 11:31, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
>> My understanding is that if there are no EFI_MEMORY_RUNTIME regions, it
>> means we can't use runtime services and should not set the bit
>> EFI_RUNTIME_SERVICES of efi.flags. But if efi_virtmap_init() return
>> true, the bit will be set.
>>
> 
> As I said, if you don't want the EFI_RUNTIME_SERVICES bit to be set
> for other reasons, don't rig efi_virtmap_init() to return false when
> it shouldn't.
> 
>>> The absence of such regions is allowed by the spec, so
>>> efi_virtmap_init() is correct imo to return success.
>>>
>> Sorry, not well know about the spec. Could you point out where the spec
>> says this?
>>
> 
> Well, I think it doesn't work that way. You are claiming that a memory
> map without at least one EFI_MEMORY_RUNTIME constitutes an error
> condition, so the burden is on you to provide a reference to the spec
> that says you must have at least one such region.

Sure, from a spec pov you're right. But where would runtime
services code/data live when there's not a single region marked
as needing a runtime mapping. IOW while the spec doesn't say
so, assuming no runtime services when there's not at least one
executable region with the runtime flag set could serve as a stop
gap measure against flawed firmware.

Jan
Ard Biesheuvel Sept. 14, 2015, 11:16 a.m. UTC | #5
On 14 September 2015 at 12:39, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 14.09.15 at 11:36, <ard.biesheuvel@linaro.org> wrote:
>> On 14 September 2015 at 11:31, Shannon Zhao <zhaoshenglong@huawei.com> wrote:
>>> My understanding is that if there are no EFI_MEMORY_RUNTIME regions, it
>>> means we can't use runtime services and should not set the bit
>>> EFI_RUNTIME_SERVICES of efi.flags. But if efi_virtmap_init() return
>>> true, the bit will be set.
>>>
>>
>> As I said, if you don't want the EFI_RUNTIME_SERVICES bit to be set
>> for other reasons, don't rig efi_virtmap_init() to return false when
>> it shouldn't.
>>
>>>> The absence of such regions is allowed by the spec, so
>>>> efi_virtmap_init() is correct imo to return success.
>>>>
>>> Sorry, not well know about the spec. Could you point out where the spec
>>> says this?
>>>
>>
>> Well, I think it doesn't work that way. You are claiming that a memory
>> map without at least one EFI_MEMORY_RUNTIME constitutes an error
>> condition, so the burden is on you to provide a reference to the spec
>> that says you must have at least one such region.
>
> Sure, from a spec pov you're right. But where would runtime
> services code/data live when there's not a single region marked
> as needing a runtime mapping. IOW while the spec doesn't say
> so, assuming no runtime services when there's not at least one
> executable region with the runtime flag set could serve as a stop
> gap measure against flawed firmware.
>

That in itself is a fair point. But the argument being made was that
it is in itself a bug for no EFI_MEMORY_RUNTIME regions to exist,
while the actual purpose of the patch is to prevent the
RuntimeServices pointer from being dereferenced on platforms like Xen
that may not be able to implement them.

But actually, even in case of Xen, you will need some
EFI_MEMORY_RUNTIME regions anyway, since the f/w vendor field and the
config and runtime services table pointers are translated to virtual
addresses by the firmware, which means the OS needs to translate them
back to physical addresses in order to dereference them before the VA
mapping is up. (I still think not using SetVirtualAddressMap() at all
would be the best approach for arm64, but unfortunately, most of my
colleagues disagree with me)
Jan Beulich Sept. 14, 2015, 11:34 a.m. UTC | #6
>>> On 14.09.15 at 13:16, <ard.biesheuvel@linaro.org> wrote:
> (I still think not using SetVirtualAddressMap() at all
> would be the best approach for arm64, but unfortunately, most of my
> colleagues disagree with me)

Any reasons they have? I'm curious because we run x86 Xen without
using this function ...

Jan
diff mbox

Patch

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index e8ca6ea..bad7f87 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -233,6 +233,7 @@  void __init efi_init(void)
 static bool __init efi_virtmap_init(void)
 {
        efi_memory_desc_t *md;
+       bool status = false;

        for_each_efi_memory_desc(&memmap, md) {
                u64 paddr, npages, size;
@@ -264,8 +265,11 @@  static bool __init efi_virtmap_init(void)
                        prot = PAGE_KERNEL;

                create_pgd_mapping(&efi_mm, paddr, md->virt_addr, size,
prot);
+               status = true;
        }
-       return true;
+       if (status)
+               return true;
+       return false;
 }