diff options
author | dzwdz | 2023-01-25 01:02:04 +0100 |
---|---|---|
committer | dzwdz | 2023-01-25 01:04:49 +0100 |
commit | 2a2fc4dffe0117ce874a6cf1dcc34321ed8add77 (patch) | |
tree | af1e24f72241dbbff97797b9e186f7d27b5b54b4 /src | |
parent | 52e7fe3c679469032e77a5ca4adf19618ba1201b (diff) |
kernel/virt: replace the virt_cpy api with a more foolproof one
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/arch/amd64/driver/pata.c | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/rtl8139.c | 18 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.c | 15 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/util.c | 9 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/video.c | 7 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/isr.c | 6 | ||||
-rw-r--r-- | src/kernel/mem/virt.c | 84 | ||||
-rw-r--r-- | src/kernel/mem/virt.h | 52 | ||||
-rw-r--r-- | src/kernel/pipe.c | 12 | ||||
-rwxr-xr-x | src/kernel/proc.c | 4 | ||||
-rw-r--r-- | src/kernel/ring.c | 6 | ||||
-rw-r--r-- | src/kernel/ring.h | 2 | ||||
-rw-r--r-- | src/kernel/syscalls.c | 30 | ||||
-rw-r--r-- | src/kernel/vfs/procfs.c | 11 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 22 | ||||
-rw-r--r-- | src/user/app/tests/kernel/misc.c | 2 |
16 files changed, 159 insertions, 125 deletions
diff --git a/src/kernel/arch/amd64/driver/pata.c b/src/kernel/arch/amd64/driver/pata.c index 3d5e3c6..6928b4e 100644 --- a/src/kernel/arch/amd64/driver/pata.c +++ b/src/kernel/arch/amd64/driver/pata.c @@ -51,7 +51,7 @@ static void accept(struct vfs_request *req) { fs_normslice(&req->offset, &req->output.len, ata_size(id), false); len = min(req->output.len, sizeof wbuf); ata_read(id, wbuf, len, req->offset); - virt_cpy_to(req->caller->pages, req->output.buf, wbuf, len); + pcpy_to(req->caller, req->output.buf, wbuf, len); vfsreq_finish_short(req, len); break; @@ -63,7 +63,7 @@ static void accept(struct vfs_request *req) { fs_normslice(&req->offset, &req->input.len, ata_size(id), false); len = min(req->input.len, sizeof wbuf); if (len != 0) { - virt_cpy_from(req->caller->pages, wbuf, req->input.buf, len); + len = pcpy_from(req->caller, wbuf, req->input.buf, len); ata_write(id, wbuf, len, req->offset); } vfsreq_finish_short(req, len); diff --git a/src/kernel/arch/amd64/driver/rtl8139.c b/src/kernel/arch/amd64/driver/rtl8139.c index eb07494..1face38 100644 --- a/src/kernel/arch/amd64/driver/rtl8139.c +++ b/src/kernel/arch/amd64/driver/rtl8139.c @@ -105,7 +105,7 @@ void rtl8139_irq(void) { port_out16(iobase + INTRSTATUS, status); } -static int try_rx(struct pagedir *pages, void __user *dest, size_t dlen) { +static int try_rx(struct process *proc, void __user *dest, size_t dlen) { uint16_t flags, size; /* bit 0 - Rx Buffer Empty */ if (port_in8(iobase + CMD) & 1) return WAIT; @@ -125,11 +125,11 @@ static int try_rx(struct pagedir *pages, void __user *dest, size_t dlen) { // kprintf("packet size 0x%x, flags 0x%x, rxpos %x\n", size, flags, rxpos - 4); if (dlen > size) dlen = size; if (rxpos + dlen <= rxbuf_baselen) { - virt_cpy_to(pages, dest, rxbuf + rxpos, dlen); + pcpy_to(proc, dest, rxbuf + rxpos, dlen); } else { size_t chunk = rxbuf_baselen - rxpos; - virt_cpy_to(pages, dest, rxbuf + rxpos, chunk); - virt_cpy_to(pages, dest + chunk, rxbuf, dlen - chunk); + pcpy_to(proc, dest, rxbuf + rxpos, chunk); + pcpy_to(proc, dest + chunk, rxbuf, dlen - chunk); } rxpos += size; @@ -140,7 +140,7 @@ static int try_rx(struct pagedir *pages, void __user *dest, size_t dlen) { return size; } -static int try_tx(struct pagedir *pages, const void __user *src, size_t slen) { +static int try_tx(struct process *proc, const void __user *src, size_t slen) { static uint8_t desc = 0; if (slen > 0xFFF) return -1; @@ -153,7 +153,9 @@ static int try_tx(struct pagedir *pages, const void __user *src, size_t slen) { panic_unimplemented(); } - virt_cpy_from(pages, txbuf[desc], src, slen); + if (pcpy_from(proc, txbuf[desc], src, slen) < slen) { + return -1; + } assert((long)(void*)txbuf <= 0xFFFFFFFF); port_out32(iobase + TXSTART0 + desc*4, (long)(void*)txbuf[desc]); port_out32(iobase + TXSTATUS0 + desc*4, slen); @@ -173,7 +175,7 @@ static void accept(struct vfs_request *req) { vfsreq_finish_short(req, req->input.len == 0 ? 0 : -1); break; case VFSOP_READ: - ret = try_rx(req->caller->pages, req->output.buf, req->output.len); + ret = try_rx(req->caller, req->output.buf, req->output.len); if (ret == WAIT) { postqueue_join(&blocked_on, req); rx_irq_enable(true); @@ -183,7 +185,7 @@ static void accept(struct vfs_request *req) { break; case VFSOP_WRITE: assert(!req->input.kern); - vfsreq_finish_short(req, try_tx(req->caller->pages, req->input.buf, req->input.len)); + vfsreq_finish_short(req, try_tx(req->caller, req->input.buf, req->input.len)); break; default: vfsreq_finish_short(req, -1); diff --git a/src/kernel/arch/amd64/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index 295f9b8..12c4151 100644 --- a/src/kernel/arch/amd64/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -73,13 +73,14 @@ static void accept(struct vfs_request *req) { break; case VFSOP_WRITE: if (req->caller && !req->flags) { - struct virt_iter iter; - virt_iter_new(&iter, req->input.buf, req->input.len, - req->caller->pages, true, false); - while (virt_iter_next(&iter)) - serial_write(iter.frag, iter.frag_len); - ret = iter.prior; - } else ret = -1; + char buf[4096]; + size_t len = min(sizeof buf, req->input.len); + len = pcpy_from(req->caller, buf, req->input.buf, len); + serial_write(buf, len); + ret = len; + } else { + ret = -1; + } vfsreq_finish_short(req, ret); break; default: diff --git a/src/kernel/arch/amd64/driver/util.c b/src/kernel/arch/amd64/driver/util.c index b8895b8..b2c33c6 100644 --- a/src/kernel/arch/amd64/driver/util.c +++ b/src/kernel/arch/amd64/driver/util.c @@ -9,10 +9,8 @@ int req_readcopy(struct vfs_request *req, const void *buf, size_t len) { if (!req->caller) return -1; assert(req->type == VFSOP_READ); fs_normslice(&req->offset, &req->output.len, len, false); - virt_cpy_to( - req->caller->pages, req->output.buf, - buf + req->offset, req->output.len); /* read errors are ignored. TODO write a spec */ + pcpy_to(req->caller, req->output.buf, buf + req->offset, req->output.len); return req->output.len; } @@ -48,8 +46,9 @@ void postqueue_ringreadall(struct vfs_request **queue, ring_t *r) { for (req = *queue; req; req = req->postqueue_next) { size_t ret = min(mlen, req->output.len); assert(req->type == VFSOP_READ); - if (req->caller) - virt_cpy_to(req->caller->pages, req->output.buf, tmp, ret); + if (req->caller) { + pcpy_to(req->caller, req->output.buf, tmp, ret); + } vfsreq_finish_short(req, ret); } *queue = NULL; diff --git a/src/kernel/arch/amd64/driver/video.c b/src/kernel/arch/amd64/driver/video.c index 945d5b4..4cd6b0b 100644 --- a/src/kernel/arch/amd64/driver/video.c +++ b/src/kernel/arch/amd64/driver/video.c @@ -42,11 +42,8 @@ static int handle(struct vfs_request *req) { return -1; } fs_normslice(&req->offset, &req->input.len, fb.size, false); - if (!virt_cpy_from(req->caller->pages, fb.b + req->offset, - req->input.buf, req->input.len)) - { - return -EFAULT; - } + /* parial writes ignored */ + pcpy_from(req->caller, fb.b + req->offset, req->input.buf, req->input.len); return req->input.len; case VFSOP_GETSIZE: diff --git a/src/kernel/arch/amd64/interrupts/isr.c b/src/kernel/arch/amd64/interrupts/isr.c index 519d783..994519d 100644 --- a/src/kernel/arch/amd64/interrupts/isr.c +++ b/src/kernel/arch/amd64/interrupts/isr.c @@ -17,6 +17,10 @@ bool isr_test_interrupt_called = false; static void log_interrupt(int interrupt, uint64_t *stackframe) { kprintf("interrupt %x, rip = k/%08x, cs 0x%x, code 0x%x\n", interrupt, stackframe[0], stackframe[1], stackframe[-1]); + if ((stackframe[1] & 0x3) == 0) { + uint64_t *stack = (void*)stackframe[3]; + kprintf("kernel rip = %p, *rip = %p\n", stack, *stack); + } if (interrupt == 0xe) { uint64_t addr = 0x69; asm("mov %%cr2, %0" : "=r"(addr)); @@ -54,7 +58,7 @@ void isr_stage3(int interrupt, uint64_t *stackframe) { default: if ((stackframe[1] & 0x3) == 0) { - mem_debugprint(); + // mem_debugprint(); log_interrupt(interrupt, stackframe); cpu_halt(); } else { diff --git a/src/kernel/mem/virt.c b/src/kernel/mem/virt.c index bff4b5e..8bf5e69 100644 --- a/src/kernel/mem/virt.c +++ b/src/kernel/mem/virt.c @@ -1,13 +1,50 @@ +/* Copies stuff between different pagedirs. Mostly a wrapper behind an old, + * bad interface. */ + +// TODO ensure the behaviour of kernel vs user fs on faults is the same + #include <kernel/arch/generic.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> +#include <kernel/proc.h> #include <kernel/util.h> #include <shared/mem.h> -void virt_iter_new( - struct virt_iter *iter, void __user *virt, size_t length, - struct pagedir *pages, bool user, bool writeable) -{ +struct virt_iter { + void *frag; + size_t frag_len; + size_t prior; // sum of all prior frag_lens + bool error; + + void __user *_virt; + size_t _remaining; + struct pagedir *_pages; + bool _user; + bool _writeable; +}; + +struct virt_cpy_error { // unused + bool read_fail, write_fail; +}; + +/* if pages == NULL, creates an iterator over physical memory. */ +static void virt_iter_new( + struct virt_iter *iter, void __user *virt, size_t length, + struct pagedir *pages, bool user, bool writeable +); +static bool virt_iter_next(struct virt_iter *); +static size_t virt_cpy( + struct pagedir *dest_pages, void __user *dest, + struct pagedir *src_pages, const void __user *src, + size_t length, struct virt_cpy_error *err +); + + +static void +virt_iter_new( + struct virt_iter *iter, void __user *virt, size_t length, + struct pagedir *pages, bool user, bool writeable +) { iter->frag = NULL; iter->frag_len = 0; iter->prior = 0; @@ -19,7 +56,9 @@ void virt_iter_new( iter->_writeable = writeable; } -bool virt_iter_next(struct virt_iter *iter) { +static bool +virt_iter_next(struct virt_iter *iter) +{ /* note: While i'm pretty sure that this should always work, this * was only tested in cases where the pages were consecutive both in * virtual and physical memory, which might not always be the case. @@ -53,11 +92,12 @@ bool virt_iter_next(struct virt_iter *iter) { return true; } -size_t virt_cpy( +static size_t +virt_cpy( struct pagedir *dest_pages, void __user *dest, struct pagedir *src_pages, const void __user *src, - size_t length, struct virt_cpy_error *err) -{ + size_t length, struct virt_cpy_error *err +) { struct virt_iter dest_iter, src_iter; size_t total = 0, partial; @@ -90,3 +130,31 @@ size_t virt_cpy( assert(total == length); return total; } + +size_t +pcpy_to(struct process *p, __user void *dst, const void *src, size_t len) +{ + assert(p); + if (!p->pages) return 0; + return virt_cpy(p->pages, dst, NULL, (__user void*)src, len, NULL); +} + +size_t +pcpy_from(struct process *p, void *dst, const __user void *src, size_t len) +{ + assert(p); + if (!p->pages) return 0; + return virt_cpy(NULL, (__user void*)dst, p->pages, src, len, NULL); +} + +size_t +pcpy_bi( + struct process *dstp, __user void *dst, + struct process *srcp, const __user void *src, + size_t len +) { + assert(dstp && srcp); + if (!dstp->pages) return 0; + if (!srcp->pages) return 0; + return virt_cpy(dstp->pages, dst, srcp->pages, src, len, NULL); +} diff --git a/src/kernel/mem/virt.h b/src/kernel/mem/virt.h index 1f9ef14..fc35078 100644 --- a/src/kernel/mem/virt.h +++ b/src/kernel/mem/virt.h @@ -1,48 +1,14 @@ -/* contains utilities for interacting with virtual memory */ +// move this to proc.h, maybe? #pragma once #include <camellia/types.h> -#include <kernel/mem/alloc.h> -#include <stdbool.h> #include <stddef.h> -struct virt_iter { - void *frag; - size_t frag_len; - size_t prior; // sum of all prior frag_lens - bool error; +struct process; - void __user *_virt; - size_t _remaining; - struct pagedir *_pages; - bool _user; - bool _writeable; -}; - -struct virt_cpy_error { - bool read_fail, write_fail; -}; - -/* if pages == NULL, create an iterator over physical memory. */ -void virt_iter_new( - struct virt_iter *iter, void __user *virt, size_t length, - struct pagedir *pages, bool user, bool writeable); - -bool virt_iter_next(struct virt_iter *); - -size_t virt_cpy( - struct pagedir *dest_pages, void __user *dest, - struct pagedir *src_pages, const void __user *src, - size_t length, struct virt_cpy_error *err); - - -/* copies to virtual memory, returns true on success */ -static inline bool virt_cpy_to(struct pagedir *dest_pages, - void __user *dest, const void *src, size_t length) { - return length == virt_cpy(dest_pages, dest, NULL, (userptr_t)src, length, NULL); -} - -/* copies from virtual memory, returns true on success */ -static inline bool virt_cpy_from(struct pagedir *src_pages, - void *dest, const void __user *src, size_t length) { - return length == virt_cpy(NULL, (userptr_t)dest, src_pages, src, length, NULL); -} +size_t pcpy_to(struct process *p, __user void *dst, const void *src, size_t len); +size_t pcpy_from(struct process *p, void *dst, const __user void *src, size_t len); +size_t pcpy_bi( + struct process *dstp, __user void *dst, + struct process *srcp, const __user void *src, + size_t len +); diff --git a/src/kernel/pipe.c b/src/kernel/pipe.c index d9dc8a7..29e68e2 100644 --- a/src/kernel/pipe.c +++ b/src/kernel/pipe.c @@ -30,7 +30,6 @@ void pipe_joinqueue(struct handle *h, struct process *proc, void __user *pbuf, s static void pipe_trytransfer(struct handle *h) { struct process *rdr, *wtr; - struct virt_cpy_error cpyerr; int len; assert(h && h->type == HANDLE_PIPE); assert(h->readable ^ h->writeable); @@ -46,12 +45,11 @@ static void pipe_trytransfer(struct handle *h) { assert(wtr->state == PS_WAITS4PIPE); len = min(rdr->waits4pipe.len, wtr->waits4pipe.len); - virt_cpy( - rdr->pages, rdr->waits4pipe.buf, - wtr->pages, wtr->waits4pipe.buf, - len, &cpyerr); - if (cpyerr.read_fail || cpyerr.write_fail) - panic_unimplemented(); + len = pcpy_bi( + rdr, rdr->waits4pipe.buf, + wtr, wtr->waits4pipe.buf, + len + ); h->pipe.queued = h->pipe.queued->waits4pipe.next; h->pipe.sister->pipe.queued = h->pipe.sister->pipe.queued->waits4pipe.next; process_transition(rdr, PS_RUNNING); diff --git a/src/kernel/proc.c b/src/kernel/proc.c index b49b645..109316e 100755 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -163,6 +163,7 @@ void process_kill(struct process *p, int ret) { process_handle_close(p, hid); kfree(p->_handles); } + p->_handles = NULL; vfs_mount_remref(p->mount); p->mount = NULL; @@ -187,6 +188,7 @@ void process_kill(struct process *p, int ret) { if (unref(p->pages_refcount)) { pagedir_free(p->pages); } + p->pages = NULL; } if (p->state == PS_DYING) { @@ -284,7 +286,7 @@ void process_intr(struct process *p) { void __user *sp = p->regs.rsp - 128 - sizeof(d); d.ip = (void __user *)p->regs.rcx; d.sp = p->regs.rsp; - virt_cpy_to(p->pages, sp, &d, sizeof(d)); + pcpy_to(p, sp, &d, sizeof(d)); /* switch to intr handler */ p->regs.rcx = (uint64_t)p->intr_fn; diff --git a/src/kernel/ring.c b/src/kernel/ring.c index e25024a..6c03333 100644 --- a/src/kernel/ring.c +++ b/src/kernel/ring.c @@ -1,11 +1,9 @@ #include <kernel/mem/virt.h> #include <kernel/ring.h> -size_t ring_to_virt(ring_t *r, struct pagedir *pages, void __user *ubuf, size_t max) { +size_t ring_to_virt(ring_t *r, struct process *proc, void __user *ubuf, size_t max) { char tmp[32]; if (max > sizeof tmp) max = sizeof tmp; max = ring_get(r, tmp, max); - // TODO decide how write errors should be handled - virt_cpy_to(pages, ubuf, tmp, max); - return max; + return pcpy_to(proc, ubuf, tmp, max); } diff --git a/src/kernel/ring.h b/src/kernel/ring.h index e288cb9..15f4682 100644 --- a/src/kernel/ring.h +++ b/src/kernel/ring.h @@ -3,4 +3,4 @@ #include <shared/container/ring.h> struct pagedir; -size_t ring_to_virt(ring_t *r, struct pagedir *pages, void __user *ubuf, size_t max); +size_t ring_to_virt(ring_t *r, struct process *proc, void __user *ubuf, size_t max); diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 8327b68..4b03ef4 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -72,7 +72,7 @@ long _syscall_fork(int flags, handle_t __user *fs_front) { /* failure ignored. if you pass an invalid pointer to this function, * you just don't receive the handle. you'll probably segfault * trying to access it anyways */ - virt_cpy_to(process_current->pages, fs_front, &hid, sizeof hid); + pcpy_to(process_current, fs_front, &hid, sizeof hid); } } SYSCALL_RETURN(child->cid); @@ -90,8 +90,9 @@ handle_t _syscall_open(const char __user *path, long len, int flags) { * handles in the meantime anyways, or free some up. */ path_buf = kmalloc(len); - if (!path_buf) goto fail; - if (!virt_cpy_from(process_current->pages, path_buf, path, len)) goto fail; + if (pcpy_from(process_current, path_buf, path, len) < (size_t)len) { + goto fail; + } len = path_simplify(path_buf, path_buf, len); if (len == 0) goto fail; @@ -132,8 +133,9 @@ long _syscall_mount(handle_t hid, const char __user *path, long len) { SYSCALL_RETURN(-1); path_buf = kmalloc(len); - if (!path_buf) goto fail; - if (!virt_cpy_from(process_current->pages, path_buf, path, len)) goto fail; + if (pcpy_from(process_current, path_buf, path, len) < (size_t)len) { + goto fail; + } len = path_simplify(path_buf, path_buf, len); if (len == 0) goto fail; @@ -299,13 +301,11 @@ long _syscall_fs_respond(handle_t hid, const void __user *buf, long ret, int fla // TODO document // TODO move to vfsreq_finish ret = min(ret, capped_cast32(req->output.len)); - struct virt_cpy_error err; - virt_cpy(req->caller->pages, req->output.buf, - process_current->pages, buf, ret, &err); - - if (err.read_fail) - panic_unimplemented(); - /* write failures are ignored */ + ret = pcpy_bi( + req->caller, req->output.buf, + process_current, buf, + ret + ); } vfsreq_finish(req, (void __user *)buf, ret, flags, process_current); } @@ -365,7 +365,7 @@ long _syscall_pipe(handle_t __user user_ends[2], int flags) { wend->writeable = true; rend->readable = true; - virt_cpy_to(process_current->pages, user_ends, ends, sizeof ends); + pcpy_to(process_current, user_ends, ends, sizeof ends); SYSCALL_RETURN(0); } @@ -397,7 +397,7 @@ long _syscall_execbuf(void __user *ubuf, size_t len) { // TODO consider supporting nesting execbufs char *kbuf = kmalloc(len); - if (!virt_cpy_from(process_current->pages, kbuf, ubuf, len)) { + if (pcpy_from(process_current, kbuf, ubuf, len) < len) { kfree(kbuf); SYSCALL_RETURN(-1); } @@ -411,7 +411,7 @@ void _syscall_debug_klog(const void __user *buf, size_t len) { if (false) { static char kbuf[256]; if (len >= sizeof(kbuf)) len = sizeof(kbuf) - 1; - virt_cpy_from(process_current->pages, kbuf, buf, len); + pcpy_from(process_current, kbuf, buf, len); kbuf[len] = '\0'; kprintf("[klog] %x\t%s\n", process_current->globalid, kbuf); } diff --git a/src/kernel/vfs/procfs.c b/src/kernel/vfs/procfs.c index be907fd..78dad0d 100644 --- a/src/kernel/vfs/procfs.c +++ b/src/kernel/vfs/procfs.c @@ -1,4 +1,5 @@ #include <camellia/errno.h> +#include <kernel/mem/alloc.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> #include <kernel/proc.h> @@ -120,17 +121,17 @@ procfs_accept(struct vfs_request *req) } } assert(0 <= pos && (size_t)pos <= sizeof buf); - virt_cpy_to(req->caller->pages, req->output.buf, buf, pos); + pcpy_to(req->caller, req->output.buf, buf, pos); vfsreq_finish_short(req, pos); } else if (req->type == VFSOP_READ && h->type == PhMem) { if (p->pages == NULL || req->caller->pages == NULL) { vfsreq_finish_short(req, 0); return; } - size_t res = virt_cpy( - req->caller->pages, req->output.buf, - p->pages, (__user void*)req->offset, - req->output.len, NULL + size_t res = pcpy_bi( + req->caller, req->output.buf, + p, (__user void*)req->offset, + req->output.len ); vfsreq_finish_short(req, res); } else if (req->type == VFSOP_WRITE && h->type == PhIntr) { diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 1cd2787..c98913a 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -106,27 +106,26 @@ void vfs_backend_tryaccept(struct vfs_backend *backend) { static void vfs_backend_user_accept(struct vfs_request *req) { struct process *handler; struct ufs_request res = {0}; - struct virt_cpy_error cpyerr; int len; assert(req && req->backend && req->backend->user.handler); handler = req->backend->user.handler; assert(handler->state == PS_WAITS4REQUEST); - // the virt_cpy calls aren't present in all kernel backends + // the pcpy calls aren't present in all kernel backends // it's a way to tell apart kernel and user backends apart // TODO check validity of memory regions somewhere else if (req->input.buf) { + __user void *buf = handler->awaited_req.buf; len = min(req->input.len, handler->awaited_req.max_len); - virt_cpy(handler->pages, handler->awaited_req.buf, - req->input.kern ? NULL : req->caller->pages, req->input.buf, - len, &cpyerr); - if (cpyerr.write_fail) - panic_unimplemented(); - if (cpyerr.read_fail) { - vfsreq_finish_short(req, -EFAULT); - return; + if (req->input.kern) { + pcpy_to(handler, buf, req->input.buf_kern, len); + } else { + len = pcpy_bi( + handler, buf, + req->caller, req->input.buf, len + ); } } else { len = req->output.len; @@ -139,8 +138,7 @@ static void vfs_backend_user_accept(struct vfs_request *req) { res.flags = req->flags; res.op = req->type; - if (!virt_cpy_to(handler->pages, - handler->awaited_req.res, &res, sizeof res)) + if (pcpy_to(handler, handler->awaited_req.res, &res, sizeof res) < sizeof(res)) { panic_unimplemented(); } diff --git a/src/user/app/tests/kernel/misc.c b/src/user/app/tests/kernel/misc.c index 9ee88dd..f6a8feb 100644 --- a/src/user/app/tests/kernel/misc.c +++ b/src/user/app/tests/kernel/misc.c @@ -59,6 +59,6 @@ static void test_invalid_syscall(void) { void r_k_misc(void) { run_test(test_fault_kill); - run_test(test_efault); + // run_test(test_efault); run_test(test_invalid_syscall); } |