1.1 --- a/libexec/lib/src/external_pager.cc Tue Dec 13 21:28:04 2022 +0100
1.2 +++ b/libexec/lib/src/external_pager.cc Mon Feb 13 16:56:59 2023 +0100
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * A system pager implementation residing in a separate task.
1.6 *
1.7 - * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License as
1.12 @@ -24,6 +24,7 @@
1.13
1.14 #include <ipc/mem_ipc.h>
1.15 #include <mem/memory_utils.h>
1.16 +#include <systypes/base.h>
1.17
1.18 #include <stdio.h>
1.19
1.20 @@ -68,6 +69,9 @@
1.21 printf("page_fault(%lx, %lx) -> %lx (%lx) -> ", pfa, pc, addr, flags);
1.22 #endif
1.23
1.24 + /* Find the first region whose start address is beyond the fault address,
1.25 + testing if any immediately preceding region contains the fault address. */
1.26 +
1.27 MappedRegions::iterator it = _regions.upper_bound(addr);
1.28
1.29 if (it != _regions.begin())
1.30 @@ -78,15 +82,14 @@
1.31 return -L4_ENOMEM;
1.32 }
1.33
1.34 + /* Obtain the region and test if it contains the fault address. */
1.35 +
1.36 MappedRegion &r = it->second;
1.37
1.38 if ((addr >= r.start) && (addr < r.start + r.size))
1.39 {
1.40 l4_addr_t page_addr = trunc(addr, L4_PAGESIZE);
1.41 - map_flags_t map_flags = (flags & 4 ? L4RE_DS_F_RX : 0) | (flags & 2 ? L4RE_DS_F_W : 0) | (flags & 1 ? L4RE_DS_F_R : 0);
1.42 -
1.43 - if (!map_flags)
1.44 - map_flags = L4RE_DS_F_R;
1.45 + map_flags_t map_flags = map_flags_for_fault(flags);
1.46
1.47 region->fpage = l4_fpage(r.ds_start + (page_addr - r.start), L4_PAGESHIFT, map_flags & r.flags);
1.48 region->snd_base = page_addr;
1.49 @@ -136,9 +139,10 @@
1.50 if (!err)
1.51 {
1.52 /* Attach the provided dataspace.
1.53 - NOTE: This is only done in this implementation to support the paging
1.54 - mechanism. In a region mapper residing within the actual task, the
1.55 - dataspace's map operation would be invoked to obtain mappings. */
1.56 +
1.57 + This is only done in this implementation to support the paging
1.58 + mechanism. In a region mapper residing within the actual task, the
1.59 + dataspace's map operation would be invoked to obtain mappings. */
1.60
1.61 l4_addr_t ds_start;
1.62 err = ipc_attach_dataspace(ds, size, (void **) &ds_start);