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

Re: [Minios-devel] [UNIKRAFT PATCH v2 1/5] lib/syscall_shim: UK_LLSYSCALL_(R_)_DEFINE variants



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

> On 3 Apr 2020, at 18:29, Simon Kuenzer <simon.kuenzer@xxxxxxxxx> wrote:
> 
> Some system calls have different signatures and return types on the
> libC API and the Linux system call ABI (e.g., brk, mount). In order
> to support implementing such libc-style wrappers manually on top of
> the syscall_shim library, we introduce so called low-level variants
> for the UK_SYSCALL_(R_)_DEFINE macros that only provide the
> uk_syscall_(e|r)_<syscall name> symbols: UK_LLSYSCALL_(R_)_DEFINE
> 
> Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
> ---
> doc/guides/developers-app.rst         | 35 ++++++++++-
> lib/syscall_shim/include/uk/syscall.h | 91 ++++++++++++++++++++-------
> 2 files changed, 102 insertions(+), 24 deletions(-)
> 
> diff --git a/doc/guides/developers-app.rst b/doc/guides/developers-app.rst
> index 6438333c..a7242e60 100644
> --- a/doc/guides/developers-app.rst
> +++ b/doc/guides/developers-app.rst
> @@ -428,10 +428,39 @@ Both macros create the following three symbols:
>     <return_type> <syscall_name>(<arg1_type> <arg1_name>,
>                                  <arg2_type> <arg2_name>, ...);
> 
> +For the case that the libc-style wrapper does not match the signature and 
> return
> +type of the underlying system call, a so called low-level variant of these 
> two
> +macros are available: ``UK_LLSYSCALL_DEFINE``, ``UK_LLSYSCALL_R_DEFINE``.
> +These macros only generate the ``uk_syscall_e_<syscall_name>`` and
> +``uk_syscall_r_<syscall_name>`` symbols. You can then provide the custom
> +libc-style wrapper on top:
> +
> +.. code-block:: c
> +
> +    #include <uk/syscall.h>
> +
> +    UK_LLSYSCALL_R_DEFINE(ssize_t, write, int, fd, const void *, buf, 
> size_t, count)
> +    {
> +        long ret;
> +
> +        ret = (long) vfs_do_write(fd, buf, count);
> +        if (ret < 0) {
> +            return -EFAULT;
> +        }
> +        return ret;
> +    }
> +
> +    ssize_t write(int fd, const void *buf, size_t count)
> +    {
> +        return (ssize_t) uk_syscall_e_write((long) fd,
> +                                            (long) buf, (long) count);
> +    }
> +
> Note: When `syscall_shim` library is not enabled, the original design idea was
> -that the macros provide the libc-style wrapper only. However, both macros
> -provide always all three variants. This is done to support the case that a
> -system call is implemented on top of another.
> +that the macros provide the libc-style wrapper only. However, all the
> +described macros are still available and populate the symbols as documented
> +here. This is done to support the case that a system call is implemented by
> +calling another.
> 
> If your library uses an ``exportsyms.uk`` file, you need to add the three
> symbols for making them public available: ::
> diff --git a/lib/syscall_shim/include/uk/syscall.h 
> b/lib/syscall_shim/include/uk/syscall.h
> index cd5c6e67..a219365b 100644
> --- a/lib/syscall_shim/include/uk/syscall.h
> +++ b/lib/syscall_shim/include/uk/syscall.h
> @@ -37,6 +37,7 @@
> #ifndef __UK_SYSCALL_H__
> #define __UK_SYSCALL_H__
> 
> +#include <uk/config.h>
> #include <uk/essentials.h>
> #include <errno.h>
> #include <uk/print.h>
> @@ -94,56 +95,83 @@ typedef long uk_syscall_arg_t;
> /* TODO: `void` as return type is currently not supported.
>  * NOTE: Workaround is to use `int` instead.
>  */
> -#define __UK_SYSCALL_DEFINE(x, rtype, name, ename, rname, ...)               
> \
> -     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__));       \
> +/*
> + * UK_LLSYSCALL_DEFINE()
> + * Low-level variant, does not provide a libc-style wrapper
> + */
> +#define __UK_LLSYSCALL_DEFINE(x, rtype, name, ename, rname, ...)     \
> +     long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
>       long rname(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
>       {                                                               \
>               int _errno = errno;                                     \
>               long ret;                                               \
>                                                                       \
>               errno = 0;                                              \
> -             ret = (long) name(                                      \
> -                     UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
> +             ret = ename(                                            \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
>               if (ret == -1)                                          \
>                       ret = errno ? -errno : -EFAULT;                 \
>               errno = _errno;                                         \
>               return ret;                                             \
>       }                                                               \
> +     static inline rtype __##ename(UK_ARG_MAPx(x,                    \
> +                                     UK_S_ARG_ACTUAL, __VA_ARGS__)); \
>       long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__))          \
>       {                                                               \
> -             return (long) name(                                     \
> +             return (long) __##ename(                                \
>                       UK_ARG_MAPx(x, UK_S_ARG_CAST_ACTUAL, __VA_ARGS__)); \
>       }                                                               \
> -     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))
> +     static inline rtype __##ename(UK_ARG_MAPx(x,                    \
> +                                               UK_S_ARG_ACTUAL, __VA_ARGS__))
> +#define _UK_LLSYSCALL_DEFINE(...) __UK_LLSYSCALL_DEFINE(__VA_ARGS__)
> +#define UK_LLSYSCALL_DEFINE(rtype, name, ...)                                
> \
> +     _UK_LLSYSCALL_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),       \
> +                          rtype,                                     \
> +                          name,                                      \
> +                          __UK_NAME2SCALLE_FN(name),                 \
> +                          __UK_NAME2SCALLR_FN(name),                 \
> +                          __VA_ARGS__)
> +
> +/*
> + * UK_SYSCALL_DEFINE()
> + * Based on UK_LLSYSCALL_DEFINE and provides a libc-style wrapper
> + */
> +#define __UK_SYSCALL_DEFINE(x, rtype, name, ename, rname, ...)               
> \
> +     long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
> +     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))        \
> +     {                                                               \
> +             return (rtype) ename(                                   \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
> +     }                                                               \
> +     __UK_LLSYSCALL_DEFINE(x, rtype, name, ename, rname, __VA_ARGS__)
> #define _UK_SYSCALL_DEFINE(...) __UK_SYSCALL_DEFINE(__VA_ARGS__)
> -#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),                  \
> +#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, ...)     \
> +/*
> + * UK_LLSYSCALL_R_DEFINE()
> + * Low-level variant, does not provide a libc-style wrapper
> + */
> +#define __UK_LLSYSCALL_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 ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __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 -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__)); \
> +             return ret;                                             \
>       }                                                               \
>       static inline long __##rname(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,    \
>                                                __VA_ARGS__));         \
> @@ -154,6 +182,27 @@ typedef long uk_syscall_arg_t;
>       }                                                               \
>       static inline long __##rname(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL,    \
>                                                __VA_ARGS__))
> +#define _UK_LLSYSCALL_R_DEFINE(...) __UK_LLSYSCALL_R_DEFINE(__VA_ARGS__)
> +#define UK_LLSYSCALL_R_DEFINE(rtype, name, ...)                              
> \
> +     _UK_LLSYSCALL_R_DEFINE(__UK_SYSCALL_DEF_NARGS(__VA_ARGS__),     \
> +                            rtype,                                   \
> +                            name,                                    \
> +                            __UK_NAME2SCALLE_FN(name),               \
> +                            __UK_NAME2SCALLR_FN(name),               \
> +                            __VA_ARGS__)
> +
> +/*
> + * UK_SYSCALL_R_DEFINE()
> + * Based on UK_LLSYSCALL_R_DEFINE and provides a libc-style wrapper
> + */
> +#define __UK_SYSCALL_R_DEFINE(x, rtype, name, ename, rname, ...)     \
> +     long ename(UK_ARG_MAPx(x, UK_S_ARG_LONG, __VA_ARGS__));         \
> +     rtype name(UK_ARG_MAPx(x, UK_S_ARG_ACTUAL, __VA_ARGS__))        \
> +     {                                                               \
> +             return (rtype) ename(                                   \
> +                     UK_ARG_MAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__)); \
> +     }                                                               \
> +     __UK_LLSYSCALL_R_DEFINE(x, rtype, name, ename, rname, __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__),       \
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> Minios-devel mailing list
> Minios-devel@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/mailman/listinfo/minios-devel


_______________________________________________
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®.