From fbbf0fa9a7ce34bc145d6561fa584c2cfb022954 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Wed, 17 Apr 2024 23:38:42 -0400 Subject: kernel: vm_map: Add support for backing file Signed-off-by: Ian Moffett --- sys/vm/vm_map.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'sys/vm') diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index 9a2fe02..19320cd 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -32,7 +32,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -173,6 +175,48 @@ vm_anon_map(void *addr, vm_prot_t prot, size_t len) return physmem; } +/* + * Create a mapping backed by a file. + * + * @addr: Address to map. + * @prot: Protection flags. + * @len: Length of mapping. + * @off: Offset. + * @fd: File descriptor. + */ +static paddr_t +vm_fd_map(void *addr, vm_prot_t prot, size_t len, off_t off, int fd) +{ + paddr_t physmem; + struct filedesc *filedes; + struct vnode *vp; + + struct proc *td = this_td(); + struct vm_page pg = {0}; + + /* Attempt to get the vnode */ + filedes = fd_from_fdnum(td, fd); + if (filedes == NULL) + return 0; + if ((vp = filedes->vnode) == NULL) + return 0; + + /* Try to create the virtual memory object */ + if (vm_obj_init(&vp->vmobj, vp) != 0) + return 0; + + /* Start with a regular anonymous mapping */ + physmem = vm_anon_map(addr, prot, len); + if (physmem == 0) { + vm_obj_destroy(vp->vmobj); + return 0; + } + + pg.physaddr = physmem; + vm_pager_get(vp->vmobj, off, len, &pg); + return physmem; +} + static int munmap(void *addr, size_t len) { @@ -241,6 +285,8 @@ mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) if (__TEST(flags, MAP_ANONYMOUS)) { /* Handle an anonymous map request */ physmem = vm_anon_map(addr, prot, len); + } else if (__TEST(flags, MAP_SHARED)) { + physmem = vm_fd_map(addr, prot, len, off, fildes); } if (physmem == 0) { -- cgit v1.2.3