On Tue, May 7, 2013 at 10:16 PM, Paolo Bonzini <pbonz...@redhat.com> wrote:
> memory_region_find() is similar to registering a MemoryListener and

But losing the priority of MemoryListener.  Had better document to
warn this, so the user will decide whether it is safe to use the
interfaces based on this or not.

> checking for the MemoryRegionSections that come from a particular
> region.  There is no reason for this to be limited to a root memory
> region.
>
> Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
> ---
>  include/exec/memory.h |   13 +++++++------
>  memory.c              |   20 +++++++++++++++-----
>  2 files changed, 22 insertions(+), 11 deletions(-)
>
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index 9e88320..efe210b 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -725,17 +725,18 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
>   *
>   * Returns a #MemoryRegionSection that describes a contiguous overlap.
>   * It will have the following characteristics:
> - *    .@offset_within_address_space >= @addr
> - *    .@offset_within_address_space + .@size <= @addr + @size
>   *    .@size = 0 iff no overlap was found
>   *    .@mr is non-%NULL iff an overlap was found
>   *
> - * @address_space: a top-level (i.e. parentless) region that contains
> - *       the region to be found
> - * @addr: start of the area within @address_space to be searched
> + * If @mr is parent-less,
> + *    .@offset_within_address_space >= @addr
> + *    .@offset_within_address_space + .@size <= @addr + @size
> + *
> + * @mr: a (possibly indirect) parent that contains the region to be found
> + * @addr: start of the area within @as to be searched
>   * @size: size of the area to be searched
>   */
> -MemoryRegionSection memory_region_find(MemoryRegion *address_space,
> +MemoryRegionSection memory_region_find(MemoryRegion *mr,
>                                         hwaddr addr, uint64_t size);
>
>  /**
> diff --git a/memory.c b/memory.c
> index 75ca281..34bfb13 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -1451,15 +1451,24 @@ static FlatRange *address_space_lookup(AddressSpace 
> *as, AddrRange addr)
>                     sizeof(FlatRange), cmp_flatrange_addr);
>  }
>
> -MemoryRegionSection memory_region_find(MemoryRegion *address_space,
> +MemoryRegionSection memory_region_find(MemoryRegion *mr,
>                                         hwaddr addr, uint64_t size)
>  {
> -    AddressSpace *as = memory_region_to_address_space(address_space);
> -    AddrRange range = addrrange_make(int128_make64(addr),
> -                                     int128_make64(size));
> -    FlatRange *fr = address_space_lookup(as, range);
>      MemoryRegionSection ret = { .mr = NULL, .size = 0 };
> +    MemoryRegion *root;
> +    AddressSpace *as;
> +    AddrRange range;
> +    FlatRange *fr;
> +
> +    addr += mr->addr;
> +    for (root = mr; root->parent; ) {
> +        root = root->parent;
> +        addr += root->addr;
> +    }
>
> +    as = memory_region_to_address_space(root);
> +    range = addrrange_make(int128_make64(addr), int128_make64(size));
> +    fr = address_space_lookup(as, range);
>      if (!fr) {
>          return ret;
>      }
> @@ -1470,6 +1479,7 @@ MemoryRegionSection memory_region_find(MemoryRegion 
> *address_space,
>      }
>
>      ret.mr = fr->mr;
> +    ret.address_space = as;
>      range = addrrange_intersection(range, fr->addr);
>      ret.offset_within_region = fr->offset_in_region;
>      ret.offset_within_region += int128_get64(int128_sub(range.start,
> --
> 1.7.1
>
>

Reply via email to