From: sashiko-bot@kernel.org
To: "Fuad Tabba" <fuad.tabba@linux.dev>
Cc: "Marc Zyngier" <maz@kernel.org>,
kvmarm@lists.linux.dev, "Oliver Upton" <oupton@kernel.org>
Subject: Re: [PATCH v5 6/8] KVM: arm64: Minimise EL2's exposure of host VGIC state during world switch
Date: Tue, 14 Jul 2026 11:53:31 +0000 [thread overview]
Message-ID: <20260714115332.1B2161F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260714101601.4142645-7-fuad.tabba@linux.dev>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] handle___vgic_v3_save_aprs erroneously overwrites the host's vgic_vmcr with a stale EL2 value.
Pre-existing issues:
- [Critical] Incomplete fix leaves identical hypervisor memory corruption vulnerability in GICv5 hypercalls.
- [Critical] The `handle___kvm_adjust_pc` hypercall blindly dereferences a host-provided `vcpu` pointer via `kern_hyp_va()` without validation.
--
--- Patch [6]: [PATCH v5 6/8] KVM: arm64: Minimise EL2's exposure of host VGIC state during world switch ---
commit bad346f74febb306b17aa647c2da5c6747345fe8
Author: Marc Zyngier <maz@kernel.org>
KVM: arm64: Minimise EL2's exposure of host VGIC state during world switch
The host passes a vgic_v3_cpu_if pointer to the __vgic_v3_save_aprs and
__vgic_v3_restore_vmcr_aprs hypercalls, which EL2 dereferences wholesale.
This patch copies only vgic_vmcr and the active priority registers between
EL2's hyp-side state and the host vCPU to minimise exposure.
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 45d717889f6ea..f3233ee343a39 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
[ ... ]
> @@ -508,16 +520,63 @@ static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt)
>
> static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt)
> {
> - DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
> + struct pkvm_hyp_vcpu *hyp_vcpu;
> + struct kvm_vcpu *host_vcpu;
>
> - __vgic_v3_save_aprs(kern_hyp_va(cpu_if));
> + host_vcpu = get_host_hyp_vcpus_from_vgic_v3_cpu_if(host_ctxt, 1,
> + &hyp_vcpu);
> + if (!host_vcpu)
> + return;
> +
> + if (unlikely(hyp_vcpu)) {
> + struct vgic_v3_cpu_if *hyp_cpu_if, *host_cpu_if;
> + int i;
> +
> + hyp_cpu_if = &hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3;
> + __vgic_v3_save_aprs(hyp_cpu_if);
> +
> + host_cpu_if = &host_vcpu->arch.vgic_cpu.vgic_v3;
> + host_cpu_if->vgic_vmcr = hyp_cpu_if->vgic_vmcr;
[Severity: High]
Does this overwrite the host's vgic_vmcr with a stale EL2 value?
When the guest performs an MMIO write to the GICv2 VMCR (emulated on a GICv3
host), the trap is handled at EL1, updating
host_vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr.
Later, if the vCPU is preempted or userspace schedules out,
__vgic_v3_save_aprs is invoked. Because __vgic_v3_save_aprs() does not read
VMCR from hardware, hyp_cpu_if->vgic_vmcr contains the stale value from the
previous guest exit.
This would silently clobber and destroy the EL1's MMIO emulation updates.
[ ... ]
This is a pre-existing issue, but I noticed a similar pattern in
handle___kvm_adjust_pc() in the same file:
arch/arm64/kvm/hyp/nvhe/hyp-main.c:handle___kvm_adjust_pc() {
...
__kvm_adjust_pc(kern_hyp_va(vcpu));
}
[Severity: Critical]
Could this allow an EL1 host to corrupt hypervisor memory?
An EL1 host can call the __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc hypercall
and provide an arbitrary TTBR1 pointer. EL2's handle___kvm_adjust_pc()
applies kern_hyp_va() without bounds-checking or validation.
When __kvm_adjust_pc() is executed:
arch/arm64/kvm/hyp/exception.c:__kvm_adjust_pc() {
if (vcpu_get_flag(vcpu, PENDING_EXCEPTION)) {
...
This dereferences the unvalidated pointer to read flags and modify memory,
giving EL1 the ability to increment 64-bit values in EL2 memory.
This is also a pre-existing issue, but a similar pattern remains in the
GICv5 counterparts:
arch/arm64/kvm/hyp/nvhe/hyp-main.c:handle___vgic_v5_save_apr() {
...
__vgic_v5_save_apr(kern_hyp_va(cpu_if));
}
arch/arm64/kvm/hyp/nvhe/hyp-main.c:handle___vgic_v5_restore_vmcr_apr() {
...
__vgic_v5_restore_vmcr_apr(kern_hyp_va(cpu_if));
}
[Severity: Critical]
Does this leave an identical memory corruption regression?
An EL1 host can call these hypercalls with an arbitrary TTBR1 pointer,
which is directly dereferenced without validation, leading to arbitrary
memory read/write against EL2.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260714101601.4142645-1-fuad.tabba@linux.dev?part=6
next prev parent reply other threads:[~2026-07-14 11:53 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-14 10:15 [PATCH v5 0/8] KVM: arm64: pKVM vCPU state management at EL2 (series A) Fuad Tabba
2026-07-14 10:15 ` [PATCH v5 1/8] KVM: arm64: Extract MPIDR computation into a shared header Fuad Tabba
2026-07-14 10:15 ` [PATCH v5 2/8] KVM: arm64: Make vcpu_{read,write}_sys_reg available to HYP code Fuad Tabba
2026-07-14 10:43 ` sashiko-bot
2026-07-14 11:19 ` Fuad Tabba
2026-07-14 10:52 ` Vincent Donnefort
2026-07-14 15:19 ` Marc Zyngier
2026-07-14 15:32 ` Fuad Tabba
2026-07-14 16:39 ` Marc Zyngier
2026-07-14 16:44 ` Fuad Tabba
2026-07-14 10:15 ` [PATCH v5 3/8] KVM: arm64: Factor out reusable vCPU reset helpers Fuad Tabba
2026-07-14 10:15 ` [PATCH v5 4/8] KVM: arm64: Move PSCI helper functions to a shared header Fuad Tabba
2026-07-14 11:10 ` sashiko-bot
2026-07-14 11:15 ` Fuad Tabba
2026-07-14 10:15 ` [PATCH v5 5/8] KVM: arm64: Add host and hypervisor vCPU lookup primitives Fuad Tabba
2026-07-14 10:15 ` [PATCH v5 6/8] KVM: arm64: Minimise EL2's exposure of host VGIC state during world switch Fuad Tabba
2026-07-14 11:53 ` sashiko-bot [this message]
2026-07-14 12:17 ` Fuad Tabba
2026-07-14 10:16 ` [PATCH v5 7/8] KVM: arm64: Add primitives to flush/sync the VGIC state at EL2 Fuad Tabba
2026-07-14 12:20 ` sashiko-bot
2026-07-14 13:04 ` Fuad Tabba
2026-07-14 10:16 ` [PATCH v5 8/8] KVM: arm64: Implement lazy vCPU state sync for non-protected guests Fuad Tabba
2026-07-14 12:33 ` sashiko-bot
2026-07-14 13:08 ` Fuad Tabba
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260714115332.1B2161F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=fuad.tabba@linux.dev \
--cc=kvmarm@lists.linux.dev \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.