From af62be7cb7db9197326082e188b3f8e066050291 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Tue, 3 Jun 2025 17:21:59 -0400 Subject: kernel: vm: Allow NULL `addr' for cdev mappings Signed-off-by: Ian Moffett --- sys/vm/vm_map.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'sys/vm') diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index a3a6f39..0ff3763 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -179,11 +179,6 @@ mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) npgs = len / DEFAULT_PAGESIZE; vas = pmap_read_vas(); - if (addr == NULL) { - pr_error("mmap: NULL addr not supported\n"); - return NULL; - } - /* Validate flags */ if (ISSET(flags, MAP_FIXED)) { pr_error("mmap: fixed mappings not yet supported\n"); @@ -221,6 +216,24 @@ mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) return NULL; } + /* + * If the address passed is NULL, just identity + * map everything. + * + * XXX: This is why the bounds check done in the + * cdev mmap() *must* be correct. + * + * TODO: Use copy-on-write for this instead. Since mapping + * certain devices may required a lot of memory to + * be referenced anyways, we could use a buffered + * copy-on-write technique where only a window of + * pages can be mapped on-demand and other pages + * freed when that window is exceeded. + */ + if (addr == NULL) { + addr = (void *)pa; + } + va = ALIGN_DOWN((vaddr_t)addr, DEFAULT_PAGESIZE); error = vm_map(vas, va, pa, prot, len); if (error != 0) { @@ -231,6 +244,11 @@ mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) goto done; } + if (addr == NULL) { + pr_error("mmap: NULL addr not supported\n"); + return NULL; + } + /* Only allocate new obj if needed */ if (map_obj == NULL) { map_obj = dynalloc(sizeof(*map_obj)); -- cgit v1.2.3