1.1 --- a/libexec/include/exec/internal_pager.h Fri Mar 24 16:14:44 2023 +0100
1.2 +++ b/libexec/include/exec/internal_pager.h Sat Mar 25 18:45:42 2023 +0100
1.3 @@ -59,6 +59,9 @@
1.4 virtual long attach(address_t *start, address_t size, map_flags_t flags,
1.5 l4_cap_idx_t ds, address_t offset, unsigned char align);
1.6
1.7 + virtual long detach(address_t addr, address_t size, map_flags_t flags,
1.8 + address_t *start, address_t *rsize, l4_cap_idx_t *ds);
1.9 +
1.10 virtual long reserve_area(address_t *start, address_t size, map_flags_t flags,
1.11 unsigned char align);
1.12 };
2.1 --- a/libexec/include/exec/memory_area.h Fri Mar 24 16:14:44 2023 +0100
2.2 +++ b/libexec/include/exec/memory_area.h Sat Mar 25 18:45:42 2023 +0100
2.3 @@ -95,7 +95,7 @@
2.4
2.5 /* Support for finding regions. */
2.6
2.7 - virtual long find(address_t addr, MemoryArea **area);
2.8 + virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent);
2.9
2.10 /* Support for finding areas. */
2.11
2.12 @@ -124,7 +124,7 @@
2.13
2.14 /* Support for finding areas. */
2.15
2.16 - virtual long find(address_t addr, MemoryArea **area);
2.17 + virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent);
2.18 };
2.19
2.20
2.21 @@ -162,7 +162,7 @@
2.22
2.23 /* Support for finding areas. */
2.24
2.25 - virtual long find(address_t addr, MemoryArea **area);
2.26 + virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent);
2.27
2.28 virtual long find(address_t *start, address_t *size, map_flags_t flags,
2.29 unsigned char align, MemoryArea **area);
3.1 --- a/libexec/lib/src/external_pager.cc Fri Mar 24 16:14:44 2023 +0100
3.2 +++ b/libexec/lib/src/external_pager.cc Sat Mar 25 18:45:42 2023 +0100
3.3 @@ -181,8 +181,8 @@
3.4
3.5 /* Obtain a region supporting the fault address. */
3.6
3.7 - MemoryArea *r;
3.8 - long err = _area.find(addr, &r);
3.9 + MemoryArea *r, *parent;
3.10 + long err = _area.find(addr, &r, &parent);
3.11
3.12 if (!err)
3.13 {
4.1 --- a/libexec/lib/src/internal_pager.cc Fri Mar 24 16:14:44 2023 +0100
4.2 +++ b/libexec/lib/src/internal_pager.cc Sat Mar 25 18:45:42 2023 +0100
4.3 @@ -101,8 +101,8 @@
4.4
4.5 /* Obtain a region supporting the fault address. */
4.6
4.7 - MemoryArea *r;
4.8 - long err = _area.find(addr, &r);
4.9 + MemoryArea *r, *parent;
4.10 + long err = _area.find(addr, &r, &parent);
4.11
4.12 if (!err)
4.13 {
4.14 @@ -170,6 +170,38 @@
4.15 return err;
4.16 }
4.17
4.18 +long InternalPager::detach(address_t addr, address_t size, map_flags_t flags,
4.19 + address_t *start, address_t *rsize, l4_cap_idx_t *ds)
4.20 +{
4.21 + /* Obtain the region supporting the given address.
4.22 + NOTE: All regions within the given range should be detached. */
4.23 +
4.24 + MemoryArea *r, *parent;
4.25 + long err = _area.find(addr, &r, &parent);
4.26 +
4.27 + if (!err)
4.28 + {
4.29 + *start = r->area_start();
4.30 + *rsize = r->area_end() - r->area_start();
4.31 + *ds = r->dataspace();
4.32 + parent->remove(*r);
4.33 +
4.34 + /* Explicitly reply so that the dataspace can be released. */
4.35 +
4.36 + complete_RegionMapper_detach(*start, *rsize, *ds);
4.37 +
4.38 + /* Free the dataspace reference in this component. Since the same dataspace
4.39 + will have multiple capability indexes, it can be unconditionally
4.40 + released. */
4.41 +
4.42 + _dataspaces.erase(*ds);
4.43 + ipc_cap_free_um(*ds);
4.44 + return IPC_MESSAGE_SENT;
4.45 + }
4.46 +
4.47 + return err;
4.48 +}
4.49 +
4.50 long InternalPager::reserve_area(address_t *start, address_t size,
4.51 map_flags_t flags, unsigned char align)
4.52 {
5.1 --- a/libexec/lib/src/memory_area.cc Fri Mar 24 16:14:44 2023 +0100
5.2 +++ b/libexec/lib/src/memory_area.cc Sat Mar 25 18:45:42 2023 +0100
5.3 @@ -50,8 +50,13 @@
5.4
5.5 /* In general, a region supports a memory access within its bounds. */
5.6
5.7 -long MemoryArea::find(address_t addr, MemoryArea **area)
5.8 +long MemoryArea::find(address_t addr, MemoryArea **area, MemoryArea **parent)
5.9 {
5.10 + /* The parent is merely propagated through this method, but is present for
5.11 + conformance to the generic method signature. */
5.12 +
5.13 + (void) parent;
5.14 +
5.15 if ((addr >= _start) && (addr < _end))
5.16 {
5.17 *area = this;
5.18 @@ -82,9 +87,10 @@
5.19
5.20 /* A reserved area does not support any memory access. */
5.21
5.22 -long ReservedMemoryArea::find(address_t addr, MemoryArea **area)
5.23 +long ReservedMemoryArea::find(address_t addr, MemoryArea **area,
5.24 + MemoryArea **parent)
5.25 {
5.26 - (void) addr; (void) area;
5.27 + (void) addr; (void) area; (void) parent;
5.28 return -L4_ENOMEM;
5.29 }
5.30
5.31 @@ -145,7 +151,8 @@
5.32
5.33 /* Find an region able to support a memory access. */
5.34
5.35 -long AvailableMemoryArea::find(address_t addr, MemoryArea **area)
5.36 +long AvailableMemoryArea::find(address_t addr, MemoryArea **area,
5.37 + MemoryArea **parent)
5.38 {
5.39 MemoryAreaMap::iterator it = _areas.upper_bound(addr);
5.40
5.41 @@ -160,8 +167,10 @@
5.42
5.43 MemoryArea *r = it->second;
5.44
5.45 + *parent = this;
5.46 +
5.47 if (r->supports(addr))
5.48 - return r->find(addr, area);
5.49 + return r->find(addr, area, parent);
5.50 }
5.51
5.52 /* Otherwise, no area within this area supports the address. */