# HG changeset patch # User Paul Boddie # Date 1679766342 -3600 # Node ID 1ce97d0e88232de7b2373730322da89cdea3d243 # Parent 754959243588dbc143ca0140ee2e0fd7bf149395 Added initial support for detaching regions. Without this, it is likely that file access operations will eventually fail due to unanticipated side-effects resulting from the accumulation of regions and dataspaces in the region mapper. diff -r 754959243588 -r 1ce97d0e8823 libexec/include/exec/internal_pager.h --- a/libexec/include/exec/internal_pager.h Fri Mar 24 16:14:44 2023 +0100 +++ b/libexec/include/exec/internal_pager.h Sat Mar 25 18:45:42 2023 +0100 @@ -59,6 +59,9 @@ virtual long attach(address_t *start, address_t size, map_flags_t flags, l4_cap_idx_t ds, address_t offset, unsigned char align); + virtual long detach(address_t addr, address_t size, map_flags_t flags, + address_t *start, address_t *rsize, l4_cap_idx_t *ds); + virtual long reserve_area(address_t *start, address_t size, map_flags_t flags, unsigned char align); }; diff -r 754959243588 -r 1ce97d0e8823 libexec/include/exec/memory_area.h --- a/libexec/include/exec/memory_area.h Fri Mar 24 16:14:44 2023 +0100 +++ b/libexec/include/exec/memory_area.h Sat Mar 25 18:45:42 2023 +0100 @@ -95,7 +95,7 @@ /* Support for finding regions. */ - virtual long find(address_t addr, MemoryArea **area); + virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent); /* Support for finding areas. */ @@ -124,7 +124,7 @@ /* Support for finding areas. */ - virtual long find(address_t addr, MemoryArea **area); + virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent); }; @@ -162,7 +162,7 @@ /* Support for finding areas. */ - virtual long find(address_t addr, MemoryArea **area); + virtual long find(address_t addr, MemoryArea **area, MemoryArea **parent); virtual long find(address_t *start, address_t *size, map_flags_t flags, unsigned char align, MemoryArea **area); diff -r 754959243588 -r 1ce97d0e8823 libexec/lib/src/external_pager.cc --- a/libexec/lib/src/external_pager.cc Fri Mar 24 16:14:44 2023 +0100 +++ b/libexec/lib/src/external_pager.cc Sat Mar 25 18:45:42 2023 +0100 @@ -181,8 +181,8 @@ /* Obtain a region supporting the fault address. */ - MemoryArea *r; - long err = _area.find(addr, &r); + MemoryArea *r, *parent; + long err = _area.find(addr, &r, &parent); if (!err) { diff -r 754959243588 -r 1ce97d0e8823 libexec/lib/src/internal_pager.cc --- a/libexec/lib/src/internal_pager.cc Fri Mar 24 16:14:44 2023 +0100 +++ b/libexec/lib/src/internal_pager.cc Sat Mar 25 18:45:42 2023 +0100 @@ -101,8 +101,8 @@ /* Obtain a region supporting the fault address. */ - MemoryArea *r; - long err = _area.find(addr, &r); + MemoryArea *r, *parent; + long err = _area.find(addr, &r, &parent); if (!err) { @@ -170,6 +170,38 @@ return err; } +long InternalPager::detach(address_t addr, address_t size, map_flags_t flags, + address_t *start, address_t *rsize, l4_cap_idx_t *ds) +{ + /* Obtain the region supporting the given address. + NOTE: All regions within the given range should be detached. */ + + MemoryArea *r, *parent; + long err = _area.find(addr, &r, &parent); + + if (!err) + { + *start = r->area_start(); + *rsize = r->area_end() - r->area_start(); + *ds = r->dataspace(); + parent->remove(*r); + + /* Explicitly reply so that the dataspace can be released. */ + + complete_RegionMapper_detach(*start, *rsize, *ds); + + /* Free the dataspace reference in this component. Since the same dataspace + will have multiple capability indexes, it can be unconditionally + released. */ + + _dataspaces.erase(*ds); + ipc_cap_free_um(*ds); + return IPC_MESSAGE_SENT; + } + + return err; +} + long InternalPager::reserve_area(address_t *start, address_t size, map_flags_t flags, unsigned char align) { diff -r 754959243588 -r 1ce97d0e8823 libexec/lib/src/memory_area.cc --- a/libexec/lib/src/memory_area.cc Fri Mar 24 16:14:44 2023 +0100 +++ b/libexec/lib/src/memory_area.cc Sat Mar 25 18:45:42 2023 +0100 @@ -50,8 +50,13 @@ /* In general, a region supports a memory access within its bounds. */ -long MemoryArea::find(address_t addr, MemoryArea **area) +long MemoryArea::find(address_t addr, MemoryArea **area, MemoryArea **parent) { + /* The parent is merely propagated through this method, but is present for + conformance to the generic method signature. */ + + (void) parent; + if ((addr >= _start) && (addr < _end)) { *area = this; @@ -82,9 +87,10 @@ /* A reserved area does not support any memory access. */ -long ReservedMemoryArea::find(address_t addr, MemoryArea **area) +long ReservedMemoryArea::find(address_t addr, MemoryArea **area, + MemoryArea **parent) { - (void) addr; (void) area; + (void) addr; (void) area; (void) parent; return -L4_ENOMEM; } @@ -145,7 +151,8 @@ /* Find an region able to support a memory access. */ -long AvailableMemoryArea::find(address_t addr, MemoryArea **area) +long AvailableMemoryArea::find(address_t addr, MemoryArea **area, + MemoryArea **parent) { MemoryAreaMap::iterator it = _areas.upper_bound(addr); @@ -160,8 +167,10 @@ MemoryArea *r = it->second; + *parent = this; + if (r->supports(addr)) - return r->find(addr, area); + return r->find(addr, area, parent); } /* Otherwise, no area within this area supports the address. */