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);
2.1 --- a/libexec/lib/src/internal_pager.cc Tue Dec 13 21:28:04 2022 +0100
2.2 +++ b/libexec/lib/src/internal_pager.cc Mon Feb 13 16:56:59 2023 +0100
2.3 @@ -1,7 +1,7 @@
2.4 /*
2.5 * A system pager implementation residing in the same task as a program.
2.6 *
2.7 - * Copyright (C) 2022 Paul Boddie <paul@boddie.org.uk>
2.8 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
2.9 *
2.10 * This program is free software; you can redistribute it and/or
2.11 * modify it under the terms of the GNU General Public License as
2.12 @@ -24,6 +24,7 @@
2.13 #include <l4/util/util.h>
2.14
2.15 #include <mem/memory_utils.h>
2.16 +#include <systypes/base.h>
2.17
2.18 #include <stdio.h>
2.19
2.20 @@ -71,6 +72,9 @@
2.21 printf("regs = %p\n; regs->user[0] = %lx\n", regs, regs->user[0]);
2.22 #endif
2.23
2.24 + /* Find the first region whose start address is beyond the fault address,
2.25 + testing if any immediately preceding region contains the fault address. */
2.26 +
2.27 MappedRegions::iterator it = _regions.upper_bound(addr);
2.28
2.29 if (it != _regions.begin())
2.30 @@ -96,10 +100,7 @@
2.31
2.32 client_Dataspace dataspace(r.ds);
2.33 l4_snd_fpage_t rw_region = {0, l4_fpage(window_base, L4_PAGESHIFT, 0)};
2.34 - 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);
2.35 -
2.36 - if (!map_flags)
2.37 - map_flags = L4RE_DS_F_R;
2.38 + map_flags_t map_flags = map_flags_for_fault(flags);
2.39
2.40 #if DEBUG
2.41 printf("window_base = %lx; window_size = %lx\n", window_base, window_size);
3.1 --- a/libsystypes/include/systypes/base.h Tue Dec 13 21:28:04 2022 +0100
3.2 +++ b/libsystypes/include/systypes/base.h Mon Feb 13 16:56:59 2023 +0100
3.3 @@ -39,6 +39,10 @@
3.4 typedef l4_uint64_t map_address_t;
3.5 typedef unsigned long map_flags_t;
3.6
3.7 +/* Conversions. */
3.8 +
3.9 +map_flags_t map_flags_for_fault(l4_umword_t flags);
3.10 +
3.11 /* Types and values for notification. */
3.12
3.13 typedef l4_uint64_t notify_flags_t;
4.1 --- a/libsystypes/lib/src/Makefile Tue Dec 13 21:28:04 2022 +0100
4.2 +++ b/libsystypes/lib/src/Makefile Mon Feb 13 16:56:59 2023 +0100
4.3 @@ -4,7 +4,7 @@
4.4 TARGET = libsystypes.so libsystypes.a
4.5 PC_FILENAME = libsystypes
4.6
4.7 -SRC_C = stat.c
4.8 +SRC_C = base.c stat.c
4.9
4.10 REQUIRES_LIBS = l4re_c-util
4.11
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/libsystypes/lib/src/base.c Mon Feb 13 16:56:59 2023 +0100
5.3 @@ -0,0 +1,42 @@
5.4 +/*
5.5 + * Utility functions for base types.
5.6 + *
5.7 + * Copyright (C) 2022, 2023 Paul Boddie <paul@boddie.org.uk>
5.8 + *
5.9 + * This program is free software; you can redistribute it and/or
5.10 + * modify it under the terms of the GNU General Public License as
5.11 + * published by the Free Software Foundation; either version 2 of
5.12 + * the License, or (at your option) any later version.
5.13 + *
5.14 + * This program is distributed in the hope that it will be useful,
5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.17 + * GNU General Public License for more details.
5.18 + *
5.19 + * You should have received a copy of the GNU General Public License
5.20 + * along with this program; if not, write to the Free Software
5.21 + * Foundation, Inc., 51 Franklin Street, Fifth Floor,
5.22 + * Boston, MA 02110-1301, USA
5.23 + */
5.24 +
5.25 +#include <l4/re/c/dataspace.h>
5.26 +
5.27 +#include "base.h"
5.28 +
5.29 +
5.30 +
5.31 +/* Return mapping flags corresponding to page fault flags. */
5.32 +
5.33 +map_flags_t map_flags_for_fault(l4_umword_t flags)
5.34 +{
5.35 + map_flags_t map_flags = (flags & 4 ? L4RE_DS_F_RX : 0) |
5.36 + (flags & 2 ? L4RE_DS_F_W : 0) |
5.37 + (flags & 1 ? L4RE_DS_F_R : 0);
5.38 +
5.39 + if (!map_flags)
5.40 + map_flags = L4RE_DS_F_R;
5.41 +
5.42 + return map_flags;
5.43 +}
5.44 +
5.45 +// vim: tabstop=2 expandtab shiftwidth=2