Skip to content

Commit c76c067

Browse files
niklas88joergroedel
authored andcommitted
s390/pci: Use dma-iommu layer
While s390 already has a standard IOMMU driver and previous changes have added I/O TLB flushing operations this driver is currently only used for user-space PCI access such as vfio-pci. For the DMA API s390 instead utilizes its own implementation in arch/s390/pci/pci_dma.c which drives the same hardware and shares some code but requires a complex and fragile hand over between DMA API and IOMMU API use of a device and despite code sharing still leads to significant duplication and maintenance effort. Let's utilize the common code DMAP API implementation from drivers/iommu/dma-iommu.c instead allowing us to get rid of arch/s390/pci/pci_dma.c. Reviewed-by: Matthew Rosato <[email protected]> Signed-off-by: Niklas Schnelle <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent b6f8887 commit c76c067

File tree

13 files changed

+402
-939
lines changed

13 files changed

+402
-939
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,7 +2220,7 @@
22202220
forcing Dual Address Cycle for PCI cards supporting
22212221
greater than 32-bit addressing.
22222222

2223-
iommu.strict= [ARM64, X86] Configure TLB invalidation behaviour
2223+
iommu.strict= [ARM64, X86, S390] Configure TLB invalidation behaviour
22242224
Format: { "0" | "1" }
22252225
0 - Lazy mode.
22262226
Request that DMA unmap operations use deferred
@@ -5611,9 +5611,10 @@
56115611
s390_iommu= [HW,S390]
56125612
Set s390 IOTLB flushing mode
56135613
strict
5614-
With strict flushing every unmap operation will result in
5615-
an IOTLB flush. Default is lazy flushing before reuse,
5616-
which is faster.
5614+
With strict flushing every unmap operation will result
5615+
in an IOTLB flush. Default is lazy flushing before
5616+
reuse, which is faster. Deprecated, equivalent to
5617+
iommu.strict=1.
56175618

56185619
s390_iommu_aperture= [KNL,S390]
56195620
Specifies the size of the per device DMA address space

arch/s390/include/asm/pci.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,6 @@ struct zpci_dev {
159159
unsigned long *dma_table;
160160
int tlb_refresh;
161161

162-
spinlock_t iommu_bitmap_lock;
163-
unsigned long *iommu_bitmap;
164-
unsigned long *lazy_bitmap;
165-
unsigned long iommu_size;
166-
unsigned long iommu_pages;
167-
unsigned int next_bit;
168-
169162
struct iommu_device iommu_dev; /* IOMMU core handle */
170163

171164
char res_name[16];

arch/s390/include/asm/pci_clp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ struct clp_fh_list_entry {
5050
#define CLP_UTIL_STR_LEN 64
5151
#define CLP_PFIP_NR_SEGMENTS 4
5252

53+
/* PCI function type numbers */
54+
#define PCI_FUNC_TYPE_ISM 0x5 /* ISM device */
55+
5356
extern bool zpci_unique_uid;
5457

5558
struct clp_rsp_slpc_pci {

arch/s390/include/asm/pci_dma.h

Lines changed: 10 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -82,117 +82,16 @@ enum zpci_ioat_dtype {
8282
#define ZPCI_TABLE_VALID_MASK 0x20
8383
#define ZPCI_TABLE_PROT_MASK 0x200
8484

85-
static inline unsigned int calc_rtx(dma_addr_t ptr)
86-
{
87-
return ((unsigned long) ptr >> ZPCI_RT_SHIFT) & ZPCI_INDEX_MASK;
88-
}
89-
90-
static inline unsigned int calc_sx(dma_addr_t ptr)
91-
{
92-
return ((unsigned long) ptr >> ZPCI_ST_SHIFT) & ZPCI_INDEX_MASK;
93-
}
94-
95-
static inline unsigned int calc_px(dma_addr_t ptr)
96-
{
97-
return ((unsigned long) ptr >> PAGE_SHIFT) & ZPCI_PT_MASK;
98-
}
99-
100-
static inline void set_pt_pfaa(unsigned long *entry, phys_addr_t pfaa)
101-
{
102-
*entry &= ZPCI_PTE_FLAG_MASK;
103-
*entry |= (pfaa & ZPCI_PTE_ADDR_MASK);
104-
}
105-
106-
static inline void set_rt_sto(unsigned long *entry, phys_addr_t sto)
107-
{
108-
*entry &= ZPCI_RTE_FLAG_MASK;
109-
*entry |= (sto & ZPCI_RTE_ADDR_MASK);
110-
*entry |= ZPCI_TABLE_TYPE_RTX;
111-
}
112-
113-
static inline void set_st_pto(unsigned long *entry, phys_addr_t pto)
114-
{
115-
*entry &= ZPCI_STE_FLAG_MASK;
116-
*entry |= (pto & ZPCI_STE_ADDR_MASK);
117-
*entry |= ZPCI_TABLE_TYPE_SX;
118-
}
119-
120-
static inline void validate_rt_entry(unsigned long *entry)
121-
{
122-
*entry &= ~ZPCI_TABLE_VALID_MASK;
123-
*entry &= ~ZPCI_TABLE_OFFSET_MASK;
124-
*entry |= ZPCI_TABLE_VALID;
125-
*entry |= ZPCI_TABLE_LEN_RTX;
126-
}
127-
128-
static inline void validate_st_entry(unsigned long *entry)
129-
{
130-
*entry &= ~ZPCI_TABLE_VALID_MASK;
131-
*entry |= ZPCI_TABLE_VALID;
132-
}
133-
134-
static inline void invalidate_pt_entry(unsigned long *entry)
135-
{
136-
WARN_ON_ONCE((*entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_INVALID);
137-
*entry &= ~ZPCI_PTE_VALID_MASK;
138-
*entry |= ZPCI_PTE_INVALID;
139-
}
140-
141-
static inline void validate_pt_entry(unsigned long *entry)
142-
{
143-
WARN_ON_ONCE((*entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID);
144-
*entry &= ~ZPCI_PTE_VALID_MASK;
145-
*entry |= ZPCI_PTE_VALID;
146-
}
147-
148-
static inline void entry_set_protected(unsigned long *entry)
149-
{
150-
*entry &= ~ZPCI_TABLE_PROT_MASK;
151-
*entry |= ZPCI_TABLE_PROTECTED;
152-
}
153-
154-
static inline void entry_clr_protected(unsigned long *entry)
155-
{
156-
*entry &= ~ZPCI_TABLE_PROT_MASK;
157-
*entry |= ZPCI_TABLE_UNPROTECTED;
158-
}
159-
160-
static inline int reg_entry_isvalid(unsigned long entry)
161-
{
162-
return (entry & ZPCI_TABLE_VALID_MASK) == ZPCI_TABLE_VALID;
163-
}
164-
165-
static inline int pt_entry_isvalid(unsigned long entry)
166-
{
167-
return (entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID;
168-
}
169-
170-
static inline unsigned long *get_rt_sto(unsigned long entry)
171-
{
172-
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RTX)
173-
return phys_to_virt(entry & ZPCI_RTE_ADDR_MASK);
174-
else
175-
return NULL;
176-
177-
}
178-
179-
static inline unsigned long *get_st_pto(unsigned long entry)
180-
{
181-
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_SX)
182-
return phys_to_virt(entry & ZPCI_STE_ADDR_MASK);
183-
else
184-
return NULL;
185-
}
186-
187-
/* Prototypes */
188-
void dma_free_seg_table(unsigned long);
189-
unsigned long *dma_alloc_cpu_table(gfp_t gfp);
190-
void dma_cleanup_tables(unsigned long *);
191-
unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr,
192-
gfp_t gfp);
193-
void dma_update_cpu_trans(unsigned long *entry, phys_addr_t page_addr, int flags);
194-
195-
extern const struct dma_map_ops s390_pci_dma_ops;
85+
struct zpci_iommu_ctrs {
86+
atomic64_t mapped_pages;
87+
atomic64_t unmapped_pages;
88+
atomic64_t global_rpcits;
89+
atomic64_t sync_map_rpcits;
90+
atomic64_t sync_rpcits;
91+
};
92+
93+
struct zpci_dev;
19694

95+
struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev);
19796

19897
#endif

arch/s390/pci/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Makefile for the s390 PCI subsystem.
44
#
55

6-
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \
6+
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_clp.o pci_sysfs.o \
77
pci_event.o pci_debug.o pci_insn.o pci_mmio.o \
88
pci_bus.o pci_kvm_hook.o
99
obj-$(CONFIG_PCI_IOV) += pci_iov.o

arch/s390/pci/pci.c

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
124124

125125
WARN_ON_ONCE(iota & 0x3fff);
126126
fib.pba = base;
127-
fib.pal = limit;
127+
/* Work around off by one in ISM virt device */
128+
if (zdev->pft == PCI_FUNC_TYPE_ISM && limit > base)
129+
fib.pal = limit + (1 << 12);
130+
else
131+
fib.pal = limit;
128132
fib.iota = iota | ZPCI_IOTA_RTTO_FLAG;
129133
fib.gd = zdev->gisa;
130134
cc = zpci_mod_fc(req, &fib, status);
@@ -582,7 +586,6 @@ int pcibios_device_add(struct pci_dev *pdev)
582586
pdev->no_vf_scan = 1;
583587

584588
pdev->dev.groups = zpci_attr_groups;
585-
pdev->dev.dma_ops = &s390_pci_dma_ops;
586589
zpci_map_resources(pdev);
587590

588591
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
@@ -756,8 +759,6 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
756759
if (zdev->dma_table)
757760
rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
758761
virt_to_phys(zdev->dma_table), &status);
759-
else
760-
rc = zpci_dma_init_device(zdev);
761762
if (rc) {
762763
zpci_disable_device(zdev);
763764
return rc;
@@ -865,11 +866,6 @@ int zpci_deconfigure_device(struct zpci_dev *zdev)
865866
if (zdev->zbus->bus)
866867
zpci_bus_remove_device(zdev, false);
867868

868-
if (zdev->dma_table) {
869-
rc = zpci_dma_exit_device(zdev);
870-
if (rc)
871-
return rc;
872-
}
873869
if (zdev_enabled(zdev)) {
874870
rc = zpci_disable_device(zdev);
875871
if (rc)
@@ -918,8 +914,6 @@ void zpci_release_device(struct kref *kref)
918914
if (zdev->zbus->bus)
919915
zpci_bus_remove_device(zdev, false);
920916

921-
if (zdev->dma_table)
922-
zpci_dma_exit_device(zdev);
923917
if (zdev_enabled(zdev))
924918
zpci_disable_device(zdev);
925919

@@ -1109,10 +1103,6 @@ static int __init pci_base_init(void)
11091103
if (rc)
11101104
goto out_irq;
11111105

1112-
rc = zpci_dma_init();
1113-
if (rc)
1114-
goto out_dma;
1115-
11161106
rc = clp_scan_pci_devices();
11171107
if (rc)
11181108
goto out_find;
@@ -1122,8 +1112,6 @@ static int __init pci_base_init(void)
11221112
return 0;
11231113

11241114
out_find:
1125-
zpci_dma_exit();
1126-
out_dma:
11271115
zpci_irq_exit();
11281116
out_irq:
11291117
zpci_mem_exit();

arch/s390/pci/pci_bus.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,6 @@ static int zpci_bus_prepare_device(struct zpci_dev *zdev)
4747
rc = zpci_enable_device(zdev);
4848
if (rc)
4949
return rc;
50-
rc = zpci_dma_init_device(zdev);
51-
if (rc) {
52-
zpci_disable_device(zdev);
53-
return rc;
54-
}
5550
}
5651

5752
if (!zdev->has_resources) {

arch/s390/pci/pci_debug.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ static char *pci_fmt3_names[] = {
5353
};
5454

5555
static char *pci_sw_names[] = {
56-
"Allocated pages",
5756
"Mapped pages",
5857
"Unmapped pages",
58+
"Global RPCITs",
59+
"Sync Map RPCITs",
60+
"Sync RPCITs",
5961
};
6062

6163
static void pci_fmb_show(struct seq_file *m, char *name[], int length,
@@ -69,10 +71,14 @@ static void pci_fmb_show(struct seq_file *m, char *name[], int length,
6971

7072
static void pci_sw_counter_show(struct seq_file *m)
7173
{
72-
struct zpci_dev *zdev = m->private;
73-
atomic64_t *counter = &zdev->allocated_pages;
74+
struct zpci_iommu_ctrs *ctrs = zpci_get_iommu_ctrs(m->private);
75+
atomic64_t *counter;
7476
int i;
7577

78+
if (!ctrs)
79+
return;
80+
81+
counter = &ctrs->mapped_pages;
7682
for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
7783
seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
7884
atomic64_read(counter));

0 commit comments

Comments
 (0)