pmap: Fix lookup function and add test for it
authorLukas Humbel <humbell@inf.ethz.ch>
Wed, 2 Oct 2019 14:34:41 +0000 (16:34 +0200)
committerLukas Humbel <humbell@inf.ethz.ch>
Wed, 2 Oct 2019 14:34:41 +0000 (16:34 +0200)
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 <lukas.humbel@inf.ethz.ch>

lib/barrelfish/arch/x86_64/pmap.c
tools/harness/tests/pmaplookup.py [new file with mode: 0644]
usr/tests/pmaplookup/Hakefile [new file with mode: 0644]
usr/tests/pmaplookup/main.c [new file with mode: 0644]

index 4ecd7fd..b6f9ce6 100644 (file)
@@ -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 (file)
index 0000000..f7dacb3
--- /dev/null
@@ -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 (file)
index 0000000..d06124c
--- /dev/null
@@ -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 (file)
index 0000000..a3e4619
--- /dev/null
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <barrelfish/barrelfish.h>
+
+#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<di_len;i++){
+        printf("pt idx =" PRIfmtPTIDX "", GET_PTIDX(di+i));
+        printf("   offset = %"PRIxGENVADDR "\n" , di[i].offset);
+        char buf[512];
+        debug_print_cap_at_capref(buf, 512, di[i].cap);
+        printf("   cap = %s\n",buf);
+    }
+#endif
+
+    for(size_t off=0; off < SIZE; off += BASE_PAGE_SIZE){ 
+        test_lookup(frame, (uintptr_t)va, off);
+    }
+
+    printf("pmaplookuptest passed successfully!\n");
+    return 0;
+}