vm: region: add a function to write data from a kernel buffer to a vm-region
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
#include <kernel/vm.h>
|
#include <kernel/vm.h>
|
||||||
|
|
||||||
#define VM_REGION_NAME_MAX 64
|
#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_region;
|
||||||
struct vm_object;
|
struct vm_object;
|
||||||
@@ -157,6 +157,15 @@ extern kern_status_t vm_region_read_kernel(
|
|||||||
void *dest,
|
void *dest,
|
||||||
size_t *nr_read);
|
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(
|
extern kern_status_t vm_region_memmove(
|
||||||
struct vm_region *dest_region,
|
struct vm_region *dest_region,
|
||||||
virt_addr_t dest_ptr,
|
virt_addr_t dest_ptr,
|
||||||
|
|||||||
@@ -1713,6 +1713,52 @@ kern_status_t vm_region_read_kernel(
|
|||||||
return status;
|
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(
|
kern_status_t vm_region_memmove(
|
||||||
struct vm_region *dest_region,
|
struct vm_region *dest_region,
|
||||||
virt_addr_t dest_ptr,
|
virt_addr_t dest_ptr,
|
||||||
|
|||||||
Reference in New Issue
Block a user