On 03/06/2025 23:15, Stewart Hildebrand wrote:
> On 5/14/25 03:31, Orzel, Michal wrote:
>> On 13/05/2025 21:54, Stewart Hildebrand wrote:
>>> Similarly to fba1b0974dd8, when a device is passed through to a
>>> direct-map dom0less domU, the xen,reg ranges may overlap with the
>>> extended regions. Remove xen,reg from direct-map domU extended regions.
>>>
>>> Introduce rangeset_count_ranges().
>>>
>>> Take the opportunity to update the comment ahead of find_memory_holes().
>>>
>>> Signed-off-by: Stewart Hildebrand <stewart.hildebr...@amd.com>
>>> ---
>>> v2->v3:
>>> * new patch
>>> ---
>>>  xen/arch/arm/domain_build.c | 57 +++++++++++++++++++++++++++++++++----
>>>  xen/common/rangeset.c       | 14 +++++++++
>>>  xen/include/xen/rangeset.h  |  2 ++
>>>  3 files changed, 68 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>>> index b189a7cfae9f..3cdf5839bc98 100644
>>> --- a/xen/arch/arm/domain_build.c
>>> +++ b/xen/arch/arm/domain_build.c
>>> @@ -824,15 +824,17 @@ static int __init handle_pci_range(const struct 
>>> dt_device_node *dev,
>>>  }
>>>  
>>>  /*
>>> - * Find the holes in the Host DT which can be exposed to Dom0 as extended
>>> - * regions for the special memory mappings. In order to calculate regions
>>> - * we exclude every addressable memory region described by "reg" and 
>>> "ranges"
>>> - * properties from the maximum possible addressable physical memory range:
>>> + * Find the holes in the Host DT which can be exposed to Dom0 or a 
>>> direct-map
>>> + * domU as extended regions for the special memory mappings. In order to
>>> + * calculate regions we exclude every addressable memory region described 
>>> by
>>> + * "reg" and "ranges" properties from the maximum possible addressable 
>>> physical
>>> + * memory range:
>>>   * - MMIO
>>>   * - Host RAM
>>>   * - PCI aperture
>>>   * - Static shared memory regions, which are described by special property
>>>   *   "xen,shared-mem"
>>> + * - xen,reg mappings
>>>   */
>>>  static int __init find_memory_holes(const struct kernel_info *kinfo,
>>>                                      struct membanks *ext_regions)
>>> @@ -914,6 +916,13 @@ static int __init find_memory_holes(const struct 
>>> kernel_info *kinfo,
>>>          }
>>>      }
>>>  
>>> +    if ( kinfo->xen_reg_assigned )
>>> +    {
>>> +        res = rangeset_subtract(mem_holes, kinfo->xen_reg_assigned);
>>> +        if ( res )
>>> +            goto out;
>>> +    }
>>> +
>>>      start = 0;
>>>      end = (1ULL << p2m_ipa_bits) - 1;
>>>      res = rangeset_report_ranges(mem_holes, PFN_DOWN(start), PFN_DOWN(end),
>>> @@ -994,11 +1003,30 @@ static int __init find_domU_holes(const struct 
>>> kernel_info *kinfo,
>>>      return res;
>>>  }
>>>  
>>> +static int __init rangeset_to_membank(unsigned long s_gfn, unsigned long 
>>> e_gfn,
>>> +                                      void *data)
>>> +{
>>> +    struct membanks *membank = data;
>>> +    paddr_t s = pfn_to_paddr(s_gfn);
>>> +    paddr_t e = pfn_to_paddr(e_gfn + 1) - 1;
>>> +
>>> +    if ( membank->nr_banks >= membank->max_banks )
>>> +        return 0;
>>> +
>>> +    membank->bank[membank->nr_banks].start = s;
>>> +    membank->bank[membank->nr_banks].size = e - s + 1;
>>> +    membank->nr_banks++;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>  static int __init find_host_extended_regions(const struct kernel_info 
>>> *kinfo,
>>>                                               struct membanks *ext_regions)
>>>  {
>>>      int res;
>>>      struct membanks *gnttab = membanks_xzalloc(1, MEMORY);
>>> +    struct membanks *xen_reg = membanks_xzalloc(
>>> +        max(1, rangeset_count_ranges(kinfo->xen_reg_assigned)), MEMORY);
>> You allocate at least 1 membank even though xen_reg_assigned may be empty 
>> because:
>>  - this function is called for hwdom - no xen,reg
>>  - there may be no xen,reg i.e. no passthrough
> 
> Ah, sorry, there's no need to allocate at least 1. This can just be:
> 
>     struct membanks *xen_reg = membanks_xzalloc(
>         rangeset_count_ranges(kinfo->arch.xen_reg_assigned), MEMORY);
No, it cannot. membanks_xzalloc() calls xzalloc_flex_struct(). If you pass 0
as size, the latter will calculate offset to FAM[0]. In other words, the
allocation will succeed but only for members up to FAM[0] (i.e. only for struct
membanks_hdr).

Also, even if you conditionally allocate for xen_reg_assigned or set NULL, in
latter case you will end up with mem_banks containing NULL member. AFAICT that's
not something expected by the users of mem_banks (+ it gives unneeded 
iteration).

~Michal


Reply via email to