From 6742231dfc2d975a2cdda9ea5f2bc4ded996a2a1 Mon Sep 17 00:00:00 2001 From: Lukas Humbel Date: Wed, 2 Oct 2019 16:34:41 +0200 Subject: [PATCH] pmap: Fix lookup function and add test for it The pmap lookup function was always reporting offset 0 and the next lower base page size. This is wrong when a capability bigger than a page is mapped (as it is usually the case). Signed-off-by: Lukas Humbel --- lib/barrelfish/arch/x86_64/pmap.c | 4 +- tools/harness/tests/pmaplookup.py | 34 ++++++++++++++++ usr/tests/pmaplookup/Hakefile | 16 ++++++++ usr/tests/pmaplookup/main.c | 78 +++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 tools/harness/tests/pmaplookup.py create mode 100644 usr/tests/pmaplookup/Hakefile create mode 100644 usr/tests/pmaplookup/main.c diff --git a/lib/barrelfish/arch/x86_64/pmap.c b/lib/barrelfish/arch/x86_64/pmap.c index 4ecd7fd..b6f9ce6 100644 --- a/lib/barrelfish/arch/x86_64/pmap.c +++ b/lib/barrelfish/arch/x86_64/pmap.c @@ -984,8 +984,8 @@ static errval_t lookup(struct pmap *pmap, genvaddr_t vaddr, } if (info) { - info->vaddr = vaddr & ~(genvaddr_t)(find_info.page_size - 1); - info->size = find_info.page_size; + info->vaddr = find_info.page->u.frame.vaddr; + info->size = find_info.page_size * find_info.page->v.u.frame.pte_count; info->cap = find_info.page->v.cap; info->offset = find_info.page->v.u.frame.offset; info->flags = find_info.page->v.u.frame.flags; diff --git a/tools/harness/tests/pmaplookup.py b/tools/harness/tests/pmaplookup.py new file mode 100644 index 0000000..f7dacb3 --- /dev/null +++ b/tools/harness/tests/pmaplookup.py @@ -0,0 +1,34 @@ +########################################################################## +# Copyright (c) 2009, ETH Zurich. +# All rights reserved. +# +# This file is distributed under the terms in the attached LICENSE file. +# If you do not find this file, copies can be found by writing to: +# ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. +########################################################################## + +import re +import tests +from common import TestCommon +from results import PassFailResult + +@tests.add_test +class PmapLookupTest(TestCommon): + '''Test the lookup call of pmap''' + name = "pmaplookup" + + def get_modules(self, build, machine): + modules = super(PmapLookupTest, self).get_modules(build, machine) + modules.add_module("pmaplookuptest") + return modules + + def get_finish_string(self): + return "pmaplookuptest passed successfully!" + + def process_data(self, testdir, rawiter): + # the test passed iff the last line is the finish string + lastline = '' + for line in rawiter: + lastline = line + passed = lastline.startswith(self.get_finish_string()) + return PassFailResult(passed) diff --git a/usr/tests/pmaplookup/Hakefile b/usr/tests/pmaplookup/Hakefile new file mode 100644 index 0000000..d06124c --- /dev/null +++ b/usr/tests/pmaplookup/Hakefile @@ -0,0 +1,16 @@ +-------------------------------------------------------------------------- +-- Copyright (c) 2018, ETH Zurich. +-- All rights reserved. +-- +-- This file is distributed under the terms in the attached LICENSE file. +-- If you do not find this file, copies can be found by writing to: +-- ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. +-- +-- Hakefile for /usr/tests/malloc +-- +-- Diverse memory tests. +-- +-------------------------------------------------------------------------- + +[ build application { target = "pmaplookuptest", cFiles = [ "main.c" ] } +] diff --git a/usr/tests/pmaplookup/main.c b/usr/tests/pmaplookup/main.c new file mode 100644 index 0000000..a3e4619 --- /dev/null +++ b/usr/tests/pmaplookup/main.c @@ -0,0 +1,78 @@ +#include +#include + +#define DEBUG_TEST 0 + +static void test_lookup(struct capref expected_cap, genvaddr_t addr, size_t offset){ + addr += offset; + errval_t err; + struct pmap * my_pmap = get_current_pmap(); + assert(my_pmap != NULL); + struct pmap_mapping_info mi; + err = my_pmap->f.lookup(my_pmap, addr, &mi); + if(err_is_fail(err)){ + USER_PANIC_ERR(err, "pmap lookup"); + } + + +#if DEBUG_TEST + printf("=== pmap_mapping_info of 0x%"PRIxGENVADDR" ===\n", addr); + printf(" vaddr=0x%"PRIxGENVADDR"\n", mi.vaddr); + printf(" size=%zu\n", mi.size); + char buf[512]; + debug_print_cap_at_capref(buf, 512, mi.cap); + printf(" cap = %s\n",buf); + printf(" offset=0x%" PRIxGENVADDR "\n", mi.offset); +#endif + + assert(capcmp(mi.cap, expected_cap)); + assert(mi.offset + (addr - mi.vaddr) == offset); +} + +int main(void){ + printf("Hello world from pmap_test\n"); + + struct capref frame; + size_t retsize; + errval_t err; + + #define SIZE (1024*1024*2) + + err = frame_alloc(&frame, SIZE, &retsize); + assert(err_is_ok(err)); + + struct frame_identity fi; + err = cap_identify_mappable(frame, &fi); + + assert(err_is_ok(err)); + + void *va; + err = vspace_map_one_frame_attr(&va, retsize, frame, + VREGION_FLAGS_READ_WRITE_NOCACHE, NULL, NULL); + assert(err_is_ok(err)); + + //lookup + printf("va = %p\n", va); + struct pmap * my_pmap = get_current_pmap(); + assert(my_pmap != NULL); + +#if DEBUG_TEST + struct pmap_dump_info di[128]; + size_t di_len = 0; + my_pmap->f.dump(my_pmap,di,128,&di_len); + for(int i=0; i