Re: [PATCH v1 09/11] KVM: arm64: Type-check hypercall arguments at the caller
Fuad Tabba <[email protected]> Thu, 30 Jul 2026 14:47:42 +0100
| Newsgroups | org.kernel.vger.linux-trace-kernel,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CA+EHjTwT38rV0DQKW7R0=ZVHvQU0jnvJbjDBqnpmNgu34biuMA@mail.gmail.com> |
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.