1.1 --- a/libexec/lib/src/external_pager.cc Tue Mar 14 23:51:57 2023 +0100
1.2 +++ b/libexec/lib/src/external_pager.cc Wed Mar 15 00:33:40 2023 +0100
1.3 @@ -58,7 +58,7 @@
1.4
1.5 void ExternalPager::close()
1.6 {
1.7 - printf("Pager closing...\n");
1.8 + printf("External pager closing...\n");
1.9
1.10 /* Remove pager regions to avoid unmapping them twice. */
1.11
1.12 @@ -77,15 +77,22 @@
1.13
1.14 /* Unmap all remaining regions. */
1.15
1.16 - MappedRegions::iterator it;
1.17 + AvailableMemoryArea::iterator it;
1.18
1.19 - for (it = _regions.begin(); it != _regions.end(); it++)
1.20 + for (it = _area.begin(); it != _area.end(); it++)
1.21 {
1.22 - MappedRegion &r = it->second;
1.23 + MemoryArea *r = *it;
1.24 +
1.25 + if (r->is_mapped())
1.26 + ipc_detach_dataspace((void *) r->dataspace_start());
1.27 + }
1.28
1.29 - ipc_detach_dataspace((void *) r.ds_start);
1.30 - ipc_cap_free_um(r.ds);
1.31 - }
1.32 + /* Free all capabilities. */
1.33 +
1.34 + Capabilities::iterator itc;
1.35 +
1.36 + for (itc = _dataspaces.begin(); itc != _dataspaces.end(); itc++)
1.37 + ipc_cap_free_um(*itc);
1.38
1.39 /* Remove the created task. */
1.40
1.41 @@ -172,61 +179,47 @@
1.42 printf("page_fault(%lx, %lx) -> %lx (%lx) -> ", pfa, pc, addr, flags);
1.43 #endif
1.44
1.45 - /* Find the first region whose start address is beyond the fault address,
1.46 - testing if any immediately preceding region contains the fault address. */
1.47 -
1.48 - MappedRegions::iterator it = _regions.upper_bound(addr);
1.49 + /* Obtain a region supporting the fault address. */
1.50
1.51 - if (it != _regions.begin())
1.52 - it--;
1.53 - else
1.54 - {
1.55 - printf("not mapped at %lx for pc %lx\n", addr, pc);
1.56 - return -L4_ENOMEM;
1.57 - }
1.58 + MemoryArea *r;
1.59 + long err = _area.find(addr, &r);
1.60
1.61 - /* Obtain the region and test if it contains the fault address. */
1.62 -
1.63 - MappedRegion &r = it->second;
1.64 -
1.65 - if ((addr >= r.start) && (addr < r.start + r.size))
1.66 + if (!err)
1.67 {
1.68 l4_addr_t page_addr = trunc(addr, L4_PAGESIZE);
1.69 map_flags_t map_flags = map_flags_for_fault(flags);
1.70
1.71 - region->fpage = l4_fpage(r.ds_start + (page_addr - r.start), L4_PAGESHIFT, map_flags & r.flags);
1.72 + region->fpage = l4_fpage(r->dataspace_start() + (page_addr - r->area_start()), L4_PAGESHIFT, map_flags & r->flags());
1.73 region->snd_base = page_addr;
1.74
1.75 #if DEBUG
1.76 printf("%lx...%lx from %lx...%lx offset %lx size %d rights %x ds %lx\n",
1.77 - r.start, region->snd_base,
1.78 - r.ds_start, l4_fpage_memaddr(region->fpage),
1.79 - addr - r.start,
1.80 + r->area_start(), region->snd_base,
1.81 + r->dataspace_start(), l4_fpage_memaddr(region->fpage),
1.82 + addr - r->area_start(),
1.83 l4_fpage_size(region->fpage),
1.84 l4_fpage_rights(region->fpage),
1.85 - r.ds);
1.86 + r->dataspace());
1.87
1.88 printf("%lx -> ", addr);
1.89
1.90 for (unsigned int i = 0; i < sizeof(l4_umword_t); i++)
1.91 - printf("%02x", *((unsigned char *)(r.ds_start + (addr - r.start) + i)));
1.92 + printf("%02x", *((unsigned char *)(r->dataspace_start() + (addr - r->area_start()) + i)));
1.93
1.94 printf("\n");
1.95 #endif
1.96
1.97 - if (r.flags & L4RE_RM_F_W)
1.98 - l4_touch_rw((const void *) (r.ds_start + (page_addr - r.start)), L4_PAGESIZE);
1.99 + if (r->flags() & L4RE_RM_F_W)
1.100 + l4_touch_rw((const void *) (r->dataspace_start() + (page_addr - r->area_start())), L4_PAGESIZE);
1.101 else
1.102 - l4_touch_ro((const void *) (r.ds_start + (page_addr - r.start)), L4_PAGESIZE);
1.103 + l4_touch_ro((const void *) (r->dataspace_start() + (page_addr - r->area_start())), L4_PAGESIZE);
1.104
1.105 return L4_EOK;
1.106 }
1.107
1.108 -#if DEBUG
1.109 - printf("not mapped!\n");
1.110 -#endif
1.111 + printf("not mapped at %lx for pc %lx\n", addr, pc);
1.112
1.113 - return -L4_ENOMEM;
1.114 + return err;
1.115 }
1.116
1.117 /* Attach a region for provision when page faults occur. This is required in
1.118 @@ -237,7 +230,12 @@
1.119 l4_cap_idx_t ds, address_t offset,
1.120 unsigned char align)
1.121 {
1.122 - long err = ExecPager::find(start, &size, flags, offset, align);
1.123 + // NOTE: Determine the purpose of offset.
1.124 +
1.125 + (void) offset;
1.126 +
1.127 + MemoryArea *area;
1.128 + long err = ExecPager::find(start, &size, flags, align, &area);
1.129
1.130 /* Without an error, attach the dataspace. */
1.131
1.132 @@ -257,8 +255,12 @@
1.133
1.134 l4_touch_rw((const void *) ds_start, size);
1.135
1.136 - MappedRegion r(*start, size, flags & L4RE_DS_F_RIGHTS_MASK, ds, ds_start);
1.137 - add(r);
1.138 + MappedRegion r(*start, *start + size, flags & L4RE_DS_F_RIGHTS_MASK, ds, ds_start);
1.139 + area->add(r);
1.140 +
1.141 + /* Record dataspaces separately. */
1.142 +
1.143 + _dataspaces.insert(ds);
1.144 }
1.145
1.146 /* Discard the imported dataspace if its region cannot be accommodated. */
1.147 @@ -281,6 +283,8 @@
1.148
1.149 if (sig == 0)
1.150 {
1.151 + printf("Signal from task.\n");
1.152 +
1.153 /* Once the program exits, the IPC gate connecting the program with its
1.154 internal pager can be released. */
1.155