@@ -327,6 +327,8 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
327
327
return 0 ;
328
328
}
329
329
330
+ #define GIC_LPI_MAX_INTID ((1 << INTERRUPT_ID_BITS_ITS) - 1)
331
+
330
332
/*
331
333
* Create a snapshot of the current LPIs targeting @vcpu, so that we can
332
334
* enumerate those LPIs without holding any lock.
@@ -335,6 +337,7 @@ static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
335
337
int vgic_copy_lpi_list (struct kvm * kvm , struct kvm_vcpu * vcpu , u32 * * intid_ptr )
336
338
{
337
339
struct vgic_dist * dist = & kvm -> arch .vgic ;
340
+ XA_STATE (xas , & dist -> lpi_xa , GIC_LPI_OFFSET );
338
341
struct vgic_irq * irq ;
339
342
unsigned long flags ;
340
343
u32 * intids ;
@@ -353,14 +356,18 @@ int vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr)
353
356
return - ENOMEM ;
354
357
355
358
raw_spin_lock_irqsave (& dist -> lpi_list_lock , flags );
356
- list_for_each_entry (irq , & dist -> lpi_list_head , lpi_list ) {
359
+ rcu_read_lock ();
360
+
361
+ xas_for_each (& xas , irq , GIC_LPI_MAX_INTID ) {
357
362
if (i == irq_count )
358
363
break ;
359
364
/* We don't need to "get" the IRQ, as we hold the list lock. */
360
365
if (vcpu && irq -> target_vcpu != vcpu )
361
366
continue ;
362
367
intids [i ++ ] = irq -> intid ;
363
368
}
369
+
370
+ rcu_read_unlock ();
364
371
raw_spin_unlock_irqrestore (& dist -> lpi_list_lock , flags );
365
372
366
373
* intid_ptr = intids ;
0 commit comments