Linux KVM/arm64 development list
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Fuad Tabba" <fuad.tabba@linux.dev>
Cc: kvmarm@lists.linux.dev, "Oliver Upton" <oupton@kernel.org>,
	"Marc Zyngier" <maz@kernel.org>
Subject: Re: [PATCH v5 7/8] KVM: arm64: Add primitives to flush/sync the VGIC state at EL2
Date: Tue, 14 Jul 2026 12:20:15 +0000	[thread overview]
Message-ID: <20260714122015.EDCB71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260714101601.4142645-8-fuad.tabba@linux.dev>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Missing its_vpe copy in flush_hyp_vgic_state breaks GICv4 virtual LPI injection

Pre-existing issues:
- [High] KVM_SET_ONE_REG updates to GICv3 VMCR are silently dropped under pKVM during vcpu_put()
--

--- Patch [7]: [PATCH v5 7/8] KVM: arm64: Add primitives to flush/sync the VGIC state at EL2 ---
commit 5a3c12abf480537e61537f1e45492ee3e349846c
Author: Marc Zyngier <maz@kernel.org>

KVM: arm64: Add primitives to flush/sync the VGIC state at EL2

pKVM performs its own world switch for protected VMs but has no primitives
to move the per-vCPU VGIC state between the host and hypervisor vCPU
contexts. Add flush_hyp_vgic_state() and sync_hyp_vgic_state().

> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index f3233ee343a39..2db56146ec493 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -104,6 +104,45 @@ static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
>  	*host_data_ptr(fp_owner) = FP_STATE_HOST_OWNED;
>  }
>  
> +static void flush_hyp_vgic_state(struct pkvm_hyp_vcpu *hyp_vcpu)
> +{
> +	struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> +	struct vgic_v3_cpu_if *host_cpu_if, *hyp_cpu_if;
> +	unsigned int used_lrs, i;
> +
> +	host_cpu_if	= &host_vcpu->arch.vgic_cpu.vgic_v3;
> +	hyp_cpu_if	= &hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3;
> +
> +	used_lrs	= host_cpu_if->used_lrs;
> +	used_lrs	= min(used_lrs, hyp_gicv3_nr_lr);
> +
> +	hyp_cpu_if->vgic_hcr	= host_cpu_if->vgic_hcr;
> +	/* Should be a one-off */
> +	hyp_cpu_if->vgic_sre	= (ICC_SRE_EL1_DIB |
> +				   ICC_SRE_EL1_DFB |
> +				   ICC_SRE_EL1_SRE);
> +	hyp_cpu_if->used_lrs	= used_lrs;
> +
> +	for (i = 0; i < used_lrs; i++)
> +		hyp_cpu_if->vgic_lr[i] = host_cpu_if->vgic_lr[i];
> +}

[Severity: High]
Does this code miss copying the its_vpe struct?

Previously, this was a full struct assignment. By explicitly copying fields
instead, its_vpe is omitted, leaving its_vpe.its_vm as NULL in the
hypervisor vCPU state.

When the guest runs, __vgic_v3_activate_traps() executes at EL2 and relies
on this field:

arch/arm64/kvm/hyp/vgic-v3-sr.c:__vgic_v3_activate_traps() {
    if (static_branch_unlikely(&vgic_v3_cpuif_trap) ||
        cpu_if->its_vpe.its_vm || !cpu_if->vgic_sre)
        write_gicreg(vgic_ich_hcr_trap_bits() | ICH_HCR_EL2_En, ICH_HCR_EL2);
    ...
}

Since its_vm is NULL, ICH_HCR_EL2_En is not set. Could this break GICv4
direct virtual LPI injection for non-protected guests?

[ ... ]

> @@ -166,9 +199,6 @@ static void flush_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>  static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>  {
>  	struct kvm_vcpu *host_vcpu = hyp_vcpu->host_vcpu;
> -	struct vgic_v3_cpu_if *hyp_cpu_if = &hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3;
> -	struct vgic_v3_cpu_if *host_cpu_if = &host_vcpu->arch.vgic_cpu.vgic_v3;
> -	unsigned int i;
>  
>  	fpsimd_sve_sync(&hyp_vcpu->vcpu);
>  	sync_debug_state(hyp_vcpu);
> @@ -181,10 +211,7 @@ static void sync_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu)
>  
>  	host_vcpu->arch.iflags		= hyp_vcpu->vcpu.arch.iflags;
>  
> -	host_cpu_if->vgic_hcr		= hyp_cpu_if->vgic_hcr;
> -	host_cpu_if->vgic_vmcr		= hyp_cpu_if->vgic_vmcr;
> -	for (i = 0; i < hyp_cpu_if->used_lrs; ++i)
> -		host_cpu_if->vgic_lr[i] = hyp_cpu_if->vgic_lr[i];
> +	sync_hyp_vgic_state(hyp_vcpu);
>  }

[Severity: High]
This is a pre-existing issue, but does handle___vgic_v3_save_aprs()
silently drop userspace modifications to the GICv3 VMCR?

When userspace sets the VMCR register, vcpu_load() first calls
handle___vgic_v3_restore_vmcr_aprs(), which copies host_cpu_if->vgic_vmcr
to the hyp vCPU. KVM_SET_ONE_REG then updates the host copy of the register.

Finally, vcpu_put() calls handle___vgic_v3_save_aprs():

arch/arm64/kvm/hyp/nvhe/hyp-main.c:handle___vgic_v3_save_aprs() {
    ...
    hyp_cpu_if = &hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3;
    ...
    host_cpu_if = &host_vcpu->arch.vgic_cpu.vgic_v3;
    host_cpu_if->vgic_vmcr = hyp_cpu_if->vgic_vmcr;
}

Doesn't this unconditionally overwrite the new host value (set by
KVM_SET_ONE_REG) with the old value stored in the hyp vCPU at load time,
potentially breaking VM migration and state restoration?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260714101601.4142645-1-fuad.tabba@linux.dev?part=7

  reply	other threads:[~2026-07-14 12:20 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
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 [this message]
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=20260714122015.EDCB71F000E9@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox