From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Will Deacon <will@kernel.org>
Cc: kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Quentin Perret <qperret@google.com>,
Fuad Tabba <tabba@google.com>,
Vincent Donnefort <vdonnefort@google.com>,
Mostafa Saleh <smostafa@google.com>
Subject: Re: [PATCH v2 07/35] KVM: arm64: Remove is_protected_kvm_enabled() checks from hypercalls
Date: Tue, 10 Feb 2026 14:53:15 +0000 [thread overview]
Message-ID: <aYtGWwcVrDQeGCma@raptor> (raw)
In-Reply-To: <20260119124629.2563-8-will@kernel.org>
Hi Will,
On Mon, Jan 19, 2026 at 12:46:00PM +0000, Will Deacon wrote:
> When pKVM is not enabled, the host shouldn't issue pKVM-specific
> hypercalls and so there's no point checking for this in the pKVM
> hypercall handlers.
>
> Remove the redundant is_protected_kvm_enabled() checks from each
> hypercall and instead rejig the hypercall table so that the
> pKVM-specific hypercalls are unreachable when pKVM is not being used.
>
> Reviewed-by: Quentin Perret <qperret@google.com>
> Signed-off-by: Will Deacon <will@kernel.org>
> ---
> arch/arm64/include/asm/kvm_asm.h | 20 ++++++----
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 63 ++++++++++--------------------
> 2 files changed, 32 insertions(+), 51 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index a1ad12c72ebf..2076005e9253 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -60,16 +60,9 @@ enum __kvm_host_smccc_func {
> __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs,
> __KVM_HOST_SMCCC_FUNC___vgic_v3_get_gic_config,
> __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize,
> + __KVM_HOST_SMCCC_FUNC_MIN_PKVM = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize,
>
> /* Hypercalls available after pKVM finalisation */
This comment should be removed, I think the functions that follow, up to
and including __KVM_HOST_SMCCC_FUNC_MAX_NO_PKVM, are also available with
kvm-arm.mode=nvhe.
If you agree that the comment should be removed, maybe a different name for
the define above would be more appropriate, one that does not imply pkvm?
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
> - __KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
> __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc,
> __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run,
> __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context,
> @@ -81,6 +74,17 @@ enum __kvm_host_smccc_func {
> __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
> __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs,
> __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
> + __KVM_HOST_SMCCC_FUNC_MAX_NO_PKVM = __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
> +
> + /* Hypercalls available only when pKVM has finalised */
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_relax_perms_guest,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_wrprotect_guest,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_test_clear_young_guest,
> + __KVM_HOST_SMCCC_FUNC___pkvm_host_mkyoung_guest,
> __KVM_HOST_SMCCC_FUNC___pkvm_reserve_vm,
> __KVM_HOST_SMCCC_FUNC___pkvm_unreserve_vm,
> __KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index a7c689152f68..eb5cfe32b2c9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -169,9 +169,6 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
> DECLARE_REG(u64, hcr_el2, host_ctxt, 3);
> struct pkvm_hyp_vcpu *hyp_vcpu;
>
> - if (!is_protected_kvm_enabled())
> - return;
> -
> hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
> if (!hyp_vcpu)
> return;
I've always wondered about this. For some hypercalls, all the handler does is
marshal the arguments for the actual function (for example,
handle___kvm_adjust_pc() -> __kvm_adjust_pc()), but for others, like this one,
the handler also has extra checks before calling the actual function. Would you
mind explaining what the rationale is?
As someone who is not intimately familiar with the code, I find this surprising,
and each time I want to understand what a hypercall does (in this case,
__pkvm_vcpu_load()), I have to remind myself that the handler might also have
code that is relevant if I want to get the full picture.
Thanks,
Alex
> @@ -185,12 +182,8 @@ static void handle___pkvm_vcpu_load(struct kvm_cpu_context *host_ctxt)
>
> static void handle___pkvm_vcpu_put(struct kvm_cpu_context *host_ctxt)
> {
> - struct pkvm_hyp_vcpu *hyp_vcpu;
> + struct pkvm_hyp_vcpu *hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
>
> - if (!is_protected_kvm_enabled())
> - return;
> -
> - hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> if (hyp_vcpu)
> pkvm_put_hyp_vcpu(hyp_vcpu);
> }
> @@ -254,9 +247,6 @@ static void handle___pkvm_host_share_guest(struct kvm_cpu_context *host_ctxt)
> struct pkvm_hyp_vcpu *hyp_vcpu;
> int ret = -EINVAL;
>
w> - if (!is_protected_kvm_enabled())
> - goto out;
> -
> hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> goto out;
> @@ -278,9 +268,6 @@ static void handle___pkvm_host_unshare_guest(struct kvm_cpu_context *host_ctxt)
> struct pkvm_hyp_vm *hyp_vm;
> int ret = -EINVAL;
>
> - if (!is_protected_kvm_enabled())
> - goto out;
> -
> hyp_vm = get_np_pkvm_hyp_vm(handle);
> if (!hyp_vm)
> goto out;
> @@ -298,9 +285,6 @@ static void handle___pkvm_host_relax_perms_guest(struct kvm_cpu_context *host_ct
> struct pkvm_hyp_vcpu *hyp_vcpu;
> int ret = -EINVAL;
>
> - if (!is_protected_kvm_enabled())
> - goto out;
> -
> hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> goto out;
> @@ -318,9 +302,6 @@ static void handle___pkvm_host_wrprotect_guest(struct kvm_cpu_context *host_ctxt
> struct pkvm_hyp_vm *hyp_vm;
> int ret = -EINVAL;
>
> - if (!is_protected_kvm_enabled())
> - goto out;
> -
> hyp_vm = get_np_pkvm_hyp_vm(handle);
> if (!hyp_vm)
> goto out;
> @@ -340,9 +321,6 @@ static void handle___pkvm_host_test_clear_young_guest(struct kvm_cpu_context *ho
> struct pkvm_hyp_vm *hyp_vm;
> int ret = -EINVAL;
>
> - if (!is_protected_kvm_enabled())
> - goto out;
> -
> hyp_vm = get_np_pkvm_hyp_vm(handle);
> if (!hyp_vm)
> goto out;
> @@ -359,9 +337,6 @@ static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
> struct pkvm_hyp_vcpu *hyp_vcpu;
> int ret = -EINVAL;
>
> - if (!is_protected_kvm_enabled())
> - goto out;
> -
> hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
> if (!hyp_vcpu || pkvm_hyp_vcpu_is_protected(hyp_vcpu))
> goto out;
> @@ -421,12 +396,8 @@ static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> static void handle___pkvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt)
> {
> DECLARE_REG(pkvm_handle_t, handle, host_ctxt, 1);
> - struct pkvm_hyp_vm *hyp_vm;
> + struct pkvm_hyp_vm *hyp_vm = get_np_pkvm_hyp_vm(handle);
>
> - if (!is_protected_kvm_enabled())
> - return;
> -
> - hyp_vm = get_np_pkvm_hyp_vm(handle);
> if (!hyp_vm)
> return;
>
> @@ -600,14 +571,6 @@ static const hcall_t host_hcall[] = {
> HANDLE_FUNC(__vgic_v3_get_gic_config),
> HANDLE_FUNC(__pkvm_prot_finalize),
>
> - HANDLE_FUNC(__pkvm_host_share_hyp),
> - HANDLE_FUNC(__pkvm_host_unshare_hyp),
> - HANDLE_FUNC(__pkvm_host_share_guest),
> - HANDLE_FUNC(__pkvm_host_unshare_guest),
> - HANDLE_FUNC(__pkvm_host_relax_perms_guest),
> - HANDLE_FUNC(__pkvm_host_wrprotect_guest),
> - HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
> - HANDLE_FUNC(__pkvm_host_mkyoung_guest),
> HANDLE_FUNC(__kvm_adjust_pc),
> HANDLE_FUNC(__kvm_vcpu_run),
> HANDLE_FUNC(__kvm_flush_vm_context),
> @@ -619,6 +582,15 @@ static const hcall_t host_hcall[] = {
> HANDLE_FUNC(__kvm_timer_set_cntvoff),
> HANDLE_FUNC(__vgic_v3_save_aprs),
> HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
> +
> + HANDLE_FUNC(__pkvm_host_share_hyp),
> + HANDLE_FUNC(__pkvm_host_unshare_hyp),
> + HANDLE_FUNC(__pkvm_host_share_guest),
> + HANDLE_FUNC(__pkvm_host_unshare_guest),
> + HANDLE_FUNC(__pkvm_host_relax_perms_guest),
> + HANDLE_FUNC(__pkvm_host_wrprotect_guest),
> + HANDLE_FUNC(__pkvm_host_test_clear_young_guest),
> + HANDLE_FUNC(__pkvm_host_mkyoung_guest),
> HANDLE_FUNC(__pkvm_reserve_vm),
> HANDLE_FUNC(__pkvm_unreserve_vm),
> HANDLE_FUNC(__pkvm_init_vm),
> @@ -632,7 +604,7 @@ static const hcall_t host_hcall[] = {
> static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> {
> DECLARE_REG(unsigned long, id, host_ctxt, 0);
> - unsigned long hcall_min = 0;
> + unsigned long hcall_min = 0, hcall_max = -1;
> hcall_t hfn;
>
> /*
> @@ -644,14 +616,19 @@ static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> * basis. This is all fine, however, since __pkvm_prot_finalize
> * returns -EPERM after the first call for a given CPU.
> */
> - if (static_branch_unlikely(&kvm_protected_mode_initialized))
> - hcall_min = __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize;
> + if (static_branch_unlikely(&kvm_protected_mode_initialized)) {
> + hcall_min = __KVM_HOST_SMCCC_FUNC_MIN_PKVM;
> + } else {
> + hcall_max = __KVM_HOST_SMCCC_FUNC_MAX_NO_PKVM;
> + }
>
> id &= ~ARM_SMCCC_CALL_HINTS;
> id -= KVM_HOST_SMCCC_ID(0);
>
> - if (unlikely(id < hcall_min || id >= ARRAY_SIZE(host_hcall)))
> + if (unlikely(id < hcall_min || id > hcall_max ||
> + id >= ARRAY_SIZE(host_hcall))) {
> goto inval;
> + }
>
> hfn = host_hcall[id];
> if (unlikely(!hfn))
> --
> 2.52.0.457.g6b5491de43-goog
>
>
next prev parent reply other threads:[~2026-02-10 14:53 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-19 12:45 [PATCH v2 00/35] KVM: arm64: Add support for protected guest memory with pKVM Will Deacon
2026-01-19 12:45 ` [PATCH v2 01/35] KVM: arm64: Invert KVM_PGTABLE_WALK_HANDLE_FAULT to fix pKVM walkers Will Deacon
2026-01-19 12:45 ` [PATCH v2 02/35] KVM: arm64: Don't leak stage-2 page-table if VM fails to init under pKVM Will Deacon
2026-01-19 12:45 ` [PATCH v2 03/35] KVM: arm64: Move handle check into pkvm_pgtable_stage2_destroy_range() Will Deacon
2026-01-19 12:45 ` [PATCH v2 04/35] KVM: arm64: Rename __pkvm_pgtable_stage2_unmap() Will Deacon
2026-01-19 12:45 ` [PATCH v2 05/35] KVM: arm64: Don't advertise unsupported features for protected guests Will Deacon
2026-01-19 12:45 ` [PATCH v2 06/35] KVM: arm64: Expose self-hosted debug regs as RAZ/WI " Will Deacon
2026-01-19 12:46 ` [PATCH v2 07/35] KVM: arm64: Remove is_protected_kvm_enabled() checks from hypercalls Will Deacon
2026-02-10 14:53 ` Alexandru Elisei [this message]
2026-03-03 15:45 ` Will Deacon
2026-03-06 11:33 ` Alexandru Elisei
2026-01-19 12:46 ` [PATCH v2 08/35] KVM: arm64: Ignore MMU notifier callbacks for protected VMs Will Deacon
2026-01-19 12:46 ` [PATCH v2 09/35] KVM: arm64: Prevent unsupported memslot operations on " Will Deacon
2026-01-19 12:46 ` [PATCH v2 10/35] KVM: arm64: Ignore -EAGAIN when mapping in pages for the pKVM host Will Deacon
2026-01-19 12:46 ` [PATCH v2 11/35] KVM: arm64: Split teardown hypercall into two phases Will Deacon
2026-01-19 12:46 ` [PATCH v2 12/35] KVM: arm64: Introduce __pkvm_host_donate_guest() Will Deacon
2026-01-19 12:46 ` [PATCH v2 13/35] KVM: arm64: Hook up donation hypercall to pkvm_pgtable_stage2_map() Will Deacon
2026-01-19 12:46 ` [PATCH v2 14/35] KVM: arm64: Handle aborts from protected VMs Will Deacon
2026-02-12 10:37 ` Alexandru Elisei
2026-03-04 14:06 ` Will Deacon
2026-03-06 11:34 ` Alexandru Elisei
2026-03-11 10:24 ` Fuad Tabba
2026-01-19 12:46 ` [PATCH v2 15/35] KVM: arm64: Introduce __pkvm_reclaim_dying_guest_page() Will Deacon
2026-01-19 12:46 ` [PATCH v2 16/35] KVM: arm64: Hook up reclaim hypercall to pkvm_pgtable_stage2_destroy() Will Deacon
2026-01-19 12:46 ` [PATCH v2 17/35] KVM: arm64: Refactor enter_exception64() Will Deacon
2026-01-19 12:46 ` [PATCH v2 18/35] KVM: arm64: Inject SIGSEGV on illegal accesses Will Deacon
2026-01-19 12:46 ` [PATCH v2 19/35] KVM: arm64: Avoid pointless annotation when mapping host-owned pages Will Deacon
2026-01-19 12:46 ` [PATCH v2 20/35] KVM: arm64: Generalise kvm_pgtable_stage2_set_owner() Will Deacon
2026-01-19 12:46 ` [PATCH v2 21/35] KVM: arm64: Introduce host_stage2_set_owner_metadata_locked() Will Deacon
2026-01-19 12:46 ` [PATCH v2 22/35] KVM: arm64: Change 'pkvm_handle_t' to u16 Will Deacon
2026-01-28 10:28 ` Fuad Tabba
2026-01-19 12:46 ` [PATCH v2 23/35] KVM: arm64: Annotate guest donations with handle and gfn in host stage-2 Will Deacon
2026-01-28 10:29 ` Fuad Tabba
2026-01-19 12:46 ` [PATCH v2 24/35] KVM: arm64: Introduce hypercall to force reclaim of a protected page Will Deacon
2026-02-12 17:18 ` Alexandru Elisei
2026-03-04 14:08 ` Will Deacon
2026-01-19 12:46 ` [PATCH v2 25/35] KVM: arm64: Reclaim faulting page from pKVM in spurious fault handler Will Deacon
2026-02-12 17:22 ` Alexandru Elisei
2026-03-04 14:06 ` Will Deacon
2026-01-19 12:46 ` [PATCH v2 26/35] KVM: arm64: Return -EFAULT from VCPU_RUN on access to a poisoned pte Will Deacon
2026-01-19 12:46 ` [PATCH v2 27/35] KVM: arm64: Add hvc handler at EL2 for hypercalls from protected VMs Will Deacon
2026-01-19 12:46 ` [PATCH v2 28/35] KVM: arm64: Implement the MEM_SHARE hypercall for " Will Deacon
2026-01-19 12:46 ` [PATCH v2 29/35] KVM: arm64: Implement the MEM_UNSHARE " Will Deacon
2026-01-19 12:46 ` [PATCH v2 30/35] KVM: arm64: Allow userspace to create protected VMs when pKVM is enabled Will Deacon
2026-01-19 12:46 ` [PATCH v2 31/35] KVM: arm64: Add some initial documentation for pKVM Will Deacon
2026-01-19 12:46 ` [PATCH v2 32/35] KVM: arm64: Extend pKVM page ownership selftests to cover guest donation Will Deacon
2026-01-19 12:46 ` [PATCH v2 33/35] KVM: arm64: Register 'selftest_vm' in the VM table Will Deacon
2026-01-19 12:46 ` [PATCH v2 34/35] KVM: arm64: Extend pKVM page ownership selftests to cover forced reclaim Will Deacon
2026-01-19 12:46 ` [PATCH v2 35/35] KVM: arm64: Extend pKVM page ownership selftests to cover guest hvcs Will Deacon
2026-02-10 18:58 ` [PATCH v2 00/35] KVM: arm64: Add support for protected guest memory with pKVM Trilok Soni
2026-02-10 19:03 ` Fuad Tabba
2026-02-16 10:58 ` Venkata Rao Kakani
2026-02-16 11:00 ` Fuad Tabba
2026-02-17 10:43 ` Venkata Rao Kakani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aYtGWwcVrDQeGCma@raptor \
--to=alexandru.elisei@arm.com \
--cc=catalin.marinas@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=qperret@google.com \
--cc=smostafa@google.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=vdonnefort@google.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox