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

Re: [Minios-devel] [UNIKRAFT PATCH 07/10] lib/syscall_shim: introduce syscalls macro layer



Simon Kuenzer <simon.kuenzer@xxxxxxxxx> writes:

> On 04.06.19 18:28, Yuri Volchkov wrote:
>> To provide a syscall user needs to use macro UK_SYSCALL_PROTO. The
>> syntax is the following:
>> 
>
> Hum, is UK_SYSCALL_PROTO the right name? I saw that is called 
> UK_SYSCALL_DEFINE() in patch number 8.
Oops

>
>> UK_SYSCALL_PROTO(syscall_name, argument_1_type, argument_1_name, ...)
>> {
>>      <syscall_body>;
>> }
>> 
>> Signed-off-by: Yuri Volchkov <yuri.volchkov@xxxxxxxxx>
>> ---
>>   lib/syscall_shim/Makefile.uk          |   5 ++
>>   lib/syscall_shim/include/uk/syscall.h | 100 ++++++++++++++++++++++++++
>>   2 files changed, 105 insertions(+)
>>   create mode 100644 lib/syscall_shim/include/uk/syscall.h
>> 
>> diff --git a/lib/syscall_shim/Makefile.uk b/lib/syscall_shim/Makefile.uk
>> index bb76d7b1..67677fc6 100644
>> --- a/lib/syscall_shim/Makefile.uk
>> +++ b/lib/syscall_shim/Makefile.uk
>> @@ -50,4 +50,9 @@ $(__GEN_INCLUDES_PATH)/syscall_stubs.h.new:
>>      $(Q) $(AWK) -f $(LIBSYSCALL_SHIM_BASE)/gen_stubs.awk \
>>              $(__SYSCALL_SHIM_TEMPL) > $@
>>   
>> +CINCLUDES-$(CONFIG_LIBSYSCALL_SHIM)   += -I$(LIBSYSCALL_SHIM_BUILD)/include
>> +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_CLEAN = $(__PHONY_GEN_SRC) $(__PHONY_GEN_SRC_NEW) 
>> $(__GEN_SRC)
>> diff --git a/lib/syscall_shim/include/uk/syscall.h 
>> b/lib/syscall_shim/include/uk/syscall.h
>> new file mode 100644
>> index 00000000..19161e5e
>> --- /dev/null
>> +++ b/lib/syscall_shim/include/uk/syscall.h
>> @@ -0,0 +1,100 @@
>> +#ifndef __UK_SYSCALL_H__
>> +#define __UK_SYSCALL_H__
>> +
>> +#include <errno.h>
>> +#include <uk/print.h>
>
> Doesn't essentials.h need to be included to have the UK_CONCAT macro 
> populated?
Sure

>
>> +
>> +#define __uk_scc(X) ((long) (X))
>> +typedef long syscall_arg_t;
>> +
>> +#define __uk_syscall(syscall_nr, ...) \
>> +    UK_CONCAT(uk_syscall_fn_, syscall_nr) (__VA_ARGS__)
>> +
>> +#define __uk_syscall0(n) __uk_syscall(n)
>> +#define __uk_syscall1(n,a) __uk_syscall(n,__uk_scc(a))
>> +#define __uk_syscall2(n,a,b) __uk_syscall(n,__uk_scc(a),__uk_scc(b))
>> +#define __uk_syscall3(n,a,b,c) 
>> __uk_syscall(n,__uk_scc(a),__uk_scc(b),__uk_scc(c))
>> +#define __uk_syscall4(n,a,b,c,d) 
>> __uk_syscall(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d))
>> +#define __uk_syscall5(n,a,b,c,d,e) 
>> __uk_syscall(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e))
>> +#define __uk_syscall6(n,a,b,c,d,e,f) 
>> __uk_syscall(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)(n,__uk_scc(a),__uk_scc(b),__uk_scc(c),__uk_scc(d),__uk_scc(e),__uk_scc(f),__uk_scc(g))
>> +
>> +
>> +#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
>> +#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
>> +
>> +#define __SYSCALL_DEF_NARGS_X(z, a1,a2, b1,b2, c1,c2, d1,d2, e1,e2, f1,f2, 
>> g1,g2, nr, ...) nr
>> +#define __SYSCALL_DEF_NARGS(...) __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_ARG_MAP1(m, type, arg) m(type, arg)
>> +#define UK_ARG_MAP2(m, type, arg, ...) m(type, arg), UK_ARG_MAP1(m, 
>> __VA_ARGS__)
>> +#define UK_ARG_MAP3(m, type, arg, ...) m(type, arg), UK_ARG_MAP2(m, 
>> __VA_ARGS__)
>> +#define UK_ARG_MAP4(m, type, arg, ...) m(type, arg), UK_ARG_MAP3(m, 
>> __VA_ARGS__)
>> +#define UK_ARG_MAP5(m, type, arg, ...) m(type, arg), UK_ARG_MAP4(m, 
>> __VA_ARGS__)
>> +#define UK_ARG_MAP6(m, type, arg, ...) m(type, arg), UK_ARG_MAP5(m, 
>> __VA_ARGS__)
>> +#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 S_ARG_LONG(type, arg) unsigned long arg
>> +#define S_ARG_ACTUAL(type, arg) type arg
>> +#define S_ARG_CAST(type, arg) (type) arg
>> +
>> +
>> +#ifdef CONFIG_LIBSYSCALL_SHIM
>> +#define __UK_SYSCALL_DEFINE(x, name, ...)                           \
>> +    static inline long __##name(UK_ARG_MAPx(x, S_ARG_ACTUAL, __VA_ARGS__)); 
>> \
>> +    int name(UK_ARG_MAPx(x, S_ARG_LONG, __VA_ARGS__))                       
>> \
>
> In this type casting wrapper, shouldn't this `int` be a `long` instead?
Yes it should
>
>> +    {                                                               \
>> +            long ret = __##name(                                    \
>> +                    UK_ARG_MAPx(x, S_ARG_CAST, __VA_ARGS__));               
>> \
>> +            return ret;                                             \
>> +    }                                                               \
>> +    static inline long __##name(UK_ARG_MAPx(x, S_ARG_ACTUAL, __VA_ARGS__))
>> +#else
>> +#define __UK_SYSCALL_DEFINE(x, name, ...)                           \
>> +    static inline long name(UK_ARG_MAPx(x, S_ARG_ACTUAL, __VA_ARGS__))
>> +#endif
>> +
>> +#define _UK_SYSCALL_DEFINE(...) __UK_SYSCALL_DEFINE(__VA_ARGS__)
>> +#define UK_SYSCALL_DEFINE(name, ...)                                \
>> +    _UK_SYSCALL_DEFINE(__SYSCALL_DEF_NARGS(__VA_ARGS__),    \
>> +                        __UK_NAME2SCALL_FN(name),           \
>> +                        __VA_ARGS__)
>> +
>> +#define __UK_SPROTO_ARGS_TYPE unsigned 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
>> +#define __UK_SPROTO_ARGS3()  __UK_SPROTO_ARGS2(), __UK_SPROTO_ARGS_TYPE c
>> +#define __UK_SPROTO_ARGS4()  __UK_SPROTO_ARGS3(), __UK_SPROTO_ARGS_TYPE d
>> +#define __UK_SPROTO_ARGS5()  __UK_SPROTO_ARGS4(), __UK_SPROTO_ARGS_TYPE e
>> +#define __UK_SPROTO_ARGS6()  __UK_SPROTO_ARGS5(), __UK_SPROTO_ARGS_TYPE f
>> +#define __UK_SPROTO_ARGS7()  __UK_SPROTO_ARGS6(), __UK_SPROTO_ARGS_TYPE g
>> +#define __UK_SPROTO_ARGSx(args_nr)  \
>> +    UK_CONCAT(__UK_SPROTO_ARGS, args_nr)()
>> +
>> +#define UK_SYSCALL_PROTO(args_nr, syscall_name)                     \
>> +    int UK_CONCAT(uk_syscall_, syscall_name)(       \
>> +            __UK_SPROTO_ARGSx(args_nr))
>> +
>> +#define uk_syscall_stub(syscall_name) ({                    \
>> +                    uk_pr_debug("syscall \"" syscall_name   \
>> +                                "\" is not implemented");   \
>> +                    errno = -ENOSYS;                        \
>> +                    -1;                                     \
>> +            })
>
> Hum, since your shim layer is mimicking Linux's userspace sys call 
> wrapper (<sys/syscall.h>), it is expected that a syscall function 
> handles errno and returns -1 in error cases. I suggest that you add a 
> comment to UK_SYSCALL_DEFINE() so that everyone that implements such a 
> system call is not getting confused with what a syscall in the kernel 
> means in terms of return values and arguments.
> Could you also write that the return type is `long` on such a defined 
> function? This is kind of hidden in the UK_SYSCALL_DEFINE() macro.
Alright I will add a comment
>
>> +
>> +
>> +#ifdef CONFIG_LIBSYSCALL_SHIM
>> +#include <uk/bits/syscall_nrs.h>
>> +#include <uk/bits/syscall_map.h>
>> +#include <uk/bits/provided_syscalls.h>
>> +#include <uk/bits/syscall_stubs.h>
>> +
>> +#define syscall(...)                                                        
>> \
>> +    UK_CONCAT(__uk_syscall, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
>> +#endif
>> +
>> +#endif /* __UK_SYSCALL_H__ */
>> 

-- 
Yuri Volchkov
Software Specialist

NEC Europe Ltd
Kurfürsten-Anlage 36
D-69115 Heidelberg

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