Skip to content

Commit 864d430

Browse files
committed
KVM: arm64: vgic: Rely on RCU protection in vgic_get_lpi()
Stop acquiring the lpi_list_lock in favor of RCU for protecting the read-side critical section in vgic_get_lpi(). In order for this to be safe, we also need to be careful not to take a reference on an irq with a refcount of 0, as it is about to be freed. Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent a5c7f01 commit 864d430

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

arch/arm64/kvm/vgic/vgic.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,14 @@ static struct vgic_irq *vgic_get_lpi(struct kvm *kvm, u32 intid)
6363
{
6464
struct vgic_dist *dist = &kvm->arch.vgic;
6565
struct vgic_irq *irq = NULL;
66-
unsigned long flags;
6766

68-
raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
67+
rcu_read_lock();
6968

7069
irq = xa_load(&dist->lpi_xa, intid);
71-
if (irq)
72-
vgic_get_irq_kref(irq);
70+
if (!vgic_try_get_irq_kref(irq))
71+
irq = NULL;
7372

74-
raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
73+
rcu_read_unlock();
7574

7675
return irq;
7776
}

arch/arm64/kvm/vgic/vgic.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,20 @@ void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu);
220220
void vgic_v2_save_state(struct kvm_vcpu *vcpu);
221221
void vgic_v2_restore_state(struct kvm_vcpu *vcpu);
222222

223-
static inline void vgic_get_irq_kref(struct vgic_irq *irq)
223+
static inline bool vgic_try_get_irq_kref(struct vgic_irq *irq)
224224
{
225+
if (!irq)
226+
return false;
227+
225228
if (irq->intid < VGIC_MIN_LPI)
226-
return;
229+
return true;
227230

228-
kref_get(&irq->refcount);
231+
return kref_get_unless_zero(&irq->refcount);
232+
}
233+
234+
static inline void vgic_get_irq_kref(struct vgic_irq *irq)
235+
{
236+
WARN_ON_ONCE(!vgic_try_get_irq_kref(irq));
229237
}
230238

231239
void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);

0 commit comments

Comments
 (0)