All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Oliver Upton" <oupton@kernel.org>
Cc: kvmarm@lists.linux.dev, "Marc Zyngier" <maz@kernel.org>
Subject: Re: [PATCH 04/22] KVM: arm64: nv: Only shadow writable-dirty guest descs as writable
Date: Tue, 23 Jun 2026 18:58:09 +0000	[thread overview]
Message-ID: <20260623185810.08CC61F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260623184201.1518871-5-oupton@kernel.org>

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

New issues:
- [High] Uninitialized or incorrectly evaluated `wr->dirty` field during Stage-1 page table walks causes an infinite VNCR trap loop.

Pre-existing issues:
- [High] Write-Only VNCR mappings cause an infinite trap loop because KVM falls back to `PAGE_KERNEL_NONE` but considers write faults resolved.
--

commit fb5a66a1eb4ac6175aad6cbbd38f45328f4f937b
Author: Oliver Upton <oupton@kernel.org>

KVM: arm64: nv: Only shadow writable-dirty guest descs as writable
    
KVM will soon add support for hardware dirty state management for nested
guests. In order to emulate dirty state transitions on the guest
desciptor, KVM will need to use read-only hardware mappings and re-walk
the guest page tables upon taking a permission fault.
    
Prepare by limiting shadow stage-2 and shadow VNCR translations to
read-only for writable-clean guest translations.

> diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
> index 86b499e7a9a06..7a84495a2e6d4 100644
> --- a/arch/arm64/kvm/at.c
> +++ b/arch/arm64/kvm/at.c
[ ... ]
> @@ -1317,6 +1317,7 @@ static void compute_s1_permissions(struct kvm_vcpu *vcpu,
>  			  (pan3_enabled(vcpu, wi->regime) && wr->ux));
>  	wr->pw &= !pan;
>  	wr->pr &= !pan;
> +	wr->dirty = !(wr->desc & BIT(7));

[Severity: High]
Could the unconditional use of BIT(7) here cause issues when S1PIE is
enabled?

With S1PIE, BIT(7) becomes PIIndex[3], so using it to evaluate the dirty
state might be incorrect.

Also, if the Stage-1 MMU is disabled, __kvm_translate_va() returns early
without initializing wr->dirty:

arch/arm64/kvm/at.c:__kvm_translate_va() {
        if (wr->level == S1_MMU_DISABLED) {
                wr->ur = wr->uw = wr->ux = true;
                wr->pr = wr->pw = wr->px = true;
                return 0;
        }
        ...
}

Since wr->dirty remains false (0-initialized), could this lead to an
infinite VNCR trap loop? If wr->dirty is false, the shadow fixmap mapping
is downgraded to PAGE_KERNEL_RO in kvm_map_l1_vncr().

When a guest writes to the redirected register, kvm_handle_vncr_abort()
sees vt->wr.pw is true, considers the fault handled without injecting a
permission fault, and the hardware immediately retries and traps again.

> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index b247bc1d83fa7..dcc7d0cc7c952 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
[ ... ]
> @@ -1603,7 +1605,7 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
>  
>  	vt->cpu = smp_processor_id();
>  
> -	if (vt->hpa_writable && vt->wr.pw && vt->wr.pr)
> +	if (vt->hpa_writable && vt->wr.pw && vt->wr.dirty && vt->wr.pr)
>  		prot = PAGE_KERNEL;
>  	else if (vt->wr.pr)
>  		prot = PAGE_KERNEL_RO;

[Severity: High]
This is a pre-existing issue, but how does this code handle Write-Only VNCR
mappings?

If a nested guest maps its VNCR page as Write-Only (which is possible using
POE/S1PIE), vt->wr.pr will be false. The logic here then falls through to
mapping it as PAGE_NONE:

arch/arm64/kvm/nested.c:kvm_map_l1_vncr() {
        ...
        else if (vt->wr.pr)
                prot = PAGE_KERNEL_RO;
        else
                prot = PAGE_NONE;
        ...
}

When the guest writes to the register, kvm_handle_vncr_abort() sees
vt->wr.pw is true, assumes the write fault is permitted, and returns 1
without injecting a fault.

The hardware then retries against PAGE_NONE and immediately traps again,
creating an infinite loop that can lock up the host CPU.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260623184201.1518871-1-oupton@kernel.org?part=4

  reply	other threads:[~2026-06-23 18:58 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-23 18:41 [PATCH 00/22] KVM: arm64: nv: Implement FEAT_HAFDBS, FEAT_HAFT Oliver Upton
2026-06-23 18:41 ` [PATCH 01/22] KVM: arm64: nv: Introduce struct for stage-2 walk step Oliver Upton
2026-06-23 18:41 ` [PATCH 02/22] KVM: arm64: nv: Consolidate computation of stage-2 permissions Oliver Upton
2026-06-23 18:57   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 03/22] KVM: arm64: nv: Get rid of kvm_s2_trans*() accessors Oliver Upton
2026-06-23 18:41 ` [PATCH 04/22] KVM: arm64: nv: Only shadow writable-dirty guest descs as writable Oliver Upton
2026-06-23 18:58   ` sashiko-bot [this message]
2026-06-23 20:05     ` Oliver Upton
2026-06-23 18:41 ` [PATCH 05/22] KVM: arm64: nv: Pass an access descriptor for stage-2 walks Oliver Upton
2026-06-23 19:06   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 06/22] KVM: arm64: nv: Use a helper for stage-2 descriptor updates Oliver Upton
2026-06-23 18:41 ` [PATCH 07/22] KVM: arm64: nv: Set dirty state at stage-2 Oliver Upton
2026-06-23 19:03   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 08/22] KVM: arm64: nv: Treat DBM as writable " Oliver Upton
2026-06-23 18:55   ` sashiko-bot
2026-06-23 20:08     ` Oliver Upton
2026-06-23 18:41 ` [PATCH 09/22] KVM: arm64: Compute S1 permissions as part of s1_walk() Oliver Upton
2026-06-23 18:41 ` [PATCH 10/22] KVM: arm64: Plumb through access descriptor for stage-1 Oliver Upton
2026-06-23 18:41 ` [PATCH 11/22] KVM: arm64: Use a struct for stage-1 walk context Oliver Upton
2026-06-23 18:41 ` [PATCH 12/22] KVM: arm64: Create helper for stage-1 descriptor updates Oliver Upton
2026-06-23 18:55   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 13/22] KVM: arm64: Set dirty state at stage-1 Oliver Upton
2026-06-23 18:54   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 14/22] KVM: arm64: Grant write permission when DBM is set at S1 Oliver Upton
2026-06-23 18:57   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 15/22] KVM: arm64: Don't update descriptors for "non-arch" access Oliver Upton
2026-06-23 18:41 ` [PATCH 16/22] KVM: arm64: nv: Expose FEAT_HAFDBS Oliver Upton
2026-06-23 19:01   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 17/22] KVM: arm64: Set Access flag on table descriptors at stage-1 Oliver Upton
2026-06-23 20:56   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 18/22] KVM: arm64: nv: Set access flag on table descriptors at stage-2 Oliver Upton
2026-06-23 19:05   ` sashiko-bot
2026-06-23 20:14     ` Oliver Upton
2026-06-23 18:41 ` [PATCH 19/22] KVM: arm64: nv: Expose FEAT_HAFT Oliver Upton
2026-06-23 19:05   ` sashiko-bot
2026-06-23 18:41 ` [PATCH 20/22] KVM: arm64: selftests: Only test AF behavior for emulated AT insns Oliver Upton
2026-06-23 18:42 ` [PATCH 21/22] KVM: arm64: selftests: Test AT emulation for FEAT_HAFT Oliver Upton
2026-06-23 19:05   ` sashiko-bot
2026-06-23 20:17     ` Oliver Upton
2026-06-23 18:42 ` [PATCH 22/22] HACK: KVM: arm64: nv: Set the dirty state for CMOs that fetch for write Oliver Upton

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=20260623185810.08CC61F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --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.