@@ -84,49 +84,45 @@ static void free_page_list(struct page *freelist)
84
84
}
85
85
}
86
86
87
- static struct page * free_pt_page (unsigned long pt , struct page * freelist )
87
+ static struct page * free_pt_page (u64 * pt , struct page * freelist )
88
88
{
89
- struct page * p = virt_to_page (( void * ) pt );
89
+ struct page * p = virt_to_page (pt );
90
90
91
91
p -> freelist = freelist ;
92
92
93
93
return p ;
94
94
}
95
95
96
- #define DEFINE_FREE_PT_FN (LVL , FN ) \
97
- static struct page *free_pt_##LVL (unsigned long __pt, struct page *freelist) \
98
- { \
99
- unsigned long p; \
100
- u64 *pt; \
101
- int i; \
102
- \
103
- pt = (u64 *)__pt; \
104
- \
105
- for (i = 0; i < 512; ++i) { \
106
- /* PTE present? */ \
107
- if (!IOMMU_PTE_PRESENT (pt [i ])) \
108
- continue ; \
109
- \
110
- /* Large PTE? */ \
111
- if (PM_PTE_LEVEL (pt [i ]) == 0 || \
112
- PM_PTE_LEVEL (pt [i ]) == 7 ) \
113
- continue ; \
114
- \
115
- p = (unsigned long )IOMMU_PTE_PAGE (pt [i ]); \
116
- freelist = FN (p , freelist ); \
117
- } \
118
- \
119
- return free_pt_page ((unsigned long )pt , freelist ); \
120
- }
96
+ static struct page * free_pt_lvl (u64 * pt , struct page * freelist , int lvl )
97
+ {
98
+ u64 * p ;
99
+ int i ;
100
+
101
+ for (i = 0 ; i < 512 ; ++ i ) {
102
+ /* PTE present? */
103
+ if (!IOMMU_PTE_PRESENT (pt [i ]))
104
+ continue ;
121
105
122
- DEFINE_FREE_PT_FN (l2 , free_pt_page )
123
- DEFINE_FREE_PT_FN (l3 , free_pt_l2 )
124
- DEFINE_FREE_PT_FN (l4 , free_pt_l3 )
125
- DEFINE_FREE_PT_FN (l5 , free_pt_l4 )
126
- DEFINE_FREE_PT_FN (l6 , free_pt_l5 )
106
+ /* Large PTE? */
107
+ if (PM_PTE_LEVEL (pt [i ]) == 0 ||
108
+ PM_PTE_LEVEL (pt [i ]) == 7 )
109
+ continue ;
127
110
128
- static struct page * free_sub_pt (unsigned long root , int mode ,
129
- struct page * freelist )
111
+ /*
112
+ * Free the next level. No need to look at l1 tables here since
113
+ * they can only contain leaf PTEs; just free them directly.
114
+ */
115
+ p = IOMMU_PTE_PAGE (pt [i ]);
116
+ if (lvl > 2 )
117
+ freelist = free_pt_lvl (p , freelist , lvl - 1 );
118
+ else
119
+ freelist = free_pt_page (p , freelist );
120
+ }
121
+
122
+ return free_pt_page (pt , freelist );
123
+ }
124
+
125
+ static struct page * free_sub_pt (u64 * root , int mode , struct page * freelist )
130
126
{
131
127
switch (mode ) {
132
128
case PAGE_MODE_NONE :
@@ -136,19 +132,11 @@ static struct page *free_sub_pt(unsigned long root, int mode,
136
132
freelist = free_pt_page (root , freelist );
137
133
break ;
138
134
case PAGE_MODE_2_LEVEL :
139
- freelist = free_pt_l2 (root , freelist );
140
- break ;
141
135
case PAGE_MODE_3_LEVEL :
142
- freelist = free_pt_l3 (root , freelist );
143
- break ;
144
136
case PAGE_MODE_4_LEVEL :
145
- freelist = free_pt_l4 (root , freelist );
146
- break ;
147
137
case PAGE_MODE_5_LEVEL :
148
- freelist = free_pt_l5 (root , freelist );
149
- break ;
150
138
case PAGE_MODE_6_LEVEL :
151
- freelist = free_pt_l6 (root , freelist );
139
+ free_pt_lvl (root , freelist , mode );
152
140
break ;
153
141
default :
154
142
BUG ();
@@ -364,7 +352,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
364
352
365
353
static struct page * free_clear_pte (u64 * pte , u64 pteval , struct page * freelist )
366
354
{
367
- unsigned long pt ;
355
+ u64 * pt ;
368
356
int mode ;
369
357
370
358
while (cmpxchg64 (pte , pteval , 0 ) != pteval ) {
@@ -375,7 +363,7 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
375
363
if (!IOMMU_PTE_PRESENT (pteval ))
376
364
return freelist ;
377
365
378
- pt = ( unsigned long ) IOMMU_PTE_PAGE (pteval );
366
+ pt = IOMMU_PTE_PAGE (pteval );
379
367
mode = IOMMU_PTE_MODE (pteval );
380
368
381
369
return free_sub_pt (pt , mode , freelist );
@@ -512,7 +500,6 @@ static void v1_free_pgtable(struct io_pgtable *iop)
512
500
struct amd_io_pgtable * pgtable = container_of (iop , struct amd_io_pgtable , iop );
513
501
struct protection_domain * dom ;
514
502
struct page * freelist = NULL ;
515
- unsigned long root ;
516
503
517
504
if (pgtable -> mode == PAGE_MODE_NONE )
518
505
return ;
@@ -529,8 +516,7 @@ static void v1_free_pgtable(struct io_pgtable *iop)
529
516
BUG_ON (pgtable -> mode < PAGE_MODE_NONE ||
530
517
pgtable -> mode > PAGE_MODE_6_LEVEL );
531
518
532
- root = (unsigned long )pgtable -> root ;
533
- freelist = free_sub_pt (root , pgtable -> mode , freelist );
519
+ freelist = free_sub_pt (pgtable -> root , pgtable -> mode , freelist );
534
520
535
521
free_page_list (freelist );
536
522
}
0 commit comments