@@ -56,16 +56,11 @@ struct vmd_irq {
5656/**
5757 * struct vmd_irq_list - list of driver requested IRQs mapping to a VMD vector
5858 * @irq_list: the list of irq's the VMD one demuxes to.
59- * @vmd_vector: the h/w IRQ assigned to the VMD.
60- * @index: index into the VMD MSI-X table; used for message routing.
6159 * @count: number of child IRQs assigned to this vector; used to track
6260 * sharing.
6361 */
6462struct vmd_irq_list {
6563 struct list_head irq_list ;
66- struct vmd_dev * vmd ;
67- unsigned int vmd_vector ;
68- unsigned int index ;
6964 unsigned int count ;
7065};
7166
@@ -76,7 +71,6 @@ struct vmd_dev {
7671 char __iomem * cfgbar ;
7772
7873 int msix_count ;
79- struct msix_entry * msix_entries ;
8074 struct vmd_irq_list * irqs ;
8175
8276 struct pci_sysdata sysdata ;
@@ -95,6 +89,12 @@ static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus)
9589 return container_of (bus -> sysdata , struct vmd_dev , sysdata );
9690}
9791
92+ static inline unsigned int index_from_irqs (struct vmd_dev * vmd ,
93+ struct vmd_irq_list * irqs )
94+ {
95+ return irqs - vmd -> irqs ;
96+ }
97+
9898/*
9999 * Drivers managing a device in a VMD domain allocate their own IRQs as before,
100100 * but the MSI entry for the hardware it's driving will be programmed with a
@@ -107,9 +107,11 @@ static void vmd_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
107107{
108108 struct vmd_irq * vmdirq = data -> chip_data ;
109109 struct vmd_irq_list * irq = vmdirq -> irq ;
110+ struct vmd_dev * vmd = irq_data_get_irq_handler_data (data );
110111
111112 msg -> address_hi = MSI_ADDR_BASE_HI ;
112- msg -> address_lo = MSI_ADDR_BASE_LO | MSI_ADDR_DEST_ID (irq -> index );
113+ msg -> address_lo = MSI_ADDR_BASE_LO |
114+ MSI_ADDR_DEST_ID (index_from_irqs (vmd , irq ));
113115 msg -> data = 0 ;
114116}
115117
@@ -194,16 +196,19 @@ static int vmd_msi_init(struct irq_domain *domain, struct msi_domain_info *info,
194196 struct msi_desc * desc = arg -> desc ;
195197 struct vmd_dev * vmd = vmd_from_bus (msi_desc_to_pci_dev (desc )-> bus );
196198 struct vmd_irq * vmdirq = kzalloc (sizeof (* vmdirq ), GFP_KERNEL );
199+ unsigned int index , vector ;
197200
198201 if (!vmdirq )
199202 return - ENOMEM ;
200203
201204 INIT_LIST_HEAD (& vmdirq -> node );
202205 vmdirq -> irq = vmd_next_irq (vmd , desc );
203206 vmdirq -> virq = virq ;
207+ index = index_from_irqs (vmd , vmdirq -> irq );
208+ vector = pci_irq_vector (vmd -> dev , index );
204209
205- irq_domain_set_info (domain , virq , vmdirq -> irq -> vmd_vector , info -> chip ,
206- vmdirq , handle_untracked_irq , vmd , NULL );
210+ irq_domain_set_info (domain , virq , vector , info -> chip , vmdirq ,
211+ handle_untracked_irq , vmd , NULL );
207212 return 0 ;
208213}
209214
@@ -213,6 +218,8 @@ static void vmd_msi_free(struct irq_domain *domain,
213218 struct vmd_irq * vmdirq = irq_get_chip_data (virq );
214219 unsigned long flags ;
215220
221+ synchronize_rcu ();
222+
216223 /* XXX: Potential optimization to rebalance */
217224 raw_spin_lock_irqsave (& list_lock , flags );
218225 vmdirq -> irq -> count -- ;
@@ -672,30 +679,19 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
672679 if (vmd -> msix_count < 0 )
673680 return - ENODEV ;
674681
682+ vmd -> msix_count = pci_alloc_irq_vectors (dev , 1 , vmd -> msix_count ,
683+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY );
684+ if (vmd -> msix_count < 0 )
685+ return vmd -> msix_count ;
686+
675687 vmd -> irqs = devm_kcalloc (& dev -> dev , vmd -> msix_count , sizeof (* vmd -> irqs ),
676688 GFP_KERNEL );
677689 if (!vmd -> irqs )
678690 return - ENOMEM ;
679691
680- vmd -> msix_entries = devm_kcalloc (& dev -> dev , vmd -> msix_count ,
681- sizeof (* vmd -> msix_entries ),
682- GFP_KERNEL );
683- if (!vmd -> msix_entries )
684- return - ENOMEM ;
685- for (i = 0 ; i < vmd -> msix_count ; i ++ )
686- vmd -> msix_entries [i ].entry = i ;
687-
688- vmd -> msix_count = pci_enable_msix_range (vmd -> dev , vmd -> msix_entries , 1 ,
689- vmd -> msix_count );
690- if (vmd -> msix_count < 0 )
691- return vmd -> msix_count ;
692-
693692 for (i = 0 ; i < vmd -> msix_count ; i ++ ) {
694693 INIT_LIST_HEAD (& vmd -> irqs [i ].irq_list );
695- vmd -> irqs [i ].vmd_vector = vmd -> msix_entries [i ].vector ;
696- vmd -> irqs [i ].index = i ;
697-
698- err = devm_request_irq (& dev -> dev , vmd -> irqs [i ].vmd_vector ,
694+ err = devm_request_irq (& dev -> dev , pci_irq_vector (dev , i ),
699695 vmd_irq , 0 , "vmd" , & vmd -> irqs [i ]);
700696 if (err )
701697 return err ;
0 commit comments