L4Re/departure

Changeset

545:1ce97d0e8823
2023-03-25 Paul Boddie raw files shortlog changelog graph 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.
libexec/include/exec/internal_pager.h (file) libexec/include/exec/memory_area.h (file) libexec/lib/src/external_pager.cc (file) libexec/lib/src/internal_pager.cc (file) libexec/lib/src/memory_area.cc (file)
     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. */