From f47c64e246ce68bd26893ded53e5b19332f497d1 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 25 May 2023 16:49:13 +0200 Subject: [PATCH] core: allow offset-attached managed dataspaces This patch adds the missing application of the region offset to the resolution of page faults inside managed dataspaces, which resulted in an unexpected "invalid mapping" message after attaching a managed dataspace with an offset. This limitation could be observed during the implementation of the debug monitor that locally maps a portion of the debugging target's address space, e.g., a view port of 16 MiB. All traditional uses of managed dataspaces (e.g., stack area, linker area) happened to attach the managed dataspaces from their beginning. Issue #4917 --- .../src/core/include/region_map_component.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/repos/base/src/core/include/region_map_component.h b/repos/base/src/core/include/region_map_component.h index 7025259bc6..5076e77b64 100644 --- a/repos/base/src/core/include/region_map_component.h +++ b/repos/base/src/core/include/region_map_component.h @@ -321,7 +321,8 @@ class Core::Region_map_component : private Weak_object, Mutex::Guard lock_guard(_mutex); /* skip further lookup when reaching the recursion limit */ - if (!level) return f(this, nullptr, 0, 0, dst_region_size); + if (!level) + return f(this, nullptr, 0, 0, dst_region_size); /* lookup region and dataspace */ Rm_region *region = _map.metadata((void*)addr); @@ -331,7 +332,6 @@ class Core::Region_map_component : private Weak_object, if (region && dst_region_size > region->size()) dst_region_size = region->size(); - /* calculate offset in dataspace */ addr_t ds_offset = region ? (addr - region->base() + region->offset()) : 0; @@ -340,16 +340,19 @@ class Core::Region_map_component : private Weak_object, Native_capability cap = dsc ? dsc->sub_rm() : Native_capability(); - if (!cap.valid()) return f(this, region, ds_offset, offset, dst_region_size); + if (!cap.valid()) + return f(this, region, ds_offset, offset, dst_region_size); /* in case of a nested dataspace perform a recursive lookup */ auto lambda = [&] (Region_map_component *rmc) -> Return_type { - return (!rmc) ? f(nullptr, nullptr, ds_offset, offset, dst_region_size) - : rmc->_apply_to_dataspace(ds_offset, f, - offset+region->base(), - --level, - dst_region_size); + if (rmc) + return rmc->_apply_to_dataspace(ds_offset, f, + offset + region->base() - region->offset(), + --level, + dst_region_size); + + return f(nullptr, nullptr, ds_offset, offset, dst_region_size); }; return _session_ep.apply(cap, lambda); }