@@ -94,6 +94,7 @@ enum dmar_iirg_type {
94
94
95
95
/* dmar unit runtime data */
96
96
struct dmar_drhd_rt {
97
+ uint32_t index ;
97
98
struct list_head list ;
98
99
spinlock_t lock ;
99
100
@@ -137,6 +138,25 @@ struct iommu_domain {
137
138
uint64_t trans_table_ptr ;
138
139
};
139
140
141
+ struct context_table {
142
+ struct cpu_page buses [CONFIG_IOMMU_INIT_BUS_LIMIT ];
143
+ };
144
+
145
+ static struct cpu_page root_tables [CONFIG_MAX_IOMMU_NUM ] __aligned (CPU_PAGE_SIZE );
146
+ static struct context_table ctx_tables [CONFIG_MAX_IOMMU_NUM ] __aligned (CPU_PAGE_SIZE );
147
+
148
+ static inline uint8_t *
149
+ get_root_table (uint32_t dmar_index )
150
+ {
151
+ return root_tables [dmar_index ].contents ;
152
+ }
153
+
154
+ static inline uint8_t *
155
+ get_ctx_table (uint32_t dmar_index , uint8_t bus_no )
156
+ {
157
+ return ctx_tables [dmar_index ].buses [bus_no ].contents ;
158
+ }
159
+
140
160
static struct list_head dmar_drhd_units ;
141
161
static uint32_t dmar_hdrh_unit_count ;
142
162
@@ -164,6 +184,7 @@ static void register_hrhd_units(void)
164
184
for (i = 0U ; i < info -> drhd_count ; i ++ ) {
165
185
drhd_rt = calloc (1U , sizeof (struct dmar_drhd_rt ));
166
186
ASSERT (drhd_rt != NULL , "" );
187
+ drhd_rt -> index = i ;
167
188
drhd_rt -> drhd = & info -> drhd_units [i ];
168
189
drhd_rt -> dmar_irq = IRQ_INVALID ;
169
190
dmar_register_hrhd (drhd_rt );
@@ -655,7 +676,6 @@ static void dmar_set_root_table(struct dmar_drhd_rt *dmar_uint)
655
676
{
656
677
uint64_t address ;
657
678
uint32_t status ;
658
- void * root_table_vaddr = NULL ;
659
679
660
680
spinlock_obtain (& (dmar_uint -> lock ));
661
681
@@ -667,13 +687,7 @@ static void dmar_set_root_table(struct dmar_drhd_rt *dmar_uint)
667
687
*/
668
688
669
689
if (dmar_uint -> root_table_addr == 0UL ) {
670
- root_table_vaddr = alloc_paging_struct ();
671
-
672
- if (root_table_vaddr != NULL ) {
673
- dmar_uint -> root_table_addr = hva2hpa (root_table_vaddr );
674
- } else {
675
- ASSERT (false, "failed to allocate root table!" );
676
- }
690
+ dmar_uint -> root_table_addr = hva2hpa (get_root_table (dmar_uint -> index ));
677
691
}
678
692
679
693
/* Currently don't support extended root table */
@@ -997,37 +1011,30 @@ static int add_iommu_device(const struct iommu_domain *domain, uint16_t segment,
997
1011
if (dmar_get_bitslice (root_entry -> lower ,
998
1012
ROOT_ENTRY_LOWER_PRESENT_MASK ,
999
1013
ROOT_ENTRY_LOWER_PRESENT_POS ) == 0UL ) {
1000
- void * vaddr = alloc_paging_struct ();
1001
-
1002
- if (vaddr != NULL ) {
1003
- /* create context table for the bus if not present */
1004
- context_table_addr = hva2hpa (vaddr );
1014
+ /* create context table for the bus if not present */
1015
+ context_table_addr = hva2hpa (get_ctx_table (dmar_uint -> index , bus ));
1005
1016
1006
- context_table_addr = context_table_addr >> 12 ;
1017
+ context_table_addr = context_table_addr >> CPU_PAGE_SHIFT ;
1007
1018
1008
- lower = dmar_set_bitslice (lower ,
1009
- ROOT_ENTRY_LOWER_CTP_MASK ,
1010
- ROOT_ENTRY_LOWER_CTP_POS ,
1011
- context_table_addr );
1012
- lower = dmar_set_bitslice (lower ,
1013
- ROOT_ENTRY_LOWER_PRESENT_MASK ,
1014
- ROOT_ENTRY_LOWER_PRESENT_POS , 1UL );
1019
+ lower = dmar_set_bitslice (lower ,
1020
+ ROOT_ENTRY_LOWER_CTP_MASK ,
1021
+ ROOT_ENTRY_LOWER_CTP_POS ,
1022
+ context_table_addr );
1023
+ lower = dmar_set_bitslice (lower ,
1024
+ ROOT_ENTRY_LOWER_PRESENT_MASK ,
1025
+ ROOT_ENTRY_LOWER_PRESENT_POS , 1UL );
1015
1026
1016
- root_entry -> upper = 0UL ;
1017
- root_entry -> lower = lower ;
1018
- iommu_flush_cache (dmar_uint , root_entry ,
1027
+ root_entry -> upper = 0UL ;
1028
+ root_entry -> lower = lower ;
1029
+ iommu_flush_cache (dmar_uint , root_entry ,
1019
1030
sizeof (struct dmar_root_entry ));
1020
- } else {
1021
- ASSERT (false, "failed to allocate context table!" );
1022
- return 1 ;
1023
- }
1024
1031
} else {
1025
1032
context_table_addr = dmar_get_bitslice (root_entry -> lower ,
1026
1033
ROOT_ENTRY_LOWER_CTP_MASK ,
1027
1034
ROOT_ENTRY_LOWER_CTP_POS );
1028
1035
}
1029
1036
1030
- context_table_addr = context_table_addr << 12 ;
1037
+ context_table_addr = context_table_addr << CPU_PAGE_SHIFT ;
1031
1038
1032
1039
context_table =
1033
1040
(struct dmar_context_entry * )hpa2hva (context_table_addr );
0 commit comments