summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-09-11 18:22:21 +0200
committerdzwdz2021-09-11 18:22:21 +0200
commite1789ffa14826e0c7378f974ac68c2c04ba8640c (patch)
tree933b920fd11ebcae1787be5efb1f062a5c2289bb
parentaf2f9184e03015dc3b188ea437bbf496638000ce (diff)
add some helper functions for copying between virtual and physical memory
this was already possible, but now it's slightly safer
-rw-r--r--src/kernel/mem/virt.c3
-rw-r--r--src/kernel/mem/virt.h11
-rw-r--r--src/kernel/syscalls.c9
3 files changed, 16 insertions, 7 deletions
diff --git a/src/kernel/mem/virt.c b/src/kernel/mem/virt.c
index e0d8e44..7a38a88 100644
--- a/src/kernel/mem/virt.c
+++ b/src/kernel/mem/virt.c
@@ -41,7 +41,8 @@ bool virt_iter_next(struct virt_iter *iter) {
}
} else {
// "iterate" over physical memory
- iter->frag = (void*) iter->_virt;
+ // the double cast supresses the warning about changing address spaces
+ iter->frag = (void*)(uintptr_t)iter->_virt;
}
iter->frag_len = partial;
diff --git a/src/kernel/mem/virt.h b/src/kernel/mem/virt.h
index 7dac887..78d0cb3 100644
--- a/src/kernel/mem/virt.h
+++ b/src/kernel/mem/virt.h
@@ -27,3 +27,14 @@ bool virt_iter_next(struct virt_iter *);
bool virt_cpy(
struct pagedir *dest_pages, void __user *dest,
struct pagedir *src_pages, const void __user *src, size_t length);
+
+
+inline bool virt_cpy_to(struct pagedir *dest_pages, // physical -> virtual
+ void __user *dest, const void *src, size_t length) {
+ return virt_cpy(dest_pages, dest, NULL, (userptr_t)src, length);
+}
+
+inline bool virt_cpy_from(struct pagedir *src_pages, // virtual -> physical
+ void *dest, const void __user *src, size_t length) {
+ return virt_cpy(NULL, (userptr_t)dest, src_pages, src, length);
+}
diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c
index ab4fdbb..743d5c5 100644
--- a/src/kernel/syscalls.c
+++ b/src/kernel/syscalls.c
@@ -83,8 +83,7 @@ handle_t _syscall_open(const char __user *path, int len) {
// it can handle copies to physical memory too, though
// note 2: path_buf gets freed in vfs_backend_finish
path_buf = kmalloc(len);
- if (!virt_cpy(NULL, path_buf,
- process_current->pages, path, len))
+ if (!virt_cpy_from(process_current->pages, path_buf, path, len))
goto fail;
len = path_simplify(path_buf, path_buf, len);
@@ -118,8 +117,7 @@ int _syscall_mount(handle_t handle, const char __user *path, int len) {
// copy the path to the kernel
path_buf = kmalloc(len);
- if (!virt_cpy(NULL, path_buf,
- process_current->pages, path, len))
+ if (!virt_cpy_from(process_current->pages, path_buf, path, len))
goto fail;
// simplify it
@@ -179,8 +177,7 @@ handle_t _syscall_fs_create(handle_t __user *back_user) {
process_current->handles[back].type = HANDLE_FS_BACK;
// copy the back handle to back_user
- if (!virt_cpy(process_current->pages, back_user,
- NULL, &back, sizeof(handle_t)))
+ if (!virt_cpy_to(process_current->pages, back_user, &back, sizeof(back)))
goto fail;
backend = kmalloc(sizeof *backend); // TODO never freed