From 72f2e5ebe0abaef62181112b8e8bb95f1969afbc Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Mon, 14 Mar 2016 18:36:05 +0900 Subject: [PATCH] shmobj: implement lookup_page method --- kernel/shmobj.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/kernel/shmobj.c b/kernel/shmobj.c index b49dd8f6..590187ea 100644 --- a/kernel/shmobj.c +++ b/kernel/shmobj.c @@ -34,12 +34,14 @@ static memobj_release_func_t shmobj_release; static memobj_ref_func_t shmobj_ref; static memobj_get_page_func_t shmobj_get_page; static memobj_invalidate_page_func_t shmobj_invalidate_page; +static memobj_lookup_page_func_t shmobj_lookup_page; static struct memobj_ops shmobj_ops = { .release = &shmobj_release, .ref = &shmobj_ref, .get_page = &shmobj_get_page, .invalidate_page = &shmobj_invalidate_page, + .lookup_page = &shmobj_lookup_page, }; static struct shmobj *to_shmobj(struct memobj *memobj) @@ -451,3 +453,60 @@ out: dkprintf("shmobj_invalidate_page(%p,%#lx,%#lx):%d\n", memobj, phys, pgsize, error); return error; } + +static int shmobj_lookup_page(struct memobj *memobj, off_t off, int p2align, + uintptr_t *physp, unsigned long *pflag) +{ + struct shmobj *obj = to_shmobj(memobj); + int error; + struct page *page; + uintptr_t phys; + + dkprintf("shmobj_lookup_page(%p,%#lx,%d,%p)\n", + memobj, off, p2align, physp); + memobj_lock(&obj->memobj); + if (off & ~PAGE_MASK) { + error = -EINVAL; + ekprintf("shmobj_lookup_page(%p,%#lx,%d,%p):invalid argument. %d\n", + memobj, off, p2align, physp, error); + goto out; + } + if (p2align != PAGE_P2ALIGN) { /* XXX:NYI:large pages */ + error = -ENOMEM; + ekprintf("shmobj_lookup_page(%p,%#lx,%d,%p):large page. %d\n", + memobj, off, p2align, physp, error); + goto out; + } + if (obj->real_segsz <= off) { + error = -ERANGE; + ekprintf("shmobj_lookup_page(%p,%#lx,%d,%p):beyond the end. %d\n", + memobj, off, p2align, physp, error); + goto out; + } + if ((obj->real_segsz - off) < (PAGE_SIZE << p2align)) { + error = -ENOSPC; + ekprintf("shmobj_lookup_page(%p,%#lx,%d,%p):too large. %d\n", + memobj, off, p2align, physp, error); + goto out; + } + + page = page_list_lookup(obj, off); + if (!page) { + error = -ENOENT; + dkprintf("shmobj_lookup_page(%p,%#lx,%d,%p):page not found. %d\n", + memobj, off, p2align, physp, error); + goto out; + } + phys = page_to_phys(page); + + error = 0; + if (physp) { + *physp = phys; + } + +out: + memobj_unlock(&obj->memobj); + dkprintf("shmobj_lookup_page(%p,%#lx,%d,%p):%d %#lx\n", + memobj, off, p2align, physp, error, phys); + return error; +} /* shmobj_lookup_page() */