Hi Marc,
On Thu, 30 Jul 2026 at 13:37, Marc Zyngier <[email protected]> wrote:
...
> > +/*
> > + * Generate a typed stub for each declared hypercall. kvm_call_hyp_nvhe()
> > + * resolves to the stub, so a call with the wrong argument count or types
> > + * fails to compile instead of being silently truncated to an SMCCC
> > function
> > + * number and a pile of registers. The stub inlines to the same SMCCC call
> > + * the untyped macro used to make.
> > + */
> > +#define DECLARE_KVM_HOST_HCALL(ret, name, x, ...) \
> > + static __always_inline \
> > + ret nvhe_hvc_##name(__KVM_HCALL_MAP(x, __KVM_HCALL_DECL,
> > __VA_ARGS__)) \
> > + { \
> > + return (ret)__kvm_call_hyp_nvhe(name, \
> > + __KVM_HCALL_MAP(x, __KVM_HCALL_ARGS, __VA_ARGS__)); \
> > + }
>
> One thing I find absolutely horrible is to have to specify the number
> of parameters here. It is already bad to have to comma-separate
> everything, but having to count them is too hard for me ;-).
>
> We already have facilities to count the number of parameters to a
> macro (see the COUNT_ARGS macro). You could make use of it all over
> the place.
Will Deacon mentioned the same thing yesterday (offline). I'll drop it
in v2. The count was only there because the macro that walks the pair
list is a copy of __MAP() in <linux/syscalls.h>, which gets its arity
from the SYSCALL_DEFINEn name. No better reason than that.
COUNT_ARGS() does work here. The list is (type, name) pairs, so it
counts twice the arguments, which the ladder absorbs by being indexed
on list entries:
#define __KVM_HCALL_MAP2(m, t, a, ...) m(t, a)
#define __KVM_HCALL_MAP4(m, t, a, ...) m(t, a), __KVM_HCALL_MAP2(m, __VA_ARGS__)
[...]
#define __KVM_HCALL_MAP12(m, t, a, ...) m(t, a), __KVM_HCALL_MAP10(m,
__VA_ARGS__)
#define __KVM_HCALL_MAP_N(n, m, ...) CONCATENATE(__KVM_HCALL_MAP,
n)(m, __VA_ARGS__)
#define __KVM_HCALL_MAP(m, ...)
__KVM_HCALL_MAP_N(COUNT_ARGS(__VA_ARGS__), m, __VA_ARGS__)
DECLARE_KVM_HOST_HCALL(int, __pkvm_init,
phys_addr_t, phys, unsigned long, size,
unsigned long *, per_cpu_base, u32, hyp_va_bits)
That drops 40 hand-written counts from the declarations and 40 from
the handler definitions. __KVM_HCALL_MAP_N() is for the handler side,
which truncates a fixed list of six argument registers, and takes its
count from COUNT_ARGS() as well.
I diffed the preprocessed output before and after: token-identical
apart from the __LINE__ values that shift with the declarations.
Cheers,
/fuad
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.