devobj: allow arbitrary size device file mappings
This commit is contained in:
@ -86,30 +86,27 @@ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxp
|
|||||||
int error;
|
int error;
|
||||||
struct devobj *obj = NULL;
|
struct devobj *obj = NULL;
|
||||||
const size_t npages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
|
const size_t npages = (len + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||||
|
const size_t pfn_npages = (npages / (PAGE_SIZE / sizeof(uintptr_t))) + 1;
|
||||||
|
|
||||||
dkprintf("devobj_create(%d,%lx,%lx)\n", fd, len, off);
|
dkprintf("%s: fd: %d, len: %lu, off: %lu \n", __FUNCTION__, fd, len, off);
|
||||||
#define MAX_PAGES_IN_DEVOBJ (PAGE_SIZE / sizeof(uintptr_t))
|
|
||||||
if (npages > MAX_PAGES_IN_DEVOBJ) {
|
|
||||||
error = -EFBIG;
|
|
||||||
kprintf("devobj_create(%d,%lx,%lx):too large len. %d\n", fd, len, off, error);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj = kmalloc(sizeof(*obj), IHK_MC_AP_NOWAIT);
|
obj = kmalloc(sizeof(*obj), IHK_MC_AP_NOWAIT);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
kprintf("devobj_create(%d,%lx,%lx):kmalloc failed. %d\n", fd, len, off, error);
|
kprintf("%s: error: fd: %d, len: %lu, off: %lu kmalloc failed.\n",
|
||||||
|
__FUNCTION__, fd, len, off);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
memset(obj, 0, sizeof(*obj));
|
memset(obj, 0, sizeof(*obj));
|
||||||
|
|
||||||
obj->pfn_table = allocate_pages(1, IHK_MC_AP_NOWAIT);
|
obj->pfn_table = allocate_pages(pfn_npages, IHK_MC_AP_NOWAIT);
|
||||||
if (!obj->pfn_table) {
|
if (!obj->pfn_table) {
|
||||||
error = -ENOMEM;
|
error = -ENOMEM;
|
||||||
kprintf("devobj_create(%d,%lx,%lx):allocate_pages failed. %d\n", fd, len, off, error);
|
kprintf("%s: error: fd: %d, len: %lu, off: %lu allocating PFN failed.\n",
|
||||||
|
__FUNCTION__, fd, len, off);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
memset(obj->pfn_table, 0, 1*PAGE_SIZE);
|
memset(obj->pfn_table, 0, pfn_npages * PAGE_SIZE);
|
||||||
|
|
||||||
ihk_mc_syscall_arg0(&ctx) = PAGER_REQ_MAP;
|
ihk_mc_syscall_arg0(&ctx) = PAGER_REQ_MAP;
|
||||||
ihk_mc_syscall_arg1(&ctx) = fd;
|
ihk_mc_syscall_arg1(&ctx) = fd;
|
||||||
@ -120,11 +117,13 @@ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxp
|
|||||||
|
|
||||||
error = syscall_generic_forwarding(__NR_mmap, &ctx);
|
error = syscall_generic_forwarding(__NR_mmap, &ctx);
|
||||||
if (error) {
|
if (error) {
|
||||||
kprintf("devobj_create(%d,%lx,%lx):map failed. %d\n", fd, len, off, error);
|
kprintf("%s: error: fd: %d, len: %lu, off: %lu map failed.\n",
|
||||||
|
__FUNCTION__, fd, len, off);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
dkprintf("devobj_create:handle: %lx\n", result.handle);
|
|
||||||
dkprintf("devobj_create:maxprot: %x\n", result.maxprot);
|
dkprintf("%s: fd: %d, len: %lu, off: %lu, handle: %p, maxprot: %x\n",
|
||||||
|
__FUNCTION__, fd, len, off, result.handle, result.maxprot);
|
||||||
|
|
||||||
obj->memobj.ops = &devobj_ops;
|
obj->memobj.ops = &devobj_ops;
|
||||||
obj->memobj.flags = MF_HAS_PAGER;
|
obj->memobj.flags = MF_HAS_PAGER;
|
||||||
@ -142,11 +141,12 @@ int devobj_create(int fd, size_t len, off_t off, struct memobj **objp, int *maxp
|
|||||||
out:
|
out:
|
||||||
if (obj) {
|
if (obj) {
|
||||||
if (obj->pfn_table) {
|
if (obj->pfn_table) {
|
||||||
free_pages(obj->pfn_table, 1);
|
free_pages(obj->pfn_table, pfn_npages);
|
||||||
}
|
}
|
||||||
kfree(obj);
|
kfree(obj);
|
||||||
}
|
}
|
||||||
dkprintf("devobj_create(%d,%lx,%lx): %d %p %x%d\n", fd, len, off, error, *objp, *maxprotp);
|
dkprintf("%s: ret: %d, fd: %d, len: %lu, off: %lu, handle: %p, maxprot: %x \n",
|
||||||
|
__FUNCTION__, error, fd, len, off, result.handle, result.maxprot);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user