Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu/s390: Add support for iommu_device handling

Add support for the iommu_device_register interface to make
the s390 hardware iommus visible to the iommu core and in
sysfs.

Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>

+50 -1
+7
arch/s390/include/asm/pci.h
··· 8 8 9 9 #include <linux/pci.h> 10 10 #include <linux/mutex.h> 11 + #include <linux/iommu.h> 11 12 #include <asm-generic/pci.h> 12 13 #include <asm/pci_clp.h> 13 14 #include <asm/pci_debug.h> ··· 123 122 unsigned long iommu_pages; 124 123 unsigned int next_bit; 125 124 125 + struct iommu_device iommu_dev; /* IOMMU core handle */ 126 + 126 127 char res_name[16]; 127 128 struct zpci_bar_struct bars[PCI_BAR_COUNT]; 128 129 ··· 176 173 int clp_enable_fh(struct zpci_dev *, u8); 177 174 int clp_disable_fh(struct zpci_dev *); 178 175 int clp_get_state(u32 fid, enum zpci_state *state); 176 + 177 + /* IOMMU Interface */ 178 + int zpci_init_iommu(struct zpci_dev *zdev); 179 + void zpci_destroy_iommu(struct zpci_dev *zdev); 179 180 180 181 #ifdef CONFIG_PCI 181 182 /* Error handling and recovery */
+8 -1
arch/s390/pci/pci.c
··· 776 776 777 777 zpci_exit_slot(zdev); 778 778 zpci_cleanup_bus_resources(zdev); 779 + zpci_destroy_iommu(zdev); 779 780 zpci_free_domain(zdev); 780 781 781 782 spin_lock(&zpci_list_lock); ··· 849 848 if (rc) 850 849 goto out; 851 850 851 + rc = zpci_init_iommu(zdev); 852 + if (rc) 853 + goto out_free; 854 + 852 855 mutex_init(&zdev->lock); 853 856 if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { 854 857 rc = zpci_enable_device(zdev); 855 858 if (rc) 856 - goto out_free; 859 + goto out_destroy_iommu; 857 860 } 858 861 rc = zpci_scan_bus(zdev); 859 862 if (rc) ··· 874 869 out_disable: 875 870 if (zdev->state == ZPCI_FN_STATE_ONLINE) 876 871 zpci_disable_device(zdev); 872 + out_destroy_iommu: 873 + zpci_destroy_iommu(zdev); 877 874 out_free: 878 875 zpci_free_domain(zdev); 879 876 out:
+35
drivers/iommu/s390-iommu.c
··· 18 18 */ 19 19 #define S390_IOMMU_PGSIZES (~0xFFFUL) 20 20 21 + static struct iommu_ops s390_iommu_ops; 22 + 21 23 struct s390_domain { 22 24 struct iommu_domain domain; 23 25 struct list_head devices; ··· 168 166 static int s390_iommu_add_device(struct device *dev) 169 167 { 170 168 struct iommu_group *group = iommu_group_get_for_dev(dev); 169 + struct zpci_dev *zdev = to_pci_dev(dev)->sysdata; 171 170 172 171 if (IS_ERR(group)) 173 172 return PTR_ERR(group); 174 173 175 174 iommu_group_put(group); 175 + iommu_device_link(&zdev->iommu_dev, dev); 176 176 177 177 return 0; 178 178 } ··· 201 197 s390_iommu_detach_device(domain, dev); 202 198 } 203 199 200 + iommu_device_unlink(&zdev->iommu_dev, dev); 204 201 iommu_group_remove_device(dev); 205 202 } 206 203 ··· 330 325 return 0; 331 326 332 327 return size; 328 + } 329 + 330 + int zpci_init_iommu(struct zpci_dev *zdev) 331 + { 332 + int rc = 0; 333 + 334 + rc = iommu_device_sysfs_add(&zdev->iommu_dev, NULL, NULL, 335 + "s390-iommu.%08x", zdev->fid); 336 + if (rc) 337 + goto out_err; 338 + 339 + iommu_device_set_ops(&zdev->iommu_dev, &s390_iommu_ops); 340 + 341 + rc = iommu_device_register(&zdev->iommu_dev); 342 + if (rc) 343 + goto out_sysfs; 344 + 345 + return 0; 346 + 347 + out_sysfs: 348 + iommu_device_sysfs_remove(&zdev->iommu_dev); 349 + 350 + out_err: 351 + return rc; 352 + } 353 + 354 + void zpci_destroy_iommu(struct zpci_dev *zdev) 355 + { 356 + iommu_device_unregister(&zdev->iommu_dev); 357 + iommu_device_sysfs_remove(&zdev->iommu_dev); 333 358 } 334 359 335 360 static struct iommu_ops s390_iommu_ops = {