@@ -304,6 +304,13 @@ static void channels_on_cpu_inc(struct irq_info *info)
304
304
info -> is_accounted = 1 ;
305
305
}
306
306
307
+ static void xen_irq_free_desc (unsigned int irq )
308
+ {
309
+ /* Legacy IRQ descriptors are managed by the arch. */
310
+ if (irq >= nr_legacy_irqs ())
311
+ irq_free_desc (irq );
312
+ }
313
+
307
314
static void delayed_free_irq (struct work_struct * work )
308
315
{
309
316
struct irq_info * info = container_of (to_rcu_work (work ), struct irq_info ,
@@ -315,9 +322,7 @@ static void delayed_free_irq(struct work_struct *work)
315
322
316
323
kfree (info );
317
324
318
- /* Legacy IRQ descriptors are managed by the arch. */
319
- if (irq >= nr_legacy_irqs ())
320
- irq_free_desc (irq );
325
+ xen_irq_free_desc (irq );
321
326
}
322
327
323
328
/* Constructors for packed IRQ information. */
@@ -332,7 +337,6 @@ static int xen_irq_info_common_setup(struct irq_info *info,
332
337
BUG_ON (info -> type != IRQT_UNBOUND && info -> type != type );
333
338
334
339
info -> type = type ;
335
- info -> irq = irq ;
336
340
info -> evtchn = evtchn ;
337
341
info -> cpu = cpu ;
338
342
info -> mask_reason = EVT_MASK_REASON_EXPLICIT ;
@@ -733,47 +737,45 @@ void xen_irq_lateeoi(unsigned int irq, unsigned int eoi_flags)
733
737
}
734
738
EXPORT_SYMBOL_GPL (xen_irq_lateeoi );
735
739
736
- static void xen_irq_init (unsigned irq )
740
+ static struct irq_info * xen_irq_init (unsigned int irq )
737
741
{
738
742
struct irq_info * info ;
739
743
740
744
info = kzalloc (sizeof (* info ), GFP_KERNEL );
741
- if (info == NULL )
742
- panic ("Unable to allocate metadata for IRQ%d\n" , irq );
745
+ if (info ) {
746
+ info -> irq = irq ;
747
+ info -> type = IRQT_UNBOUND ;
748
+ info -> refcnt = -1 ;
749
+ INIT_RCU_WORK (& info -> rwork , delayed_free_irq );
743
750
744
- info -> type = IRQT_UNBOUND ;
745
- info -> refcnt = -1 ;
746
- INIT_RCU_WORK (& info -> rwork , delayed_free_irq );
751
+ set_info_for_irq (irq , info );
752
+ /*
753
+ * Interrupt affinity setting can be immediate. No point
754
+ * in delaying it until an interrupt is handled.
755
+ */
756
+ irq_set_status_flags (irq , IRQ_MOVE_PCNTXT );
747
757
748
- set_info_for_irq (irq , info );
749
- /*
750
- * Interrupt affinity setting can be immediate. No point
751
- * in delaying it until an interrupt is handled.
752
- */
753
- irq_set_status_flags (irq , IRQ_MOVE_PCNTXT );
758
+ INIT_LIST_HEAD (& info -> eoi_list );
759
+ list_add_tail (& info -> list , & xen_irq_list_head );
760
+ }
754
761
755
- INIT_LIST_HEAD (& info -> eoi_list );
756
- list_add_tail (& info -> list , & xen_irq_list_head );
762
+ return info ;
757
763
}
758
764
759
- static int __must_check xen_allocate_irqs_dynamic ( int nvec )
765
+ static inline int __must_check xen_allocate_irq_dynamic ( void )
760
766
{
761
- int i , irq = irq_alloc_descs ( -1 , 0 , nvec , -1 );
767
+ int irq = irq_alloc_desc_from ( 0 , -1 );
762
768
763
769
if (irq >= 0 ) {
764
- for (i = 0 ; i < nvec ; i ++ )
765
- xen_irq_init (irq + i );
770
+ if (!xen_irq_init (irq )) {
771
+ xen_irq_free_desc (irq );
772
+ irq = -1 ;
773
+ }
766
774
}
767
775
768
776
return irq ;
769
777
}
770
778
771
- static inline int __must_check xen_allocate_irq_dynamic (void )
772
- {
773
-
774
- return xen_allocate_irqs_dynamic (1 );
775
- }
776
-
777
779
static int __must_check xen_allocate_irq_gsi (unsigned gsi )
778
780
{
779
781
int irq ;
@@ -793,7 +795,10 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
793
795
else
794
796
irq = irq_alloc_desc_at (gsi , -1 );
795
797
796
- xen_irq_init (irq );
798
+ if (!xen_irq_init (irq )) {
799
+ xen_irq_free_desc (irq );
800
+ irq = -1 ;
801
+ }
797
802
798
803
return irq ;
799
804
}
@@ -963,6 +968,11 @@ static void __unbind_from_irq(unsigned int irq)
963
968
evtchn_port_t evtchn = evtchn_from_irq (irq );
964
969
struct irq_info * info = info_for_irq (irq );
965
970
971
+ if (!info ) {
972
+ xen_irq_free_desc (irq );
973
+ return ;
974
+ }
975
+
966
976
if (info -> refcnt > 0 ) {
967
977
info -> refcnt -- ;
968
978
if (info -> refcnt != 0 )
@@ -1101,11 +1111,14 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
1101
1111
1102
1112
mutex_lock (& irq_mapping_update_lock );
1103
1113
1104
- irq = xen_allocate_irqs_dynamic ( nvec );
1114
+ irq = irq_alloc_descs ( -1 , 0 , nvec , -1 );
1105
1115
if (irq < 0 )
1106
1116
goto out ;
1107
1117
1108
1118
for (i = 0 ; i < nvec ; i ++ ) {
1119
+ if (!xen_irq_init (irq + i ))
1120
+ goto error_irq ;
1121
+
1109
1122
irq_set_chip_and_handler_name (irq + i , & xen_pirq_chip , handle_edge_irq , name );
1110
1123
1111
1124
ret = xen_irq_info_pirq_setup (irq + i , 0 , pirq + i , 0 , domid ,
@@ -1730,6 +1743,7 @@ void rebind_evtchn_irq(evtchn_port_t evtchn, int irq)
1730
1743
so there should be a proper type */
1731
1744
BUG_ON (info -> type == IRQT_UNBOUND );
1732
1745
1746
+ info -> irq = irq ;
1733
1747
(void )xen_irq_info_evtchn_setup (irq , evtchn , NULL );
1734
1748
1735
1749
mutex_unlock (& irq_mapping_update_lock );
0 commit comments