66
77#include <linux/device.h>
88#include <linux/interrupt.h>
9+ #include <linux/iommu.h>
910#include <linux/irq.h>
1011#include <linux/kernel.h>
1112#include <linux/module.h>
@@ -68,6 +69,8 @@ enum vmd_features {
6869 VMD_FEAT_CAN_BYPASS_MSI_REMAP = (1 << 4 ),
6970};
7071
72+ static DEFINE_IDA (vmd_instance_ida );
73+
7174/*
7275 * Lock for manipulating VMD IRQ lists.
7376 */
@@ -118,6 +121,8 @@ struct vmd_dev {
118121 struct pci_bus * bus ;
119122 u8 busn_start ;
120123 u8 first_vec ;
124+ char * name ;
125+ int instance ;
121126};
122127
123128static inline struct vmd_dev * vmd_from_bus (struct pci_bus * bus )
@@ -648,7 +653,7 @@ static int vmd_alloc_irqs(struct vmd_dev *vmd)
648653 INIT_LIST_HEAD (& vmd -> irqs [i ].irq_list );
649654 err = devm_request_irq (& dev -> dev , pci_irq_vector (dev , i ),
650655 vmd_irq , IRQF_NO_THREAD ,
651- " vmd" , & vmd -> irqs [i ]);
656+ vmd -> name , & vmd -> irqs [i ]);
652657 if (err )
653658 return err ;
654659 }
@@ -759,7 +764,8 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
759764 * acceptable because the guest is usually CPU-limited and MSI
760765 * remapping doesn't become a performance bottleneck.
761766 */
762- if (!(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP ) ||
767+ if (iommu_capable (vmd -> dev -> dev .bus , IOMMU_CAP_INTR_REMAP ) ||
768+ !(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP ) ||
763769 offset [0 ] || offset [1 ]) {
764770 ret = vmd_alloc_irqs (vmd );
765771 if (ret )
@@ -832,18 +838,32 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
832838 return - ENOMEM ;
833839
834840 vmd -> dev = dev ;
841+ vmd -> instance = ida_simple_get (& vmd_instance_ida , 0 , 0 , GFP_KERNEL );
842+ if (vmd -> instance < 0 )
843+ return vmd -> instance ;
844+
845+ vmd -> name = kasprintf (GFP_KERNEL , "vmd%d" , vmd -> instance );
846+ if (!vmd -> name ) {
847+ err = - ENOMEM ;
848+ goto out_release_instance ;
849+ }
850+
835851 err = pcim_enable_device (dev );
836852 if (err < 0 )
837- return err ;
853+ goto out_release_instance ;
838854
839855 vmd -> cfgbar = pcim_iomap (dev , VMD_CFGBAR , 0 );
840- if (!vmd -> cfgbar )
841- return - ENOMEM ;
856+ if (!vmd -> cfgbar ) {
857+ err = - ENOMEM ;
858+ goto out_release_instance ;
859+ }
842860
843861 pci_set_master (dev );
844862 if (dma_set_mask_and_coherent (& dev -> dev , DMA_BIT_MASK (64 )) &&
845- dma_set_mask_and_coherent (& dev -> dev , DMA_BIT_MASK (32 )))
846- return - ENODEV ;
863+ dma_set_mask_and_coherent (& dev -> dev , DMA_BIT_MASK (32 ))) {
864+ err = - ENODEV ;
865+ goto out_release_instance ;
866+ }
847867
848868 if (features & VMD_FEAT_OFFSET_FIRST_VECTOR )
849869 vmd -> first_vec = 1 ;
@@ -852,11 +872,16 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id)
852872 pci_set_drvdata (dev , vmd );
853873 err = vmd_enable_domain (vmd , features );
854874 if (err )
855- return err ;
875+ goto out_release_instance ;
856876
857877 dev_info (& vmd -> dev -> dev , "Bound to PCI domain %04x\n" ,
858878 vmd -> sysdata .domain );
859879 return 0 ;
880+
881+ out_release_instance :
882+ ida_simple_remove (& vmd_instance_ida , vmd -> instance );
883+ kfree (vmd -> name );
884+ return err ;
860885}
861886
862887static void vmd_cleanup_srcu (struct vmd_dev * vmd )
@@ -877,6 +902,8 @@ static void vmd_remove(struct pci_dev *dev)
877902 vmd_cleanup_srcu (vmd );
878903 vmd_detach_resources (vmd );
879904 vmd_remove_irq_domain (vmd );
905+ ida_simple_remove (& vmd_instance_ida , vmd -> instance );
906+ kfree (vmd -> name );
880907}
881908
882909#ifdef CONFIG_PM_SLEEP
@@ -901,7 +928,7 @@ static int vmd_resume(struct device *dev)
901928 for (i = 0 ; i < vmd -> msix_count ; i ++ ) {
902929 err = devm_request_irq (dev , pci_irq_vector (pdev , i ),
903930 vmd_irq , IRQF_NO_THREAD ,
904- " vmd" , & vmd -> irqs [i ]);
931+ vmd -> name , & vmd -> irqs [i ]);
905932 if (err )
906933 return err ;
907934 }
0 commit comments