From: Marc Zyngier <maz@kernel.org>
To: Oliver Upton <oliver.upton@linux.dev>
Cc: Wei-Lin Chang <r09922117@csie.ntu.edu.tw>,
linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.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>,
Will Deacon <will@kernel.org>,
Jintack Lim <jintack@cs.columbia.edu>,
Christoffer Dall <christoffer.dall@arm.com>
Subject: Re: [PATCH] KVM: arm64: nv: Fix s_cpu_if->vgic_lr[] indexing in vgic_v3_put_nested()
Date: Tue, 17 Jun 2025 10:26:01 +0100 [thread overview]
Message-ID: <86o6umd8ie.wl-maz@kernel.org> (raw)
In-Reply-To: <aFD0wHqZ-8CRWIW-@linux.dev>
On Tue, 17 Jun 2025 05:53:20 +0100,
Oliver Upton <oliver.upton@linux.dev> wrote:
>
> On Mon, Jun 16, 2025 at 11:54:57AM +0100, Marc Zyngier wrote:
> > On Sat, 14 Jun 2025 15:57:21 +0100,
> > Wei-Lin Chang <r09922117@csie.ntu.edu.tw> wrote:
> > >
> > > s_cpu_if->vgic_lr[] is filled continuously from index 0 to
> > > s_cpu_if->used_lrs - 1, but vgic_v3_put_nested() is indexing it using
> > > the positions of the set bits in shadow_if->lr_map. So correct it.
> > >
> > > Signed-off-by: Wei-Lin Chang <r09922117@csie.ntu.edu.tw>
> > > ---
> > > arch/arm64/kvm/vgic/vgic-v3-nested.c | 7 ++++---
> > > 1 file changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
> > > index 4f6954c30674..29741e3f077b 100644
> > > --- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
> > > +++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
> > > @@ -343,7 +343,7 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
> > > struct shadow_if *shadow_if = get_shadow_if();
> > > struct vgic_v3_cpu_if *s_cpu_if = &shadow_if->cpuif;
> > > u64 val;
> > > - int i;
> > > + int i, index = 0;
> > >
> > > __vgic_v3_save_vmcr_aprs(s_cpu_if);
> > > __vgic_v3_deactivate_traps(s_cpu_if);
> > > @@ -368,10 +368,11 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
> > > val = __vcpu_sys_reg(vcpu, ICH_LRN(i));
> > >
> > > val &= ~ICH_LR_STATE;
> > > - val |= s_cpu_if->vgic_lr[i] & ICH_LR_STATE;
> > > + val |= s_cpu_if->vgic_lr[index] & ICH_LR_STATE;
> > >
> > > __vcpu_sys_reg(vcpu, ICH_LRN(i)) = val;
> > > - s_cpu_if->vgic_lr[i] = 0;
> > > + s_cpu_if->vgic_lr[index] = 0;
> > > + index++;
> > > }
> > >
> > > shadow_if->lr_map = 0;
> >
> > Nice catch, thanks a lot for tracking it down.
> >
> > However, I think we should get rid of this double-indexing altogether,
> > or at least make it less error-prone. This thing is extremely fragile,
> > and it isn't the first time we are getting bitten with it.
> >
> > Looking at the code, it becomes pretty obvious that the shadow index
> > is always the number of bits set in lr_map, and that we could
> > completely drop the 'index' thing if we simply counted these bits
> > (which isn't that expensive).
> >
> > I came up with the (admittedly much bigger) following fix.
> >
> > Thoughts?
> >
> > M.
> >
> > From 2484950b8fc3b36cca32bf5e86ffe7975a43e0e7 Mon Sep 17 00:00:00 2001
> > From: Marc Zyngier <maz@kernel.org>
> > Date: Sun, 15 Jun 2025 16:11:38 +0100
> > Subject: [PATCH] KVM: arm64: nv: Fix tracking of shadow list registers
> >
> > Wei-Lin reports that the tracking of shadow list registers is
> > majorly broken when resync'ing the L2 state after a run, as
> > we confuse the guest's LR index with the host's, potentially
> > losing the interrupt state.
> >
> > While this could be fixed by adding yet another side index to
> > track it (Wei-Lin's fix), it may be better to refactor this
> > code to avoid having a side index altogether, limiting the
> > risk to introduce this class of bugs.
> >
> > A key observation is that the shadow index is always the number
> > of bits in the lr_map bitmap. With that, the parallel indexing
> > scheme can be completely dropped.
> >
> > While doing this, introduce a couple of helpers that abstract
> > the index conversion and some of the LR repainting, making the
> > whole exercise much simpler.
> >
> > Reported-by: Wei-Lin Chang <r09922117@csie.ntu.edu.tw>
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > Link: https://lore.kernel.org/r/20250614145721.2504524-1-r09922117@csie.ntu.edu.tw
>
> Besides Wei-Lin's comments, LGTM.
>
> Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Thanks!
For the record, I've since amended the patch to use hweight16()
instead of hweight64(), which saves us a MUL instruction. We can do
that since there is a hard limit of 16 LRs in the architecture.
M.
--
Without deviation from the norm, progress is not possible.
prev parent reply other threads:[~2025-06-17 9:26 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-14 14:57 [PATCH] KVM: arm64: nv: Fix s_cpu_if->vgic_lr[] indexing in vgic_v3_put_nested() Wei-Lin Chang
2025-06-16 5:55 ` Oliver Upton
2025-06-16 14:40 ` Wei-Lin Chang
2025-06-16 10:54 ` Marc Zyngier
2025-06-16 14:34 ` Wei-Lin Chang
2025-06-16 17:00 ` Marc Zyngier
2025-06-17 4:53 ` Oliver Upton
2025-06-17 9:26 ` Marc Zyngier [this message]
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=86o6umd8ie.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=christoffer.dall@arm.com \
--cc=jintack@cs.columbia.edu \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oliver.upton@linux.dev \
--cc=r09922117@csie.ntu.edu.tw \
--cc=suzuki.poulose@arm.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 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.