Skip to content

Commit a2392b8

Browse files
rosatomjjoergroedel
authored andcommitted
iommu/s390: support cleanup of additional table regions
Extend the existing dma_cleanup_tables to also handle region second and region first tables. Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com> Tested-by: Niklas Schnelle <schnelle@linux.ibm.com> Link: https://lore.kernel.org/r/20250411202433.181683-3-mjrosato@linux.ibm.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 83c1aec commit a2392b8

File tree

1 file changed

+64
-7
lines changed

1 file changed

+64
-7
lines changed

drivers/iommu/s390-iommu.c

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ static inline int pt_entry_isvalid(unsigned long entry)
121121
return (entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID;
122122
}
123123

124+
static inline unsigned long *get_rf_rso(unsigned long entry)
125+
{
126+
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RFX)
127+
return phys_to_virt(entry & ZPCI_RTE_ADDR_MASK);
128+
else
129+
return NULL;
130+
}
131+
132+
static inline unsigned long *get_rs_rto(unsigned long entry)
133+
{
134+
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RSX)
135+
return phys_to_virt(entry & ZPCI_RTE_ADDR_MASK);
136+
else
137+
return NULL;
138+
}
139+
124140
static inline unsigned long *get_rt_sto(unsigned long entry)
125141
{
126142
if ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RTX)
@@ -192,18 +208,59 @@ static void dma_free_seg_table(unsigned long entry)
192208
dma_free_cpu_table(sto);
193209
}
194210

195-
static void dma_cleanup_tables(unsigned long *table)
211+
static void dma_free_rt_table(unsigned long entry)
196212
{
213+
unsigned long *rto = get_rs_rto(entry);
197214
int rtx;
198215

199-
if (!table)
216+
for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++)
217+
if (reg_entry_isvalid(rto[rtx]))
218+
dma_free_seg_table(rto[rtx]);
219+
220+
dma_free_cpu_table(rto);
221+
}
222+
223+
static void dma_free_rs_table(unsigned long entry)
224+
{
225+
unsigned long *rso = get_rf_rso(entry);
226+
int rsx;
227+
228+
for (rsx = 0; rsx < ZPCI_TABLE_ENTRIES; rsx++)
229+
if (reg_entry_isvalid(rso[rsx]))
230+
dma_free_rt_table(rso[rsx]);
231+
232+
dma_free_cpu_table(rso);
233+
}
234+
235+
static void dma_cleanup_tables(struct s390_domain *domain)
236+
{
237+
int rtx, rsx, rfx;
238+
239+
if (!domain->dma_table)
200240
return;
201241

202-
for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++)
203-
if (reg_entry_isvalid(table[rtx]))
204-
dma_free_seg_table(table[rtx]);
242+
switch (domain->origin_type) {
243+
case ZPCI_TABLE_TYPE_RFX:
244+
for (rfx = 0; rfx < ZPCI_TABLE_ENTRIES; rfx++)
245+
if (reg_entry_isvalid(domain->dma_table[rfx]))
246+
dma_free_rs_table(domain->dma_table[rfx]);
247+
break;
248+
case ZPCI_TABLE_TYPE_RSX:
249+
for (rsx = 0; rsx < ZPCI_TABLE_ENTRIES; rsx++)
250+
if (reg_entry_isvalid(domain->dma_table[rsx]))
251+
dma_free_rt_table(domain->dma_table[rsx]);
252+
break;
253+
case ZPCI_TABLE_TYPE_RTX:
254+
for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++)
255+
if (reg_entry_isvalid(domain->dma_table[rtx]))
256+
dma_free_seg_table(domain->dma_table[rtx]);
257+
break;
258+
default:
259+
WARN_ONCE(1, "Invalid IOMMU table (%x)\n", domain->origin_type);
260+
return;
261+
}
205262

206-
dma_free_cpu_table(table);
263+
dma_free_cpu_table(domain->dma_table);
207264
}
208265

209266
static unsigned long *dma_alloc_page_table(gfp_t gfp)
@@ -358,7 +415,7 @@ static void s390_iommu_rcu_free_domain(struct rcu_head *head)
358415
{
359416
struct s390_domain *s390_domain = container_of(head, struct s390_domain, rcu);
360417

361-
dma_cleanup_tables(s390_domain->dma_table);
418+
dma_cleanup_tables(s390_domain);
362419
kfree(s390_domain);
363420
}
364421

0 commit comments

Comments
 (0)