From nobody Fri Oct 2 06:57:49 2026 Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4902143849B for ; Tue, 4 Aug 2026 11:23:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842638; cv=none; b=lbYRj2rFImLKMrHVUgnyhAMAcsH9gUgQ0VomQ6OkBYzU5xVg8C6xd8JE4MQ88AUD2njbrqCZJ+NuE+T8WdqE/Gy1Y/2Pne1GlOgskoFqrbDcqjaZAsf2nqn4nAnPG0Pv9ffkj9B0OsX8RSZDMK4BY4qTs99G5LTHYnICXd18Wi4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842638; c=relaxed/simple; bh=/iCvHcbpKF86s8mUijJ9mtfUoT/0j522f9t+I2F3pQY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Mp5HxwxW0W89QQVlc5B33J4HCmigDFNRlOGFAUbwGUM+llAdkOL/Zizu5VS+nSi2HtIxXHAskJMeF3M8Y0vFmtJ2A9eY4QP4fUR4TS1vaGjeZ5y4xn+H31VUxzKEzaWV25XwL9dOEHca5F/BH6rUV6sI2y9t290f3V+8giJvshg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=QNCoG8yk; arc=none smtp.client-ip=95.215.58.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="QNCoG8yk" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bVKtopwMrqzEnOyVedKGwt1g22ev9g5F8tMkWzZJze8=; b=QNCoG8yklFuiDeil1YTbf6EhTSPhfpC0uz2qzmE7+FGvUqf+AelqpV4jWMT8NaGw4TxTte K1pr8tii3dDTgXh1WA3TuVcM6VQTbvcw3aLCH/KPm3qrCNEp3XlJWMGk63BXY1jC/qVXbD YRgRULEdi4gZNsyd9/YAHgaKP+YRzvk= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 01/11] tracing: Include linux/types.h in trace_remote_event.h Date: Tue, 4 Aug 2026 12:23:07 +0100 Message-Id: <20260804112317.1937387-2-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" trace_remote_event.h uses bool without including linux/types.h, so a translation unit that includes it ahead of anything else that pulls types.h in fails to build, as with nvhe/trace.h at EL2. Fixes: 072529158e60 ("tracing: Add events to trace remotes") Acked-by: Steven Rostedt Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier Reviewed-by: Vincent Donnefort --- include/linux/trace_remote_event.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/trace_remote_event.h b/include/linux/trace_remot= e_event.h index c8ae1e1f5e721..e4cc2d4497bcf 100644 --- a/include/linux/trace_remote_event.h +++ b/include/linux/trace_remote_event.h @@ -3,6 +3,8 @@ #ifndef _LINUX_TRACE_REMOTE_EVENTS_H #define _LINUX_TRACE_REMOTE_EVENTS_H =20 +#include + struct trace_remote; struct trace_event_fields; struct trace_seq; --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-173.mta1.migadu.com (mta1.migadu.com [37.59.57.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B1B9345FFBC for ; Tue, 4 Aug 2026 11:24:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=37.59.57.117 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842643; cv=none; b=kIGugWYLd0RKVSDjhoQYchK6FutXdd4WfQg3sYL5rslDBr1NwI0CZG6RU/dTAjYvh1lAUm3BkwRy14DIpinmjO7FWWB3i+v+pC0gXbbaOSlyRzkbZIrWDytmjrjwnGNdfipPTVhO/+CWE1qjhmoqnx0yaqU8KfVoKRT2/XRqlm0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842643; c=relaxed/simple; bh=GaZD8YNbLBwQa9XjzIdEKqb+R+kYZ0rTi364A3qmdig=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=D3MMyQQ8838YbM1kDhtHhWjJT+GcmXqgl0BRolpHOTVI6/B6L+BXYB6hQghIFnpXyRfvsWjLkq0ZOfHpyA4sTGwxG0nYSUbD0o0RaZaXCo3VVsuUDBAAvPC/hYQ4EdguXxX2H1InoQMYpf20+zpxg+nUWTwGd3cc8ptQi6NAvw0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=eDqoRqm1; arc=none smtp.client-ip=37.59.57.117 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="eDqoRqm1" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842638; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mbmwUYRMkOEfVhoKhlo/B+eCrpuKcZd9NIaZ5Zet0iU=; b=eDqoRqm1YK9dMdPjeIr4nXnu2t6bsxrSU6Bfbh2YpnUq/3GDsSfWY2kXxOdu4Hf7CcLkAJ /VhPJovzgYhCypxUVb6icuVSsP+il7RdpLJnDWrEuWc0VpdPPYw0QALZXYPmxJVi6kFsEW 3bYfUYCpp7flF+XculerxD75tMmdgZQ= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 02/11] KVM: arm64: nVHE: Share the stacktrace per-CPU declarations with EL2 Date: Tue, 4 Aug 2026 12:23:08 +0100 Message-Id: <20260804112317.1937387-3-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The declarations for overflow_stack, kvm_stacktrace_info and pkvm_stacktrace are only visible to the host (the first two sit in the host-only section of stacktrace/nvhe.h, the last is private to kvm/stacktrace.c), so the definitions in nvhe/stacktrace.c compile with no declaration in sight and sparse suggests making them static. DECLARE_KVM_NVHE_PER_CPU() resolves to the right symbol name on both sides of the build: move the declarations where both can see them and include the header from the EL2 side unconditionally. No functional change intended. Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/include/asm/stacktrace/nvhe.h | 10 ++++++++-- arch/arm64/kvm/hyp/nvhe/stacktrace.c | 3 +-- arch/arm64/kvm/stacktrace.c | 3 --- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/arm64/include/asm/stacktrace/nvhe.h b/arch/arm64/include/= asm/stacktrace/nvhe.h index 171f9edef49fc..a631a577cbe5d 100644 --- a/arch/arm64/include/asm/stacktrace/nvhe.h +++ b/arch/arm64/include/asm/stacktrace/nvhe.h @@ -37,6 +37,14 @@ static inline void kvm_nvhe_unwind_init(struct unwind_st= ate *state, state->pc =3D pc; } =20 +DECLARE_KVM_NVHE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],= overflow_stack); +DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_stacktrace_info, kvm_stacktrace_i= nfo); + +#ifdef CONFIG_PKVM_STACKTRACE +DECLARE_KVM_NVHE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], + pkvm_stacktrace); +#endif + #ifndef __KVM_NVHE_HYPERVISOR__ /* * Conventional (non-protected) nVHE HYP stack unwinder @@ -45,8 +53,6 @@ static inline void kvm_nvhe_unwind_init(struct unwind_sta= te *state, * (by the host in EL1). */ =20 -DECLARE_KVM_NVHE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)],= overflow_stack); -DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_stacktrace_info, kvm_stacktrace_i= nfo); DECLARE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base); =20 void kvm_nvhe_dump_backtrace(unsigned long hyp_offset); diff --git a/arch/arm64/kvm/hyp/nvhe/stacktrace.c b/arch/arm64/kvm/hyp/nvhe= /stacktrace.c index 7c832d60d22bb..11fadbebbf1d6 100644 --- a/arch/arm64/kvm/hyp/nvhe/stacktrace.c +++ b/arch/arm64/kvm/hyp/nvhe/stacktrace.c @@ -8,6 +8,7 @@ #include #include #include +#include =20 DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_= stack) __aligned(16); @@ -35,8 +36,6 @@ static void hyp_prepare_backtrace(unsigned long fp, unsig= ned long pc) } =20 #ifdef CONFIG_PKVM_STACKTRACE -#include - DEFINE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], pkvm_sta= cktrace); =20 static struct stack_info stackinfo_get_overflow(void) diff --git a/arch/arm64/kvm/stacktrace.c b/arch/arm64/kvm/stacktrace.c index 9724c320126b7..69377195e18b7 100644 --- a/arch/arm64/kvm/stacktrace.c +++ b/arch/arm64/kvm/stacktrace.c @@ -198,9 +198,6 @@ static void hyp_dump_backtrace(unsigned long hyp_offset) } =20 #ifdef CONFIG_PKVM_STACKTRACE -DECLARE_KVM_NVHE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], - pkvm_stacktrace); - /* * pkvm_dump_backtrace - Dump the protected nVHE HYP backtrace. * --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-166.mta1.migadu.com (out-166.mta1.migadu.com [95.215.58.166]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E4D2F463B6D for ; Tue, 4 Aug 2026 11:24:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.166 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842645; cv=none; b=NqnYakkvyJDmbqi8xr9T6StKbBIQRjFvxJUToMF2QctBthSmR/g/fMABarm0CvDazMEBM0kkR3S7c29BmHl24Hk7FmIULeX346HZcJkSS9Ydxw1nWyHmbGOWtczn/oyAEe+5Do2rkxzqtnaw8UR0HkpoFujR3ANRMNOxirUlLqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842645; c=relaxed/simple; bh=964nyES0bpmlC1jVFJFVmRXV0epLfd7qUJ0SK0/0qeM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rXil0GEaYPf3Co5w09Ao7asIDpsBUTOBAjlo7qGj8fws2WoHYrBO/SI/RUyanxprtZU0E0jKKL/huK5oHrlzau/ymbvK7lQOaHHFimkt6ir488OHn5U4ljTusIzf20Fiy9S96mJrrOoDy8ZPu1gpL4OKehQ0TwBxeYR0FCVPcRY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=YqZGqwPd; arc=none smtp.client-ip=95.215.58.166 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="YqZGqwPd" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842641; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ClYTj8QzgBnO7N7CWSz26CsAj405Dm7DCBLVlh0azJ4=; b=YqZGqwPdUakNx3Kj0pYdE42UUrWCKvM7oVflZ9d6L2HfNSyl//ExpcH1U8n1BYMNOc2pqA vJFpy3x3oDZlj9TVQTjj3HLyDsLt2WNPq1nkg4Sr9u14c/0845naqk3GKFvCAgGUlvm9SD /CI9bZLu3uc/CfPOrC1f45cyPiI/ZkA= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 03/11] KVM: arm64: nVHE: Declare the hyp event IDs before defining them Date: Tue, 4 Aug 2026 12:23:09 +0100 Message-Id: <20260804112317.1937387-4-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The defining expansion of HYP_EVENT() in events.c is the first time its translation unit meets hyp_event_id_, so sparse suggests making the symbols static. Include kvm_hypevents.h ahead of define_events.h so the extern declarations come first, as with the tracepoint headers. No functional change intended. Reviewed-by: Vincent Donnefort Tested-by: Vincent Donnefort Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/kvm/hyp/nvhe/events.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/eve= nts.c index add9383aadb5a..b845be0acd117 100644 --- a/arch/arm64/kvm/hyp/nvhe/events.c +++ b/arch/arm64/kvm/hyp/nvhe/events.c @@ -7,6 +7,8 @@ #include #include =20 +#include + #include =20 int __tracing_enable_event(unsigned short id, bool enable) --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-161.mta1.migadu.com (out-161.mta1.migadu.com [95.215.58.161]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 747C04657D6 for ; Tue, 4 Aug 2026 11:24:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.161 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842649; cv=none; b=mjftLdcdl4qEK2nJkMn1fKRMpUeiqYQ8gSHQeH04OfuCc+631XDIQR0hlLOYzGw0ek048GbkN78DVXGs2lP1eiD9zA9txwSN5+rripFmbBll6EPxYgvpHBDQl65t2wpzINl24yNwqVvZXRamIYQxiPxtdlYJJ7kd0A8KMkFx7zk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842649; c=relaxed/simple; bh=CpskfQyNSuQnKK28n7Fb63ydz6/PMV/vlQveuN/a3ec=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WzG8h0Ibdp1LJz7uV3Gm6+QpIrcLXD6KU26MUWiBlHwVLwwBzHIsrmzyyboLzXtxMpryP9l8bR69wXcVt3EUBDtn6+v9irY8Z/XXuvbFfRZVfVAbbDjE2X/4hHPUu3lPeKbExd3D284PwU1XOKgR74A10xcbrZIZTKyZpuX8lno= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=KdaBFFXv; arc=none smtp.client-ip=95.215.58.161 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="KdaBFFXv" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842644; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=a5F+MIK/Sq7LP625lI93wSHp0p+82BAhT+VDlBkJm/w=; b=KdaBFFXvGDH6zK/2v7gtmrXtMtF1PrvEIUV3jGVkj/gX/sc7fxdLTzZmvme2RYlSfMuxBG ujFitJdjD68JMcxxyMmN7nJLMJUrzvgEqRTeZ+WtSwnGJfkFQfSI8zWIApquGrl2kNJlXk 30xcB/RT/++rCv+XHYUHSSrlcpVlcrg= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 04/11] KVM: arm64: nVHE: Use NULL to reset the trace buffer backing pointer Date: Tue, 4 Aug 2026 12:23:10 +0100 Message-Id: <20260804112317.1937387-5-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" bpages_backing_start is a pointer; resetting it to plain 0 triggers a sparse warning. No functional change intended. Reviewed-by: Vincent Donnefort Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/kvm/hyp/nvhe/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index e7e150ab265ff..177fe3d8fbb13 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -93,7 +93,7 @@ static void hyp_trace_buffer_unload_bpage_backing(struct = hyp_trace_buffer *trace =20 __release_host_mem(start, size); =20 - trace_buffer->bpages_backing_start =3D 0; + trace_buffer->bpages_backing_start =3D NULL; trace_buffer->bpages_backing_size =3D 0; } =20 --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 721183E9C0D for ; Tue, 4 Aug 2026 11:24:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842683; cv=none; b=IeDLHcCf3+VMhKDF8/iApbf9q3wHHrrI0rKKGRsMX3rO8/owASVX6x9Vscggt7v1hIu6nh1HeUWl13NepJh3KK9W8bH9y06csEmtHaxmU4PTYGOlqRY5FNGSTdxidTky698ALDJuFYFQ63QCchNuxLWKXr+cO2AJbNEonjBikt4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842683; c=relaxed/simple; bh=BwXfUSI8RZ5WlNlvsW4Dg8xPJP7duOd+6j4GH2NB7KQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hRXRQCxoJCoc7bOhjBDilMvInx3V1AA8mWt5/iLMJW4GNLgbiB7ciA8wERA8XDBsPZS7rb0dpKaJkJinu23V7mAix4EXyXm9A2ERspPGyQ1ItrHlP9YjQlMV8nT1ZmVsRz/xSDnj68nGPNTUGHBcfK9UF5hYtMQfH6pWYGmwfxs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PwhdSacw; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PwhdSacw" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842679; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/0h+UWlinGdaNRWQ3ePtD6vflPt+g0iOPa3K/aYZ+gU=; b=PwhdSacwEzCVjTWcbfzwkeIWM3lcgwtaHNu7bEjkh74w49DgAE276SCQ64FC6xJTMOZtB4 y2RQ00Zb9UuGd8cwgF35tELy4pYQwjzW2p+tAjoEuFdPHFi2utx3VbVBBxe9TFHZV2FT7u UHo2o27d+en1XEGIA5D3Z40uWOrljio= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 05/11] KVM: arm64: nVHE: Run the source checker under C=2 Date: Tue, 4 Aug 2026 12:23:11 +0100 Message-Id: <20260804112317.1937387-6-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The custom %.nvhe.o rule reuses rule_cc_o_c, which hooks the source checker only for C=3D1, and that only when the object is rebuilt. The C=3D2 hook, cmd_force_checksrc, hangs off the standard %.o rule that nVHE objects do not use, so "make C=3D2" silently skips every nVHE source file. Call cmd_force_checksrc after the compile rule, as the standard rule does. Fixes: 7621712918ad4 ("KVM: arm64: Add build rules for separate VHE/nVHE ob= ject files") Reviewed-by: Vincent Donnefort Tested-by: Vincent Donnefort Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/kvm/hyp/nvhe/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Mak= efile index f57450ebcb498..ccc1fe8394094 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -49,6 +49,7 @@ targets +=3D $(hyp-obj) kvm_nvhe.tmp.o kvm_nvhe.rel.o hyp= .lds hyp-reloc.S hyp-relo # avoids file name clashes for files shared with VHE. $(obj)/%.nvhe.o: $(src)/%.c FORCE $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) $(obj)/%.nvhe.o: $(src)/%.S FORCE $(call if_changed_rule,as_o_S) =20 --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B83DA4570ED for ; Tue, 4 Aug 2026 11:24:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842685; cv=none; b=Xb5KEfg8XFrkPiM+sDRO0acFkpCoMBAcerjhw+1knQHzW+pTAXkkUECkh/PcsLpM2q1whg8kWeYFCtvZ7lzCqx2NspQ/9+M71JkK4/yz8lM9aiP2evXhfWKBtmAEPDVLOyWwbcaTOt7eINLZ0G7L06lgbhFl9555jGf4M/vHT2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842685; c=relaxed/simple; bh=8eH8qSzPuak64zpqRzFkW4jtyt9rW2sXsAdwvlZWV9o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rwhfmRnBB5yPP73ZQvgyw2IWEd5Q3usawZmwCq1HnxVnEaYho3DYAuUBcZE77OrMZaxU7l0nXAVlyj/iQ/KTAJUT5cZHlcys7dK+xuJfhZl5Ob3B6rQ7roa/eLac4jPyDdZl1yRzooCnDvYzBT3c6JrxQWUYjjXpu9hupnl+UNc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=IvH9at4j; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="IvH9at4j" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842681; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sjtjOJ8VIAIzCYAs/x+lZGyja9IHYPAp3SWkrVb/Pdo=; b=IvH9at4jNKFDDVGrY64mS8X0NM2b7CHGTxAS3Kpe41eas0F5M2QeGajOUfoE+KdKSnDQJm GhSre/EaCgJeNzKeb1G1NhTY65YDGMUyvhsx7fawQHw0G1hkoyhx+1pPOIGpj5cjaCSbsE KvJFaYKiXqnO4JJURECUyYtGgGD4BWg= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 06/11] arm64: pi: Run the source checker on the libfdt objects under C=2 Date: Tue, 4 Aug 2026 12:23:12 +0100 Message-Id: <20260804112317.1937387-7-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The custom lib-%.o rule reuses rule_cc_o_c, which hooks the source checker only for C=3D1, and that only when the object is rebuilt. The C=3D2 hook, cmd_force_checksrc, hangs off the standard %.o rule, so "make C=3D2" silently skips the two libfdt objects. Call cmd_force_checksrc after the compile rule, as the standard rule does. Fixes: aacd149b6238 ("arm64: head: avoid relocating the kernel twice for KA= SLR") Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/kernel/pi/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/kernel/pi/Makefile b/arch/arm64/kernel/pi/Makefile index be92d73c25b21..96243c291e39d 100644 --- a/arch/arm64/kernel/pi/Makefile +++ b/arch/arm64/kernel/pi/Makefile @@ -34,6 +34,7 @@ $(obj)/lib-%.pi.o: OBJCOPYFLAGS +=3D --prefix-alloc-secti= ons=3D.init =20 $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(call if_changed_rule,cc_o_c) + $(call cmd,force_checksrc) =20 obj-y :=3D idreg-override.pi.o \ map_kernel.pi.o map_range.pi.o \ --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-170.mta0.migadu.com (out-170.mta0.migadu.com [91.218.175.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 221C2459AD7 for ; Tue, 4 Aug 2026 11:24:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842692; cv=none; b=X9L/IWTzVMczIuM0NpwbQSgFLCXZwGaXWSraVWwc96HOxEg9Lc3YaxAIHPAPaFOH5UHGJIjZaVPHHzrCaGMqc6lDFMrXcjElCRwhBPL/U/UNbf5HxQ7FqHvIOQ99cYWQHac+rF1kquVPnJJMNENk+AJxz4g7qSvCrmkh4dhwdWY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842692; c=relaxed/simple; bh=bQ+/Qw3KeLIOai823DsWpPtAJXBCSSsvbk1lv3ttuZ8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bF+FmiAy0wxLN1vcu6Uo1wXUx10leknRe2JswDG1etTnl6kEqV1DEdRdYXeE6TiYHCqErG/YL9umqVBRXmjremqcNr+IDIdaQsb2pg1uc4smjkdnoUZVEmzqbNYlsXHmayItR3M9UI7NPrzNK/xtcTZMFRaEAmL153/dopMN0a4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=qUoTlb+P; arc=none smtp.client-ip=91.218.175.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="qUoTlb+P" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842685; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g4PpMNlGsTWFD0SxKNjrPtX+vudl8Lxy+1dKyA5gL04=; b=qUoTlb+P1w1CxAB3haV31nhSNXZz1B03NI/XULUMlyPXzgzHgw0tQIM/kwGjR333XpybSY c+7LK++upokfs/jqvoZbJJihH1bpHkZPUgQi2kWcBfZdUOe1p2mDzlnaXEt0worXUz0xra woJ+X2ZtFCkkDBS/uSJIcyJef4hzF5M= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 07/11] KVM: arm64: nVHE: Pass host VA arguments as pointers Date: Tue, 4 Aug 2026 12:23:13 +0100 Message-Id: <20260804112317.1937387-8-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Four hypercalls take host VAs as unsigned long: the donated vm, pgd and vcpu regions, and the tracing descriptor. Retype the arguments and their EL2 consumers as void *, so that the typed hypercall declarations introduced later in the series can attach a sparse address space to them; an address space attaches only to pointers. No functional change intended. Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/kvm/hyp/include/nvhe/pkvm.h | 5 ++--- arch/arm64/kvm/hyp/include/nvhe/trace.h | 4 ++-- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 8 ++++---- arch/arm64/kvm/hyp/nvhe/pkvm.c | 11 +++++------ arch/arm64/kvm/hyp/nvhe/trace.c | 4 ++-- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/in= clude/nvhe/pkvm.h index c904647d2f760..2643a1a819668 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h @@ -69,10 +69,9 @@ void pkvm_hyp_vm_table_init(void *tbl); =20 int __pkvm_reserve_vm(void); void __pkvm_unreserve_vm(pkvm_handle_t handle); -int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva, - unsigned long pgd_hva); +int __pkvm_init_vm(struct kvm *host_kvm, void *vm_hva, void *pgd_hva); int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, - unsigned long vcpu_hva); + void *vcpu_hva); =20 int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 gfn); int __pkvm_start_teardown_vm(pkvm_handle_t handle); diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 8813ff250f8e0..4aa36fd76b9e2 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -46,7 +46,7 @@ static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu= _context *host_ctxt) void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 -int __tracing_load(unsigned long desc_va, size_t desc_size); +int __tracing_load(void *desc_va, size_t desc_size); void __tracing_unload(void); int __tracing_enable(bool enable); int __tracing_swap_reader(unsigned int cpu); @@ -59,7 +59,7 @@ static inline void tracing_commit_entry(void) { } #define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ static inline void trace_##__name(__proto) {} =20 -static inline int __tracing_load(unsigned long desc_va, size_t desc_size) = { return -ENODEV; } +static inline int __tracing_load(void *desc_va, size_t desc_size) { return= -ENODEV; } static inline void __tracing_unload(void) { } static inline int __tracing_enable(bool enable) { return -ENODEV; } static inline int __tracing_swap_reader(unsigned int cpu) { return -ENODEV= ; } diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index d3df96ed8ba42..23cb4313c60a2 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -577,8 +577,8 @@ static void handle___pkvm_unreserve_vm(struct kvm_cpu_c= ontext *host_ctxt) static void handle___pkvm_init_vm(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(struct kvm *, host_kvm, host_ctxt, 1); - DECLARE_REG(unsigned long, vm_hva, host_ctxt, 2); - DECLARE_REG(unsigned long, pgd_hva, host_ctxt, 3); + DECLARE_REG(void *, vm_hva, host_ctxt, 2); + DECLARE_REG(void *, pgd_hva, host_ctxt, 3); =20 host_kvm =3D kern_hyp_va(host_kvm); cpu_reg(host_ctxt, 1) =3D __pkvm_init_vm(host_kvm, vm_hva, pgd_hva); @@ -588,7 +588,7 @@ static void handle___pkvm_init_vcpu(struct kvm_cpu_cont= ext *host_ctxt) { DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 2); - DECLARE_REG(unsigned long, vcpu_hva, host_ctxt, 3); + DECLARE_REG(void *, vcpu_hva, host_ctxt, 3); =20 host_vcpu =3D kern_hyp_va(host_vcpu); cpu_reg(host_ctxt, 1) =3D __pkvm_init_vcpu(handle, host_vcpu, vcpu_hva); @@ -634,7 +634,7 @@ static void handle___pkvm_finalize_teardown_vm(struct k= vm_cpu_context *host_ctxt =20 static void handle___tracing_load(struct kvm_cpu_context *host_ctxt) { - DECLARE_REG(unsigned long, desc_hva, host_ctxt, 1); + DECLARE_REG(void *, desc_hva, host_ctxt, 1); DECLARE_REG(size_t, desc_size, host_ctxt, 2); =20 cpu_reg(host_ctxt, 1) =3D __tracing_load(desc_hva, desc_size); diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 24d6f164129ac..205c52535c887 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -644,9 +644,9 @@ static size_t pkvm_get_hyp_vm_size(unsigned int nr_vcpu= s) size_mul(sizeof(struct pkvm_hyp_vcpu *), nr_vcpus)); } =20 -static void *map_donated_memory_noclear(unsigned long host_va, size_t size) +static void *map_donated_memory_noclear(void *host_va, size_t size) { - void *va =3D (void *)kern_hyp_va(host_va); + void *va =3D kern_hyp_va(host_va); =20 if (!PAGE_ALIGNED(va)) return NULL; @@ -658,7 +658,7 @@ static void *map_donated_memory_noclear(unsigned long h= ost_va, size_t size) return va; } =20 -static void *map_donated_memory(unsigned long host_va, size_t size) +static void *map_donated_memory(void *host_va, size_t size) { void *va =3D map_donated_memory_noclear(host_va, size); =20 @@ -805,8 +805,7 @@ void teardown_selftest_vm(void) * * Return 0 success, negative error code on failure. */ -int __pkvm_init_vm(struct kvm *host_kvm, unsigned long vm_hva, - unsigned long pgd_hva) +int __pkvm_init_vm(struct kvm *host_kvm, void *vm_hva, void *pgd_hva) { struct pkvm_hyp_vm *hyp_vm =3D NULL; size_t vm_size, pgd_size; @@ -897,7 +896,7 @@ static int register_hyp_vcpu(struct pkvm_hyp_vm *hyp_vm, } =20 int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, - unsigned long vcpu_hva) + void *vcpu_hva) { struct pkvm_hyp_vcpu *hyp_vcpu; struct pkvm_hyp_vm *hyp_vm; diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index 177fe3d8fbb13..97203ddd3cf45 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -206,9 +206,9 @@ static bool hyp_trace_desc_is_valid(struct hyp_trace_de= sc *desc, size_t desc_siz return true; } =20 -int __tracing_load(unsigned long desc_hva, size_t desc_size) +int __tracing_load(void *desc_hva, size_t desc_size) { - struct hyp_trace_desc *desc =3D (struct hyp_trace_desc *)kern_hyp_va(desc= _hva); + struct hyp_trace_desc *desc =3D kern_hyp_va(desc_hva); int ret; =20 ret =3D __admit_host_mem(desc, desc_size); --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-182.mta0.migadu.com (out-182.mta0.migadu.com [91.218.175.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5494745D5DF for ; Tue, 4 Aug 2026 11:24:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842694; cv=none; b=Vn2mdD8AviE3CeOXpsTqRgHsAtmmeAGRetJ5m1ly6OXgHUUX6uBr69JbeqxtEQ322F4FX2j+W3gJWGdwI4oaP84M0vomMeU16wcGfB02a6bssBy3aHwj/awbdB7EhhWrpKYHhiPfJzXcsoa7cXpQWtR5y4PPb91q52UyuSexnPo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842694; c=relaxed/simple; bh=eWPvosX4xmUOLdHLHklwkbWwVFF7a9X4ZRTfU1WpQp0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OLqIbGIbWMPR3B8X6dDu4eP6H7qN5wiWJZ8MrypH4zeH0oWpEfcNjUKnii0ADAeiKccM/h5DK3ofakCEo0DWo/N2l3lVnPN+cRpAelodMEbRvYpGSYHv2Lu9KlOk3P4NfxYS1MTVqH17NX2yKF8g9Y7yElGTQudms6h/hivl3xQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=dUm5dGT7; arc=none smtp.client-ip=91.218.175.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="dUm5dGT7" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842687; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8449deZzWWvUrdWZNQWJEv7MjXt9tctoupcrsbbFYlI=; b=dUm5dGT7h7mdyEXIrZxpTMDso4kLOxaXcVYAxe6STHpItV/bTJGMkcs+WLo3LTyl8ab7Ux CTHJROw8Vw7Aixv0Xd8KZ3b/fxIlvdHhYYZ5XWXzKmrmrWjpaEOGpnE4iGlF0fYNFgZtw/ Nxm9HZI8thBeXPemgLLVl/iDJdk810M= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 08/11] KVM: arm64: Move the host hypercall interface to its own header Date: Tue, 4 Aug 2026 12:23:14 +0100 Message-Id: <20260804112317.1937387-9-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Move the kvm_call_hyp() dispatch macros and pkvm_handle_t out of kvm_host.h into a new kvm_hcall.h, giving the host<->hyp hypercall interface a single home that subsequent patches build on to restore type-checking across the boundary. The only adjustment to the moved code is the checkpatch-mandated space in "while (0)". No functional change intended. Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/include/asm/kvm_hcall.h | 68 ++++++++++++++++++++++++++++++ arch/arm64/include/asm/kvm_host.h | 48 +-------------------- 2 files changed, 69 insertions(+), 47 deletions(-) create mode 100644 arch/arm64/include/asm/kvm_hcall.h diff --git a/arch/arm64/include/asm/kvm_hcall.h b/arch/arm64/include/asm/kv= m_hcall.h new file mode 100644 index 0000000000000..d925b2c28a3d8 --- /dev/null +++ b/arch/arm64/include/asm/kvm_hcall.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * The host<->hyp hypercall interface. + * + * Copyright (C) 2026 Google LLC + * Author: Fuad Tabba + */ + +#ifndef __ARM64_KVM_HCALL_H__ +#define __ARM64_KVM_HCALL_H__ + +#include +#include +#include +#include + +#include +#include +#include + +typedef u16 pkvm_handle_t; + +#ifndef __KVM_NVHE_HYPERVISOR__ +#define kvm_call_hyp_nvhe(f, ...) \ + ({ \ + struct arm_smccc_res res; \ + \ + arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(f), \ + ##__VA_ARGS__, &res); \ + if (WARN_ON(res.a0 !=3D SMCCC_RET_SUCCESS)) \ + res.a1 =3D -EOPNOTSUPP; \ + \ + res.a1; \ + }) + +/* + * The isb() below is there to guarantee the same behaviour on VHE as on != VHE, + * where the eret to EL1 acts as a context synchronization event. + */ +#define kvm_call_hyp(f, ...) \ + do { \ + if (has_vhe()) { \ + f(__VA_ARGS__); \ + isb(); \ + } else { \ + kvm_call_hyp_nvhe(f, ##__VA_ARGS__); \ + } \ + } while (0) + +#define kvm_call_hyp_ret(f, ...) \ + ({ \ + typeof(f(__VA_ARGS__)) ret; \ + \ + if (has_vhe()) { \ + ret =3D f(__VA_ARGS__); \ + } else { \ + ret =3D kvm_call_hyp_nvhe(f, ##__VA_ARGS__); \ + } \ + \ + ret; \ + }) +#else /* __KVM_NVHE_HYPERVISOR__ */ +#define kvm_call_hyp(f, ...) f(__VA_ARGS__) +#define kvm_call_hyp_ret(f, ...) f(__VA_ARGS__) +#define kvm_call_hyp_nvhe(f, ...) f(__VA_ARGS__) +#endif /* __KVM_NVHE_HYPERVISOR__ */ + +#endif /* __ARM64_KVM_HCALL_H__ */ diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm= _host.h index bae2c4f92ef5c..81d359ac7af14 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -27,6 +27,7 @@ #include #include #include +#include #include =20 #define __KVM_HAVE_ARCH_INTC_INITIALIZED @@ -251,8 +252,6 @@ struct kvm_smccc_features { unsigned long vendor_hyp_bmap_2; /* Function numbers 64-127 */ }; =20 -typedef u16 pkvm_handle_t; - struct kvm_protected_vm { pkvm_handle_t handle; struct kvm_hyp_memcache teardown_mc; @@ -1252,51 +1251,6 @@ void kvm_arm_resume_guest(struct kvm *kvm); =20 #define vcpu_has_run_once(vcpu) (!!READ_ONCE((vcpu)->pid)) =20 -#ifndef __KVM_NVHE_HYPERVISOR__ -#define kvm_call_hyp_nvhe(f, ...) \ - ({ \ - struct arm_smccc_res res; \ - \ - arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(f), \ - ##__VA_ARGS__, &res); \ - if (WARN_ON(res.a0 !=3D SMCCC_RET_SUCCESS)) \ - res.a1 =3D -EOPNOTSUPP; \ - \ - res.a1; \ - }) - -/* - * The isb() below is there to guarantee the same behaviour on VHE as on != VHE, - * where the eret to EL1 acts as a context synchronization event. - */ -#define kvm_call_hyp(f, ...) \ - do { \ - if (has_vhe()) { \ - f(__VA_ARGS__); \ - isb(); \ - } else { \ - kvm_call_hyp_nvhe(f, ##__VA_ARGS__); \ - } \ - } while(0) - -#define kvm_call_hyp_ret(f, ...) \ - ({ \ - typeof(f(__VA_ARGS__)) ret; \ - \ - if (has_vhe()) { \ - ret =3D f(__VA_ARGS__); \ - } else { \ - ret =3D kvm_call_hyp_nvhe(f, ##__VA_ARGS__); \ - } \ - \ - ret; \ - }) -#else /* __KVM_NVHE_HYPERVISOR__ */ -#define kvm_call_hyp(f, ...) f(__VA_ARGS__) -#define kvm_call_hyp_ret(f, ...) f(__VA_ARGS__) -#define kvm_call_hyp_nvhe(f, ...) f(__VA_ARGS__) -#endif /* __KVM_NVHE_HYPERVISOR__ */ - int handle_exit(struct kvm_vcpu *vcpu, int exception_index); void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index); =20 --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-171.mta0.migadu.com (out-171.mta0.migadu.com [91.218.175.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C59C463B99 for ; Tue, 4 Aug 2026 11:24:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842697; cv=none; b=s8RdXQNdDX7gEAW9s19m78rGcgrSetxcRvUh6G+I2eaXH4xiiyRSofXo4l+iI+WzwiBrpnzS9AnWNWQeQ255SfaaJrMphSM6b//4IIofp6M4tmKZa5wrwzSrCUIJRzyLAPV7Gs4lick/ZF48DrwFO3pJOTCYm3mTp+dX8EZfVhE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842697; c=relaxed/simple; bh=5a9l6Sw6T0J0nBKyDXHAjIiM7aBvuVwEeXIjz+GjzV4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WntMCN2E6zQG+fKmfQZl0kE5YRopFURV8z+SaT1baoovKDVvHUc7VNlCHgd7sGy4vjgyubrkuxcW6lfCv6i1Dx0m2yLKhoRtl2/wkoeGSYeCDp4Fe9mmYFhQXaQTllaXC+pRomdr+h+9XTJnoIdvDomxb0+ftLvDiGASlVjLdwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=QevjB7ql; arc=none smtp.client-ip=91.218.175.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="QevjB7ql" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842690; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jCN0ua4jPnxMt+MX9mcnwd7Rp1FLD6yfINBr+OmlU1M=; b=QevjB7ql5IZfPjZuw++82Ifm9du2Hts9rttzGm6dlrbKVHJh+t5rGHGkxmmkjJ5Et5j++g DZNuF13XB1lzUw3Eiof8HoF9kxYVrP1NK55Wu91ryt6m8TYa46FKLAKKbj0DsRdUPVyJuV u6cQWt36aZgvnX/wHIaG9IRZh3PVDP8= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 09/11] KVM: arm64: Type-check hypercall arguments at the caller Date: Tue, 4 Aug 2026 12:23:15 +0100 Message-Id: <20260804112317.1937387-10-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Marc Zyngier --- arch/arm64/include/asm/kvm_hcall.h | 152 ++++++++++++++++++++++++++++- arch/arm64/kvm/hyp_trace.c | 2 +- 2 files changed, 152 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_hcall.h b/arch/arm64/include/asm/kv= m_hcall.h index d925b2c28a3d8..541331a8d67e1 100644 --- a/arch/arm64/include/asm/kvm_hcall.h +++ b/arch/arm64/include/asm/kvm_hcall.h @@ -9,6 +9,7 @@ #ifndef __ARM64_KVM_HCALL_H__ #define __ARM64_KVM_HCALL_H__ =20 +#include #include #include #include @@ -16,12 +17,37 @@ =20 #include #include +#include #include =20 typedef u16 pkvm_handle_t; =20 +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 . The ladder is indexed by list entries, two per + * argument; __KVM_HCALL_MAP_N() takes that count explicitly. + */ +#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_A= RGS__) +#define __KVM_HCALL_MAP6(m, t, a, ...) m(t, a), __KVM_HCALL_MAP4(m, __VA_A= RGS__) +#define __KVM_HCALL_MAP8(m, t, a, ...) m(t, a), __KVM_HCALL_MAP6(m, __VA_A= RGS__) +#define __KVM_HCALL_MAP10(m, t, a, ...) m(t, a), __KVM_HCALL_MAP8(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__) + +#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 +59,29 @@ typedef u16 pkvm_handle_t; res.a1; \ }) =20 +/* + * 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 functi= on + * 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, ...) \ + static __always_inline \ + ret nvhe_hvc_##name(__KVM_HCALL_MAP(__KVM_HCALL_DECL, __VA_ARGS__)) \ + { \ + return (ret)__kvm_call_hyp_nvhe(name, \ + __KVM_HCALL_MAP(__KVM_HCALL_ARGS, __VA_ARGS__));\ + } + +#define DECLARE_KVM_HOST_HCALL0(ret, name) \ + static __always_inline ret nvhe_hvc_##name(void) \ + { \ + return (ret)__kvm_call_hyp_nvhe(name); \ + } + +#define kvm_call_hyp_nvhe(f, ...) nvhe_hvc_##f(__VA_ARGS__) + /* * The isb() below is there to guarantee the same behaviour on VHE as on != VHE, * where the eret to EL1 acts as a context synchronization event. @@ -63,6 +112,107 @@ typedef u16 pkvm_handle_t; #define kvm_call_hyp(f, ...) f(__VA_ARGS__) #define kvm_call_hyp_ret(f, ...) f(__VA_ARGS__) #define kvm_call_hyp_nvhe(f, ...) f(__VA_ARGS__) + +#define DECLARE_KVM_HOST_HCALL(ret, name, ...) +#define DECLARE_KVM_HOST_HCALL0(ret, name) #endif /* __KVM_NVHE_HYPERVISOR__ */ =20 +/* Hypercalls that are unavailable once pKVM has finalised. */ +DECLARE_KVM_HOST_HCALL(int, __pkvm_init, + phys_addr_t, phys, unsigned long, size, + unsigned long *, per_cpu_base, u32, hyp_va_bits) +DECLARE_KVM_HOST_HCALL(ulong, __pkvm_create_private_mapping, + phys_addr_t, phys, size_t, size, u64, prot) +DECLARE_KVM_HOST_HCALL(int, __pkvm_cpu_set_vector, + enum arm64_hyp_spectre_vector, slot) +DECLARE_KVM_HOST_HCALL0(void, __kvm_enable_ssbs) +DECLARE_KVM_HOST_HCALL0(void, __vgic_v3_init_lrs) +DECLARE_KVM_HOST_HCALL0(u64, __vgic_v3_get_gic_config) + +DECLARE_KVM_HOST_HCALL0(int, __pkvm_prot_finalize) + +/* Hypercalls that are always available and common to [nh]VHE/pKVM. */ +DECLARE_KVM_HOST_HCALL(void, __kvm_adjust_pc, + struct kvm_vcpu *, vcpu) +DECLARE_KVM_HOST_HCALL(int, __kvm_vcpu_run, + struct kvm_vcpu *, vcpu) +DECLARE_KVM_HOST_HCALL0(void, __kvm_flush_vm_context) +DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa, + struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) +DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa_nsh, + struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) +DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid, + struct kvm_s2_mmu *, mmu) +DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_range, + struct kvm_s2_mmu *, mmu, phys_addr_t, start, unsigned long, pages) +DECLARE_KVM_HOST_HCALL(void, __kvm_flush_cpu_context, + struct kvm_s2_mmu *, mmu) +DECLARE_KVM_HOST_HCALL(void, __kvm_timer_set_cntvoff, + u64, cntvoff) +DECLARE_KVM_HOST_HCALL(int, __tracing_load, + void *, desc_hva, size_t, desc_size) +DECLARE_KVM_HOST_HCALL0(void, __tracing_unload) +DECLARE_KVM_HOST_HCALL(int, __tracing_enable, + bool, enable) +DECLARE_KVM_HOST_HCALL(int, __tracing_swap_reader, + unsigned int, cpu) +DECLARE_KVM_HOST_HCALL(void, __tracing_update_clock, + u32, mult, u32, shift, u64, epoch_ns, u64, epoch_cyc) +DECLARE_KVM_HOST_HCALL(int, __tracing_reset, + unsigned int, cpu) +DECLARE_KVM_HOST_HCALL(int, __tracing_enable_event, + unsigned short, id, bool, enable) +DECLARE_KVM_HOST_HCALL(void, __tracing_write_event, + u64, id) +DECLARE_KVM_HOST_HCALL(void, __vgic_v3_save_aprs, + struct vgic_v3_cpu_if *, cpu_if) +DECLARE_KVM_HOST_HCALL(void, __vgic_v3_restore_vmcr_aprs, + struct vgic_v3_cpu_if *, cpu_if) +DECLARE_KVM_HOST_HCALL(void, __vgic_v5_save_apr, + struct vgic_v5_cpu_if *, cpu_if) +DECLARE_KVM_HOST_HCALL(void, __vgic_v5_restore_vmcr_apr, + struct vgic_v5_cpu_if *, cpu_if) + +/* Hypercalls that are available only when pKVM has finalised. */ +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_share_hyp, + u64, pfn) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_unshare_hyp, + u64, pfn) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_donate_guest, + u64, pfn, u64, gfn) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_share_guest, + u64, pfn, u64, gfn, u64, nr_pages, u64, prot) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_unshare_guest, + pkvm_handle_t, handle, u64, gfn, u64, nr_pages) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_relax_perms_guest, + u64, gfn, u64, prot) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_wrprotect_guest, + pkvm_handle_t, handle, u64, gfn, u64, nr_pages) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_test_clear_young_guest, + pkvm_handle_t, handle, u64, gfn, u64, nr_pages, bool, mkold) +DECLARE_KVM_HOST_HCALL(int, __pkvm_host_mkyoung_guest, + u64, gfn) +DECLARE_KVM_HOST_HCALL0(int, __pkvm_reserve_vm) +DECLARE_KVM_HOST_HCALL(void, __pkvm_unreserve_vm, + pkvm_handle_t, handle) +DECLARE_KVM_HOST_HCALL(int, __pkvm_init_vm, + struct kvm *, host_kvm, void *, vm_hva, void *, pgd_hva) +DECLARE_KVM_HOST_HCALL(int, __pkvm_init_vcpu, + pkvm_handle_t, handle, struct kvm_vcpu *, host_vcpu, + void *, vcpu_hva) +DECLARE_KVM_HOST_HCALL0(int, __pkvm_vcpu_in_poison_fault) +DECLARE_KVM_HOST_HCALL(int, __pkvm_force_reclaim_guest_page, + phys_addr_t, phys) +DECLARE_KVM_HOST_HCALL(int, __pkvm_reclaim_dying_guest_page, + pkvm_handle_t, handle, u64, gfn) +DECLARE_KVM_HOST_HCALL(int, __pkvm_start_teardown_vm, + pkvm_handle_t, handle) +DECLARE_KVM_HOST_HCALL(int, __pkvm_finalize_teardown_vm, + pkvm_handle_t, handle) +DECLARE_KVM_HOST_HCALL(void, __pkvm_vcpu_load, + pkvm_handle_t, handle, unsigned int, vcpu_idx, u64, hcr_el2) +DECLARE_KVM_HOST_HCALL0(void, __pkvm_vcpu_put) +DECLARE_KVM_HOST_HCALL(void, __pkvm_tlb_flush_vmid, + pkvm_handle_t, handle) + #endif /* __ARM64_KVM_HCALL_H__ */ diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c index 9644c424819b7..44937e257375a 100644 --- a/arch/arm64/kvm/hyp_trace.c +++ b/arch/arm64/kvm/hyp_trace.c @@ -269,7 +269,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigne= d long size, void *priv) if (ret) goto err_free_buffer; =20 - ret =3D kvm_call_hyp_nvhe(__tracing_load, (unsigned long)desc, desc_size); + ret =3D kvm_call_hyp_nvhe(__tracing_load, desc, desc_size); if (ret) goto err_unload_pages; =20 --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-165.mta1.migadu.com (out-165.mta1.migadu.com [95.215.58.165]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 484E343849B; Tue, 4 Aug 2026 11:25:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.165 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842735; cv=none; b=ZiI6LzELXyFLbFNEjGb0QogzGgXjMIVsWOwUR2e1O+RJt+UpYvXElSadPl3UrNXxSMFw84olNK7qi2QkYMoqEqVj3YXb0YULdzoGmf/G8jfatdSrIXsNds2ABruEESR32bLk4kZ1HqxKTlUPPati8eRL2c8hFAa3AGe6q+aIqbA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842735; c=relaxed/simple; bh=N0pteTNOvRjcmqU3N3qqB1lpbPvVEvuenDsvcnQdumI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NEu4fBXpNTy6gF32Xoo5y6C3Hb78VHgC0WulUinUWr/d6mBhHnGf1J32LB9LfUfoo0tufsBzi+AngiLuLtRw+bRYf9iqkXHdhLsi+hbzrhXG6plVUUENSxVmXvQqAMAcYx9UHMfctMx28HJzOHBWcLcYe+h+ccSjZYTROW6j3wI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=YI5nUiz9; arc=none smtp.client-ip=95.215.58.165 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="YI5nUiz9" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842730; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ZHD6A4UIQQgIZMwmWm7fVgNNHXZHotPGBDcCnToNBaQ=; b=YI5nUiz9ad6UuIienytS6X2Q6CdA/yLgebmYWyZ5xozI73A5PTfAwHui5heKml017aEyag 4PYlwOsC91Ec2JbDAWjy0WzGjRFXLeVashjvw2mQk8BZPRSZ4XRMIZoh6GHixDim8iR5VH g7Wl05s+HILOulJWWb2uMXt45V4eSXg= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 10/11] KVM: arm64: nVHE: Check hypercall handlers against the declared ABI Date: Tue, 4 Aug 2026 12:23:16 +0100 Message-Id: <20260804112317.1937387-11-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Each hypercall handler unmarshals its arguments from the host context with hand-written DECLARE_REG() casts that nothing ties to what the caller passed: a handler can disagree with its caller in argument type, count or register index without a diagnostic. Generate the unmarshalling instead. DEFINE_KVM_HOST_HCALL() expands to the handle_() glue, modelled on the syscall wrappers, and checks the handler's parameter list against the signature declared in kvm_hcall.h, so both ends of every hypercall are now compiled against the same declaration. Handler bodies keep their logic and lose the DECLARE_REG() and return-register boilerplate. The compiled handlers are instruction-for-instruction identical, apart from flush_hyp_vcpu() and sync_hyp_vcpu() now being inlined into their only caller. The return-register store is picked by the declared return type, so a void handler needs no macro of its own. The type is pasted into the store's name, which has to be a single word, so __pkvm_create_private_mapping is declared ulong. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/include/asm/kvm_hcall.h | 13 +- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 410 +++++++++++++---------------- 2 files changed, 197 insertions(+), 226 deletions(-) diff --git a/arch/arm64/include/asm/kvm_hcall.h b/arch/arm64/include/asm/kv= m_hcall.h index 541331a8d67e1..8688875fb4005 100644 --- a/arch/arm64/include/asm/kvm_hcall.h +++ b/arch/arm64/include/asm/kvm_hcall.h @@ -44,6 +44,8 @@ struct vgic_v5_cpu_if; #define __KVM_HCALL_MAP(m, ...) __KVM_HCALL_MAP_N(COUNT_ARGS(__VA_ARGS__),= m, __VA_ARGS__) =20 #define __KVM_HCALL_DECL(t, a) t a +#define __KVM_HCALL_LONG(t, a) unsigned long a +#define __KVM_HCALL_CAST(t, a) (__force t) a #define __KVM_HCALL_ARGS(t, a) a =20 #ifndef __KVM_NVHE_HYPERVISOR__ @@ -113,8 +115,15 @@ struct vgic_v5_cpu_if; #define kvm_call_hyp_ret(f, ...) f(__VA_ARGS__) #define kvm_call_hyp_nvhe(f, ...) f(__VA_ARGS__) =20 -#define DECLARE_KVM_HOST_HCALL(ret, name, ...) -#define DECLARE_KVM_HOST_HCALL0(ret, name) +/* + * At EL2 each declaration emits the canonical signature of the hypercall, + * which DEFINE_KVM_HOST_HCALL() in hyp-main.c checks the handler + * definition against. + */ +#define DECLARE_KVM_HOST_HCALL(ret, name, ...) \ + typedef ret kvm_host_hcall_sig_##name(__KVM_HCALL_MAP(__KVM_HCALL_DECL, _= _VA_ARGS__)); +#define DECLARE_KVM_HOST_HCALL0(ret, name) \ + typedef ret kvm_host_hcall_sig_##name(void); #endif /* __KVM_NVHE_HYPERVISOR__ */ =20 /* Hypercalls that are unavailable once pKVM has finalised. */ diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 23cb4313c60a2..675d607727929 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -24,6 +24,48 @@ =20 DEFINE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params); =20 +/* + * Define a hypercall handler: handle_ unmarshals the arguments from + * the host context and hands them, correctly typed, to the body that + * follows the macro. The parameter list is type-checked against the + * signature declared in , so the handler cannot drift + * from what the typed caller stubs marshal in. Modelled on the syscall + * wrappers. + */ +/* Truncate the fixed list of argument registers to the declared signature= . */ +#define KVM_HOST_HCALL_REGS(...) \ + __KVM_HCALL_MAP_N(COUNT_ARGS(__VA_ARGS__), __KVM_HCALL_ARGS \ + ,, cpu_reg(host_ctxt, 1),, cpu_reg(host_ctxt, 2) \ + ,, cpu_reg(host_ctxt, 3),, cpu_reg(host_ctxt, 4) \ + ,, cpu_reg(host_ctxt, 5),, cpu_reg(host_ctxt, 6)) + +#define set_cpu_reg_ulong(ctxt, r, v) { cpu_reg(ctxt, r) =3D v; } +#define set_cpu_reg_u64(ctxt, r, v) { cpu_reg(ctxt, r) =3D v; } +#define set_cpu_reg_int(ctxt, r, v) { cpu_reg(ctxt, r) =3D v; } +#define set_cpu_reg_void(ctxt, r, v) { v; } +#define set_cpu_reg(ctxt, r, t, v) set_cpu_reg_##t(ctxt, r, v) + +#define DEFINE_KVM_HOST_HCALL(ret, name, ...) \ + static kvm_host_hcall_sig_##name __do_##name; \ + static __always_inline \ + ret __se_##name(__KVM_HCALL_MAP(__KVM_HCALL_LONG, __VA_ARGS__)) \ + { \ + return __do_##name(__KVM_HCALL_MAP(__KVM_HCALL_CAST, __VA_ARGS__)); \ + } \ + static void handle_##name(struct kvm_cpu_context *host_ctxt) \ + { \ + set_cpu_reg(host_ctxt, 1, ret, __se_##name(KVM_HOST_HCALL_REGS(__VA_ARGS= __))); \ + } \ + static ret __do_##name(__KVM_HCALL_MAP(__KVM_HCALL_DECL, __VA_ARGS__)) + +#define DEFINE_KVM_HOST_HCALL0(ret, name) \ + static kvm_host_hcall_sig_##name __do_##name; \ + static void handle_##name(struct kvm_cpu_context *host_ctxt) \ + { \ + set_cpu_reg(host_ctxt, 1, ret, __do_##name()); \ + } \ + static ret __do_##name(void) + /* Number of implemented GICv3 LRs. Used by flush_hyp_vcpu(). */ unsigned int hyp_gicv3_nr_lr; =20 @@ -185,11 +227,9 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vc= pu) host_cpu_if->vgic_lr[i] =3D hyp_cpu_if->vgic_lr[i]; } =20 -static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __pkvm_vcpu_load, + pkvm_handle_t, handle, unsigned int, vcpu_idx, u64, hcr_el2) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - DECLARE_REG(unsigned int, vcpu_idx, host_ctxt, 2); - DECLARE_REG(u64, hcr_el2, host_ctxt, 3); struct pkvm_hyp_vcpu *hyp_vcpu; =20 hyp_vcpu =3D pkvm_load_hyp_vcpu(handle, vcpu_idx); @@ -206,7 +246,7 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_cont= ext *host_ctxt) } } =20 -static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL0(void, __pkvm_vcpu_put) { struct pkvm_hyp_vcpu *hyp_vcpu =3D pkvm_get_loaded_hyp_vcpu(); =20 @@ -214,9 +254,9 @@ static void handle___pkvm_vcpu_put(struct kvm_cpu_conte= xt *host_ctxt) pkvm_put_hyp_vcpu(hyp_vcpu); } =20 -static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __kvm_vcpu_run, + struct kvm_vcpu *, host_vcpu) { - DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 1); int ret; =20 if (unlikely(is_protected_kvm_enabled())) { @@ -228,15 +268,11 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_cont= ext *host_ctxt) * loading a vcpu. Therefore, if SME features enabled the host * is misbehaving. */ - if (unlikely(system_supports_sme() && read_sysreg_s(SYS_SVCR))) { - ret =3D -EINVAL; - goto out; - } + if (unlikely(system_supports_sme() && read_sysreg_s(SYS_SVCR))) + return -EINVAL; =20 - if (!hyp_vcpu) { - ret =3D -EINVAL; - goto out; - } + if (!hyp_vcpu) + return -EINVAL; =20 flush_hyp_vcpu(hyp_vcpu); =20 @@ -251,8 +287,8 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_contex= t *host_ctxt) ret =3D __kvm_vcpu_run(vcpu); fpsimd_lazy_switch_to_host(vcpu); } -out: - cpu_reg(host_ctxt, 1) =3D ret; + + return ret; } =20 static int pkvm_refill_memcache(struct pkvm_hyp_vcpu *hyp_vcpu) @@ -264,184 +300,150 @@ static int pkvm_refill_memcache(struct pkvm_hyp_vcp= u *hyp_vcpu) &host_vcpu->arch.pkvm_memcache); } =20 -static void handle___pkvm_host_donate_guest(struct kvm_cpu_context *host_c= txt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_donate_guest, + u64, pfn, u64, gfn) { - DECLARE_REG(u64, pfn, host_ctxt, 1); - DECLARE_REG(u64, gfn, host_ctxt, 2); struct pkvm_hyp_vcpu *hyp_vcpu; - int ret =3D -EINVAL; + int ret; =20 hyp_vcpu =3D pkvm_get_loaded_hyp_vcpu(); if (!hyp_vcpu || !pkvm_hyp_vcpu_is_protected(hyp_vcpu)) - goto out; + return -EINVAL; =20 ret =3D pkvm_refill_memcache(hyp_vcpu); if (ret) - goto out; + return ret; =20 - ret =3D __pkvm_host_donate_guest(pfn, gfn, hyp_vcpu); -out: - cpu_reg(host_ctxt, 1) =3D ret; + return __pkvm_host_donate_guest(pfn, gfn, hyp_vcpu); } =20 -static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ct= xt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_share_guest, + u64, pfn, u64, gfn, u64, nr_pages, u64, prot) { - DECLARE_REG(u64, pfn, host_ctxt, 1); - DECLARE_REG(u64, gfn, host_ctxt, 2); - DECLARE_REG(u64, nr_pages, host_ctxt, 3); - DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4); struct pkvm_hyp_vcpu *hyp_vcpu; - int ret =3D -EINVAL; + int ret; =20 hyp_vcpu =3D pkvm_get_loaded_hyp_vcpu(); if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu)) - goto out; + return -EINVAL; =20 ret =3D pkvm_refill_memcache(hyp_vcpu); if (ret) - goto out; + return ret; =20 - ret =3D __pkvm_host_share_guest(pfn, gfn, nr_pages, hyp_vcpu, prot); -out: - cpu_reg(host_ctxt, 1) =3D ret; + return __pkvm_host_share_guest(pfn, gfn, nr_pages, hyp_vcpu, prot); } =20 -static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_= ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_unshare_guest, + pkvm_handle_t, handle, u64, gfn, u64, nr_pages) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - DECLARE_REG(u64, gfn, host_ctxt, 2); - DECLARE_REG(u64, nr_pages, host_ctxt, 3); struct pkvm_hyp_vm *hyp_vm; - int ret =3D -EINVAL; + int ret; =20 hyp_vm =3D get_np_pkvm_hyp_vm(handle); if (!hyp_vm) - goto out; + return -EINVAL; =20 ret =3D __pkvm_host_unshare_guest(gfn, nr_pages, hyp_vm); put_pkvm_hyp_vm(hyp_vm); -out: - cpu_reg(host_ctxt, 1) =3D ret; + + return ret; } =20 -static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *h= ost_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_relax_perms_guest, + u64, gfn, u64, prot) { - DECLARE_REG(u64, gfn, host_ctxt, 1); - DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 2); struct pkvm_hyp_vcpu *hyp_vcpu; - int ret =3D -EINVAL; =20 hyp_vcpu =3D pkvm_get_loaded_hyp_vcpu(); if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu)) - goto out; + return -EINVAL; =20 - ret =3D __pkvm_host_relax_perms_guest(gfn, hyp_vcpu, prot); -out: - cpu_reg(host_ctxt, 1) =3D ret; + return __pkvm_host_relax_perms_guest(gfn, hyp_vcpu, prot); } =20 -static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *hos= t_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_wrprotect_guest, + pkvm_handle_t, handle, u64, gfn, u64, nr_pages) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - DECLARE_REG(u64, gfn, host_ctxt, 2); - DECLARE_REG(u64, nr_pages, host_ctxt, 3); struct pkvm_hyp_vm *hyp_vm; - int ret =3D -EINVAL; + int ret; =20 hyp_vm =3D get_np_pkvm_hyp_vm(handle); if (!hyp_vm) - goto out; + return -EINVAL; =20 ret =3D __pkvm_host_wrprotect_guest(gfn, nr_pages, hyp_vm); put_pkvm_hyp_vm(hyp_vm); -out: - cpu_reg(host_ctxt, 1) =3D ret; + + return ret; } =20 -static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_conte= xt *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_test_clear_young_guest, + pkvm_handle_t, handle, u64, gfn, u64, nr_pages, bool, mkold) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - DECLARE_REG(u64, gfn, host_ctxt, 2); - DECLARE_REG(u64, nr_pages, host_ctxt, 3); - DECLARE_REG(bool, mkold, host_ctxt, 4); struct pkvm_hyp_vm *hyp_vm; - int ret =3D -EINVAL; + int ret; =20 hyp_vm =3D get_np_pkvm_hyp_vm(handle); if (!hyp_vm) - goto out; + return -EINVAL; =20 ret =3D __pkvm_host_test_clear_young_guest(gfn, nr_pages, mkold, hyp_vm); put_pkvm_hyp_vm(hyp_vm); -out: - cpu_reg(host_ctxt, 1) =3D ret; + + return ret; } =20 -static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_= ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_mkyoung_guest, + u64, gfn) { - DECLARE_REG(u64, gfn, host_ctxt, 1); struct pkvm_hyp_vcpu *hyp_vcpu; - int ret =3D -EINVAL; =20 hyp_vcpu =3D pkvm_get_loaded_hyp_vcpu(); if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu)) - goto out; + return -EINVAL; =20 - ret =3D __pkvm_host_mkyoung_guest(gfn, hyp_vcpu); -out: - cpu_reg(host_ctxt, 1) =3D ret; + return __pkvm_host_mkyoung_guest(gfn, hyp_vcpu); } =20 -static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __kvm_adjust_pc, + struct kvm_vcpu *, vcpu) { - DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); - __kvm_adjust_pc(kern_hyp_va(vcpu)); } =20 -static void handle___kvm_flush_vm_context(struct kvm_cpu_context *host_ctx= t) +DEFINE_KVM_HOST_HCALL0(void, __kvm_flush_vm_context) { __kvm_flush_vm_context(); } =20 -static void handle___kvm_tlb_flush_vmid_ipa(struct kvm_cpu_context *host_c= txt) +DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa, + struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) { - DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - DECLARE_REG(phys_addr_t, ipa, host_ctxt, 2); - DECLARE_REG(int, level, host_ctxt, 3); - __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); } =20 -static void handle___kvm_tlb_flush_vmid_ipa_nsh(struct kvm_cpu_context *ho= st_ctxt) +DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa_nsh, + struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) { - DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - DECLARE_REG(phys_addr_t, ipa, host_ctxt, 2); - DECLARE_REG(int, level, host_ctxt, 3); - __kvm_tlb_flush_vmid_ipa_nsh(kern_hyp_va(mmu), ipa, level); } =20 -static void -handle___kvm_tlb_flush_vmid_range(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_range, + struct kvm_s2_mmu *, mmu, phys_addr_t, start, unsigned long, pages) { - DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - DECLARE_REG(phys_addr_t, start, host_ctxt, 2); - DECLARE_REG(unsigned long, pages, host_ctxt, 3); - __kvm_tlb_flush_vmid_range(kern_hyp_va(mmu), start, pages); } =20 -static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid, + struct kvm_s2_mmu *, mmu) { - DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); } =20 -static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __pkvm_tlb_flush_vmid, + pkvm_handle_t, handle) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); struct pkvm_hyp_vm *hyp_vm =3D get_np_pkvm_hyp_vm(handle); =20 if (!hyp_vm) @@ -451,19 +453,19 @@ static void handle___pkvm_tlb_flush_vmid(struct kvm_c= pu_context *host_ctxt) put_pkvm_hyp_vm(hyp_vm); } =20 -static void handle___kvm_flush_cpu_context(struct kvm_cpu_context *host_ct= xt) +DEFINE_KVM_HOST_HCALL(void, __kvm_flush_cpu_context, + struct kvm_s2_mmu *, mmu) { - DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); - __kvm_flush_cpu_context(kern_hyp_va(mmu)); } =20 -static void handle___kvm_timer_set_cntvoff(struct kvm_cpu_context *host_ct= xt) +DEFINE_KVM_HOST_HCALL(void, __kvm_timer_set_cntvoff, + u64, cntvoff) { - __kvm_timer_set_cntvoff(cpu_reg(host_ctxt, 1)); + __kvm_timer_set_cntvoff(cntvoff); } =20 -static void handle___kvm_enable_ssbs(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL0(void, __kvm_enable_ssbs) { u64 tmp; =20 @@ -472,72 +474,61 @@ static void handle___kvm_enable_ssbs(struct kvm_cpu_c= ontext *host_ctxt) write_sysreg_el2(tmp, SYS_SCTLR); } =20 -static void handle___vgic_v3_get_gic_config(struct kvm_cpu_context *host_c= txt) +DEFINE_KVM_HOST_HCALL0(u64, __vgic_v3_get_gic_config) { - cpu_reg(host_ctxt, 1) =3D __vgic_v3_get_gic_config(); + return __vgic_v3_get_gic_config(); } =20 -static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL0(void, __vgic_v3_init_lrs) { __vgic_v3_init_lrs(); } =20 -static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __vgic_v3_save_aprs, + struct vgic_v3_cpu_if *, cpu_if) { - DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); - __vgic_v3_save_aprs(kern_hyp_va(cpu_if)); } =20 -static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *hos= t_ctxt) +DEFINE_KVM_HOST_HCALL(void, __vgic_v3_restore_vmcr_aprs, + struct vgic_v3_cpu_if *, cpu_if) { - DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1); - __vgic_v3_restore_vmcr_aprs(kern_hyp_va(cpu_if)); } =20 -static void handle___pkvm_init(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_init, + phys_addr_t, phys, unsigned long, size, + unsigned long *, per_cpu_base, u32, hyp_va_bits) { - DECLARE_REG(phys_addr_t, phys, host_ctxt, 1); - DECLARE_REG(unsigned long, size, host_ctxt, 2); - DECLARE_REG(unsigned long *, per_cpu_base, host_ctxt, 3); - DECLARE_REG(u32, hyp_va_bits, host_ctxt, 4); - /* * __pkvm_init() will return only if an error occurred, otherwise it * will tail-call in __pkvm_init_finalise() which will have to deal * with the host context directly. */ - cpu_reg(host_ctxt, 1) =3D __pkvm_init(phys, size, per_cpu_base, hyp_va_bi= ts); + return __pkvm_init(phys, size, per_cpu_base, hyp_va_bits); } =20 -static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_cpu_set_vector, + enum arm64_hyp_spectre_vector, slot) { - DECLARE_REG(enum arm64_hyp_spectre_vector, slot, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D pkvm_cpu_set_vector(slot); + return pkvm_cpu_set_vector(slot); } =20 -static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_share_hyp, + u64, pfn) { - DECLARE_REG(u64, pfn, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __pkvm_host_share_hyp(pfn); + return __pkvm_host_share_hyp(pfn); } =20 -static void handle___pkvm_host_unshare_hyp(struct kvm_cpu_context *host_ct= xt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_host_unshare_hyp, + u64, pfn) { - DECLARE_REG(u64, pfn, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __pkvm_host_unshare_hyp(pfn); + return __pkvm_host_unshare_hyp(pfn); } =20 -static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *h= ost_ctxt) +DEFINE_KVM_HOST_HCALL(ulong, __pkvm_create_private_mapping, + phys_addr_t, phys, size_t, size, u64, prot) { - DECLARE_REG(phys_addr_t, phys, host_ctxt, 1); - DECLARE_REG(size_t, size, host_ctxt, 2); - DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 3); - /* * __pkvm_create_private_mapping() populates a pointer with the * hypervisor start address of the allocation. @@ -548,160 +539,131 @@ static void handle___pkvm_create_private_mapping(st= ruct kvm_cpu_context *host_ct * Instead pass the allocation address as the return value (or return * ERR_PTR() on failure). */ - unsigned long haddr; + ulong haddr; int err =3D __pkvm_create_private_mapping(phys, size, prot, &haddr); =20 if (err) - haddr =3D (unsigned long)ERR_PTR(err); + haddr =3D (ulong)ERR_PTR(err); =20 - cpu_reg(host_ctxt, 1) =3D haddr; + return haddr; } =20 -static void handle___pkvm_prot_finalize(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL0(int, __pkvm_prot_finalize) { - cpu_reg(host_ctxt, 1) =3D __pkvm_prot_finalize(); + return __pkvm_prot_finalize(); } =20 -static void handle___pkvm_reserve_vm(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL0(int, __pkvm_reserve_vm) { - cpu_reg(host_ctxt, 1) =3D __pkvm_reserve_vm(); + return __pkvm_reserve_vm(); } =20 -static void handle___pkvm_unreserve_vm(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __pkvm_unreserve_vm, + pkvm_handle_t, handle) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - __pkvm_unreserve_vm(handle); } =20 -static void handle___pkvm_init_vm(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_init_vm, + struct kvm *, host_kvm, void *, vm_hva, void *, pgd_hva) { - DECLARE_REG(struct kvm *, host_kvm, host_ctxt, 1); - DECLARE_REG(void *, vm_hva, host_ctxt, 2); - DECLARE_REG(void *, pgd_hva, host_ctxt, 3); - - host_kvm =3D kern_hyp_va(host_kvm); - cpu_reg(host_ctxt, 1) =3D __pkvm_init_vm(host_kvm, vm_hva, pgd_hva); + return __pkvm_init_vm(kern_hyp_va(host_kvm), vm_hva, pgd_hva); } =20 -static void handle___pkvm_init_vcpu(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_init_vcpu, + pkvm_handle_t, handle, struct kvm_vcpu *, host_vcpu, + void *, vcpu_hva) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - DECLARE_REG(struct kvm_vcpu *, host_vcpu, host_ctxt, 2); - DECLARE_REG(void *, vcpu_hva, host_ctxt, 3); - - host_vcpu =3D kern_hyp_va(host_vcpu); - cpu_reg(host_ctxt, 1) =3D __pkvm_init_vcpu(handle, host_vcpu, vcpu_hva); + return __pkvm_init_vcpu(handle, kern_hyp_va(host_vcpu), vcpu_hva); } =20 -static void handle___pkvm_vcpu_in_poison_fault(struct kvm_cpu_context *hos= t_ctxt) +DEFINE_KVM_HOST_HCALL0(int, __pkvm_vcpu_in_poison_fault) { - int ret; struct pkvm_hyp_vcpu *hyp_vcpu =3D pkvm_get_loaded_hyp_vcpu(); =20 - ret =3D hyp_vcpu ? __pkvm_vcpu_in_poison_fault(hyp_vcpu) : -EINVAL; - cpu_reg(host_ctxt, 1) =3D ret; + return hyp_vcpu ? __pkvm_vcpu_in_poison_fault(hyp_vcpu) : -EINVAL; } =20 -static void handle___pkvm_force_reclaim_guest_page(struct kvm_cpu_context = *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_force_reclaim_guest_page, + phys_addr_t, phys) { - DECLARE_REG(phys_addr_t, phys, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __pkvm_host_force_reclaim_page_guest(phys); + return __pkvm_host_force_reclaim_page_guest(phys); } =20 -static void handle___pkvm_reclaim_dying_guest_page(struct kvm_cpu_context = *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_reclaim_dying_guest_page, + pkvm_handle_t, handle, u64, gfn) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - DECLARE_REG(u64, gfn, host_ctxt, 2); - - cpu_reg(host_ctxt, 1) =3D __pkvm_reclaim_dying_guest_page(handle, gfn); + return __pkvm_reclaim_dying_guest_page(handle, gfn); } =20 -static void handle___pkvm_start_teardown_vm(struct kvm_cpu_context *host_c= txt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_start_teardown_vm, + pkvm_handle_t, handle) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __pkvm_start_teardown_vm(handle); + return __pkvm_start_teardown_vm(handle); } =20 -static void handle___pkvm_finalize_teardown_vm(struct kvm_cpu_context *hos= t_ctxt) +DEFINE_KVM_HOST_HCALL(int, __pkvm_finalize_teardown_vm, + pkvm_handle_t, handle) { - DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __pkvm_finalize_teardown_vm(handle); + return __pkvm_finalize_teardown_vm(handle); } =20 -static void handle___tracing_load(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __tracing_load, + void *, desc_hva, size_t, desc_size) { - DECLARE_REG(void *, desc_hva, host_ctxt, 1); - DECLARE_REG(size_t, desc_size, host_ctxt, 2); - - cpu_reg(host_ctxt, 1) =3D __tracing_load(desc_hva, desc_size); + return __tracing_load(desc_hva, desc_size); } =20 -static void handle___tracing_unload(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL0(void, __tracing_unload) { __tracing_unload(); } =20 -static void handle___tracing_enable(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __tracing_enable, + bool, enable) { - DECLARE_REG(bool, enable, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __tracing_enable(enable); + return __tracing_enable(enable); } =20 -static void handle___tracing_swap_reader(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __tracing_swap_reader, + unsigned int, cpu) { - DECLARE_REG(unsigned int, cpu, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __tracing_swap_reader(cpu); + return __tracing_swap_reader(cpu); } =20 -static void handle___tracing_update_clock(struct kvm_cpu_context *host_ctx= t) +DEFINE_KVM_HOST_HCALL(void, __tracing_update_clock, + u32, mult, u32, shift, u64, epoch_ns, u64, epoch_cyc) { - DECLARE_REG(u32, mult, host_ctxt, 1); - DECLARE_REG(u32, shift, host_ctxt, 2); - DECLARE_REG(u64, epoch_ns, host_ctxt, 3); - DECLARE_REG(u64, epoch_cyc, host_ctxt, 4); - __tracing_update_clock(mult, shift, epoch_ns, epoch_cyc); } =20 -static void handle___tracing_reset(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(int, __tracing_reset, + unsigned int, cpu) { - DECLARE_REG(unsigned int, cpu, host_ctxt, 1); - - cpu_reg(host_ctxt, 1) =3D __tracing_reset(cpu); + return __tracing_reset(cpu); } =20 -static void handle___tracing_enable_event(struct kvm_cpu_context *host_ctx= t) +DEFINE_KVM_HOST_HCALL(int, __tracing_enable_event, + unsigned short, id, bool, enable) { - DECLARE_REG(unsigned short, id, host_ctxt, 1); - DECLARE_REG(bool, enable, host_ctxt, 2); - - cpu_reg(host_ctxt, 1) =3D __tracing_enable_event(id, enable); + return __tracing_enable_event(id, enable); } =20 -static void handle___tracing_write_event(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __tracing_write_event, + u64, id) { - DECLARE_REG(u64, id, host_ctxt, 1); - trace_selftest(id); } =20 -static void handle___vgic_v5_save_apr(struct kvm_cpu_context *host_ctxt) +DEFINE_KVM_HOST_HCALL(void, __vgic_v5_save_apr, + struct vgic_v5_cpu_if *, cpu_if) { - DECLARE_REG(struct vgic_v5_cpu_if *, cpu_if, host_ctxt, 1); - __vgic_v5_save_apr(kern_hyp_va(cpu_if)); } =20 -static void handle___vgic_v5_restore_vmcr_apr(struct kvm_cpu_context *host= _ctxt) +DEFINE_KVM_HOST_HCALL(void, __vgic_v5_restore_vmcr_apr, + struct vgic_v5_cpu_if *, cpu_if) { - DECLARE_REG(struct vgic_v5_cpu_if *, cpu_if, host_ctxt, 1); - __vgic_v5_restore_vmcr_apr(kern_hyp_va(cpu_if)); } =20 --=20 2.39.5 From nobody Fri Oct 2 06:57:49 2026 Received: from out-183.mta1.migadu.com (out-183.mta1.migadu.com [95.215.58.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 880744582E6 for ; Tue, 4 Aug 2026 11:25:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.183 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842739; cv=none; b=Zr6l+EQYIQXIXmNvVYAzrDCuqTtXe2LkJVzt5IFTy4auEL7r3KqEZFhsq839kuFImzjc4zylx3cAGc9L3sqwtR+GedMgyUdXyA7AkKAHAY/SffKiutIQxdCtOLY4bAgqnklCmNp/DBoIf46VtPqmBKofShrqpCQ6jKRS1OSojn8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785842739; c=relaxed/simple; bh=W/f2MqPcKbNqTP609tDYx9BTt3Xvy1UxR6DzZonNuug=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=DcRtEBm3AjAmA6902KpbQGIuqA0tnecpfH70ViOu6WYbvKih10BfZ1KUQXfFRuM161I2nGE556VXwG2Fl404IJHntme/M5h6XogNEW3LUhKopugMci6dNDfBMrccOCyOT4kRkIy8B0eJ0akDY56OXriKpqrVkXUuM8P8s9mD8sg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=UpOcNIjL; arc=none smtp.client-ip=95.215.58.183 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="UpOcNIjL" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1785842733; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sXfFnsGcA6PeDyCYsmMIOqvu1VZ/vUQ3jHuHXmbJ4BA=; b=UpOcNIjLumy3l959VTsZ6Oau8gXCdNbXZZTOwifeBqmyMDKat0OnBHoCp/VV7XSb7w5Roy O3VSRmBKtN9/Z9hg2IwvxNSd/XXp4Az3dYjQeiZVjNNJQll0JRsvvRCS7BVMY125WVy3BS B0ClCKo+Pw3aPgKSCgcffBSSl7SkIyw= From: Fuad Tabba To: maz@kernel.org, oupton@kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev Cc: 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, fuad.tabba@linux.dev Subject: [PATCH v3 11/11] KVM: arm64: Tag host-VA hypercall parameters __kern Date: Tue, 4 Aug 2026 12:23:17 +0100 Message-Id: <20260804112317.1937387-12-fuad.tabba@linux.dev> In-Reply-To: <20260804112317.1937387-1-fuad.tabba@linux.dev> References: <20260804112317.1937387-1-fuad.tabba@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The nVHE hypervisor takes host virtual addresses as hypercall arguments and translates each with kern_hyp_va() before use. Nothing marks them as host-owned, so dereferencing one untranslated at EL2 - a recurring bug class - is invisible to the compiler. Add a __kern sparse address space, active only for EL2 code, and tag the host-VA parameters in the hypercall declarations. kern_hyp_va_host() is the only sanctioned unwrap: it translates the address, preserves the pointee type (stripped of qualifiers, as with the percpu accessors) and drops the tag with a __force cast, so an untranslated host VA fails sparse. The tag flows from the shared declaration into the generated handler and on into the donated-memory and tracing-descriptor helpers, so a handler cannot extract a host VA without it. Host code sees plain pointers, and the tag is checker-only: no code is generated. Signed-off-by: Fuad Tabba Reviewed-by: Marc Zyngier --- arch/arm64/include/asm/kvm_hcall.h | 43 ++++++++++++------- arch/arm64/include/asm/kvm_mmu.h | 10 +++++ arch/arm64/kvm/hyp/include/nvhe/pkvm.h | 6 ++- arch/arm64/kvm/hyp/include/nvhe/trace.h | 5 ++- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 57 +++++++++++++------------ arch/arm64/kvm/hyp/nvhe/pkvm.c | 11 ++--- arch/arm64/kvm/hyp/nvhe/trace.c | 4 +- 7 files changed, 82 insertions(+), 54 deletions(-) diff --git a/arch/arm64/include/asm/kvm_hcall.h b/arch/arm64/include/asm/kv= m_hcall.h index 8688875fb4005..14ed463527e56 100644 --- a/arch/arm64/include/asm/kvm_hcall.h +++ b/arch/arm64/include/asm/kvm_hcall.h @@ -28,6 +28,18 @@ struct kvm_vcpu; struct vgic_v3_cpu_if; struct vgic_v5_cpu_if; =20 +/* + * A host VA carried by a hypercall argument. At EL2 such a pointer must n= ot + * be dereferenced until it is translated with kern_hyp_va_host(); sparse + * flags any use that skips the translation. The tag describes the EL2 view + * only: the host dereferences its own VAs freely. + */ +#if defined(__KVM_NVHE_HYPERVISOR__) && defined(__CHECKER__) +#define __kern __attribute__((noderef, address_space(__kern))) +#else +#define __kern +#endif + /* * Hypercall signatures are declared as (type, name) argument pairs. * __KVM_HCALL_MAP() applies a macro to each pair, in the mold of __MAP() @@ -142,24 +154,24 @@ DECLARE_KVM_HOST_HCALL0(int, __pkvm_prot_finalize) =20 /* Hypercalls that are always available and common to [nh]VHE/pKVM. */ DECLARE_KVM_HOST_HCALL(void, __kvm_adjust_pc, - struct kvm_vcpu *, vcpu) + struct kvm_vcpu __kern *, vcpu) DECLARE_KVM_HOST_HCALL(int, __kvm_vcpu_run, - struct kvm_vcpu *, vcpu) + struct kvm_vcpu __kern *, vcpu) DECLARE_KVM_HOST_HCALL0(void, __kvm_flush_vm_context) DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa, - struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) + struct kvm_s2_mmu __kern *, mmu, phys_addr_t, ipa, int, level) DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa_nsh, - struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) + struct kvm_s2_mmu __kern *, mmu, phys_addr_t, ipa, int, level) DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid, - struct kvm_s2_mmu *, mmu) + struct kvm_s2_mmu __kern *, mmu) DECLARE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_range, - struct kvm_s2_mmu *, mmu, phys_addr_t, start, unsigned long, pages) + struct kvm_s2_mmu __kern *, mmu, phys_addr_t, start, unsigned long, pages) DECLARE_KVM_HOST_HCALL(void, __kvm_flush_cpu_context, - struct kvm_s2_mmu *, mmu) + struct kvm_s2_mmu __kern *, mmu) DECLARE_KVM_HOST_HCALL(void, __kvm_timer_set_cntvoff, u64, cntvoff) DECLARE_KVM_HOST_HCALL(int, __tracing_load, - void *, desc_hva, size_t, desc_size) + void __kern *, desc_hva, size_t, desc_size) DECLARE_KVM_HOST_HCALL0(void, __tracing_unload) DECLARE_KVM_HOST_HCALL(int, __tracing_enable, bool, enable) @@ -174,13 +186,13 @@ DECLARE_KVM_HOST_HCALL(int, __tracing_enable_event, DECLARE_KVM_HOST_HCALL(void, __tracing_write_event, u64, id) DECLARE_KVM_HOST_HCALL(void, __vgic_v3_save_aprs, - struct vgic_v3_cpu_if *, cpu_if) + struct vgic_v3_cpu_if __kern *, cpu_if) DECLARE_KVM_HOST_HCALL(void, __vgic_v3_restore_vmcr_aprs, - struct vgic_v3_cpu_if *, cpu_if) + struct vgic_v3_cpu_if __kern *, cpu_if) DECLARE_KVM_HOST_HCALL(void, __vgic_v5_save_apr, - struct vgic_v5_cpu_if *, cpu_if) + struct vgic_v5_cpu_if __kern *, cpu_if) DECLARE_KVM_HOST_HCALL(void, __vgic_v5_restore_vmcr_apr, - struct vgic_v5_cpu_if *, cpu_if) + struct vgic_v5_cpu_if __kern *, cpu_if) =20 /* Hypercalls that are available only when pKVM has finalised. */ DECLARE_KVM_HOST_HCALL(int, __pkvm_host_share_hyp, @@ -205,10 +217,11 @@ DECLARE_KVM_HOST_HCALL0(int, __pkvm_reserve_vm) DECLARE_KVM_HOST_HCALL(void, __pkvm_unreserve_vm, pkvm_handle_t, handle) DECLARE_KVM_HOST_HCALL(int, __pkvm_init_vm, - struct kvm *, host_kvm, void *, vm_hva, void *, pgd_hva) + struct kvm __kern *, host_kvm, void __kern *, vm_hva, + void __kern *, pgd_hva) DECLARE_KVM_HOST_HCALL(int, __pkvm_init_vcpu, - pkvm_handle_t, handle, struct kvm_vcpu *, host_vcpu, - void *, vcpu_hva) + pkvm_handle_t, handle, struct kvm_vcpu __kern *, host_vcpu, + void __kern *, vcpu_hva) DECLARE_KVM_HOST_HCALL0(int, __pkvm_vcpu_in_poison_fault) DECLARE_KVM_HOST_HCALL(int, __pkvm_force_reclaim_guest_page, phys_addr_t, phys) diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_= mmu.h index 6eae7e7e2a684..57f65257bb56d 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -7,6 +7,8 @@ #ifndef __ARM64_KVM_MMU_H__ #define __ARM64_KVM_MMU_H__ =20 +#include + #include #include #include @@ -140,6 +142,14 @@ static __always_inline unsigned long __kern_hyp_va(uns= igned long v) =20 #define kern_hyp_va(v) ((typeof(v))(__kern_hyp_va((unsigned long)(v)))) =20 +/* + * Translate a __kern-tagged host VA, dropping the tag: the only sanctioned + * unwrap. Translation only, no ownership or bounds validation; the result + * carries the pointee type stripped of the tag and of any cv-qualifiers. + */ +#define kern_hyp_va_host(v) \ + ((TYPEOF_UNQUAL(*(v)) *)__kern_hyp_va((unsigned long)(__force void *)(v))) + extern u32 __hyp_va_bits; =20 /* diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/in= clude/nvhe/pkvm.h index 2643a1a819668..c1171451e1be7 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h @@ -7,6 +7,7 @@ #ifndef __ARM64_KVM_NVHE_PKVM_H__ #define __ARM64_KVM_NVHE_PKVM_H__ =20 +#include #include =20 #include @@ -69,9 +70,10 @@ void pkvm_hyp_vm_table_init(void *tbl); =20 int __pkvm_reserve_vm(void); void __pkvm_unreserve_vm(pkvm_handle_t handle); -int __pkvm_init_vm(struct kvm *host_kvm, void *vm_hva, void *pgd_hva); +int __pkvm_init_vm(struct kvm *host_kvm, void __kern *vm_hva, + void __kern *pgd_hva); int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, - void *vcpu_hva); + void __kern *vcpu_hva); =20 int __pkvm_reclaim_dying_guest_page(pkvm_handle_t handle, u64 gfn); int __pkvm_start_teardown_vm(pkvm_handle_t handle); diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/i= nclude/nvhe/trace.h index 4aa36fd76b9e2..c2db9f70ea265 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/trace.h +++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h @@ -4,6 +4,7 @@ =20 #include =20 +#include #include =20 static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu_context *host_ct= xt) @@ -46,7 +47,7 @@ static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu= _context *host_ctxt) void *tracing_reserve_entry(unsigned long length); void tracing_commit_entry(void); =20 -int __tracing_load(void *desc_va, size_t desc_size); +int __tracing_load(void __kern *desc_va, size_t desc_size); void __tracing_unload(void); int __tracing_enable(bool enable); int __tracing_swap_reader(unsigned int cpu); @@ -59,7 +60,7 @@ static inline void tracing_commit_entry(void) { } #define HYP_EVENT(__name, __proto, __struct, __assign, __printk) \ static inline void trace_##__name(__proto) {} =20 -static inline int __tracing_load(void *desc_va, size_t desc_size) { return= -ENODEV; } +static inline int __tracing_load(void __kern *desc_va, size_t desc_size) {= return -ENODEV; } static inline void __tracing_unload(void) { } static inline int __tracing_enable(bool enable) { return -ENODEV; } static inline int __tracing_swap_reader(unsigned int cpu) { return -ENODEV= ; } diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/h= yp-main.c index 675d607727929..96dbe18209577 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -255,7 +255,7 @@ DEFINE_KVM_HOST_HCALL0(void, __pkvm_vcpu_put) } =20 DEFINE_KVM_HOST_HCALL(int, __kvm_vcpu_run, - struct kvm_vcpu *, host_vcpu) + struct kvm_vcpu __kern *, host_vcpu) { int ret; =20 @@ -280,7 +280,7 @@ DEFINE_KVM_HOST_HCALL(int, __kvm_vcpu_run, =20 sync_hyp_vcpu(hyp_vcpu); } else { - struct kvm_vcpu *vcpu =3D kern_hyp_va(host_vcpu); + struct kvm_vcpu *vcpu =3D kern_hyp_va_host(host_vcpu); =20 /* The host is fully trusted, run its vCPU directly. */ fpsimd_lazy_switch_to_guest(vcpu); @@ -407,9 +407,9 @@ DEFINE_KVM_HOST_HCALL(int, __pkvm_host_mkyoung_guest, } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_adjust_pc, - struct kvm_vcpu *, vcpu) + struct kvm_vcpu __kern *, vcpu) { - __kvm_adjust_pc(kern_hyp_va(vcpu)); + __kvm_adjust_pc(kern_hyp_va_host(vcpu)); } =20 DEFINE_KVM_HOST_HCALL0(void, __kvm_flush_vm_context) @@ -418,27 +418,27 @@ DEFINE_KVM_HOST_HCALL0(void, __kvm_flush_vm_context) } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa, - struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) + struct kvm_s2_mmu __kern *, mmu, phys_addr_t, ipa, int, level) { - __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); + __kvm_tlb_flush_vmid_ipa(kern_hyp_va_host(mmu), ipa, level); } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_ipa_nsh, - struct kvm_s2_mmu *, mmu, phys_addr_t, ipa, int, level) + struct kvm_s2_mmu __kern *, mmu, phys_addr_t, ipa, int, level) { - __kvm_tlb_flush_vmid_ipa_nsh(kern_hyp_va(mmu), ipa, level); + __kvm_tlb_flush_vmid_ipa_nsh(kern_hyp_va_host(mmu), ipa, level); } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid_range, - struct kvm_s2_mmu *, mmu, phys_addr_t, start, unsigned long, pages) + struct kvm_s2_mmu __kern *, mmu, phys_addr_t, start, unsigned long, pages) { - __kvm_tlb_flush_vmid_range(kern_hyp_va(mmu), start, pages); + __kvm_tlb_flush_vmid_range(kern_hyp_va_host(mmu), start, pages); } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_tlb_flush_vmid, - struct kvm_s2_mmu *, mmu) + struct kvm_s2_mmu __kern *, mmu) { - __kvm_tlb_flush_vmid(kern_hyp_va(mmu)); + __kvm_tlb_flush_vmid(kern_hyp_va_host(mmu)); } =20 DEFINE_KVM_HOST_HCALL(void, __pkvm_tlb_flush_vmid, @@ -454,9 +454,9 @@ DEFINE_KVM_HOST_HCALL(void, __pkvm_tlb_flush_vmid, } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_flush_cpu_context, - struct kvm_s2_mmu *, mmu) + struct kvm_s2_mmu __kern *, mmu) { - __kvm_flush_cpu_context(kern_hyp_va(mmu)); + __kvm_flush_cpu_context(kern_hyp_va_host(mmu)); } =20 DEFINE_KVM_HOST_HCALL(void, __kvm_timer_set_cntvoff, @@ -485,15 +485,15 @@ DEFINE_KVM_HOST_HCALL0(void, __vgic_v3_init_lrs) } =20 DEFINE_KVM_HOST_HCALL(void, __vgic_v3_save_aprs, - struct vgic_v3_cpu_if *, cpu_if) + struct vgic_v3_cpu_if __kern *, cpu_if) { - __vgic_v3_save_aprs(kern_hyp_va(cpu_if)); + __vgic_v3_save_aprs(kern_hyp_va_host(cpu_if)); } =20 DEFINE_KVM_HOST_HCALL(void, __vgic_v3_restore_vmcr_aprs, - struct vgic_v3_cpu_if *, cpu_if) + struct vgic_v3_cpu_if __kern *, cpu_if) { - __vgic_v3_restore_vmcr_aprs(kern_hyp_va(cpu_if)); + __vgic_v3_restore_vmcr_aprs(kern_hyp_va_host(cpu_if)); } =20 DEFINE_KVM_HOST_HCALL(int, __pkvm_init, @@ -565,16 +565,17 @@ DEFINE_KVM_HOST_HCALL(void, __pkvm_unreserve_vm, } =20 DEFINE_KVM_HOST_HCALL(int, __pkvm_init_vm, - struct kvm *, host_kvm, void *, vm_hva, void *, pgd_hva) + struct kvm __kern *, host_kvm, void __kern *, vm_hva, + void __kern *, pgd_hva) { - return __pkvm_init_vm(kern_hyp_va(host_kvm), vm_hva, pgd_hva); + return __pkvm_init_vm(kern_hyp_va_host(host_kvm), vm_hva, pgd_hva); } =20 DEFINE_KVM_HOST_HCALL(int, __pkvm_init_vcpu, - pkvm_handle_t, handle, struct kvm_vcpu *, host_vcpu, - void *, vcpu_hva) + pkvm_handle_t, handle, struct kvm_vcpu __kern *, host_vcpu, + void __kern *, vcpu_hva) { - return __pkvm_init_vcpu(handle, kern_hyp_va(host_vcpu), vcpu_hva); + return __pkvm_init_vcpu(handle, kern_hyp_va_host(host_vcpu), vcpu_hva); } =20 DEFINE_KVM_HOST_HCALL0(int, __pkvm_vcpu_in_poison_fault) @@ -609,7 +610,7 @@ DEFINE_KVM_HOST_HCALL(int, __pkvm_finalize_teardown_vm, } =20 DEFINE_KVM_HOST_HCALL(int, __tracing_load, - void *, desc_hva, size_t, desc_size) + void __kern *, desc_hva, size_t, desc_size) { return __tracing_load(desc_hva, desc_size); } @@ -656,15 +657,15 @@ DEFINE_KVM_HOST_HCALL(void, __tracing_write_event, } =20 DEFINE_KVM_HOST_HCALL(void, __vgic_v5_save_apr, - struct vgic_v5_cpu_if *, cpu_if) + struct vgic_v5_cpu_if __kern *, cpu_if) { - __vgic_v5_save_apr(kern_hyp_va(cpu_if)); + __vgic_v5_save_apr(kern_hyp_va_host(cpu_if)); } =20 DEFINE_KVM_HOST_HCALL(void, __vgic_v5_restore_vmcr_apr, - struct vgic_v5_cpu_if *, cpu_if) + struct vgic_v5_cpu_if __kern *, cpu_if) { - __vgic_v5_restore_vmcr_apr(kern_hyp_va(cpu_if)); + __vgic_v5_restore_vmcr_apr(kern_hyp_va_host(cpu_if)); } =20 typedef void (*hcall_t)(struct kvm_cpu_context *); diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 205c52535c887..9c33d983058a3 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -644,9 +644,9 @@ static size_t pkvm_get_hyp_vm_size(unsigned int nr_vcpu= s) size_mul(sizeof(struct pkvm_hyp_vcpu *), nr_vcpus)); } =20 -static void *map_donated_memory_noclear(void *host_va, size_t size) +static void *map_donated_memory_noclear(void __kern *host_va, size_t size) { - void *va =3D kern_hyp_va(host_va); + void *va =3D kern_hyp_va_host(host_va); =20 if (!PAGE_ALIGNED(va)) return NULL; @@ -658,7 +658,7 @@ static void *map_donated_memory_noclear(void *host_va, = size_t size) return va; } =20 -static void *map_donated_memory(void *host_va, size_t size) +static void *map_donated_memory(void __kern *host_va, size_t size) { void *va =3D map_donated_memory_noclear(host_va, size); =20 @@ -805,7 +805,8 @@ void teardown_selftest_vm(void) * * Return 0 success, negative error code on failure. */ -int __pkvm_init_vm(struct kvm *host_kvm, void *vm_hva, void *pgd_hva) +int __pkvm_init_vm(struct kvm *host_kvm, void __kern *vm_hva, + void __kern *pgd_hva) { struct pkvm_hyp_vm *hyp_vm =3D NULL; size_t vm_size, pgd_size; @@ -896,7 +897,7 @@ static int register_hyp_vcpu(struct pkvm_hyp_vm *hyp_vm, } =20 int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu, - void *vcpu_hva) + void __kern *vcpu_hva) { struct pkvm_hyp_vcpu *hyp_vcpu; struct pkvm_hyp_vm *hyp_vm; diff --git a/arch/arm64/kvm/hyp/nvhe/trace.c b/arch/arm64/kvm/hyp/nvhe/trac= e.c index 97203ddd3cf45..4410006321a99 100644 --- a/arch/arm64/kvm/hyp/nvhe/trace.c +++ b/arch/arm64/kvm/hyp/nvhe/trace.c @@ -206,9 +206,9 @@ static bool hyp_trace_desc_is_valid(struct hyp_trace_de= sc *desc, size_t desc_siz return true; } =20 -int __tracing_load(void *desc_hva, size_t desc_size) +int __tracing_load(void __kern *desc_hva, size_t desc_size) { - struct hyp_trace_desc *desc =3D kern_hyp_va(desc_hva); + struct hyp_trace_desc *desc =3D kern_hyp_va_host(desc_hva); int ret; =20 ret =3D __admit_host_mem(desc, desc_size); --=20 2.39.5