diff mbox series

[U-Boot,v8,02/30] efi: sandbox: Adjust memory usage for sandbox

Message ID 20180618140835.195901-3-sjg@chromium.org
State Superseded
Delegated to: Alexander Graf
Headers show
Series efi: Enable sandbox support for EFI loader | expand

Commit Message

Simon Glass June 18, 2018, 2:08 p.m. UTC
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.

Also use mapmem instead of a cast to convert a memory address to a
pointer.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v8: None
Changes in v7:
- Move some of the code from efi_memory_init() into a separate function

Changes in v6: None
Changes in v5: None
Changes in v4: None
Changes in v3: None
Changes in v2:
- Update to use mapmem instead of a cast

 lib/efi_loader/efi_memory.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

Comments

Heinrich Schuchardt June 20, 2018, 6:10 a.m. UTC | #1
On 06/18/2018 04:08 PM, Simon Glass wrote:
> 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.
> 
> Also use mapmem instead of a cast to convert a memory address to a
> pointer.

This is not reflected in the patch.

> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
> Changes in v8: None
> Changes in v7:
> - Move some of the code from efi_memory_init() into a separate function
> 
> Changes in v6: None
> Changes in v5: None
> Changes in v4: None
> Changes in v3: None
> Changes in v2:
> - Update to use mapmem instead of a cast
> 
>  lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
> index ec66af98ea..c6410613c7 100644
> --- a/lib/efi_loader/efi_memory.c
> +++ b/lib/efi_loader/efi_memory.c
> @@ -9,6 +9,7 @@
>  #include <efi_loader.h>
>  #include <inttypes.h>
>  #include <malloc.h>
> +#include <mapmem.h>

I cannot see any use of this include in the patch.

>  #include <watchdog.h>
>  #include <linux/list_sort.h>
>  
> @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
>  			       &t);
>  
>  	if (r == EFI_SUCCESS) {
> -		struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
> +		struct efi_pool_allocation *alloc = map_sysmem(t, size);
>  		alloc->num_pages = num_pages;
>  		*buffer = alloc->data;
>  	}
> @@ -496,14 +497,13 @@ __weak void efi_add_known_memory(void)
>  	}
>  }
>  
> -int efi_memory_init(void)
> +/* Add memory regions for U-Boot's memory and for the runtime services code */
> +static void add_u_boot_and_runtime(void)
>  {
>  	unsigned long runtime_start, runtime_end, runtime_pages;
>  	unsigned long uboot_start, uboot_pages;
>  	unsigned long uboot_stack_size = 16 * 1024 * 1024;
>  
> -	efi_add_known_memory();
> -
>  	/* Add U-Boot */
>  	uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
>  	uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
> @@ -516,6 +516,14 @@ int efi_memory_init(void)
>  	runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
>  	efi_add_memory_map(runtime_start, runtime_pages,
>  			   EFI_RUNTIME_SERVICES_CODE, false);
> +}
> +
> +int efi_memory_init(void)
> +{
> +	efi_add_known_memory();
> +
> +	if (!IS_ENABLED(CONFIG_SANDBOX))
> +		add_u_boot_and_runtime();

Is the sandbox not using relocation? A comment is missing in the code
here to explain why add_u_boot_and_runtime() should not be called for
the sandbox.

Best regards

Heinrich

>  
>  #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
>  	/* Request a 32bit 64MB bounce buffer region */
>
Alexander Graf June 20, 2018, 8:54 a.m. UTC | #2
On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
> On 06/18/2018 04:08 PM, Simon Glass wrote:
>> 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.
>>
>> Also use mapmem instead of a cast to convert a memory address to a
>> pointer.
> This is not reflected in the patch.
>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v8: None
>> Changes in v7:
>> - Move some of the code from efi_memory_init() into a separate function
>>
>> Changes in v6: None
>> Changes in v5: None
>> Changes in v4: None
>> Changes in v3: None
>> Changes in v2:
>> - Update to use mapmem instead of a cast
>>
>>   lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>   1 file changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>> index ec66af98ea..c6410613c7 100644
>> --- a/lib/efi_loader/efi_memory.c
>> +++ b/lib/efi_loader/efi_memory.c
>> @@ -9,6 +9,7 @@
>>   #include <efi_loader.h>
>>   #include <inttypes.h>
>>   #include <malloc.h>
>> +#include <mapmem.h>
> I cannot see any use of this include in the patch.
>
>>   #include <watchdog.h>
>>   #include <linux/list_sort.h>
>>   
>> @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
>>   			       &t);
>>   
>>   	if (r == EFI_SUCCESS) {
>> -		struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
>> +		struct efi_pool_allocation *alloc = map_sysmem(t, size);

^^^

This is where mapmem.h gets used. And yes, it's the wrong place. So NAK 
on the patch as-is.


Alex
Simon Glass June 21, 2018, 2:02 a.m. UTC | #3
Hi Alex,

On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>
>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>
>>> 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.
>>>
>>> Also use mapmem instead of a cast to convert a memory address to a
>>> pointer.
>>
>> This is not reflected in the patch.
>>
>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>> ---
>>>
>>> Changes in v8: None
>>> Changes in v7:
>>> - Move some of the code from efi_memory_init() into a separate function
>>>
>>> Changes in v6: None
>>> Changes in v5: None
>>> Changes in v4: None
>>> Changes in v3: None
>>> Changes in v2:
>>> - Update to use mapmem instead of a cast
>>>
>>>   lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>   1 file changed, 12 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>>> index ec66af98ea..c6410613c7 100644
>>> --- a/lib/efi_loader/efi_memory.c
>>> +++ b/lib/efi_loader/efi_memory.c
>>> @@ -9,6 +9,7 @@
>>>   #include <efi_loader.h>
>>>   #include <inttypes.h>
>>>   #include <malloc.h>
>>> +#include <mapmem.h>
>>
>> I cannot see any use of this include in the patch.
>>
>>>   #include <watchdog.h>
>>>   #include <linux/list_sort.h>
>>>   @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>> efi_uintn_t size, void **buffer)
>>>                                &t);
>>>         if (r == EFI_SUCCESS) {
>>> -               struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
>>> +               struct efi_pool_allocation *alloc = map_sysmem(t, size);
>
>
> ^^^
>
> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK on
> the patch as-is.

What is wrong with it?

Regards,
Simon
Simon Glass June 21, 2018, 2:02 a.m. UTC | #4
Hi Heinrich,

On 20 June 2018 at 00:10, Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
> On 06/18/2018 04:08 PM, Simon Glass wrote:
>> 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.
>>
>> Also use mapmem instead of a cast to convert a memory address to a
>> pointer.
>
> This is not reflected in the patch.
>
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v8: None
>> Changes in v7:
>> - Move some of the code from efi_memory_init() into a separate function
>>
>> Changes in v6: None
>> Changes in v5: None
>> Changes in v4: None
>> Changes in v3: None
>> Changes in v2:
>> - Update to use mapmem instead of a cast
>>
>>  lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>  1 file changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>> index ec66af98ea..c6410613c7 100644
>> --- a/lib/efi_loader/efi_memory.c
>> +++ b/lib/efi_loader/efi_memory.c
>> @@ -9,6 +9,7 @@
>>  #include <efi_loader.h>
>>  #include <inttypes.h>
>>  #include <malloc.h>
>> +#include <mapmem.h>
>
> I cannot see any use of this include in the patch.

Please see ^^^^^^^ below, for example.

>
>>  #include <watchdog.h>
>>  #include <linux/list_sort.h>
>>
>> @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
>>                              &t);
>>
>>       if (r == EFI_SUCCESS) {
>> -             struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
>> +             struct efi_pool_allocation *alloc = map_sysmem(t, size);

^^^^^^^^^^^^

>>               alloc->num_pages = num_pages;
>>               *buffer = alloc->data;
>>       }
>> @@ -496,14 +497,13 @@ __weak void efi_add_known_memory(void)
>>       }
>>  }
>>
>> -int efi_memory_init(void)
>> +/* Add memory regions for U-Boot's memory and for the runtime services code */
>> +static void add_u_boot_and_runtime(void)
>>  {
>>       unsigned long runtime_start, runtime_end, runtime_pages;
>>       unsigned long uboot_start, uboot_pages;
>>       unsigned long uboot_stack_size = 16 * 1024 * 1024;
>>
>> -     efi_add_known_memory();
>> -
>>       /* Add U-Boot */
>>       uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
>>       uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
>> @@ -516,6 +516,14 @@ int efi_memory_init(void)
>>       runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
>>       efi_add_memory_map(runtime_start, runtime_pages,
>>                          EFI_RUNTIME_SERVICES_CODE, false);
>> +}
>> +
>> +int efi_memory_init(void)
>> +{
>> +     efi_add_known_memory();
>> +
>> +     if (!IS_ENABLED(CONFIG_SANDBOX))
>> +             add_u_boot_and_runtime();
>
> Is the sandbox not using relocation? A comment is missing in the code
> here to explain why add_u_boot_and_runtime() should not be called for
> the sandbox.

That's right, sandbox does not use relocation. But the real point is
that its code is not within the sandbox memory map. Sandbox uses a
emulated RAM buffer, separate from the U-Boot code and stack.

Regards,
Simon
Alexander Graf June 21, 2018, 9:52 a.m. UTC | #5
On 06/21/2018 04:02 AM, Simon Glass wrote:
> Hi Alex,
>
> On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
>> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>> 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.
>>>>
>>>> Also use mapmem instead of a cast to convert a memory address to a
>>>> pointer.
>>> This is not reflected in the patch.
>>>
>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>> ---
>>>>
>>>> Changes in v8: None
>>>> Changes in v7:
>>>> - Move some of the code from efi_memory_init() into a separate function
>>>>
>>>> Changes in v6: None
>>>> Changes in v5: None
>>>> Changes in v4: None
>>>> Changes in v3: None
>>>> Changes in v2:
>>>> - Update to use mapmem instead of a cast
>>>>
>>>>    lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>>    1 file changed, 12 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>>>> index ec66af98ea..c6410613c7 100644
>>>> --- a/lib/efi_loader/efi_memory.c
>>>> +++ b/lib/efi_loader/efi_memory.c
>>>> @@ -9,6 +9,7 @@
>>>>    #include <efi_loader.h>
>>>>    #include <inttypes.h>
>>>>    #include <malloc.h>
>>>> +#include <mapmem.h>
>>> I cannot see any use of this include in the patch.
>>>
>>>>    #include <watchdog.h>
>>>>    #include <linux/list_sort.h>
>>>>    @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>>> efi_uintn_t size, void **buffer)
>>>>                                 &t);
>>>>          if (r == EFI_SUCCESS) {
>>>> -               struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
>>>> +               struct efi_pool_allocation *alloc = map_sysmem(t, size);
>>
>> ^^^
>>
>> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK on
>> the patch as-is.
> What is wrong with it?

Efi_allocate_pool calls efi_allocate_pages() which according to spec 
returns a pointer. So efi_allocate_pool() should not have to map 
anything, because it does not receive an addres.


Alex
Simon Glass June 21, 2018, 7:45 p.m. UTC | #6
Hi Alex,

On 21 June 2018 at 03:52, Alexander Graf <agraf@suse.de> wrote:
> On 06/21/2018 04:02 AM, Simon Glass wrote:
>>
>> Hi Alex,
>>
>> On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
>>>
>>> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>>>
>>>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>>>
>>>>> 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.
>>>>>
>>>>> Also use mapmem instead of a cast to convert a memory address to a
>>>>> pointer.
>>>>
>>>> This is not reflected in the patch.
>>>>
>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>> ---
>>>>>
>>>>> Changes in v8: None
>>>>> Changes in v7:
>>>>> - Move some of the code from efi_memory_init() into a separate function
>>>>>
>>>>> Changes in v6: None
>>>>> Changes in v5: None
>>>>> Changes in v4: None
>>>>> Changes in v3: None
>>>>> Changes in v2:
>>>>> - Update to use mapmem instead of a cast
>>>>>
>>>>>    lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>>>    1 file changed, 12 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>>>>> index ec66af98ea..c6410613c7 100644
>>>>> --- a/lib/efi_loader/efi_memory.c
>>>>> +++ b/lib/efi_loader/efi_memory.c
>>>>> @@ -9,6 +9,7 @@
>>>>>    #include <efi_loader.h>
>>>>>    #include <inttypes.h>
>>>>>    #include <malloc.h>
>>>>> +#include <mapmem.h>
>>>>
>>>> I cannot see any use of this include in the patch.
>>>>
>>>>>    #include <watchdog.h>
>>>>>    #include <linux/list_sort.h>
>>>>>    @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>>>> efi_uintn_t size, void **buffer)
>>>>>                                 &t);
>>>>>          if (r == EFI_SUCCESS) {
>>>>> -               struct efi_pool_allocation *alloc = (void
>>>>> *)(uintptr_t)t;
>>>>> +               struct efi_pool_allocation *alloc = map_sysmem(t,
>>>>> size);
>>>
>>>
>>> ^^^
>>>
>>> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK
>>> on
>>> the patch as-is.
>>
>> What is wrong with it?
>
>
> Efi_allocate_pool calls efi_allocate_pages() which according to spec returns
> a pointer. So efi_allocate_pool() should not have to map anything, because
> it does not receive an addres.

You are referring to efi_allocate_pages_ext() I suspect. In my series
this does the mapping, so that efi_allocate_pages() uses addresses
only. We could rename it if you like.

Regards,
Simon
Alexander Graf June 22, 2018, 12:08 p.m. UTC | #7
On 06/21/2018 09:45 PM, Simon Glass wrote:
> Hi Alex,
>
> On 21 June 2018 at 03:52, Alexander Graf <agraf@suse.de> wrote:
>> On 06/21/2018 04:02 AM, Simon Glass wrote:
>>> Hi Alex,
>>>
>>> On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
>>>> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>>>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>>>> 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.
>>>>>>
>>>>>> Also use mapmem instead of a cast to convert a memory address to a
>>>>>> pointer.
>>>>> This is not reflected in the patch.
>>>>>
>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>> ---
>>>>>>
>>>>>> Changes in v8: None
>>>>>> Changes in v7:
>>>>>> - Move some of the code from efi_memory_init() into a separate function
>>>>>>
>>>>>> Changes in v6: None
>>>>>> Changes in v5: None
>>>>>> Changes in v4: None
>>>>>> Changes in v3: None
>>>>>> Changes in v2:
>>>>>> - Update to use mapmem instead of a cast
>>>>>>
>>>>>>     lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>>>>     1 file changed, 12 insertions(+), 4 deletions(-)
>>>>>>
>>>>>> diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
>>>>>> index ec66af98ea..c6410613c7 100644
>>>>>> --- a/lib/efi_loader/efi_memory.c
>>>>>> +++ b/lib/efi_loader/efi_memory.c
>>>>>> @@ -9,6 +9,7 @@
>>>>>>     #include <efi_loader.h>
>>>>>>     #include <inttypes.h>
>>>>>>     #include <malloc.h>
>>>>>> +#include <mapmem.h>
>>>>> I cannot see any use of this include in the patch.
>>>>>
>>>>>>     #include <watchdog.h>
>>>>>>     #include <linux/list_sort.h>
>>>>>>     @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>>>>> efi_uintn_t size, void **buffer)
>>>>>>                                  &t);
>>>>>>           if (r == EFI_SUCCESS) {
>>>>>> -               struct efi_pool_allocation *alloc = (void
>>>>>> *)(uintptr_t)t;
>>>>>> +               struct efi_pool_allocation *alloc = map_sysmem(t,
>>>>>> size);
>>>>
>>>> ^^^
>>>>
>>>> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK
>>>> on
>>>> the patch as-is.
>>> What is wrong with it?
>>
>> Efi_allocate_pool calls efi_allocate_pages() which according to spec returns
>> a pointer. So efi_allocate_pool() should not have to map anything, because
>> it does not receive an addres.
> You are referring to efi_allocate_pages_ext() I suspect. In my series
> this does the mapping, so that efi_allocate_pages() uses addresses
> only. We could rename it if you like.

I don't think we should rename things there. I really think there is a 
fundamental misunderstanding here on what the APIs are supposed to do. 
Basically:

   efi_allocate_pages() is mmap() in Liunx
   efi_allocate_pool() is malloc() in Linux

plus a few extra features of course, but you can think of them at the 
same level.

When a payload calls efi_allocate_pool, that really calls into a more 
sophisticated memory allocator usually which can allocate small chunks 
of memory efficiently. Given the amount of RAM modern systems have, I 
opted for simplicity though so I just mapped it to basically allocate 
pages using efi_allocate_pages().

As for _ext functions, the *only* thing we want in an _ext function is 
to isolate the logic that EFI_CALL() would do otherwise - namely swap 
gd. No more.


Alex
Simon Glass June 22, 2018, 7:28 p.m. UTC | #8
Hi Alex,

On 22 June 2018 at 06:08, Alexander Graf <agraf@suse.de> wrote:
> On 06/21/2018 09:45 PM, Simon Glass wrote:
>>
>> Hi Alex,
>>
>> On 21 June 2018 at 03:52, Alexander Graf <agraf@suse.de> wrote:
>>>
>>> On 06/21/2018 04:02 AM, Simon Glass wrote:
>>>>
>>>> Hi Alex,
>>>>
>>>> On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
>>>>>
>>>>> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>>>>>
>>>>>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>> Also use mapmem instead of a cast to convert a memory address to a
>>>>>>> pointer.
>>>>>>
>>>>>> This is not reflected in the patch.
>>>>>>
>>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>>> ---
>>>>>>>
>>>>>>> Changes in v8: None
>>>>>>> Changes in v7:
>>>>>>> - Move some of the code from efi_memory_init() into a separate
>>>>>>> function
>>>>>>>
>>>>>>> Changes in v6: None
>>>>>>> Changes in v5: None
>>>>>>> Changes in v4: None
>>>>>>> Changes in v3: None
>>>>>>> Changes in v2:
>>>>>>> - Update to use mapmem instead of a cast
>>>>>>>
>>>>>>>     lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>>>>>     1 file changed, 12 insertions(+), 4 deletions(-)
>>>>>>>
>>>>>>> diff --git a/lib/efi_loader/efi_memory.c
>>>>>>> b/lib/efi_loader/efi_memory.c
>>>>>>> index ec66af98ea..c6410613c7 100644
>>>>>>> --- a/lib/efi_loader/efi_memory.c
>>>>>>> +++ b/lib/efi_loader/efi_memory.c
>>>>>>> @@ -9,6 +9,7 @@
>>>>>>>     #include <efi_loader.h>
>>>>>>>     #include <inttypes.h>
>>>>>>>     #include <malloc.h>
>>>>>>> +#include <mapmem.h>
>>>>>>
>>>>>> I cannot see any use of this include in the patch.
>>>>>>
>>>>>>>     #include <watchdog.h>
>>>>>>>     #include <linux/list_sort.h>
>>>>>>>     @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>>>>>> efi_uintn_t size, void **buffer)
>>>>>>>                                  &t);
>>>>>>>           if (r == EFI_SUCCESS) {
>>>>>>> -               struct efi_pool_allocation *alloc = (void
>>>>>>> *)(uintptr_t)t;
>>>>>>> +               struct efi_pool_allocation *alloc = map_sysmem(t,
>>>>>>> size);
>>>>>
>>>>>
>>>>> ^^^
>>>>>
>>>>> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK
>>>>> on
>>>>> the patch as-is.
>>>>
>>>> What is wrong with it?
>>>
>>>
>>> Efi_allocate_pool calls efi_allocate_pages() which according to spec
>>> returns
>>> a pointer. So efi_allocate_pool() should not have to map anything,
>>> because
>>> it does not receive an addres.
>>
>> You are referring to efi_allocate_pages_ext() I suspect. In my series
>> this does the mapping, so that efi_allocate_pages() uses addresses
>> only. We could rename it if you like.
>
>
> I don't think we should rename things there. I really think there is a
> fundamental misunderstanding here on what the APIs are supposed to do.
> Basically:
>
>   efi_allocate_pages() is mmap() in Liunx
>   efi_allocate_pool() is malloc() in Linux
>
> plus a few extra features of course, but you can think of them at the same
> level.
>
> When a payload calls efi_allocate_pool, that really calls into a more
> sophisticated memory allocator usually which can allocate small chunks of
> memory efficiently. Given the amount of RAM modern systems have, I opted for
> simplicity though so I just mapped it to basically allocate pages using
> efi_allocate_pages().
>
> As for _ext functions, the *only* thing we want in an _ext function is to
> isolate the logic that EFI_CALL() would do otherwise - namely swap gd. No
> more.

Well, we can move things around, but fundamentally I think the current
efi_allocate_pages() needs something that maps its memory. In my patch
I put this in the ..._ext() function. I feel that the uint64_t *
prarameter of efi_allocate_pages() is really confusing, since it
implies an address rather than a pointer.

My vote would be to rename the function entirely and change the API to
work with pointers (doing the mapping inside itself).
Alexander Graf June 23, 2018, 7:31 a.m. UTC | #9
On 22.06.18 21:28, Simon Glass wrote:
> Hi Alex,
> 
> On 22 June 2018 at 06:08, Alexander Graf <agraf@suse.de> wrote:
>> On 06/21/2018 09:45 PM, Simon Glass wrote:
>>>
>>> Hi Alex,
>>>
>>> On 21 June 2018 at 03:52, Alexander Graf <agraf@suse.de> wrote:
>>>>
>>>> On 06/21/2018 04:02 AM, Simon Glass wrote:
>>>>>
>>>>> Hi Alex,
>>>>>
>>>>> On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
>>>>>>
>>>>>> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>>>>>>
>>>>>>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> Also use mapmem instead of a cast to convert a memory address to a
>>>>>>>> pointer.
>>>>>>>
>>>>>>> This is not reflected in the patch.
>>>>>>>
>>>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>>>> ---
>>>>>>>>
>>>>>>>> Changes in v8: None
>>>>>>>> Changes in v7:
>>>>>>>> - Move some of the code from efi_memory_init() into a separate
>>>>>>>> function
>>>>>>>>
>>>>>>>> Changes in v6: None
>>>>>>>> Changes in v5: None
>>>>>>>> Changes in v4: None
>>>>>>>> Changes in v3: None
>>>>>>>> Changes in v2:
>>>>>>>> - Update to use mapmem instead of a cast
>>>>>>>>
>>>>>>>>     lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>>>>>>     1 file changed, 12 insertions(+), 4 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/lib/efi_loader/efi_memory.c
>>>>>>>> b/lib/efi_loader/efi_memory.c
>>>>>>>> index ec66af98ea..c6410613c7 100644
>>>>>>>> --- a/lib/efi_loader/efi_memory.c
>>>>>>>> +++ b/lib/efi_loader/efi_memory.c
>>>>>>>> @@ -9,6 +9,7 @@
>>>>>>>>     #include <efi_loader.h>
>>>>>>>>     #include <inttypes.h>
>>>>>>>>     #include <malloc.h>
>>>>>>>> +#include <mapmem.h>
>>>>>>>
>>>>>>> I cannot see any use of this include in the patch.
>>>>>>>
>>>>>>>>     #include <watchdog.h>
>>>>>>>>     #include <linux/list_sort.h>
>>>>>>>>     @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>>>>>>> efi_uintn_t size, void **buffer)
>>>>>>>>                                  &t);
>>>>>>>>           if (r == EFI_SUCCESS) {
>>>>>>>> -               struct efi_pool_allocation *alloc = (void
>>>>>>>> *)(uintptr_t)t;
>>>>>>>> +               struct efi_pool_allocation *alloc = map_sysmem(t,
>>>>>>>> size);
>>>>>>
>>>>>>
>>>>>> ^^^
>>>>>>
>>>>>> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK
>>>>>> on
>>>>>> the patch as-is.
>>>>>
>>>>> What is wrong with it?
>>>>
>>>>
>>>> Efi_allocate_pool calls efi_allocate_pages() which according to spec
>>>> returns
>>>> a pointer. So efi_allocate_pool() should not have to map anything,
>>>> because
>>>> it does not receive an addres.
>>>
>>> You are referring to efi_allocate_pages_ext() I suspect. In my series
>>> this does the mapping, so that efi_allocate_pages() uses addresses
>>> only. We could rename it if you like.
>>
>>
>> I don't think we should rename things there. I really think there is a
>> fundamental misunderstanding here on what the APIs are supposed to do.
>> Basically:
>>
>>   efi_allocate_pages() is mmap() in Liunx
>>   efi_allocate_pool() is malloc() in Linux
>>
>> plus a few extra features of course, but you can think of them at the same
>> level.
>>
>> When a payload calls efi_allocate_pool, that really calls into a more
>> sophisticated memory allocator usually which can allocate small chunks of
>> memory efficiently. Given the amount of RAM modern systems have, I opted for
>> simplicity though so I just mapped it to basically allocate pages using
>> efi_allocate_pages().
>>
>> As for _ext functions, the *only* thing we want in an _ext function is to
>> isolate the logic that EFI_CALL() would do otherwise - namely swap gd. No
>> more.
> 
> Well, we can move things around, but fundamentally I think the current
> efi_allocate_pages() needs something that maps its memory. In my patch
> I put this in the ..._ext() function. I feel that the uint64_t *
> prarameter of efi_allocate_pages() is really confusing, since it
> implies an address rather than a pointer.

I agree that it's confusing, but it's probably the only thing that works
when running on a 32bit platform.

> My vote would be to rename the function entirely and change the API to
> work with pointers (doing the mapping inside itself).

The problem I see there is that we're trying to do a shim that is as
tiny as possible for real efi functionality. I don't know if splitting
the function is going to give us real improvements in readability or
maintainability, since there will be people who will come from an EFI
background and grasp what the EFI functions do, but not our internal layers.

What we could do is something the other way around: An internal wrapper
on top of efi_allocate_pages. Something like efi_get_mem() which takes
an address in one parameter and returns a pointer in another. But that
function would just call efi_allocate_pages(). If that again is a static
inline function, code size shouldn't even change.


Alex
Simon Glass June 25, 2018, 3:02 a.m. UTC | #10
Hi Alex,

On 23 June 2018 at 01:31, Alexander Graf <agraf@suse.de> wrote:
>
>
> On 22.06.18 21:28, Simon Glass wrote:
>> Hi Alex,
>>
>> On 22 June 2018 at 06:08, Alexander Graf <agraf@suse.de> wrote:
>>> On 06/21/2018 09:45 PM, Simon Glass wrote:
>>>>
>>>> Hi Alex,
>>>>
>>>> On 21 June 2018 at 03:52, Alexander Graf <agraf@suse.de> wrote:
>>>>>
>>>>> On 06/21/2018 04:02 AM, Simon Glass wrote:
>>>>>>
>>>>>> Hi Alex,
>>>>>>
>>>>>> On 20 June 2018 at 02:54, Alexander Graf <agraf@suse.de> wrote:
>>>>>>>
>>>>>>> On 06/20/2018 08:10 AM, Heinrich Schuchardt wrote:
>>>>>>>>
>>>>>>>> On 06/18/2018 04:08 PM, Simon Glass wrote:
>>>>>>>>>
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>> Also use mapmem instead of a cast to convert a memory address to a
>>>>>>>>> pointer.
>>>>>>>>
>>>>>>>> This is not reflected in the patch.
>>>>>>>>
>>>>>>>>> Signed-off-by: Simon Glass <sjg@chromium.org>
>>>>>>>>> ---
>>>>>>>>>
>>>>>>>>> Changes in v8: None
>>>>>>>>> Changes in v7:
>>>>>>>>> - Move some of the code from efi_memory_init() into a separate
>>>>>>>>> function
>>>>>>>>>
>>>>>>>>> Changes in v6: None
>>>>>>>>> Changes in v5: None
>>>>>>>>> Changes in v4: None
>>>>>>>>> Changes in v3: None
>>>>>>>>> Changes in v2:
>>>>>>>>> - Update to use mapmem instead of a cast
>>>>>>>>>
>>>>>>>>>     lib/efi_loader/efi_memory.c | 16 ++++++++++++----
>>>>>>>>>     1 file changed, 12 insertions(+), 4 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git a/lib/efi_loader/efi_memory.c
>>>>>>>>> b/lib/efi_loader/efi_memory.c
>>>>>>>>> index ec66af98ea..c6410613c7 100644
>>>>>>>>> --- a/lib/efi_loader/efi_memory.c
>>>>>>>>> +++ b/lib/efi_loader/efi_memory.c
>>>>>>>>> @@ -9,6 +9,7 @@
>>>>>>>>>     #include <efi_loader.h>
>>>>>>>>>     #include <inttypes.h>
>>>>>>>>>     #include <malloc.h>
>>>>>>>>> +#include <mapmem.h>
>>>>>>>>
>>>>>>>> I cannot see any use of this include in the patch.
>>>>>>>>
>>>>>>>>>     #include <watchdog.h>
>>>>>>>>>     #include <linux/list_sort.h>
>>>>>>>>>     @@ -393,7 +394,7 @@ efi_status_t efi_allocate_pool(int pool_type,
>>>>>>>>> efi_uintn_t size, void **buffer)
>>>>>>>>>                                  &t);
>>>>>>>>>           if (r == EFI_SUCCESS) {
>>>>>>>>> -               struct efi_pool_allocation *alloc = (void
>>>>>>>>> *)(uintptr_t)t;
>>>>>>>>> +               struct efi_pool_allocation *alloc = map_sysmem(t,
>>>>>>>>> size);
>>>>>>>
>>>>>>>
>>>>>>> ^^^
>>>>>>>
>>>>>>> This is where mapmem.h gets used. And yes, it's the wrong place. So NAK
>>>>>>> on
>>>>>>> the patch as-is.
>>>>>>
>>>>>> What is wrong with it?
>>>>>
>>>>>
>>>>> Efi_allocate_pool calls efi_allocate_pages() which according to spec
>>>>> returns
>>>>> a pointer. So efi_allocate_pool() should not have to map anything,
>>>>> because
>>>>> it does not receive an addres.
>>>>
>>>> You are referring to efi_allocate_pages_ext() I suspect. In my series
>>>> this does the mapping, so that efi_allocate_pages() uses addresses
>>>> only. We could rename it if you like.
>>>
>>>
>>> I don't think we should rename things there. I really think there is a
>>> fundamental misunderstanding here on what the APIs are supposed to do.
>>> Basically:
>>>
>>>   efi_allocate_pages() is mmap() in Liunx
>>>   efi_allocate_pool() is malloc() in Linux
>>>
>>> plus a few extra features of course, but you can think of them at the same
>>> level.
>>>
>>> When a payload calls efi_allocate_pool, that really calls into a more
>>> sophisticated memory allocator usually which can allocate small chunks of
>>> memory efficiently. Given the amount of RAM modern systems have, I opted for
>>> simplicity though so I just mapped it to basically allocate pages using
>>> efi_allocate_pages().
>>>
>>> As for _ext functions, the *only* thing we want in an _ext function is to
>>> isolate the logic that EFI_CALL() would do otherwise - namely swap gd. No
>>> more.
>>
>> Well, we can move things around, but fundamentally I think the current
>> efi_allocate_pages() needs something that maps its memory. In my patch
>> I put this in the ..._ext() function. I feel that the uint64_t *
>> prarameter of efi_allocate_pages() is really confusing, since it
>> implies an address rather than a pointer.
>
> I agree that it's confusing, but it's probably the only thing that works
> when running on a 32bit platform.
>
>> My vote would be to rename the function entirely and change the API to
>> work with pointers (doing the mapping inside itself).
>
> The problem I see there is that we're trying to do a shim that is as
> tiny as possible for real efi functionality. I don't know if splitting
> the function is going to give us real improvements in readability or
> maintainability, since there will be people who will come from an EFI
> background and grasp what the EFI functions do, but not our internal layers.

I'm not sure either, but it might be worth taking a look once the dust settles.

>
> What we could do is something the other way around: An internal wrapper
> on top of efi_allocate_pages. Something like efi_get_mem() which takes
> an address in one parameter and returns a pointer in another. But that
> function would just call efi_allocate_pages(). If that again is a static
> inline function, code size shouldn't even change.

Well I think the problem is the API using addresses in one method and
pointers in another. We can't fix that.

Maybe that would work. One of us should take a look down the track.

Regards,
Simon
diff mbox series

Patch

diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index ec66af98ea..c6410613c7 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -9,6 +9,7 @@ 
 #include <efi_loader.h>
 #include <inttypes.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <watchdog.h>
 #include <linux/list_sort.h>
 
@@ -393,7 +394,7 @@  efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
 			       &t);
 
 	if (r == EFI_SUCCESS) {
-		struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
+		struct efi_pool_allocation *alloc = map_sysmem(t, size);
 		alloc->num_pages = num_pages;
 		*buffer = alloc->data;
 	}
@@ -496,14 +497,13 @@  __weak void efi_add_known_memory(void)
 	}
 }
 
-int efi_memory_init(void)
+/* Add memory regions for U-Boot's memory and for the runtime services code */
+static void add_u_boot_and_runtime(void)
 {
 	unsigned long runtime_start, runtime_end, runtime_pages;
 	unsigned long uboot_start, uboot_pages;
 	unsigned long uboot_stack_size = 16 * 1024 * 1024;
 
-	efi_add_known_memory();
-
 	/* Add U-Boot */
 	uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
 	uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
@@ -516,6 +516,14 @@  int efi_memory_init(void)
 	runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
 	efi_add_memory_map(runtime_start, runtime_pages,
 			   EFI_RUNTIME_SERVICES_CODE, false);
+}
+
+int efi_memory_init(void)
+{
+	efi_add_known_memory();
+
+	if (!IS_ENABLED(CONFIG_SANDBOX))
+		add_u_boot_and_runtime();
 
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
 	/* Request a 32bit 64MB bounce buffer region */