vm: region: implement reading from a user-space vm-region into a kernel buffer
This commit is contained in:
@@ -122,6 +122,15 @@ extern virt_addr_t vm_region_get_base_address(const struct vm_region *region);
|
|||||||
|
|
||||||
extern void vm_region_dump(struct vm_region *region);
|
extern void vm_region_dump(struct vm_region *region);
|
||||||
|
|
||||||
|
/* read data from the user-space area of a vm-region into a kernel-mode buffer
|
||||||
|
*/
|
||||||
|
extern kern_status_t vm_region_read_kernel(
|
||||||
|
struct vm_region *src_region,
|
||||||
|
virt_addr_t src_ptr,
|
||||||
|
size_t count,
|
||||||
|
void *dest,
|
||||||
|
size_t *nr_read);
|
||||||
|
|
||||||
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,
|
||||||
|
|||||||
@@ -1239,6 +1239,46 @@ virt_addr_t vm_region_get_base_address(const struct vm_region *region)
|
|||||||
return entry_absolute_address(®ion->vr_entry);
|
return entry_absolute_address(®ion->vr_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kern_status_t vm_region_read_kernel(
|
||||||
|
struct vm_region *src_region,
|
||||||
|
virt_addr_t src_ptr,
|
||||||
|
size_t count,
|
||||||
|
void *destp,
|
||||||
|
size_t *nr_read)
|
||||||
|
{
|
||||||
|
struct vm_iterator src;
|
||||||
|
char *dest = destp;
|
||||||
|
|
||||||
|
vm_iterator_begin(
|
||||||
|
&src,
|
||||||
|
src_region,
|
||||||
|
src_ptr,
|
||||||
|
VM_PROT_READ | VM_PROT_USER);
|
||||||
|
|
||||||
|
kern_status_t status = KERN_OK;
|
||||||
|
size_t r = 0;
|
||||||
|
|
||||||
|
while (r < count && src.it_max) {
|
||||||
|
size_t remaining = count - r;
|
||||||
|
size_t to_move = MIN(src.it_max, remaining);
|
||||||
|
memmove(dest, src.it_buf, to_move);
|
||||||
|
|
||||||
|
status = vm_iterator_seek(&src, to_move);
|
||||||
|
if (status != KERN_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
r += to_move;
|
||||||
|
dest += to_move;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr_read) {
|
||||||
|
*nr_read = 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