@@ -79,18 +79,44 @@ static void s390_domain_free(struct iommu_domain *domain)
7979{
8080 struct s390_domain * s390_domain = to_s390_domain (domain );
8181
82+ WARN_ON (!list_empty (& s390_domain -> devices ));
8283 dma_cleanup_tables (s390_domain -> dma_table );
8384 kfree (s390_domain );
8485}
8586
87+ static void __s390_iommu_detach_device (struct zpci_dev * zdev )
88+ {
89+ struct s390_domain * s390_domain = zdev -> s390_domain ;
90+ struct s390_domain_device * domain_device , * tmp ;
91+ unsigned long flags ;
92+
93+ if (!s390_domain )
94+ return ;
95+
96+ spin_lock_irqsave (& s390_domain -> list_lock , flags );
97+ list_for_each_entry_safe (domain_device , tmp , & s390_domain -> devices ,
98+ list ) {
99+ if (domain_device -> zdev == zdev ) {
100+ list_del (& domain_device -> list );
101+ kfree (domain_device );
102+ break ;
103+ }
104+ }
105+ spin_unlock_irqrestore (& s390_domain -> list_lock , flags );
106+
107+ zpci_unregister_ioat (zdev , 0 );
108+ zdev -> s390_domain = NULL ;
109+ zdev -> dma_table = NULL ;
110+ }
111+
86112static int s390_iommu_attach_device (struct iommu_domain * domain ,
87113 struct device * dev )
88114{
89115 struct s390_domain * s390_domain = to_s390_domain (domain );
90116 struct zpci_dev * zdev = to_zpci_dev (dev );
91117 struct s390_domain_device * domain_device ;
92118 unsigned long flags ;
93- int cc , rc ;
119+ int cc , rc = 0 ;
94120
95121 if (!zdev )
96122 return - ENODEV ;
@@ -99,24 +125,18 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
99125 if (!domain_device )
100126 return - ENOMEM ;
101127
102- if (zdev -> dma_table && !zdev -> s390_domain ) {
103- cc = zpci_dma_exit_device (zdev );
104- if (cc ) {
105- rc = - EIO ;
106- goto out_free ;
107- }
108- }
109-
110128 if (zdev -> s390_domain )
111- zpci_unregister_ioat (zdev , 0 );
129+ __s390_iommu_detach_device (zdev );
130+ else if (zdev -> dma_table )
131+ zpci_dma_exit_device (zdev );
112132
113- zdev -> dma_table = s390_domain -> dma_table ;
114133 cc = zpci_register_ioat (zdev , 0 , zdev -> start_dma , zdev -> end_dma ,
115- virt_to_phys (zdev -> dma_table ));
134+ virt_to_phys (s390_domain -> dma_table ));
116135 if (cc ) {
117136 rc = - EIO ;
118- goto out_restore ;
137+ goto out_free ;
119138 }
139+ zdev -> dma_table = s390_domain -> dma_table ;
120140
121141 spin_lock_irqsave (& s390_domain -> list_lock , flags );
122142 /* First device defines the DMA range limits */
@@ -127,9 +147,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
127147 /* Allow only devices with identical DMA range limits */
128148 } else if (domain -> geometry .aperture_start != zdev -> start_dma ||
129149 domain -> geometry .aperture_end != zdev -> end_dma ) {
130- rc = - EINVAL ;
131150 spin_unlock_irqrestore (& s390_domain -> list_lock , flags );
132- goto out_restore ;
151+ rc = - EINVAL ;
152+ goto out_unregister ;
133153 }
134154 domain_device -> zdev = zdev ;
135155 zdev -> s390_domain = s390_domain ;
@@ -138,14 +158,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
138158
139159 return 0 ;
140160
141- out_restore :
142- if (!zdev -> s390_domain ) {
143- zpci_dma_init_device (zdev );
144- } else {
145- zdev -> dma_table = zdev -> s390_domain -> dma_table ;
146- zpci_register_ioat (zdev , 0 , zdev -> start_dma , zdev -> end_dma ,
147- virt_to_phys (zdev -> dma_table ));
148- }
161+ out_unregister :
162+ zpci_unregister_ioat (zdev , 0 );
163+ zdev -> dma_table = NULL ;
149164out_free :
150165 kfree (domain_device );
151166
@@ -155,32 +170,12 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
155170static void s390_iommu_detach_device (struct iommu_domain * domain ,
156171 struct device * dev )
157172{
158- struct s390_domain * s390_domain = to_s390_domain (domain );
159173 struct zpci_dev * zdev = to_zpci_dev (dev );
160- struct s390_domain_device * domain_device , * tmp ;
161- unsigned long flags ;
162- int found = 0 ;
163174
164- if (!zdev )
165- return ;
175+ WARN_ON (zdev -> s390_domain != to_s390_domain (domain ));
166176
167- spin_lock_irqsave (& s390_domain -> list_lock , flags );
168- list_for_each_entry_safe (domain_device , tmp , & s390_domain -> devices ,
169- list ) {
170- if (domain_device -> zdev == zdev ) {
171- list_del (& domain_device -> list );
172- kfree (domain_device );
173- found = 1 ;
174- break ;
175- }
176- }
177- spin_unlock_irqrestore (& s390_domain -> list_lock , flags );
178-
179- if (found && (zdev -> s390_domain == s390_domain )) {
180- zdev -> s390_domain = NULL ;
181- zpci_unregister_ioat (zdev , 0 );
182- zpci_dma_init_device (zdev );
183- }
177+ __s390_iommu_detach_device (zdev );
178+ zpci_dma_init_device (zdev );
184179}
185180
186181static struct iommu_device * s390_iommu_probe_device (struct device * dev )
@@ -198,24 +193,13 @@ static struct iommu_device *s390_iommu_probe_device(struct device *dev)
198193static void s390_iommu_release_device (struct device * dev )
199194{
200195 struct zpci_dev * zdev = to_zpci_dev (dev );
201- struct iommu_domain * domain ;
202196
203197 /*
204- * This is a workaround for a scenario where the IOMMU API common code
205- * "forgets" to call the detach_dev callback: After binding a device
206- * to vfio-pci and completing the VFIO_SET_IOMMU ioctl (which triggers
207- * the attach_dev), removing the device via
208- * "echo 1 > /sys/bus/pci/devices/.../remove" won't trigger detach_dev,
209- * only release_device will be called via the BUS_NOTIFY_REMOVED_DEVICE
210- * notifier.
211- *
212- * So let's call detach_dev from here if it hasn't been called before.
198+ * release_device is expected to detach any domain currently attached
199+ * to the device, but keep it attached to other devices in the group.
213200 */
214- if (zdev && zdev -> s390_domain ) {
215- domain = iommu_get_domain_for_dev (dev );
216- if (domain )
217- s390_iommu_detach_device (domain , dev );
218- }
201+ if (zdev )
202+ __s390_iommu_detach_device (zdev );
219203}
220204
221205static int s390_iommu_update_trans (struct s390_domain * s390_domain ,
0 commit comments