Re: [PATCH v4 31/48] KVM: arm64: gic-v5: Add GICv5 EL1 sysreg userspace accessors
Sascha Bischoff <[email protected]> Fri, 31 Jul 2026 14:27:02 +0000
| Newsgroups | dev.linux.lists.sashiko-reviews,dev.linux.lists.kvmarm,org.kernel.vger.kvm |
|---|---|
| Message-ID | <[email protected]> |
On Fri, 2026-07-24 at 12:09 +0000, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 2 potential > issue(s) to consider: > - [High] Incorrect priority mask `ICC_PPI_PRIORITYR_PRIORITY_MASK` > corrupts GICv5 PPI priorities during save/restore. > - [High] Restoring the pending state of a level-triggered PPI > overwrites the hardware wire state (`line_level`) instead of the > software latch (`pending_latch`). > -- > > --- Patch [31]: [PATCH v4 31/48] KVM: arm64: gic-v5: Add GICv5 EL1 > sysreg userspace accessors --- > commit bdb3308b5e4c3913da8b93ef491dc97004fe3ff0 > Author: Sascha Bischoff <[email protected]> > > KVM: arm64: gic-v5: Add GICv5 EL1 sysreg userspace accessors > > Now that KVM is at the point where it is able to run meaningful VMs > with GICv5, it is important to be able to save/restore the GICv5 > state > in order to allow for VM migration. > > > diff --git a/arch/arm64/kvm/vgic-sys-reg-v5.c > > b/arch/arm64/kvm/vgic-sys-reg-v5.c > > new file mode 100644 > > index 0000000000000..6b255eacbf60d > > --- /dev/null > > +++ b/arch/arm64/kvm/vgic-sys-reg-v5.c > > @@ -0,0 +1,519 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright (C) 2025, 2026 Arm Ltd. > > + */ > > + > > +/* > > + * VGICv5 system registers handling functions for AArch64 mode > > + */ > > + > > +#include <linux/irqchip/arm-gic-v5.h> > > + > > +#include <linux/kvm.h> > > +#include <linux/kvm_host.h> > > +#include <linux/wordpart.h> > > + > > +#include <asm/kvm_emulate.h> > > + > > +#include "vgic/vgic.h" > > +#include "sys_regs.h" > > + > > +#define > > ICC_PPI_PRIORITYR_PRIORITY_MASK REPEAT_BYTE(0x1f) > > [Severity: High] > Does this mask correctly preserve the priority bits? GIC priority > fields are > typically left-aligned in their 8-bit bytes (e.g., using bits [7:3], > which > corresponds to a mask of 0xf8). Pasting directly from the A.a GICv5 specification Section 9.4.6, the priority fields in any of the PPI priority registers are: PRIORITY<x>, bits [60:56, 52:48, 44:40, 36:32, 28:24, 20:16, 12:8, 4:0], for x = 7 to 0 Unless I'm very much mistaken, that's 0x1f repeated for every byte. > > Applying REPEAT_BYTE(0x1f) later in set_gic_ppi_priorityr() appears > to > isolate the bottom 5 bits (including the RAZ/WI bits [2:0]) and clear > the > top valid priority bits, which could silently zero out the priorities > when the > VMM restores the SYS_ICC_PPI_PRIORITYR<n>_EL1 registers during > migration. > > [ ... ] > > > +static int set_gic_ppi_pendr(struct kvm_vcpu *vcpu, > > + const struct sys_reg_desc *r, u64 > > val) > > +{ > > + int i, start, end, reg = r->Op2 % 2; > > + > > + /* If we only support architected PPIs, return */ > > + if (VGIC_V5_NR_PRIVATE_IRQS == 64 && reg == 1) > > + return 0; > > + > > + /* > > + * Update each struct vgic_irq with the pending state, > > treating Level > > + * and Edge interrupts differently. The exposed PPI mask > > is applied > > + * later, when vgic_v5_finalize_ppi_state() runs on first > > entry to each > > + * vCPU. See comment on set_gic_ppi_enabler() for details. > > + */ > > + start = reg * 64; > > + end = min(start + 64, VGIC_V5_NR_PRIVATE_IRQS); > > + for (i = start; i < end; i++) { > > + u32 intid = vgic_v5_make_ppi(i); > > + struct vgic_irq *irq; > > + > > + irq = vgic_get_vcpu_irq(vcpu, intid); > > + > > + scoped_guard(raw_spinlock_irqsave, &irq->irq_lock) > > { > > + bool level = !!(val & BIT_ULL(i - start)); > > + > > + if (irq->config == VGIC_CONFIG_LEVEL) > > + irq->line_level = level; > > [Severity: High] > Could this corrupt the interrupt state during VM migration by writing > to > the hardware wire state rather than the software pending latch? > > The SYS_ICC_PPI_SPENDR<n>_EL1 restore from userspace represents the > software > pending state. If we set irq->line_level here for level-triggered > interrupts, > it overwrites the ephemeral physical wire state (which gets re- > evaluated by > backing hardware, like the arch timer) and the software-pended state > would be > lost. Should this set irq->pending_latch for level interrupts as > well? No, I don't think that we should. For things like the arch timer, that's using DVI anyhow, so we mask off those bits before writing the state to the ICH_PPI_* registers. > > > + else > > + irq->pending_latch = level; > > + } > > + > > + vgic_put_irq(vcpu->kvm, irq); > > + } > Thanks, Sascha