From b1bdb89ca499e2c1ea94fdd6099de71d4594a33d Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 1 Mar 2026 19:09:30 +0000 Subject: [PATCH] vm: region: add a function to write data from a kernel buffer to a vm-region --- include/kernel/vm-region.h | 11 ++++++++- vm/vm-region.c | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/kernel/vm-region.h b/include/kernel/vm-region.h index 3c08fef..0a92f4b 100644 --- a/include/kernel/vm-region.h +++ b/include/kernel/vm-region.h @@ -6,7 +6,7 @@ #include #define VM_REGION_NAME_MAX 64 -#define VM_REGION_COPY_ALL ((size_t) - 1) +#define VM_REGION_COPY_ALL ((size_t)-1) struct vm_region; struct vm_object; @@ -157,6 +157,15 @@ extern kern_status_t vm_region_read_kernel( void *dest, size_t *nr_read); +/* write data to the user-space area of a vm-region from a kernel-mode buffer + */ +extern kern_status_t vm_region_write_kernel( + struct vm_region *dst_region, + virt_addr_t dst_ptr, + size_t count, + const void *src, + size_t *nr_written); + extern kern_status_t vm_region_memmove( struct vm_region *dest_region, virt_addr_t dest_ptr, diff --git a/vm/vm-region.c b/vm/vm-region.c index 6358f84..81dbe67 100644 --- a/vm/vm-region.c +++ b/vm/vm-region.c @@ -1713,6 +1713,52 @@ kern_status_t vm_region_read_kernel( return status; } +kern_status_t vm_region_write_kernel( + struct vm_region *dst_region, + virt_addr_t dst_ptr, + size_t count, + const void *srcp, + size_t *nr_written) +{ + if (dst_region->vr_status != VM_REGION_ONLINE) { + return KERN_BAD_STATE; + } + + struct vm_iterator dst; + const char *src = srcp; + + vm_iterator_begin( + &dst, + dst_region, + dst_ptr, + VM_PROT_WRITE | VM_PROT_USER); + + kern_status_t status = KERN_OK; + size_t r = 0; + + while (r < count && dst.it_max) { + size_t remaining = count - r; + size_t to_move = MIN(dst.it_max, remaining); + memmove(dst.it_buf, src, to_move); + + status = vm_iterator_seek(&dst, to_move); + if (status != KERN_OK) { + break; + } + + r += to_move; + src += to_move; + } + + vm_iterator_finish(&dst); + + if (nr_written) { + *nr_written = r; + } + + return status; +} + kern_status_t vm_region_memmove( struct vm_region *dest_region, virt_addr_t dest_ptr,