whiterose

linux unikernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/whiterose

commit 7dc5e716dcb08abc6b593bb4b3ae5531feaa7396
parent d723fba160d47df298b70d4c2c830fdcea36a482
Author: Louis Solofrizzo <louis@ne02ptzero.me>
Date:   Tue, 23 Apr 2019 07:37:50 +0200

ukl: Proper KLinux code formatting

Signed-off-by: Louis Solofrizzo <louis@ne02ptzero.me>

Diffstat:
Ainclude/ukl/ukl_internals.h | 9+++++++++
Minit/main.c | 23+++++++++++------------
Mukl/fcntl/fcntl.c | 197+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mukl/fcntl/open.c | 40++++++++++++++++++++--------------------
Mukl/unistd/close.c | 23++++++++++++-----------
Mukl/unistd/read.c | 27++++++++++++++-------------
Mukl/unistd/write.c | 158+++++++++++++++++++++++++++++++++++++++----------------------------------------
7 files changed, 240 insertions(+), 237 deletions(-)

diff --git a/include/ukl/ukl_internals.h b/include/ukl/ukl_internals.h @@ -0,0 +1,9 @@ +#ifndef UKL_INTERNALS_H +#define UKL_INTERNALS_H + +#define UKL_BAD_FD(fn, d) \ + printk(KERN_ERR "Trying to call " fn \ + "() with bad file descriptor: %d", \ + d) + +#endif /* UKL_INTERNALS_H */ diff --git a/init/main.c b/init/main.c @@ -351,8 +351,8 @@ __setup("init=", init_setup); bool ukl_mode = false; static int __init ukl_kernel(char *str) { - ukl_mode = true; - return 1; + ukl_mode = true; + return 1; } early_param("ukl", ukl_kernel); #endif /* CONFIG_UKL_LINUX */ @@ -1019,11 +1019,11 @@ extern int ukl_main(void); static int run_ukl_main(void) { - printk("Launching Unikernel...\n"); - kthread_run((void*)ukl_main, NULL, "UKL"); - while (1) - cond_resched(); - return 0; + printk("Launching Unikernel...\n"); + kthread_run((void *)ukl_main, NULL, "UKL"); + while (1) + cond_resched(); + return 0; } #endif /* CONFIG_UKL_LINUX */ @@ -1108,11 +1108,10 @@ static int __ref kernel_init(void *unused) rcu_end_inkernel_boot(); #ifdef CONFIG_UKL_LINUX - if (ukl_mode) - { - run_ukl_main(); - return 0; - } + if (ukl_mode) { + run_ukl_main(); + return 0; + } #endif /* CONFIG_UKL_LINUX */ diff --git a/ukl/fcntl/fcntl.c b/ukl/fcntl/fcntl.c @@ -2,112 +2,109 @@ #include <unistd.h> #include <linux/security.h> -extern long do_fcntl(int fd, unsigned int cmd, unsigned long arg, struct file *filp); +#include <ukl/ukl_internals.h> + +extern long do_fcntl(int fd, unsigned int cmd, unsigned long arg, + struct file *filp); extern int check_fcntl_cmd(unsigned cmd); static long sys_fcntl(int fd, unsigned int cmd, unsigned long arg) { - struct fd f = fdget_raw(fd); /* Get the file associated with the file descriptor */ - long err = -EBADF; - - /* Not a file, nothing to do! */ - if (!f.file) - return err; - - /* On PATH mode, check that the cmd issued is compliant */ - if (unlikely(f.file->f_mode) & FMODE_PATH) - { - if (!check_fcntl_cmd(cmd)) - { - /* cmd is not compliant, release the file lock and return the err */ - fdput(f); - return err; - } - } - - /* Check the rights on file */ - err = security_file_fcntl(f.file, cmd, arg); - - /* Do the syscall */ - if (!err) - err = do_fcntl(fd, cmd, arg, f.file); - - /* Release the lock and return the code */ - fdput(f); - return err; + struct fd f = fdget_raw( + fd); /* Get the file associated with the file descriptor */ + long err = -EBADF; + + /* Not a file, nothing to do! */ + if (!f.file) + return err; + + /* On PATH mode, check that the cmd issued is compliant */ + if (unlikely(f.file->f_mode) & FMODE_PATH) { + if (!check_fcntl_cmd(cmd)) { + /* cmd is not compliant, release the file lock and return the err */ + fdput(f); + return err; + } + } + + /* Check the rights on file */ + err = security_file_fcntl(f.file, cmd, arg); + + /* Do the syscall */ + if (!err) + err = do_fcntl(fd, cmd, arg, f.file); + + /* Release the lock and return the code */ + fdput(f); + return err; } int fcntl(int fd, int cmd, ...) { - unsigned long arg; - va_list ap; - - if (fd >= 0 && fd <= 2) - { - printk(KERN_ERR "Trying to call fcntl() with %d file descriptor\n", fd); - return -EINVAL; - } - - /** - * Little trick used to mock stdin, stdout and stderr for UKL - * Don't make any sense in kernel space, since a fd could very well - * be 0. - */ - fd -= 3; - - /* Read optionnals arguments */ - va_start(ap, cmd); - arg = va_arg(ap, unsigned long); - va_end(ap); - - if (cmd == F_SETFL) - arg |= O_LARGEFILE; - - if (cmd == F_SETLKW) - return sys_fcntl(fd, cmd, arg); - - /* If the fd is a socket, get the process owner's pid */ - if (cmd == F_GETOWN) - { - struct f_owner_ex ex; - int ret = sys_fcntl(fd, F_GETOWN_EX, &ex); - - if (ret == -EINVAL) - return sys_fcntl(fd, cmd, arg); - - if (ret) - return ret; - return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; - } - - /* Clone the fd, with FD_CLOEXEC flag */ - if (cmd == F_DUPFD_CLOEXEC) - { - int ret = sys_fcntl(fd, F_DUPFD_CLOEXEC, arg); /* Try to dup */ - - if (ret != -EINVAL) - { - /* Dup successful, set the flag and return the new fd */ - if (ret >= 0) - sys_fcntl(ret, F_SETFD, FD_CLOEXEC); - return ret; - } - - /* Dup has failed, cleanup and return error */ - ret = sys_fcntl(fd, F_DUPFD_CLOEXEC, 0); - if (ret != -EINVAL) - { - if (ret >= 0) - close(ret); - return -EINVAL; - } - - /* Last try, make the dup and set in two calls */ - ret = sys_fcntl(fd, F_DUPFD, arg); - if (ret >= 0) - sys_fcntl(ret, F_SETFD, FD_CLOEXEC); - return ret; - } - - return sys_fcntl(fd, cmd, arg); + unsigned long arg; + va_list ap; + + if (fd >= 0 && fd <= 2) { + UKL_BAD_FD("fcntl", fd); + return -EINVAL; + } + + /* + * Little trick used to mock stdin, stdout and stderr for UKL + * Don't make any sense in kernel space, since a fd could very well + * be 0. + */ + fd -= 3; + + /* Read optionnals arguments */ + va_start(ap, cmd); + arg = va_arg(ap, unsigned long); + va_end(ap); + + if (cmd == F_SETFL) + arg |= O_LARGEFILE; + + if (cmd == F_SETLKW) + return sys_fcntl(fd, cmd, arg); + + /* If the fd is a socket, get the process owner's pid */ + if (cmd == F_GETOWN) { + struct f_owner_ex ex; + int ret = sys_fcntl(fd, F_GETOWN_EX, &ex); + + if (ret == -EINVAL) + return sys_fcntl(fd, cmd, arg); + + if (ret) + return ret; + return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid; + } + + /* Clone the fd, with FD_CLOEXEC flag */ + if (cmd == F_DUPFD_CLOEXEC) { + int ret = sys_fcntl(fd, F_DUPFD_CLOEXEC, arg); /* Try to dup */ + + if (ret != -EINVAL) { + /* Dup successful, set the flag and return the new fd */ + if (ret >= 0) + sys_fcntl(ret, F_SETFD, FD_CLOEXEC); + return ret; + } + + /* Dup has failed, cleanup and return error */ + ret = sys_fcntl(fd, F_DUPFD_CLOEXEC, 0); + if (ret != -EINVAL) { + if (ret >= 0) + close(ret); + return -EINVAL; + } + + /* Last try, make the dup and set in two calls */ + ret = sys_fcntl(fd, F_DUPFD, arg); + if (ret >= 0) + sys_fcntl(ret, F_SETFD, FD_CLOEXEC); + return ret; + } + + return sys_fcntl(fd, cmd, arg); } diff --git a/ukl/fcntl/open.c b/ukl/fcntl/open.c @@ -2,32 +2,32 @@ #include <linux/syscalls.h> #include <stdarg.h> +#include <ukl/ukl_internals.h> int open(const char *filename, int flags, ...) { - umode_t mode = 0; - int ret = -1; + umode_t mode = 0; + int ret = -1; - /* Parse the flags */ - if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) - { - va_list ap; + /* Parse the flags */ + if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) { + va_list ap; - va_start(ap, flags); - mode = va_arg(ap, umode_t); - va_end(ap); - } + va_start(ap, flags); + mode = va_arg(ap, umode_t); + va_end(ap); + } - /* Make the call */ - ret = do_sys_open(AT_FDCWD, filename, flags, mode); + /* Make the call */ + ret = do_sys_open(AT_FDCWD, filename, flags, mode); - if (ret >= 0 && (flags & O_CLOEXEC)) - fcntl(ret + 3, F_SETFD, FD_CLOEXEC); + if (ret >= 0 && (flags & O_CLOEXEC)) + fcntl(ret + 3, F_SETFD, FD_CLOEXEC); - /** - * Little trick used to mock stdin, stdout and stderr for UKL - * Don't make any sense in kernel space, since a fd could very well - * be 0, so we start at 3. - */ - return ret + 3; + /* + * Little trick used to mock stdin, stdout and stderr for UKL + * Don't make any sense in kernel space, since a fd could very well + * be 0, so we start at 3. + */ + return ret + 3; } diff --git a/ukl/unistd/close.c b/ukl/unistd/close.c @@ -1,18 +1,19 @@ #include <unistd.h> #include <linux/syscalls.h> +#include <ukl/ukl_internals.h> + int close(int fd) { - if (fd >= 0 && fd <= 2) - { - printk(KERN_ERR "Trying to call close() with %d file descriptor\n", fd); - return -EINVAL; - } + if (fd >= 0 && fd <= 2) { + UKL_BAD_FD("close", fd); + return -EINVAL; + } - /** - * Little trick used to mock stdin, stdout and stderr for UKL - * Don't make any sense in kernel space, since a fd could very well - * be 0. - */ - return ksys_close(fd - 3); + /* + * Little trick used to mock stdin, stdout and stderr for UKL + * Don't make any sense in kernel space, since a fd could very well + * be 0. + */ + return ksys_close(fd - 3); } diff --git a/ukl/unistd/read.c b/ukl/unistd/read.c @@ -1,21 +1,22 @@ #include <unistd.h> #include <linux/syscalls.h> +#include <ukl/ukl_internals.h> + ssize_t read(int fd, void *buf, size_t count) { - /* We don't support pipe, stdin, stdout or stderr reading */ - if (fd >= 0 && fd <= 2) - { - printk(KERN_ERR "Trying to call read() with %d file descriptor\n", fd); - return -EINVAL; - } + /* We don't support pipe, stdin, stdout or stderr reading */ + if (fd >= 0 && fd <= 2) { + UKL_BAD_FD("read", fd); + return -EINVAL; + } - /** - * Little trick used to mock stdin, stdout and stderr for UKL - * Don't make any sense in kernel space, since a fd could very well - * be 0. - */ - fd -= 3; + /* + * Little trick used to mock stdin, stdout and stderr for UKL + * Don't make any sense in kernel space, since a fd could very well + * be 0. + */ + fd -= 3; - return ksys_read(fd, buf, count); + return ksys_read(fd, buf, count); } diff --git a/ukl/unistd/write.c b/ukl/unistd/write.c @@ -2,110 +2,106 @@ #include <linux/syscalls.h> #include <linux/console.h> +#include <ukl/ukl_internals.h> + static DEFINE_RAW_SPINLOCK(console_owner_lock); -static struct task_struct *console_owner; -static bool console_waiter; +static struct task_struct *console_owner; +static bool console_waiter; #ifdef CONFIG_LOCKDEP -static struct lockdep_map console_owner_dep_map = { - .name = "console_owner" -}; +static struct lockdep_map console_owner_dep_map = { .name = "console_owner" }; #endif /* CONFIG_LOCKDEP */ static void console_lock_spinning_enable(void) { - /* Lock, save the current thread as the console owner, and unlock */ - raw_spin_lock(&console_owner_lock); - console_owner = current; - raw_spin_unlock(&console_owner_lock); + /* Lock, save the current thread as the console owner, and unlock */ + raw_spin_lock(&console_owner_lock); + console_owner = current; + raw_spin_unlock(&console_owner_lock); - /* Take the console lock */ - spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); + /* Take the console lock */ + spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); } static int console_lock_spinning_disable_and_check(void) { - int waiter; + int waiter; - /* Lock, atomically set the waiter, reset the console owner, and unlock */ - raw_spin_lock(&console_owner_lock); - waiter = READ_ONCE(console_waiter); - console_owner = NULL; - raw_spin_unlock(&console_owner_lock); + /* Lock, atomically set the waiter, reset the console owner, and unlock */ + raw_spin_lock(&console_owner_lock); + waiter = READ_ONCE(console_waiter); + console_owner = NULL; + raw_spin_unlock(&console_owner_lock); - /* No waiters, release the spin lock */ - if (!waiter) - { - spin_release(&console_owner_dep_map, 1, _THIS_IP_); - return 0; - } + /* No waiters, release the spin lock */ + if (!waiter) { + spin_release(&console_owner_dep_map, 1, _THIS_IP_); + return 0; + } - /* The waiter is now free to continue */ - WRITE_ONCE(console_waiter, false); + /* The waiter is now free to continue */ + WRITE_ONCE(console_waiter, false); - spin_release(&console_owner_dep_map, 1, _THIS_IP_); + spin_release(&console_owner_dep_map, 1, _THIS_IP_); - /* - * Hand off console_lock to waiter. The waiter will perform - * the up(). After this, the waiter is the console_lock owner. - */ - mutex_release(&console_lock_dep_map, 1, _THIS_IP_); + /* + * Hand off console_lock to waiter. The waiter will perform + * the up(). After this, the waiter is the console_lock owner. + */ + mutex_release(&console_lock_dep_map, 1, _THIS_IP_); - return 1; + return 1; } static void write_to_console(const char *buf, size_t count) { - struct console *con; - - /* No console drives to speak of */ - if (!console_drivers) - return; - - /* For each known console */ - for_each_console(con) - { - /* Console is not enabled */ - if (!(con->flags & CON_ENABLED)) - continue; - - /* Cannot write to this console */ - if (!con->write) - continue; - - /* CPU is not ready */ - if (!cpu_online(smp_processor_id()) && - !(con->flags & CON_ANYTIME)) - continue; - else - con->write(con, buf, count); - } + struct console *con; + + /* No console drives to speak of */ + if (!console_drivers) + return; + + /* For each known console */ + for_each_console (con) { + /* Console is not enabled */ + if (!(con->flags & CON_ENABLED)) + continue; + + /* Cannot write to this console */ + if (!con->write) + continue; + + /* CPU is not ready */ + if (!cpu_online(smp_processor_id()) && + !(con->flags & CON_ANYTIME)) + continue; + else + con->write(con, buf, count); + } } ssize_t write(int fd, const void *buf, size_t count) { - /* We don't support pipe writing in KSpace */ - if (fd == 0) - { - printk(KERN_WARNING "Attempt to write to fd 0!\n"); - return 0; - } - - /** - * Writing to stdout or stderr, that don't exist in KSpace, - * so write them directly to the console. - */ - if (fd == 1 || fd == 2) - { - /* Take the console lock, write and release the lock */ - console_lock_spinning_enable(); - write_to_console(buf, count); - console_lock_spinning_disable_and_check(); - } - - /** - * Little trick used to mock stdin, stdout and stderr for UKL - * Don't make any sense in kernel space, since a fd could very well - * be 0. - */ - return ksys_write(fd - 3, buf, count); + /* We don't support pipe writing in KSpace */ + if (fd == 0) { + UKL_BAD_FD("write", 0); + return -EINVAL; + } + + /* + * Writing to stdout or stderr, that don't exist in KSpace, + * so write them directly to the console. + */ + if (fd == 1 || fd == 2) { + /* Take the console lock, write and release the lock */ + console_lock_spinning_enable(); + write_to_console(buf, count); + console_lock_spinning_disable_and_check(); + } + + /* + * Little trick used to mock stdin, stdout and stderr for UKL + * Don't make any sense in kernel space, since a fd could very well + * be 0. + */ + return ksys_write(fd - 3, buf, count); }