|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 4/7] xen/arm: Parse xen,shared-mem when host phys address is not provided
Hi Luca,
On 23/04/2024 10:25, Luca Fancellu wrote:
>
>
> Handle the parsing of the 'xen,shared-mem' property when the host physical
> address is not provided, this commit is introducing the logic to parse it,
> but the functionality is still not implemented and will be part of future
> commits.
>
> Rework the logic inside process_shm_node to check the shm_id before doing
> the other checks, because it ease the logic itself, add more comment on
> the logic.
> Now when the host physical address is not provided, the value
> INVALID_PADDR is chosen to signal this condition and it is stored as
> start of the bank, due to that change also early_print_info_shmem and
> init_sharedmem_pages are changed, to don't handle banks with start equal
> to INVALID_PADDR.
>
> Another change is done inside meminfo_overlap_check, to skip banks that
> are starting with the start address INVALID_PADDR, that function is used
> to check banks from reserved memory and ACPI and it's unlikely for these
also from shmem
> bank to have the start address as INVALID_PADDR. The change holds
> because of this consideration.
On arm64 and LPAE arm32 we don't have this problem. In theory we could have a
bank
starting at INVALID_PADDR if PA range was 32bit but as the comment above the
function states,
wrapping around is not handled. You might want to use it as a justification to
be clear.
>
> Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx>
> ---
> xen/arch/arm/setup.c | 3 +-
> xen/arch/arm/static-shmem.c | 129 +++++++++++++++++++++++++-----------
> 2 files changed, 93 insertions(+), 39 deletions(-)
>
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index d242674381d4..f15d40a85a5f 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -297,7 +297,8 @@ static bool __init meminfo_overlap_check(const struct
> membanks *mem,
> bank_start = mem->bank[i].start;
> bank_end = bank_start + mem->bank[i].size;
>
> - if ( region_end <= bank_start || region_start >= bank_end )
> + if ( INVALID_PADDR == bank_start || region_end <= bank_start ||
> + region_start >= bank_end )
> continue;
> else
> {
> diff --git a/xen/arch/arm/static-shmem.c b/xen/arch/arm/static-shmem.c
> index 24e40495a481..1c03bb7f1882 100644
> --- a/xen/arch/arm/static-shmem.c
> +++ b/xen/arch/arm/static-shmem.c
> @@ -264,6 +264,12 @@ int __init process_shm(struct domain *d, struct
> kernel_info *kinfo,
> pbase = boot_shm_bank->start;
> psize = boot_shm_bank->size;
>
> + if ( INVALID_PADDR == pbase )
> + {
> + printk("%pd: host physical address must be chosen by users at
> the moment.", d);
The dot at the end is not needed.
> + return -EINVAL;
> + }
> +
> /*
> * xen,shared-mem = <pbase, gbase, size>;
> * TODO: pbase is optional.
> @@ -382,7 +388,8 @@ int __init process_shm_node(const void *fdt, int node,
> uint32_t address_cells,
> {
> const struct fdt_property *prop, *prop_id, *prop_role;
> const __be32 *cell;
> - paddr_t paddr, gaddr, size, end;
> + paddr_t paddr = INVALID_PADDR;
> + paddr_t gaddr, size, end;
> struct membanks *mem = bootinfo_get_shmem();
> struct shmem_membank_extra *shmem_extra = bootinfo_get_shmem_extra();
> unsigned int i;
> @@ -437,24 +444,37 @@ int __init process_shm_node(const void *fdt, int node,
> uint32_t address_cells,
> if ( !prop )
> return -ENOENT;
>
> + cell = (const __be32 *)prop->data;
> if ( len != dt_cells_to_size(address_cells + size_cells + address_cells)
> )
> {
> - if ( len == dt_cells_to_size(size_cells + address_cells) )
> - printk("fdt: host physical address must be chosen by users at
> the moment.\n");
> -
> - printk("fdt: invalid `xen,shared-mem` property.\n");
> - return -EINVAL;
> + if ( len == dt_cells_to_size(address_cells + size_cells) )
> + device_tree_get_reg(&cell, address_cells, size_cells, &gaddr,
> + &size);
> + else
> + {
> + printk("fdt: invalid `xen,shared-mem` property.\n");
> + return -EINVAL;
> + }
> }
> + else
> + {
> + device_tree_get_reg(&cell, address_cells, address_cells, &paddr,
> + &gaddr);
> + size = dt_next_cell(size_cells, &cell);
>
> - cell = (const __be32 *)prop->data;
> - device_tree_get_reg(&cell, address_cells, address_cells, &paddr, &gaddr);
> - size = dt_next_cell(size_cells, &cell);
> + if ( !IS_ALIGNED(paddr, PAGE_SIZE) )
> + {
> + printk("fdt: physical address 0x%"PRIpaddr" is not suitably
> aligned.\n",
> + paddr);
> + return -EINVAL;
> + }
>
> - if ( !IS_ALIGNED(paddr, PAGE_SIZE) )
> - {
> - printk("fdt: physical address 0x%"PRIpaddr" is not suitably
> aligned.\n",
> - paddr);
> - return -EINVAL;
> + end = paddr + size;
> + if ( end <= paddr )
> + {
> + printk("fdt: static shared memory region %s overflow\n", shm_id);
> + return -EINVAL;
> + }
> }
>
> if ( !IS_ALIGNED(gaddr, PAGE_SIZE) )
> @@ -476,41 +496,69 @@ int __init process_shm_node(const void *fdt, int node,
> uint32_t address_cells,
> return -EINVAL;
> }
>
> - end = paddr + size;
> - if ( end <= paddr )
> - {
> - printk("fdt: static shared memory region %s overflow\n", shm_id);
> - return -EINVAL;
> - }
> -
> for ( i = 0; i < mem->nr_banks; i++ )
> {
> /*
> * Meet the following check:
> + * when host address is provided:
- when would read better
> * 1) The shm ID matches and the region exactly match
> * 2) The shm ID doesn't match and the region doesn't overlap
> * with an existing one
> + * when host address is not provided:
> + * 1) The shm ID matches and the region size exactly match
> */
> - if ( paddr == mem->bank[i].start && size == mem->bank[i].size )
> + bool paddr_assigned = INVALID_PADDR == paddr;
parenthesis around INVALID_PADDR == paddr
> + bool shm_id_match = strncmp(shm_id, shmem_extra[i].shm_id,
> + MAX_SHM_ID_LENGTH) == 0;
why not if ( strncmp... given no other use of this variable other than the one
below?
> + if ( shm_id_match )
> {
> - if ( strncmp(shm_id, shmem_extra[i].shm_id,
> - MAX_SHM_ID_LENGTH) == 0 )
> + /*
> + * Regions have same shm_id (cases):
> + * 1) physical host address is supplied:
> + * - OK: paddr is equal and size is equal (same region)
> + * - Fail: paddr doesn't match or size doesn't match (there
> + * cannot exists two shmem regions with same shm_id)
> + * 2) physical host address is NOT supplied:
> + * - OK: size is equal (same region)
> + * - Fail: size is not equal (same shm_id must identify only
> one
> + * region, there can't be two different regions with
> same
> + * shm_id)
> + */
> + bool start_match = paddr_assigned ? (paddr ==
> mem->bank[i].start) :
> + true;
> +
> + if ( start_match && size == mem->bank[i].size )
> break;
> else
> {
> - printk("fdt: xen,shm-id %s does not match for all the nodes
> using the same region.\n",
> + printk("fdt: different shared memory region could not share
> the same shm ID %s\n",
> shm_id);
> return -EINVAL;
> }
> }
> - else if ( strncmp(shm_id, shmem_extra[i].shm_id,
> - MAX_SHM_ID_LENGTH) != 0 )
> - continue;
> else
> {
There is no need for this else and entire block given that the block within if
either calls break or return
> - printk("fdt: different shared memory region could not share the
> same shm ID %s\n",
> - shm_id);
> - return -EINVAL;
> + /*
> + * Regions have different shm_id (cases):
> + * 1) physical host address is supplied:
> + * - OK: paddr different, or size different (case where
> paddr
> + * is equal but psize is different are wrong, but they
> + * are handled later when checking for overlapping)
> + * - Fail: paddr equal and size equal (the same region can't
> be
> + * identified with different shm_id)
> + * 2) physical host address is NOT supplied:
> + * - OK: Both have different shm_id so even with same size
> they
> + * can exists
> + */
> + if ( !paddr_assigned || paddr != mem->bank[i].start ||
> + size != mem->bank[i].size )
> + continue;
> + else
> + {
> + printk("fdt: xen,shm-id %s does not match for all the nodes
> using the same region.\n",
> + shm_id);
> + return -EINVAL;
> + }
> }
> }
>
> @@ -518,7 +566,8 @@ int __init process_shm_node(const void *fdt, int node,
> uint32_t address_cells,
> {
> if (i < mem->max_banks)
> {
> - if ( check_reserved_regions_overlap(paddr, size) )
> + if ( (paddr != INVALID_PADDR) &&
> + check_reserved_regions_overlap(paddr, size) )
> return -EINVAL;
>
> /* Static shared memory shall be reserved from any other use. */
> @@ -588,13 +637,16 @@ void __init early_print_info_shmem(void)
> {
> const struct membanks *shmem = bootinfo_get_shmem();
> unsigned int bank;
> + unsigned int printed = 0;
>
> for ( bank = 0; bank < shmem->nr_banks; bank++ )
> - {
> - printk(" SHMEM[%u]: %"PRIpaddr" - %"PRIpaddr"\n", bank,
> - shmem->bank[bank].start,
> - shmem->bank[bank].start + shmem->bank[bank].size - 1);
> - }
> + if ( shmem->bank[bank].start != INVALID_PADDR )
> + {
> + printk(" SHMEM[%u]: %"PRIpaddr" - %"PRIpaddr"\n", printed,
> + shmem->bank[bank].start,
> + shmem->bank[bank].start + shmem->bank[bank].size - 1);
> + printed++;
NIT: you could initialize and increment it as part of the for loop
> + }
> }
>
> void __init init_sharedmem_pages(void)
> @@ -603,7 +655,8 @@ void __init init_sharedmem_pages(void)
> unsigned int bank;
>
> for ( bank = 0 ; bank < shmem->nr_banks; bank++ )
> - init_staticmem_bank(&shmem->bank[bank]);
> + if ( shmem->bank[bank].start != INVALID_PADDR )
> + init_staticmem_bank(&shmem->bank[bank]);
> }
>
> int __init remove_shm_from_rangeset(const struct kernel_info *kinfo,
> --
> 2.34.1
>
~Michal
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |