Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: arm64: GICv3: nv: Plug L1 LR sync into deactivation primitive

Pretty much like the rest of the LR handling, deactivation of an
L2 interrupt gets reflected in the L1 LRs, and therefore must be
propagated into the L1 shadow state if the interrupt is HW-bound.

Instead of directly handling the active state (which looks a bit
off as it ignores locking and L1->L0 HW propagation), use the new
deactivation primitive to perform the deactivation and deal with
the required maintenance.

Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Link: https://msgid.link/20251120172540.2267180-36-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>

authored by

Marc Zyngier and committed by
Oliver Upton
6dd333c8 eb33ffa2

+9 -10
+9 -10
arch/arm64/kvm/vgic/vgic-v3-nested.c
··· 280 280 281 281 for_each_set_bit(i, &shadow_if->lr_map, kvm_vgic_global_state.nr_lr) { 282 282 u64 val, host_lr, lr; 283 - struct vgic_irq *irq; 284 283 285 284 host_lr = __gic_v3_get_lr(lr_map_idx_to_shadow_idx(shadow_if, i)); 286 285 ··· 289 290 val |= host_lr & ICH_LR_STATE; 290 291 __vcpu_assign_sys_reg(vcpu, ICH_LRN(i), val); 291 292 292 - if (!(lr & ICH_LR_HW) || !(lr & ICH_LR_STATE)) 293 + /* 294 + * Deactivation of a HW interrupt: the LR must have the HW 295 + * bit set, have been in a non-invalid state before the run, 296 + * and now be in an invalid state. If any of that doesn't 297 + * hold, we're done with this LR. 298 + */ 299 + if (!((lr & ICH_LR_HW) && (lr & ICH_LR_STATE) && 300 + !(host_lr & ICH_LR_STATE))) 293 301 continue; 294 302 295 303 /* ··· 304 298 * need to emulate the HW effect between the guest hypervisor 305 299 * and the nested guest. 306 300 */ 307 - irq = vgic_get_vcpu_irq(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr)); 308 - if (WARN_ON(!irq)) /* Shouldn't happen as we check on load */ 309 - continue; 310 - 311 - if (!(host_lr & ICH_LR_STATE)) 312 - irq->active = false; 313 - 314 - vgic_put_irq(vcpu->kvm, irq); 301 + vgic_v3_deactivate(vcpu, FIELD_GET(ICH_LR_PHYS_ID_MASK, lr)); 315 302 } 316 303 317 304 /* We need these to be synchronised to generate the MI */