From: Marc Zyngier <maz@kernel.org>
To: Fuad Tabba <fuad.tabba@linux.dev>
Cc: oupton@kernel.org, linux-arm-kernel@lists.infradead.org,
kvmarm@lists.linux.dev, catalin.marinas@arm.com, will@kernel.org,
rostedt@goodmis.org, mhiramat@kernel.org,
alexandru.elisei@arm.com, vdonnefort@google.com,
joey.gouly@arm.com, seiden@linux.ibm.com, suzuki.poulose@arm.com,
yuzenghui@huawei.com, qperret@google.com, ardb@kernel.org,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
tabba@google.com
Subject: Re: [PATCH v1 09/11] KVM: arm64: Type-check hypercall arguments at the caller
Date: Thu, 30 Jul 2026 13:37:49 +0100 [thread overview]
Message-ID: <86jyqcd55u.wl-maz@kernel.org> (raw)
In-Reply-To: <20260720161343.1367007-10-fuad.tabba@linux.dev>
On Mon, 20 Jul 2026 17:13:41 +0100,
Fuad Tabba <fuad.tabba@linux.dev> wrote:
>
> kvm_call_hyp_nvhe() reduces its target to an SMCCC function number, so
> the compiler never sees a callable: arguments that are wrong in number,
> type or order are silently marshalled into registers. The kvm_call_hyp()
> wrappers only catch this on the VHE branch, and the pKVM-only hypercalls
> have no such branch.
>
> Declare each hypercall's signature once in kvm_hcall.h and generate a
> typed stub from it, in the mold of the syscall wrappers. Make
> kvm_call_hyp_nvhe() resolve to the stub so every caller is checked
> against the declared signature; a stale or mistyped call now fails to
> compile. The stubs inline to the same SMCCC call the untyped macro used
> to make: the compiled callers are unchanged, apart from hypercall
> returns now being tested at their declared width.
>
> The stage-2 protection arguments are declared u64 rather than
> enum kvm_pgtable_prot, as kvm_pgtable.h includes linux/kvm_host.h and
> the enum cannot be completed here.
>
> Assisted-by: Antigravity:gemini-3.1-pro
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
> arch/arm64/include/asm/kvm_hcall.h | 165 ++++++++++++++++++++++++++++-
> arch/arm64/kvm/hyp_trace.c | 2 +-
> 2 files changed, 165 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_hcall.h b/arch/arm64/include/asm/kvm_hcall.h
> index d925b2c28a3d8..51bfd14748464 100644
> --- a/arch/arm64/include/asm/kvm_hcall.h
> +++ b/arch/arm64/include/asm/kvm_hcall.h
> @@ -16,12 +16,35 @@
>
> #include <asm/barrier.h>
> #include <asm/kvm_asm.h>
> +#include <asm/spectre.h>
> #include <asm/virt.h>
>
> typedef u16 pkvm_handle_t;
>
> +struct kvm;
> +struct kvm_s2_mmu;
> +struct kvm_vcpu;
> +struct vgic_v3_cpu_if;
> +struct vgic_v5_cpu_if;
> +
> +/*
> + * Hypercall signatures are declared as (type, name) argument pairs.
> + * __KVM_HCALL_MAP() applies a macro to each pair, in the mold of __MAP()
> + * in <linux/syscalls.h>.
> + */
> +#define __KVM_HCALL_MAP1(m, t, a, ...) m(t, a)
> +#define __KVM_HCALL_MAP2(m, t, a, ...) m(t, a), __KVM_HCALL_MAP1(m, __VA_ARGS__)
> +#define __KVM_HCALL_MAP3(m, t, a, ...) m(t, a), __KVM_HCALL_MAP2(m, __VA_ARGS__)
> +#define __KVM_HCALL_MAP4(m, t, a, ...) m(t, a), __KVM_HCALL_MAP3(m, __VA_ARGS__)
> +#define __KVM_HCALL_MAP5(m, t, a, ...) m(t, a), __KVM_HCALL_MAP4(m, __VA_ARGS__)
> +#define __KVM_HCALL_MAP6(m, t, a, ...) m(t, a), __KVM_HCALL_MAP5(m, __VA_ARGS__)
> +#define __KVM_HCALL_MAP(n, ...) __KVM_HCALL_MAP##n(__VA_ARGS__)
> +
> +#define __KVM_HCALL_DECL(t, a) t a
> +#define __KVM_HCALL_ARGS(t, a) a
> +
> #ifndef __KVM_NVHE_HYPERVISOR__
> -#define kvm_call_hyp_nvhe(f, ...) \
> +#define __kvm_call_hyp_nvhe(f, ...) \
> ({ \
> struct arm_smccc_res res; \
> \
> @@ -33,6 +56,43 @@ typedef u16 pkvm_handle_t;
> res.a1; \
> })
>
> +/*
> + * 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.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
next prev parent reply other threads:[~2026-07-30 12:38 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 16:13 [PATCH v1 00/11] KVM: arm64: Restore type-checking across the host/hyp hypercall boundary Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 01/11] tracing: Include linux/types.h in trace_remote_event.h Fuad Tabba
2026-07-20 18:32 ` Steven Rostedt
2026-07-20 16:13 ` [PATCH v1 02/11] KVM: arm64: nVHE: Share the stacktrace per-CPU declarations with EL2 Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 03/11] KVM: arm64: nVHE: Declare the hyp event IDs before defining them Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 04/11] KVM: arm64: nVHE: Use NULL to reset the trace buffer backing pointer Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 05/11] KVM: arm64: nVHE: Run the source checker under C=2 Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 06/11] arm64: pi: Run the source checker on the libfdt objects " Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 07/11] KVM: arm64: nVHE: Pass host VA arguments as pointers Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 08/11] KVM: arm64: Move the host hypercall interface to its own header Fuad Tabba
2026-07-20 16:13 ` [PATCH v1 09/11] KVM: arm64: Type-check hypercall arguments at the caller Fuad Tabba
2026-07-30 12:37 ` Marc Zyngier [this message]
2026-07-30 13:47 ` Fuad Tabba
2026-07-20 16:24 ` [PATCH v1 10/11] KVM: arm64: nVHE: Check hypercall handlers against the declared ABI Fuad Tabba
2026-07-20 16:24 ` [PATCH v1 11/11] KVM: arm64: Tag host-VA hypercall parameters __hostva Fuad Tabba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=86jyqcd55u.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=alexandru.elisei@arm.com \
--cc=ardb@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=fuad.tabba@linux.dev \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=oupton@kernel.org \
--cc=qperret@google.com \
--cc=rostedt@goodmis.org \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=vdonnefort@google.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox