[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH 4/6] lib/syscall_shim: Raw system calls



Reviewed-by: Gaulthier Gain <gaulthier.gain@xxxxxxxxx>

> On 11 Dec 2019, at 15:19, Simon Kuenzer <simon.kuenzer@xxxxxxxxx> wrote:
> 
> This patch introduces the concept for distinguishing system call
> implementations: libc-style and raw. These concepts differentiate how
> error handling is implemented: "libc-style" handlers return -1 and set
> errno to corresponding error code. "Raw" handlers return negative
> error codes and never touch errno. To simplify implementation, the
> commit introduces a set of macros: `UK_SYSCALL_DEFINE` and
> `UK_SYSCALL_R_DEFINE`. These macros automatically create wrappers so
> that each system call handler is available in both styles; independent
> of its implementation style. Both macros will also provide the
> libc-wrapper.
> It is intended that the compile option: "Dropping unused functions and
> symbols" should be used to remove all system call versions from the
> final binary that are not in use. This commit also provides
> uk_syscall_r() as a raw equivalent to uk_syscall() (libc-style).
> 
> Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> ---
> lib/syscall_shim/Makefile.uk                  |  17 +-
> lib/syscall_shim/gen_provided.awk             |   5 +-
> lib/syscall_shim/gen_stubs.awk                |   8 +-
> lib/syscall_shim/gen_syscall_map.awk          |   3 +-
> .../{gen_entry.awk => gen_uk_syscall.awk}     |   7 +-
> lib/syscall_shim/gen_uk_syscall_r.awk         |  39 +++++
> lib/syscall_shim/include/uk/syscall.h         | 158 +++++++++++++-----
> .../{entry.c.in_end => uk_syscall.c.in_end}   |   2 +-
> lib/syscall_shim/uk_syscall_r.c.in_end        |  15 ++
> lib/vfscore/exportsyms.uk                     |   3 +-
> lib/vfscore/main.c                            |   9 +-
> 11 files changed, 196 insertions(+), 70 deletions(-)
> rename lib/syscall_shim/{gen_entry.awk => gen_uk_syscall.awk} (77%)
> create mode 100644 lib/syscall_shim/gen_uk_syscall_r.awk
> rename lib/syscall_shim/{entry.c.in_end => uk_syscall.c.in_end} (84%)
> create mode 100644 lib/syscall_shim/uk_syscall_r.c.in_end
> 
> diff --git a/lib/syscall_shim/Makefile.uk b/lib/syscall_shim/Makefile.uk
> index 015e3aad..7afa2014 100644
> --- a/lib/syscall_shim/Makefile.uk
> +++ b/lib/syscall_shim/Makefile.uk
> @@ -8,7 +8,8 @@ LIBSYSCALL_SHIM_PHONY_SRC += 
> $(LIBSYSCALL_SHIM_BUILD)/provided_syscalls.h.in
> LIBSYSCALL_SHIM_PHONY_SRC_NEW := $(addsuffix .new, 
> $(LIBSYSCALL_SHIM_PHONY_SRC))
> 
> LIBSYSCALL_SHIM_GEN_SRC := 
> $(LIBSYSCALL_SHIM_INCLUDES_PATH)/provided_syscalls.h
> -LIBSYSCALL_SHIM_GEN_SRC += $(LIBSYSCALL_SHIM_BUILD)/syscall_entry.c
> +LIBSYSCALL_SHIM_GEN_SRC += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall.c
> +LIBSYSCALL_SHIM_GEN_SRC += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_r.c
> LIBSYSCALL_SHIM_GEN_SRC += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_name.c
> LIBSYSCALL_SHIM_GEN_SRC += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_name_p.c
> 
> @@ -40,10 +41,15 @@ $(LIBSYSCALL_SHIM_INCLUDES_PATH)/provided_syscalls.h: 
> $(LIBSYSCALL_SHIM_BASE)/ge
>               $(AWK) -F '-' -f  $(LIBSYSCALL_SHIM_BASE)/gen_provided.awk \
>               $(LIBSYSCALL_SHIM_BUILD)/provided_syscalls.h.in > $@)
> 
> -$(LIBSYSCALL_SHIM_BUILD)/syscall_entry.c: 
> $(LIBSYSCALL_SHIM_BUILD)/provided_syscalls.h.in 
> $(LIBSYSCALL_SHIM_BASE)/gen_entry.awk $(LIBSYSCALL_SHIM_BASE)/entry.c.in_end
> +$(LIBSYSCALL_SHIM_BUILD)/uk_syscall.c: 
> $(LIBSYSCALL_SHIM_BUILD)/provided_syscalls.h.in 
> $(LIBSYSCALL_SHIM_BASE)/gen_uk_syscall.awk 
> $(LIBSYSCALL_SHIM_BASE)/uk_syscall.c.in_end
>       $(call build_cmd,GEN,libsyscall_shim,$(notdir $@), \
> -             $(AWK) -F '-' -f $(LIBSYSCALL_SHIM_BASE)/gen_entry.awk $< > $@ 
> && \
> -             cat $(LIBSYSCALL_SHIM_BASE)/entry.c.in_end >> $@)
> +             $(AWK) -F '-' -f $(LIBSYSCALL_SHIM_BASE)/gen_uk_syscall.awk $< 
> > $@ && \
> +             cat $(LIBSYSCALL_SHIM_BASE)/uk_syscall.c.in_end >> $@)
> +
> +$(LIBSYSCALL_SHIM_BUILD)/uk_syscall_r.c: 
> $(LIBSYSCALL_SHIM_BUILD)/provided_syscalls.h.in 
> $(LIBSYSCALL_SHIM_BASE)/gen_uk_syscall_r.awk 
> $(LIBSYSCALL_SHIM_BASE)/uk_syscall_r.c.in_end
> +     $(call build_cmd,GEN,libsyscall_shim,$(notdir $@), \
> +             $(AWK) -F '-' -f $(LIBSYSCALL_SHIM_BASE)/gen_uk_syscall_r.awk 
> $< > $@ && \
> +             cat $(LIBSYSCALL_SHIM_BASE)/uk_syscall_r.c.in_end >> $@)
> 
> $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_name.c: 
> $(LIBSYSCALL_SHIM_BASE)/gen_uk_syscall_name.awk $(LIBSYSCALL_SHIM_TEMPL)
>       $(call build_cmd,GEN,libsyscall_shim,$(notdir $@), \
> @@ -68,7 +74,8 @@ CXXINCLUDES-$(CONFIG_LIBSYSCALL_SHIM) += 
> -I$(LIBSYSCALL_SHIM_BUILD)/include
> CINCLUDES-y   += -I$(LIBSYSCALL_SHIM_BASE)/include
> CXXINCLUDES-y += -I$(LIBSYSCALL_SHIM_BASE)/include
> 
> -LIBSYSCALL_SHIM_SRCS-y += $(LIBSYSCALL_SHIM_BUILD)/syscall_entry.c
> +LIBSYSCALL_SHIM_SRCS-y += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall.c
> +LIBSYSCALL_SHIM_SRCS-y += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_r.c
> LIBSYSCALL_SHIM_SRCS-y += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_name.c
> LIBSYSCALL_SHIM_SRCS-y += $(LIBSYSCALL_SHIM_BUILD)/uk_syscall_name_p.c
> 
> diff --git a/lib/syscall_shim/gen_provided.awk 
> b/lib/syscall_shim/gen_provided.awk
> index 0810893b..f2d648ad 100644
> --- a/lib/syscall_shim/gen_provided.awk
> +++ b/lib/syscall_shim/gen_provided.awk
> @@ -1,5 +1,6 @@
> BEGIN {print "/* Automatically generated file; DO NOT EDIT */"}
> /[a-zA-Z0-9]+-[0-9]+/{
> -     printf "\n#define HAVE_uk_syscall_%s t", $1;
> -     printf "\nUK_SYSCALL_PROTO(%s, %s);\n", $2, $1;
> +     printf "\n#define HAVE_uk_syscall_%s t\n", $1;
> +     printf "UK_SYSCALL_E_PROTO(%s, %s);\n", $2, $1;
> +     printf "UK_SYSCALL_R_PROTO(%s, %s);\n", $2, $1;
> }
> diff --git a/lib/syscall_shim/gen_stubs.awk b/lib/syscall_shim/gen_stubs.awk
> index de136f18..a9371265 100644
> --- a/lib/syscall_shim/gen_stubs.awk
> +++ b/lib/syscall_shim/gen_stubs.awk
> @@ -1,8 +1,8 @@
> BEGIN { print "/* Auto generated file. Do not edit */" }
> /#define __NR_/ {
>       name = substr($2,6);
> -     uk_name = "uk_syscall_" name
> -     printf "\n#ifndef HAVE_%s", uk_name;
> -     printf "\n#define %s(...) uk_syscall_stub(\"%s\")", uk_name, name;
> -     printf "\n#endif /* HAVE_%s */\n", uk_name;
> +     printf "\n#ifndef HAVE_uk_syscall_%s", name;
> +     printf "\n#define uk_syscall_e_%s(...) uk_syscall_e_stub(\"%s\")", 
> name, name;
> +     printf "\n#define uk_syscall_r_%s(...) uk_syscall_r_stub(\"%s\")", 
> name, name;
> +     printf "\n#endif /* !HAVE_uk_syscall_%s */\n", name;
> }
> diff --git a/lib/syscall_shim/gen_syscall_map.awk 
> b/lib/syscall_shim/gen_syscall_map.awk
> index 99b247dd..b65a0007 100644
> --- a/lib/syscall_shim/gen_syscall_map.awk
> +++ b/lib/syscall_shim/gen_syscall_map.awk
> @@ -1,4 +1,5 @@
> BEGIN {print "/* Automatically generated file; DO NOT EDIT */\n"}
> /#define __NR_/{
> -     printf "#define uk_syscall_fn_%s(...) uk_syscall_%s(__VA_ARGS__)\n", 
> $3,substr($2,6)
> +     printf "#define uk_syscall_fn_%s(...)   
> uk_syscall_e_%s(__VA_ARGS__)\n", $3,substr($2,6)
> +     printf "#define uk_syscall_r_fn_%s(...) 
> uk_syscall_r_%s(__VA_ARGS__)\n", $3,substr($2,6)
> }
> diff --git a/lib/syscall_shim/gen_entry.awk 
> b/lib/syscall_shim/gen_uk_syscall.awk
> similarity index 77%
> rename from lib/syscall_shim/gen_entry.awk
> rename to lib/syscall_shim/gen_uk_syscall.awk
> index 92457089..2f2e1fa9 100644
> --- a/lib/syscall_shim/gen_entry.awk
> +++ b/lib/syscall_shim/gen_uk_syscall.awk
> @@ -5,7 +5,7 @@ BEGIN {
>       print "#include <uk/syscall.h>"
>       print "#include <uk/print.h>\n"
> 
> -     printf "static inline long __syscall_dynamic(long nr, "
> +     printf "static inline long __uk_syscall(long nr, "
>       for (i = 1; i < max_args; i++)
>               printf "long arg%d, ",i
>       printf "long arg%d)\n{\n", max_args
> @@ -20,10 +20,9 @@ BEGIN {
> /[a-zA-Z0-9]+-[0-9]+/{
>       name = $1
>       sys_name = "SYS_" name
> -     uk_name = "uk_syscall_" name
>       args_nr = $2 + 0
>       printf "\tcase %s:\n", sys_name;
> -     printf "\t\treturn %s(", uk_name;
> +     printf "\t\treturn uk_syscall_e_%s(", name;
>       for (i = 1; i < args_nr; i++)
>               printf("arg%d, ", i)
>       if (args_nr > 0)
> @@ -33,7 +32,7 @@ BEGIN {
> 
> END {
>       printf "\tdefault:\n"
> -     printf "\t\tuk_pr_debug(\"syscall nr %%ld is not implemented\", nr);\n"
> +     printf "\t\tuk_pr_debug(\"syscall \\\"%%s\\\" is not available\\n\", 
> uk_syscall_name(nr));\n"
>       printf "\t\terrno = -ENOSYS;\n"
>       printf "\t\treturn -1;\n"
>       printf "\t}\n}\n"
> diff --git a/lib/syscall_shim/gen_uk_syscall_r.awk 
> b/lib/syscall_shim/gen_uk_syscall_r.awk
> new file mode 100644
> index 00000000..c591fc47
> --- /dev/null
> +++ b/lib/syscall_shim/gen_uk_syscall_r.awk
> @@ -0,0 +1,39 @@
> +BEGIN {
> +     max_args = 6
> +     print "/* Auto generated file. DO NOT EDIT */\n\n"
> +
> +     print "#include <uk/syscall.h>"
> +     print "#include <uk/print.h>\n"
> +
> +     printf "static inline long __uk_syscall_r(long nr, "
> +     for (i = 1; i < max_args; i++)
> +             printf "long arg%d, ",i
> +     printf "long arg%d)\n{\n", max_args
> +
> +     for (i = 1; i <= max_args; i++)
> +             printf "\t(void) arg%d;\n", i
> +
> +     print "\n\tswitch (nr) {"
> +}
> +
> +
> +/[a-zA-Z0-9]+-[0-9]+/{
> +     name = $1
> +     sys_name = "SYS_" name
> +     uk_syscall_r = "uk_syscall_r_" name
> +     args_nr = $2 + 0
> +     printf "\tcase %s:\n", sys_name;
> +     printf "\t\treturn %s(", uk_syscall_r;
> +     for (i = 1; i < args_nr; i++)
> +             printf("arg%d, ", i)
> +     if (args_nr > 0)
> +             printf("arg%d", args_nr)
> +     printf(");\n")
> +}
> +
> +END {
> +     printf "\tdefault:\n"
> +     printf "\t\tuk_pr_debug(\"syscall \\\"%%s\\\" is not available\\n\", 
> uk_syscall_name(nr));\n"
> +     printf "\t\treturn -ENOSYS;\n"
> +     printf "\t}\n}\n"
> +}
> diff --git a/lib/syscall_shim/include/uk/syscall.h 
> b/lib/syscall_shim/include/uk/syscall.h
> index 54946119..cd5c6e67 100644
> --- a/lib/syscall_shim/include/uk/syscall.h
> +++ b/lib/syscall_shim/include/uk/syscall.h
> @@ -46,6 +46,8 @@ typedef long uk_syscall_arg_t;
> 
> #define __uk_syscall_fn(syscall_nr, ...) \
>       UK_CONCAT(uk_syscall_fn_, syscall_nr) (__VA_ARGS__)
> +#define __uk_syscall_r_fn(syscall_nr, ...) \
> +     UK_CONCAT(uk_syscall_r_fn_, syscall_nr) (__VA_ARGS__)
> 
> #define __uk_syscall0(n) __uk_syscall_fn(n)
> #define __uk_syscall1(n,a) __uk_syscall_fn(n,__uk_scc(a))
> @@ -56,6 +58,14 @@ typedef long uk_syscall_arg_t;
> #define __uk_syscall6(n,a,b,c,d,e,f) 
> __uk_syscall_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e),__uk_scc(f))
> #define __uk_syscall7(n,a,b,c,d,e,f,g) 
> __uk_syscall_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e),__uk_scc(f),__uk_scc(g))
> 
> +#define __uk_syscall0_r(n) __uk_syscall_r_fn(n)
> +#define __uk_syscall1_r(n,a) __uk_syscall_r_fn(n,__uk_scc(a))
> +#define __uk_syscall2_r(n,a,b) __uk_syscall_r_fn(n,__uk_scc(a),__uk_scc(b))
> +#define __uk_syscall3_r(n,a,b,c) 
> __uk_syscall_r_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c))
> +#define __uk_syscall4_r(n,a,b,c,d) 
> __uk_syscall_r_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d))
> +#define __uk_syscall5_r(n,a,b,c,d,e) 
> __uk_syscall_r_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e))
> +#define __uk_syscall6_r(n,a,b,c,d,e,f) 
> __uk_syscall_r_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e),__uk_scc(f))
> +#define __uk_syscall7_r(n,a,b,c,d,e,f,g) 
> __uk_syscall_r_fn(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e),__uk_scc(f),__uk_scc(g))
> 
> #define __UK_SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
> #define __UK_SYSCALL_NARGS(...) 
> __UK_SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
> @@ -63,7 +73,8 @@ typedef long uk_syscall_arg_t;
> #define __UK_SYSCALL_DEF_NARGS_X(z, a1,a2, b1,b2, c1,c2, d1,d2, e1,e2, f1,f2, 
> g1,g2, nr, ...) nr
> #define __UK_SYSCALL_DEF_NARGS(...) __UK_SYSCALL_DEF_NARGS_X(__VA_ARGS__, 
> 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1,0)
> 
> -#define __UK_NAME2SCALL_FN(name) UK_CONCAT(uk_syscall_, name)
> +#define __UK_NAME2SCALLE_FN(name) UK_CONCAT(uk_syscall_e_, name)
> +#define __UK_NAME2SCALLR_FN(name) UK_CONCAT(uk_syscall_r_, name)
> 
> #define UK_ARG_MAP1(m, type, arg) m(type, arg)
> #define UK_ARG_MAP2(m, type, arg, ...) m(type, arg), UK_ARG_MAP1(m, 
> __VA_ARGS__)
> @@ -74,49 +85,86 @@ typedef long uk_syscall_arg_t;
> #define UK_ARG_MAP7(m, type, arg, ...) m(type, arg), UK_ARG_MAP6(m, 
> __VA_ARGS__)
> #define UK_ARG_MAPx(nr_args, ...) UK_CONCAT(UK_ARG_MAP, nr_args)(__VA_ARGS__)
> 
> -#define UK_S_ARG_LONG(type, arg)   unsigned long arg
> +#define UK_S_ARG_LONG(type, arg)   long arg
> #define UK_S_ARG_ACTUAL(type, arg) type arg
> -#define UK_S_ARG_CAST(type, arg)   (type) arg
> +#define UK_S_ARG_CAST_LONG(type, arg)   (long) arg
> +#define UK_S_ARG_CAST_ACTUAL(type, arg) (type) arg
> 
> -
> -/* NOTE and TODO:
> - *   Currently all the functions in unikraft which are mimicking
> - *   libc behavior (writev, open, mount, etc) are handling 'errno'
> - *   on their own. To comply with that syscall_shim expects syscall
> - *   implementation to set errno, and return 0 in case of success
> - *   or -1 (or whatever the man page says) in case of failure.
> - *
> - *   This has to be reconsidered later. The corresponding functions
> - *   in unikraft should not touch errno, and syscall_shim should
> - *   provide 2 syscall functions - one that handles return and the
> - *   one which does not.
> - *
> - *   A good reference would be musl implementation.
> +/* System call implementation that uses errno and returns -1 on errors */
> +/* TODO: `void` as return type is currently not supported.
> + * NOTE: Workaround is to use `int` instead.
> */
> -#ifdef CONFIG_LIBSYSCALL_SHIM
> -#define __UK_SYSCALL_DEFINE(x, name, ...)                            \
> -     static inline long __##name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,     \
> -                                             __VA_ARGS__));          \
> -     long name(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))           \
> +#define __UK_SYSCALL_DEFINE(x, rtype, name, ename, rname, ...)               
> \
> +     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__));       \
> +     long rname(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
>       {                                                               \
> -             long ret = __##name(                                    \
> -                     UK_ARG_MAPx(x, UK_S_ARG_CAST, __VA_ARGS__));    \
> +             int _errno = errno;                                     \
> +             long ret;                                               \
> +                                                                     \
> +             errno = 0;                                              \
> +             ret = (long) name(                                      \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
> +             if (ret == -1)                                          \
> +                     ret = errno ? -errno : -EFAULT;                 \
> +             errno = _errno;                                         \
>               return ret;                                             \
>       }                                                               \
> -     static inline long __##name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,     \
> -                                             __VA_ARGS__))
> -#else
> -#define __UK_SYSCALL_DEFINE(x, name, ...)                            \
> -     static inline long name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))
> -#endif
> -
> +     long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
> +     {                                                               \
> +             return (long) name(                                     \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
> +     }                                                               \
> +     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))
> #define _UK_SYSCALL_DEFINE(...) __UK_SYSCALL_DEFINE(__VA_ARGS__)
> -#define UK_SYSCALL_DEFINE(name, ...)                         \
> -     _UK_SYSCALL_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__), \
> -                         __UK_NAME2SCALL_FN(name),           \
> -                         __VA_ARGS__)
> -
> -#define __UK_SPROTO_ARGS_TYPE unsigned long
> +#define UK_SYSCALL_DEFINE(rtype, name, ...)                         \
> +     _UK_SYSCALL_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),        \
> +                        rtype,                                      \
> +                        name,                                       \
> +                        __UK_NAME2SCALLE_FN(name),                  \
> +                        __UK_NAME2SCALLR_FN(name),                  \
> +                        __VA_ARGS__)
> +
> +/* Raw system call implementation that is returning negative codes on errors 
> */
> +/* TODO: `void` as return type is currently not supported.
> + * NOTE: Workaround is to use `int` instead.
> + */
> +#define __UK_SYSCALL_R_DEFINE(x, rtype, name, ename, rname, ...)     \
> +     long rname(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
> +     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))        \
> +     {                                                               \
> +             long ret = rname(                                       \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
> +             if (ret < 0) {                                          \
> +                     errno = (int) -ret;                             \
> +                     return (rtype) -1;                              \
> +             }                                                       \
> +             return (rtype) ret;                                     \
> +     }                                                               \
> +     long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
> +     {                                                               \
> +             return (long) name(                                     \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
> +     }                                                               \
> +     static inline long __##rname(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,    \
> +                                              __VA_ARGS__));         \
> +     long rname(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
> +     {                                                               \
> +             return __##rname(                                       \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
> +     }                                                               \
> +     static inline long __##rname(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,    \
> +                                              __VA_ARGS__))
> +#define _UK_SYSCALL_R_DEFINE(...) __UK_SYSCALL_R_DEFINE(__VA_ARGS__)
> +#define UK_SYSCALL_R_DEFINE(rtype, name, ...)                                
> \
> +     _UK_SYSCALL_R_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),       \
> +                          rtype,                                     \
> +                          name,                                      \
> +                          __UK_NAME2SCALLE_FN(name),                 \
> +                          __UK_NAME2SCALLR_FN(name),                 \
> +                          __VA_ARGS__)
> +
> +
> +#define __UK_SPROTO_ARGS_TYPE long
> #define __UK_SPROTO_ARGS0()  void
> #define __UK_SPROTO_ARGS1()  __UK_SPROTO_ARGS_TYPE a
> #define __UK_SPROTO_ARGS2()  __UK_SPROTO_ARGS1(), __UK_SPROTO_ARGS_TYPE b
> @@ -128,15 +176,22 @@ typedef long uk_syscall_arg_t;
> #define __UK_SPROTO_ARGSx(args_nr)  \
>       UK_CONCAT(__UK_SPROTO_ARGS, args_nr)()
> 
> -#define UK_SYSCALL_PROTO(args_nr, syscall_name)                      \
> -     long __UK_NAME2SCALLE_FN(syscall_name)(                 \
> -             __UK_SPROTO_ARGSx(args_nr))
> +#define UK_SYSCALL_E_PROTO(args_nr, syscall_name)                    \
> +     long __UK_NAME2SCALLE_FN(syscall_name)(__UK_SPROTO_ARGSx(args_nr))
> +#define UK_SYSCALL_R_PROTO(args_nr, syscall_name)                    \
> +     long __UK_NAME2SCALLR_FN(syscall_name)(__UK_SPROTO_ARGSx(args_nr))
> 
> -#define uk_syscall_stub(syscall_name) ({                     \
> -                     uk_pr_debug("syscall \"" syscall_name   \
> -                                 "\" is not implemented\n"); \
> -                     errno = -ENOSYS;                        \
> -                     -1;                                     \
> +#define uk_syscall_e_stub(syscall_name) ({                           \
> +                     uk_pr_debug("System call \"" syscall_name       \
> +                                 "\" is not available (-ENOSYS)\n"); \
> +                     errno = -ENOSYS;                                \
> +                     -1;                                             \
> +             })
> +
> +#define uk_syscall_r_stub(syscall_name) ({                           \
> +                     uk_pr_debug("System call \"" syscall_name       \
> +                                 "\" is not available (-ENOSYS)\n"); \
> +                     -ENOSYS;                                        \
>               })
> 
> 
> @@ -146,6 +201,7 @@ typedef long uk_syscall_arg_t;
> #include <uk/bits/provided_syscalls.h>
> #include <uk/bits/syscall_stubs.h>
> 
> +/* System call, returns -1 and sets errno on errors */
> long uk_syscall(long n, ...);
> 
> /*
> @@ -156,6 +212,18 @@ long uk_syscall(long n, ...);
> #define uk_syscall_static(...)                                                
> \
>       UK_CONCAT(__uk_syscall, __UK_SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
> 
> +/* Raw system call, returns negative codes on errors */
> +long uk_syscall_r(long n, ...);
> +
> +/*
> + * Use this variant instead of `uk_syscall_r()` whenever the system call 
> number
> + * is a constant. This macro maps the function call directly to the target
> + * handler instead of doing a look-up at runtime
> + */
> +#define uk_syscall_r_static(...)                                     \
> +     UK_CONCAT(__uk_syscall,                                         \
> +               UK_CONCAT(__UK_SYSCALL_NARGS(__VA_ARGS__)), _r)(__VA_ARGS__)
> +
> /**
> * Returns a string with the name of the system call number `nr`.
> *
> diff --git a/lib/syscall_shim/entry.c.in_end 
> b/lib/syscall_shim/uk_syscall.c.in_end
> similarity index 84%
> rename from lib/syscall_shim/entry.c.in_end
> rename to lib/syscall_shim/uk_syscall.c.in_end
> index 78cb96ad..79a8b7fd 100644
> --- a/lib/syscall_shim/entry.c.in_end
> +++ b/lib/syscall_shim/uk_syscall.c.in_end
> @@ -11,5 +11,5 @@ long uk_syscall(long n, ...)
>       e=va_arg(ap, long);
>       f=va_arg(ap, long);
>       va_end(ap);
> -     return __syscall_dynamic(n,a,b,c,d,e,f);
> +     return __uk_syscall(n,a,b,c,d,e,f);
> }
> diff --git a/lib/syscall_shim/uk_syscall_r.c.in_end 
> b/lib/syscall_shim/uk_syscall_r.c.in_end
> new file mode 100644
> index 00000000..f2b9fc8e
> --- /dev/null
> +++ b/lib/syscall_shim/uk_syscall_r.c.in_end
> @@ -0,0 +1,15 @@
> +
> +long uk_syscall_r(long n, ...)
> +{
> +     va_list ap;
> +     long a,b,c,d,e,f;
> +     va_start(ap, n);
> +     a=va_arg(ap, long);
> +     b=va_arg(ap, long);
> +     c=va_arg(ap, long);
> +     d=va_arg(ap, long);
> +     e=va_arg(ap, long);
> +     f=va_arg(ap, long);
> +     va_end(ap);
> +     return __uk_syscall_r(n,a,b,c,d,e,f);
> +}
> diff --git a/lib/vfscore/exportsyms.uk b/lib/vfscore/exportsyms.uk
> index 2b8bd43d..d3ebf547 100644
> --- a/lib/vfscore/exportsyms.uk
> +++ b/lib/vfscore/exportsyms.uk
> @@ -76,7 +76,8 @@ faccessat
> readlink
> fallocate
> lseek
> -uk_syscall_writev
> +uk_syscall_e_writev
> +uk_syscall_r_writev
> umask
> dentry_alloc
> dentry_init
> diff --git a/lib/vfscore/main.c b/lib/vfscore/main.c
> index cf84a0e0..b9abe1ef 100644
> --- a/lib/vfscore/main.c
> +++ b/lib/vfscore/main.c
> @@ -444,13 +444,8 @@ ssize_t pwritev(int fd, const struct iovec *iov, int 
> iovcnt, off_t offset)
> }
> LFS64(pwritev);
> 
> -ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
> -{
> -     return pwritev(fd, iov, iovcnt, -1);
> -}
> -
> -UK_SYSCALL_DEFINE(writev, unsigned long, fd, const struct iovec *, vec,
> -               unsigned long, vlen)
> +UK_SYSCALL_DEFINE(ssize_t, writev,
> +               int, fd, const struct iovec *, vec, int, vlen)
> {
>       return pwritev(fd, vec, vlen, -1);
> }
> -- 
> 2.20.1
> 


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.