> On 23 Sep 2021, at 17:59, Stefano Stabellini <sstabell...@kernel.org> wrote:
> 
> On Thu, 23 Sep 2021, Luca Fancellu wrote:
>>>> +/*
>>>> + * Binaries will be translated into bootmodules, the maximum number for 
>>>> them is
>>>> + * MAX_MODULES where we should remove a unit for Xen and one for Xen DTB
>>>> + */
>>>> +#define MAX_DOM0LESS_MODULES (MAX_MODULES - 2)
>>>> +static struct file __initdata dom0less_file;
>>>> +static dom0less_module_name __initdata 
>>>> dom0less_modules[MAX_DOM0LESS_MODULES];
>>>> +static unsigned int __initdata dom0less_modules_available =
>>>> +                               MAX_DOM0LESS_MODULES;
>>>> +static unsigned int __initdata dom0less_modules_idx;
>>> 
>>> This is a lot better!
>>> 
>>> We don't need both dom0less_modules_idx and dom0less_modules_available.
>>> You can just do:
>>> 
>>> #define dom0less_modules_available (MAX_DOM0LESS_MODULES - 
>>> dom0less_modules_idx)
>>> static unsigned int __initdata dom0less_modules_idx;
>>> 
>>> But maybe we can even get rid of dom0less_modules_available entirely?
>>> 
>>> We can change the check at the beginning of allocate_dom0less_file to:
>>> 
>>> if ( dom0less_modules_idx == dom0less_modules_available )
>>>   blexit
>>> 
>>> Would that work?
>> 
>> I thought about it but I think they need to stay, because 
>> dom0less_modules_available is the
>> upper bound for the additional dom0less modules (it is decremented each time 
>> a dom0 module
>> Is added), instead dom0less_modules_idx is the typical index for the array 
>> of dom0less modules.
> 
> [...]
> 
> 
>>>> +    /*
>>>> +     * Check if there is any space left for a domU module, the variable
>>>> +     * dom0less_modules_available is updated each time we use 
>>>> read_file(...)
>>>> +     * successfully.
>>>> +     */
>>>> +    if ( !dom0less_modules_available )
>>>> +        blexit(L"No space left for domU modules");
>>> 
>>> This is the check that could be based on dom0less_modules_idx
>>> 
>> 
>> The only way I see to have it based on dom0less_modules_idx will be to 
>> compare it
>> to the amount of modules still available, that is not constant because it is 
>> dependent
>> on how many dom0 modules are loaded, so still two variables needed.
>> Don’t know if I’m missing something.
> 
> I think I understand where the confusion comes from. I am appending a
> small patch to show what I had in mind. We are already accounting for
> Xen and the DTB when declaring MAX_DOM0LESS_MODULES (MAX_MODULES - 2).
> The other binaries are the Dom0 kernel and ramdisk, however, in my setup
> they don't trigger a call to handle_dom0less_module_node because they
> are compatible xen,linux-zimage and xen,linux-initrd.
> 
> However, the Dom0 kernel and ramdisk can be also compatible
> multiboot,kernel and multiboot,ramdisk. If that is the case, then they
> would indeed trigger a call to handle_dom0less_module_node.
> 
> I think that is not a good idea: a function called
> handle_dom0less_module_node should only be called for dom0less modules
> (domUs) and not dom0.
> 
> But from the memory consumption point of view, it would be better
> actually to catch dom0 modules too as you intended. In that case we need to:
> 
> - add a check for xen,linux-zimage and xen,linux-initrd in
>  handle_dom0less_module_node also
> 
> - rename handle_dom0less_domain_node, handle_dom0less_module_node,
>  dom0less_file, dom0less_modules, dom0less_modules_idx to something
>  else more generic
> 
> 
> For instance they could be called:
> 
> handle_domain_node
> handle_module_node
> module_file
> modules
> modules_idx
> 
> 
> 
> 
> diff --git a/xen/arch/arm/efi/efi-boot.h b/xen/arch/arm/efi/efi-boot.h
> index e2b007ece0..812d0bd607 100644
> --- a/xen/arch/arm/efi/efi-boot.h
> +++ b/xen/arch/arm/efi/efi-boot.h
> @@ -22,8 +22,6 @@ typedef struct {
> #define MAX_DOM0LESS_MODULES (MAX_MODULES - 2)
> static struct file __initdata dom0less_file;
> static dom0less_module_name __initdata dom0less_modules[MAX_DOM0LESS_MODULES];
> -static unsigned int __initdata dom0less_modules_available =
> -                               MAX_DOM0LESS_MODULES;
> static unsigned int __initdata dom0less_modules_idx;
> 
> #define ERROR_DOM0LESS_FILE_NOT_FOUND (-1)
> @@ -592,14 +590,6 @@ static void __init efi_arch_handle_module(const struct 
> file *file,
>          * stop here.
>          */
>         blexit(L"Unknown module type");
> -
> -    /*
> -     * dom0less_modules_available is decremented here because for each dom0
> -     * file added, there will be an additional bootmodule, so the number
> -     * of dom0less module files will be decremented because there is
> -     * a maximum amount of bootmodules that can be loaded.
> -     */
> -    dom0less_modules_available--;
> }
> 
> /*
> @@ -643,7 +633,7 @@ static unsigned int __init 
> allocate_dom0less_file(EFI_FILE_HANDLE dir_handle,
>      * dom0less_modules_available is updated each time we use read_file(...)
>      * successfully.
>      */
> -    if ( !dom0less_modules_available )
> +    if ( dom0less_modules_idx == MAX_DOM0LESS_MODULES )
>         blexit(L"No space left for domU modules");
> 
>     module_name.s = (char*) name;

Hi Stefano,

Yes I understand what you mean, unfortunately it can’t be done, I will explain 
why in details
because the UEFI code is very tricky in the way it was written.

Dom0 modules and xsm-policy are handled in boot.c by read_section(…) or 
read_file(…) and
both call handle_file_info(…) that inside calls efi_arch_handle_module(…).
Dom0less modules (xen,domain child modules) are handled in efi-boot.h by 
handle_dom0less_module_node(…)
that may call allocate_dom0less_file(…) and (to reuse code) calls read_file(…).

So there can be maximum (MAX_MODULES-2) boot modules because at start in 
start_xen(…)
we add Xen and the DTB as boot modules.

This amount is to be shared among dom0 modules (kernel, ramdisk), xsm-policy 
and domU
modules (kernel, ramdisk, dtb).

The thing is that we don’t know how many dom0 modules will be specified and 
also for the xsm-policy.

In your code example, let’s say I have MAX_DOM0LESS_MODULES=(32-2) so 30 
modules available,
If I declare a Dom0 kernel and 30 DomU kernels, it will pass the check, but on 
boot I think it will ignore
the exceeding modules.

For that reason we need to keep track of how many “slots” are available, so in 
my code every time the
read_file(…)/read_section(…) is called, the dom0less_modules_available is 
decremented.

If we want to get rid of one variable, we can just assume the dom0 modules and 
xsm-policy will be always
loaded and we can set MAX_DOM0LESS_MODULES=(MAX_MODULES - 2 - 3) where 3 is 
dom0 kernel,
dom0 ramdisk and xsm-policy. If the user doesn’t load any of them, we just lost 
3 slots.

Another solution can be keeping just the dom0less_modules_available and every 
time loop backward in the array
starting from that position and stopping when we have a 
dom0less_module_name.name == NULL so we
know we have an available slot or we reach below zero and we know there is no 
space. But I think it’s not
worthy.

So if you really want to have only one variable, I will remove space from 
MAX_DOM0LESS_MODULES and
I will push it in v3.

Cheers,
Luca









Reply via email to