# HG changeset patch # User Paul Boddie # Date 1676303819 -3600 # Node ID 0d4afc27f760b2e1738c0d9cf150e3d0d5901c99 # Parent c735e5869ff4a55d7bba7a5454fba166a901c4de Introduced a function for converting to mapping flags from page fault flags. diff -r c735e5869ff4 -r 0d4afc27f760 libexec/lib/src/external_pager.cc --- a/libexec/lib/src/external_pager.cc Tue Dec 13 21:28:04 2022 +0100 +++ b/libexec/lib/src/external_pager.cc Mon Feb 13 16:56:59 2023 +0100 @@ -1,7 +1,7 @@ /* * A system pager implementation residing in a separate task. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,6 +24,7 @@ #include #include +#include #include @@ -68,6 +69,9 @@ printf("page_fault(%lx, %lx) -> %lx (%lx) -> ", pfa, pc, addr, flags); #endif + /* Find the first region whose start address is beyond the fault address, + testing if any immediately preceding region contains the fault address. */ + MappedRegions::iterator it = _regions.upper_bound(addr); if (it != _regions.begin()) @@ -78,15 +82,14 @@ return -L4_ENOMEM; } + /* Obtain the region and test if it contains the fault address. */ + MappedRegion &r = it->second; if ((addr >= r.start) && (addr < r.start + r.size)) { l4_addr_t page_addr = trunc(addr, L4_PAGESIZE); - 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); - - if (!map_flags) - map_flags = L4RE_DS_F_R; + map_flags_t map_flags = map_flags_for_fault(flags); region->fpage = l4_fpage(r.ds_start + (page_addr - r.start), L4_PAGESHIFT, map_flags & r.flags); region->snd_base = page_addr; @@ -136,9 +139,10 @@ if (!err) { /* Attach the provided dataspace. - NOTE: This is only done in this implementation to support the paging - mechanism. In a region mapper residing within the actual task, the - dataspace's map operation would be invoked to obtain mappings. */ + + This is only done in this implementation to support the paging + mechanism. In a region mapper residing within the actual task, the + dataspace's map operation would be invoked to obtain mappings. */ l4_addr_t ds_start; err = ipc_attach_dataspace(ds, size, (void **) &ds_start); diff -r c735e5869ff4 -r 0d4afc27f760 libexec/lib/src/internal_pager.cc --- a/libexec/lib/src/internal_pager.cc Tue Dec 13 21:28:04 2022 +0100 +++ b/libexec/lib/src/internal_pager.cc Mon Feb 13 16:56:59 2023 +0100 @@ -1,7 +1,7 @@ /* * A system pager implementation residing in the same task as a program. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,6 +24,7 @@ #include #include +#include #include @@ -71,6 +72,9 @@ printf("regs = %p\n; regs->user[0] = %lx\n", regs, regs->user[0]); #endif + /* Find the first region whose start address is beyond the fault address, + testing if any immediately preceding region contains the fault address. */ + MappedRegions::iterator it = _regions.upper_bound(addr); if (it != _regions.begin()) @@ -96,10 +100,7 @@ client_Dataspace dataspace(r.ds); l4_snd_fpage_t rw_region = {0, l4_fpage(window_base, L4_PAGESHIFT, 0)}; - 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); - - if (!map_flags) - map_flags = L4RE_DS_F_R; + map_flags_t map_flags = map_flags_for_fault(flags); #if DEBUG printf("window_base = %lx; window_size = %lx\n", window_base, window_size); diff -r c735e5869ff4 -r 0d4afc27f760 libsystypes/include/systypes/base.h --- a/libsystypes/include/systypes/base.h Tue Dec 13 21:28:04 2022 +0100 +++ b/libsystypes/include/systypes/base.h Mon Feb 13 16:56:59 2023 +0100 @@ -39,6 +39,10 @@ typedef l4_uint64_t map_address_t; typedef unsigned long map_flags_t; +/* Conversions. */ + +map_flags_t map_flags_for_fault(l4_umword_t flags); + /* Types and values for notification. */ typedef l4_uint64_t notify_flags_t; diff -r c735e5869ff4 -r 0d4afc27f760 libsystypes/lib/src/Makefile --- a/libsystypes/lib/src/Makefile Tue Dec 13 21:28:04 2022 +0100 +++ b/libsystypes/lib/src/Makefile Mon Feb 13 16:56:59 2023 +0100 @@ -4,7 +4,7 @@ TARGET = libsystypes.so libsystypes.a PC_FILENAME = libsystypes -SRC_C = stat.c +SRC_C = base.c stat.c REQUIRES_LIBS = l4re_c-util diff -r c735e5869ff4 -r 0d4afc27f760 libsystypes/lib/src/base.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libsystypes/lib/src/base.c Mon Feb 13 16:56:59 2023 +0100 @@ -0,0 +1,42 @@ +/* + * Utility functions for base types. + * + * Copyright (C) 2022, 2023 Paul Boddie + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA + */ + +#include + +#include "base.h" + + + +/* Return mapping flags corresponding to page fault flags. */ + +map_flags_t map_flags_for_fault(l4_umword_t flags) +{ + 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); + + if (!map_flags) + map_flags = L4RE_DS_F_R; + + return map_flags; +} + +// vim: tabstop=2 expandtab shiftwidth=2