1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/dma-mapping.h>
3 #include <asm/iommu_table.h>
4 #include <linux/string.h>
5 #include <linux/kallsyms.h>
10 static struct iommu_table_entry
* __init
11 find_dependents_of(struct iommu_table_entry
*start
,
12 struct iommu_table_entry
*finish
,
13 struct iommu_table_entry
*q
)
15 struct iommu_table_entry
*p
;
20 for (p
= start
; p
< finish
; p
++)
21 if (p
->detect
== q
->depend
)
28 void __init
sort_iommu_table(struct iommu_table_entry
*start
,
29 struct iommu_table_entry
*finish
) {
31 struct iommu_table_entry
*p
, *q
, tmp
;
33 for (p
= start
; p
< finish
; p
++) {
35 q
= find_dependents_of(start
, finish
, p
);
36 /* We are bit sneaky here. We use the memory address to figure
37 * out if the node we depend on is past our point, if so, swap.
41 memmove(p
, q
, sizeof(*p
));
50 void __init
check_iommu_entries(struct iommu_table_entry
*start
,
51 struct iommu_table_entry
*finish
)
53 struct iommu_table_entry
*p
, *q
, *x
;
55 /* Simple cyclic dependency checker. */
56 for (p
= start
; p
< finish
; p
++) {
57 q
= find_dependents_of(start
, finish
, p
);
58 x
= find_dependents_of(start
, finish
, q
);
60 printk(KERN_ERR
"CYCLIC DEPENDENCY FOUND! %pS depends on %pS and vice-versa. BREAKING IT.\n",
61 p
->detect
, q
->detect
);
62 /* Heavy handed way..*/
67 for (p
= start
; p
< finish
; p
++) {
68 q
= find_dependents_of(p
, finish
, p
);
70 printk(KERN_ERR
"EXECUTION ORDER INVALID! %pS should be called before %pS!\n",
71 p
->detect
, q
->detect
);
76 void __init
check_iommu_entries(struct iommu_table_entry
*start
,
77 struct iommu_table_entry
*finish
)