From bc16e5b71821d8ba796a643dcbbfd9a6fdc3b170 Mon Sep 17 00:00:00 2001 From: Hajime Tazaki Date: Sat, 5 Dec 2015 00:55:18 +0900 Subject: [PATCH] lkl: add new API, LKL system call API, for POSIX userspace applications This commit introduce new userspace API, prefixed lkl_sys_wrapper_(), which preserves the same signature with what the (ordinal) system call wrapper API has. Function arguments signatures are same as LKL system call API (i.e., lkl_sys_xxx()), but the return values are different: upon errors happened, LKL system call API returns a negative value which kernel functions returns where this new API returns -1 and set error value by newly introduce host_ops callback entry, ops->seterrno(). Signed-off-by: Hajime Tazaki --- arch/lkl/Makefile | 2 +- arch/lkl/include/uapi/asm/host_ops.h | 2 + arch/lkl/include/uapi/asm/syscalls.h | 58 ++++++++++++++++++++++------ arch/lkl/kernel/setup.c | 5 +++ tools/lkl/lib/posix-host.c | 7 ++++ 5 files changed, 62 insertions(+), 12 deletions(-) diff --git a/arch/lkl/Makefile b/arch/lkl/Makefile index 5280a5ac90a0fe..c390734e0006c2 100644 --- a/arch/lkl/Makefile +++ b/arch/lkl/Makefile @@ -20,7 +20,7 @@ endif LDFLAGS_vmlinux += -r LKL_ENTRY_POINTS := lkl_start_kernel lkl_sys_halt lkl_syscall lkl_trigger_irq \ - lkl_get_free_irq lkl_put_irq + lkl_get_free_irq lkl_put_irq lkl_get_host_ops core-y += arch/lkl/kernel/ diff --git a/arch/lkl/include/uapi/asm/host_ops.h b/arch/lkl/include/uapi/asm/host_ops.h index e126154cbeaa4b..a963baf4f0c5de 100644 --- a/arch/lkl/include/uapi/asm/host_ops.h +++ b/arch/lkl/include/uapi/asm/host_ops.h @@ -12,6 +12,7 @@ * is provided here for convenience to be implemented by the host library. * * @print - optional operation that receives console messages + * @seterrno - called to set errno for applications in thread local storage. * * @panic - called during a kernel panic * @@ -39,6 +40,7 @@ struct lkl_host_operations { const char *virtio_devices; void (*print)(const char *str, int len); + void (*seterrno)(int); void (*panic)(void); void* (*sem_alloc)(int count); diff --git a/arch/lkl/include/uapi/asm/syscalls.h b/arch/lkl/include/uapi/asm/syscalls.h index 50e5b7c5c3203b..750352271d04be 100644 --- a/arch/lkl/include/uapi/asm/syscalls.h +++ b/arch/lkl/include/uapi/asm/syscalls.h @@ -92,6 +92,7 @@ typedef __s64 s64; #include #include +#include /* Define data structures used in system calls that are not defined in UAPI * headers */ @@ -137,6 +138,16 @@ struct ustat { long lkl_syscall(long no, long *params); long lkl_sys_halt(void); +struct lkl_host_operations *lkl_get_host_ops(void); + +static inline void lkl_host_seterrno(int error) +{ + struct lkl_host_operations *host_ops; + + host_ops = lkl_get_host_ops(); + if (host_ops && host_ops->seterrno) + host_ops->seterrno(error); +} #define __MAP0(m,...) #define __MAP1(m,t,a) m(t,a) @@ -150,19 +161,44 @@ long lkl_sys_halt(void); #define __SC_LONG(t, a) (long)a #define __SC_DECL(t, a) t a -#define LKL_SYSCALL0(name) \ - static inline long lkl_sys_##name(void) \ - { \ - long params[6]; \ - return lkl_syscall(__lkl__NR_##name, params); \ +#define LKL_SYSCALL0(name) \ + static inline long lkl_sys_##name(void) \ + { \ + long params[6]; \ + return lkl_syscall(__lkl__NR_##name, params); \ + }; \ + static inline \ + long lkl_sys_wrapper_##name(void) \ + { \ + int ret; \ + long params[6]; \ + ret = lkl_syscall(__lkl__NR_##name, params); \ + if (ret < 0) { \ + lkl_host_seterrno(ret); \ + ret = -1; \ + } \ + return ret; \ } -#define LKL_SYSCALLx(x, name, ...) \ - static inline \ - long lkl_sys_##name(__MAP(x, __SC_DECL, __VA_ARGS__)) \ - { \ - long params[6] = { __MAP(x, __SC_LONG, __VA_ARGS__) }; \ - return lkl_syscall(__lkl__NR_##name, params); \ + +#define LKL_SYSCALLx(x, name, ...) \ + static inline \ + long lkl_sys_##name(__MAP(x, __SC_DECL, __VA_ARGS__)) \ + { \ + long params[6] = { __MAP(x, __SC_LONG, __VA_ARGS__) }; \ + return lkl_syscall(__lkl__NR_##name, params); \ + } \ + static inline \ + long lkl_sys_wrapper_##name(__MAP(x, __SC_DECL, __VA_ARGS__)) \ + { \ + int ret; \ + long params[6] = { __MAP(x, __SC_LONG, __VA_ARGS__) }; \ + ret = lkl_syscall(__lkl__NR_##name, params); \ + if (ret < 0) { \ + lkl_host_seterrno(ret); \ + ret = -1; \ + } \ + return ret; \ } #define SYSCALL_DEFINE0(name, ...) LKL_SYSCALL0(name) diff --git a/arch/lkl/kernel/setup.c b/arch/lkl/kernel/setup.c index 35d9f269af0d5d..f1cb5aa2c71b0e 100644 --- a/arch/lkl/kernel/setup.c +++ b/arch/lkl/kernel/setup.c @@ -104,6 +104,11 @@ int __init lkl_start_kernel(struct lkl_host_operations *ops, return ret; } +struct lkl_host_operations *lkl_get_host_ops(void) +{ + return lkl_ops; +} + void machine_halt(void) { halt = true; diff --git a/tools/lkl/lib/posix-host.c b/tools/lkl/lib/posix-host.c index 1d2a7b1508422a..58e4145365a4e6 100644 --- a/tools/lkl/lib/posix-host.c +++ b/tools/lkl/lib/posix-host.c @@ -22,6 +22,12 @@ static void print(const char *str, int len) ret = write(STDOUT_FILENO, str, len); } +static void seterrno(int error) +{ + /* LKL to Linux translation (assuming posix-host is Linux */ + errno = -error; +} + struct pthread_sem { pthread_mutex_t lock; int count; @@ -156,6 +162,7 @@ struct lkl_host_operations lkl_host_ops = { .ioremap = lkl_ioremap, .iomem_access = lkl_iomem_access, .virtio_devices = lkl_virtio_devs, + .seterrno = seterrno }; int fd_get_capacity(union lkl_disk_backstore bs, unsigned long long *res)