Re: [PATCH v1 09/11] KVM: arm64: Type-check hypercall arguments at the caller
From: Fuad Tabba <fuad.tabba@linux.dev>
Date: 2026-07-30 13:48:42
Also in:
kvmarm, linux-arm-kernel, lkml
Hi Marc, On Thu, 30 Jul 2026 at 13:37, Marc Zyngier [off-list ref] wrote: ...
quoted
+/* + * 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.