From 4f1b3f22ef1a1873fbed7ede7accae2857a558e5 Mon Sep 17 00:00:00 2001 From: Naoki Hamada Date: Wed, 2 Jul 2014 12:39:08 +0900 Subject: [PATCH] Working code for infrastructure. modified: executer/kernel/mcctrl.h modified: executer/kernel/syscall.c modified: kernel/include/syscall.h modified: kernel/mem.c --- executer/kernel/mcctrl.h | 3 +- executer/kernel/syscall.c | 124 ++++++++++++++++++++++---------------- kernel/include/syscall.h | 2 +- kernel/mem.c | 9 ++- 4 files changed, 80 insertions(+), 58 deletions(-) diff --git a/executer/kernel/mcctrl.h b/executer/kernel/mcctrl.h index f52b62ef..b4990b81 100644 --- a/executer/kernel/mcctrl.h +++ b/executer/kernel/mcctrl.h @@ -54,10 +54,11 @@ #define DO_USER_MODE #define __NR_coredump 999 + struct coretable { int len; void *addr; -} +}; struct ikc_scd_packet { int msg; diff --git a/executer/kernel/syscall.c b/executer/kernel/syscall.c index b941535d..6726bc33 100644 --- a/executer/kernel/syscall.c +++ b/executer/kernel/syscall.c @@ -1158,6 +1158,74 @@ static void clear_pte_range(uintptr_t start, uintptr_t len) return; } +/* xxx */ + +static int writecore(ihk_os_t os, unsigned long rcoretable, int chunks) { + struct file *file; + struct coretable *coretable; + int ret, len, i, tablesize, size, error = 0; + mm_segment_t oldfs = get_fs(); + unsigned long phys, tablephys, rphys; + ihk_device_t dev = ihk_os_to_dev(os); + char *pt; + + dprintk("coredump called as a pseudo syscall\n"); + + if (chunks <= 0) { + dprintk("no core data found!(%d)\n", chunks); + error = -EINVAL; + goto fail; + } + + set_fs(KERNEL_DS); + + /* Every Linux documentation insists we should not + * open a file in the kernel module, but our karma makes + * leads us here. Precisely, Here we emulate the core + * dump routine of the Linux kernel in linux/fs/exec.c. + * So we have a legitimate reason to do this. + */ + file = filp_open("core", O_CREAT | O_RDWR | O_LARGEFILE, 0600); + if (IS_ERR(file) || !file->f_op || !file->f_op->write) { + dprintk("cannot open core file\n"); + error = PTR_ERR(file); + goto fail; + } + + /* first we map the chunk table */ + tablesize = sizeof(struct coretable) * chunks; + tablephys = ihk_device_map_memory(dev, rcoretable, tablesize); + coretable = ihk_device_map_virtual(dev, tablephys, tablesize, NULL, 0); + for (i = 0; i < chunks; i++) { + /* map and write the chunk out */ + rphys = (unsigned long) coretable[i].addr; + size = coretable[i].len; + phys = ihk_device_map_memory(dev, rphys, size); + pt = ihk_device_map_virtual(dev, phys, size, NULL, 0); + ret = file->f_op->write(file, pt, size, &file->f_pos); + if (ret != size) { + dprintk("core file write failed(%d).\n", ret); + error = PTR_ERR(file); + break; + } + /* unmap the chunk out */ + ihk_device_unmap_virtual(dev, pt, size); + ihk_device_unmap_memory(dev, phys, size); + } + /* unmap the chunk table */ + ihk_device_unmap_virtual(dev, coretable, tablesize); + ihk_device_unmap_memory(dev, tablephys, tablesize); + filp_close(file, NULL); +fail: + set_fs(oldfs); + if (error == -ENOSYS) { + /* make sure we do not travel to user land */ + error = -EINVAL; + } + return error; +} + + int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, struct syscall_request *sc) { int error; @@ -1237,60 +1305,10 @@ int __do_in_kernel_syscall(ihk_os_t os, struct mcctrl_channel *c, struct syscall } case __NR_coredump: - /* xxx */ - dprintk("coredump called as a pseudo syscall\n"); - { - struct file *file; - int ret, len, chunks, i; - Mm_segment_t oldfs = get_fs(); - struct coretable *coretable; - unsigned long phys, tablephys, rphys; - unsigned long *pt; - int tablesize, size; - - set_fs(KERNEL_DS); - /* Any Linux documentation states that we should not - * open a file from a kernel module, but our karma makes - * leads us to do this. Precisely, Here we emulate the core - * dump routine of the Linux kernel in linux/fs/exec.c. - * So we have a legitimate reason. - */ - file = filp_open("core", O_CREAT | O_RDWR | O_LARGEFILE, 0600); - if (IS_ERR(file) || !file->f_op || !file->f_op->write) { - dprintk("cannot open core file\n"); - goto fail; - } - chunks = req->args[0]; /* > 0 */ - /* first we map the chunk table */ - tablesize = sizeof(struct coretable) * chunks; - tablephys = ihk_device_map_memory(ihk_os_to_dev(os), req->args[1], tablesize); - coretable = ihk_device_map_virtula(ihk_os_dev(os), tablephys, tablesize, NULL, 0); - for (i = 0; i < chunks; i++) { - /* xxx:map and write the chunk out */ - rphys = coretable[i].addr; - size = coretable[i].len; - phys = ihk_device_map_memory(ihk_os_to_dev(os), rphys, size); - pt = ihk_device_map_virtula(ihk_os_dev(os), phys, size, NULL, 0); - ret = file->f_op->write(file, pt, size, &file->f_pos); - if (ret != len) { - dprintk("core file write failed(%d).\n", ret); - break; - } - ihk_device_unmap_virtual(ihk_os_to_dev(os), pt, PAGE_SIZE); - ihk_device_unmap_memory(ihk_os_to_dev(os), phys, PAGE_SIZE); - } - /* xxx:unmap the chunk */ - /* unmap the chunk table */ - ihk_device_unmap_virtual(ihk_os_to_dev(os), coretable, PAGE_SIZE); - ihk_device_unmap_memory(ihk_os_to_dev(os), tablephys, PAGE_SIZE); - fail: - filp_close(file, NULL); - set_fs(oldfs); - - } - error = 0; - ret = 0; + error = writecore(os, sc->args[1], sc->args[0]); + ret = 0; break; + default: error = -ENOSYS; goto out; diff --git a/kernel/include/syscall.h b/kernel/include/syscall.h index 4d1b8761..1e4404f2 100644 --- a/kernel/include/syscall.h +++ b/kernel/include/syscall.h @@ -227,6 +227,6 @@ enum { struct coretable { int len; void *addr; -} +}; #endif diff --git a/kernel/mem.c b/kernel/mem.c index 5eeceb5a..d7da0f99 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -213,9 +213,12 @@ static void unhandled_page_fault(struct process *proc, void *fault_addr, void *r int ret; struct coretable coreentry[3]; - coreentry[0] = {8, virt_to_phys("this is ")}; - coreentry[1] = {7, virt_to_phys("a test ")}; - coreentry[2] = {15, virt_to_phys("for coredump.\n")}; + coreentry[0].len = 8; + coreentry[0].addr = virt_to_phys("this is "); + coreentry[1].len = 7; + coreentry[1].addr = virt_to_phys("a test "); + coreentry[2].len = 15; + coreentry[2].addr = virt_to_phys("for coredump.\n"); request.number = __NR_coredump; request.args[0] = 3;