Skip to content

Commit 0ed5967

Browse files
rosatomjjoergroedel
authored andcommitted
iommu/s390: handle IOAT registration based on domain
At this point, the dma_table is really a property of the s390-iommu domain. Rather than checking its contents elsewhere in the codebase, move the code that registers the table with firmware into s390-iommu and make a decision what to register with firmware based upon the type of domain in use for the device in question. Tested-by: Niklas Schnelle <[email protected]> Reviewed-by: Niklas Schnelle <[email protected]> Signed-off-by: Matthew Rosato <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent d236843 commit 0ed5967

File tree

5 files changed

+66
-42
lines changed

5 files changed

+66
-42
lines changed

arch/s390/include/asm/pci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ extern struct airq_iv *zpci_aif_sbv;
217217
struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
218218
int zpci_add_device(struct zpci_dev *zdev);
219219
int zpci_enable_device(struct zpci_dev *);
220+
int zpci_reenable_device(struct zpci_dev *zdev);
220221
int zpci_disable_device(struct zpci_dev *);
221222
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
222223
int zpci_deconfigure_device(struct zpci_dev *zdev);
@@ -245,6 +246,7 @@ void update_uid_checking(bool new);
245246
/* IOMMU Interface */
246247
int zpci_init_iommu(struct zpci_dev *zdev);
247248
void zpci_destroy_iommu(struct zpci_dev *zdev);
249+
int zpci_iommu_register_ioat(struct zpci_dev *zdev, u8 *status);
248250

249251
#ifdef CONFIG_PCI
250252
static inline bool zpci_use_mio(struct zpci_dev *zdev)

arch/s390/kvm/pci.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,6 @@ static void kvm_s390_pci_dev_release(struct zpci_dev *zdev)
433433
static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
434434
{
435435
struct zpci_dev *zdev = opaque;
436-
u8 status;
437436
int rc;
438437

439438
if (!zdev)
@@ -480,13 +479,7 @@ static int kvm_s390_pci_register_kvm(void *opaque, struct kvm *kvm)
480479
*/
481480
zdev->gisa = (u32)virt_to_phys(&kvm->arch.sie_page2->gisa);
482481

483-
rc = zpci_enable_device(zdev);
484-
if (rc)
485-
goto clear_gisa;
486-
487-
/* Re-register the IOMMU that was already created */
488-
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
489-
virt_to_phys(zdev->dma_table), &status);
482+
rc = zpci_reenable_device(zdev);
490483
if (rc)
491484
goto clear_gisa;
492485

@@ -516,7 +509,6 @@ static void kvm_s390_pci_unregister_kvm(void *opaque)
516509
{
517510
struct zpci_dev *zdev = opaque;
518511
struct kvm *kvm;
519-
u8 status;
520512

521513
if (!zdev)
522514
return;
@@ -550,12 +542,7 @@ static void kvm_s390_pci_unregister_kvm(void *opaque)
550542
goto out;
551543
}
552544

553-
if (zpci_enable_device(zdev))
554-
goto out;
555-
556-
/* Re-register the IOMMU that was already created */
557-
zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
558-
virt_to_phys(zdev->dma_table), &status);
545+
zpci_reenable_device(zdev);
559546

560547
out:
561548
spin_lock(&kvm->arch.kzdev_list_lock);

arch/s390/pci/pci.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,13 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
124124
struct zpci_fib fib = {0};
125125
u8 cc;
126126

127-
WARN_ON_ONCE(iota & 0x3fff);
128127
fib.pba = base;
129128
/* Work around off by one in ISM virt device */
130129
if (zdev->pft == PCI_FUNC_TYPE_ISM && limit > base)
131130
fib.pal = limit + (1 << 12);
132131
else
133132
fib.pal = limit;
134-
fib.iota = iota | ZPCI_IOTA_RTTO_FLAG;
133+
fib.iota = iota;
135134
fib.gd = zdev->gisa;
136135
cc = zpci_mod_fc(req, &fib, status);
137136
if (cc)
@@ -690,6 +689,23 @@ int zpci_enable_device(struct zpci_dev *zdev)
690689
}
691690
EXPORT_SYMBOL_GPL(zpci_enable_device);
692691

692+
int zpci_reenable_device(struct zpci_dev *zdev)
693+
{
694+
u8 status;
695+
int rc;
696+
697+
rc = zpci_enable_device(zdev);
698+
if (rc)
699+
return rc;
700+
701+
rc = zpci_iommu_register_ioat(zdev, &status);
702+
if (rc)
703+
zpci_disable_device(zdev);
704+
705+
return rc;
706+
}
707+
EXPORT_SYMBOL_GPL(zpci_reenable_device);
708+
693709
int zpci_disable_device(struct zpci_dev *zdev)
694710
{
695711
u32 fh = zdev->fh;
@@ -739,7 +755,6 @@ EXPORT_SYMBOL_GPL(zpci_disable_device);
739755
*/
740756
int zpci_hot_reset_device(struct zpci_dev *zdev)
741757
{
742-
u8 status;
743758
int rc;
744759

745760
lockdep_assert_held(&zdev->state_lock);
@@ -758,19 +773,9 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
758773
return rc;
759774
}
760775

761-
rc = zpci_enable_device(zdev);
762-
if (rc)
763-
return rc;
764-
765-
if (zdev->dma_table)
766-
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
767-
virt_to_phys(zdev->dma_table), &status);
768-
if (rc) {
769-
zpci_disable_device(zdev);
770-
return rc;
771-
}
776+
rc = zpci_reenable_device(zdev);
772777

773-
return 0;
778+
return rc;
774779
}
775780

776781
/**

arch/s390/pci/pci_sysfs.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ static DEVICE_ATTR_RO(mio_enabled);
5252

5353
static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
5454
{
55-
u8 status;
5655
int ret;
5756

5857
pci_stop_and_remove_bus_device(pdev);
@@ -70,16 +69,8 @@ static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
7069
return ret;
7170
}
7271

73-
ret = zpci_enable_device(zdev);
74-
if (ret)
75-
return ret;
72+
ret = zpci_reenable_device(zdev);
7673

77-
if (zdev->dma_table) {
78-
ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
79-
virt_to_phys(zdev->dma_table), &status);
80-
if (ret)
81-
zpci_disable_device(zdev);
82-
}
8374
return ret;
8475
}
8576

drivers/iommu/s390-iommu.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,46 @@ static void zdev_s390_domain_update(struct zpci_dev *zdev,
381381
spin_unlock_irqrestore(&zdev->dom_lock, flags);
382382
}
383383

384+
static int s390_iommu_domain_reg_ioat(struct zpci_dev *zdev,
385+
struct iommu_domain *domain, u8 *status)
386+
{
387+
struct s390_domain *s390_domain;
388+
int rc = 0;
389+
u64 iota;
390+
391+
switch (domain->type) {
392+
case IOMMU_DOMAIN_IDENTITY:
393+
rc = zpci_register_ioat(zdev, 0, zdev->start_dma,
394+
zdev->end_dma, 0, status);
395+
break;
396+
case IOMMU_DOMAIN_BLOCKED:
397+
/* Nothing to do in this case */
398+
break;
399+
default:
400+
s390_domain = to_s390_domain(domain);
401+
iota = virt_to_phys(s390_domain->dma_table) |
402+
ZPCI_IOTA_RTTO_FLAG;
403+
rc = zpci_register_ioat(zdev, 0, zdev->start_dma,
404+
zdev->end_dma, iota, status);
405+
}
406+
407+
return rc;
408+
}
409+
410+
int zpci_iommu_register_ioat(struct zpci_dev *zdev, u8 *status)
411+
{
412+
unsigned long flags;
413+
int rc;
414+
415+
spin_lock_irqsave(&zdev->dom_lock, flags);
416+
417+
rc = s390_iommu_domain_reg_ioat(zdev, zdev->s390_domain, status);
418+
419+
spin_unlock_irqrestore(&zdev->dom_lock, flags);
420+
421+
return rc;
422+
}
423+
384424
static int blocking_domain_attach_device(struct iommu_domain *domain,
385425
struct device *dev)
386426
{
@@ -422,8 +462,7 @@ static int s390_iommu_attach_device(struct iommu_domain *domain,
422462
blocking_domain_attach_device(&blocking_domain, dev);
423463

424464
/* If we fail now DMA remains blocked via blocking domain */
425-
cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
426-
virt_to_phys(s390_domain->dma_table), &status);
465+
cc = s390_iommu_domain_reg_ioat(zdev, domain, &status);
427466
if (cc && status != ZPCI_PCI_ST_FUNC_NOT_AVAIL)
428467
return -EIO;
429468
zdev->dma_table = s390_domain->dma_table;

0 commit comments

Comments
 (0)