Skip to content

Commit f05bfeb

Browse files
tw4452852lijinxia
authored andcommitted
hv: vtd: remove dynamic page allocation for root&ctx table
Preserve pages for each vtd root table and ctx table Tracked-On: #861 Signed-off-by: Tw <wei.tan@intel.com> Reviewed-by: Binbin Wu <binbin.wu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 1b1338b commit f05bfeb

File tree

2 files changed

+40
-29
lines changed

2 files changed

+40
-29
lines changed

hypervisor/arch/x86/vtd.c

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ enum dmar_iirg_type {
9494

9595
/* dmar unit runtime data */
9696
struct dmar_drhd_rt {
97+
uint32_t index;
9798
struct list_head list;
9899
spinlock_t lock;
99100

@@ -137,6 +138,25 @@ struct iommu_domain {
137138
uint64_t trans_table_ptr;
138139
};
139140

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+
140160
static struct list_head dmar_drhd_units;
141161
static uint32_t dmar_hdrh_unit_count;
142162

@@ -164,6 +184,7 @@ static void register_hrhd_units(void)
164184
for (i = 0U; i < info->drhd_count; i++) {
165185
drhd_rt = calloc(1U, sizeof(struct dmar_drhd_rt));
166186
ASSERT(drhd_rt != NULL, "");
187+
drhd_rt->index = i;
167188
drhd_rt->drhd = &info->drhd_units[i];
168189
drhd_rt->dmar_irq = IRQ_INVALID;
169190
dmar_register_hrhd(drhd_rt);
@@ -655,7 +676,6 @@ static void dmar_set_root_table(struct dmar_drhd_rt *dmar_uint)
655676
{
656677
uint64_t address;
657678
uint32_t status;
658-
void *root_table_vaddr = NULL;
659679

660680
spinlock_obtain(&(dmar_uint->lock));
661681

@@ -667,13 +687,7 @@ static void dmar_set_root_table(struct dmar_drhd_rt *dmar_uint)
667687
*/
668688

669689
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));
677691
}
678692

679693
/* Currently don't support extended root table */
@@ -997,37 +1011,30 @@ static int add_iommu_device(const struct iommu_domain *domain, uint16_t segment,
9971011
if (dmar_get_bitslice(root_entry->lower,
9981012
ROOT_ENTRY_LOWER_PRESENT_MASK,
9991013
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));
10051016

1006-
context_table_addr = context_table_addr >> 12;
1017+
context_table_addr = context_table_addr >> CPU_PAGE_SHIFT;
10071018

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);
10151026

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,
10191030
sizeof(struct dmar_root_entry));
1020-
} else {
1021-
ASSERT(false, "failed to allocate context table!");
1022-
return 1;
1023-
}
10241031
} else {
10251032
context_table_addr = dmar_get_bitslice(root_entry->lower,
10261033
ROOT_ENTRY_LOWER_CTP_MASK,
10271034
ROOT_ENTRY_LOWER_CTP_POS);
10281035
}
10291036

1030-
context_table_addr = context_table_addr << 12;
1037+
context_table_addr = context_table_addr << CPU_PAGE_SHIFT;
10311038

10321039
context_table =
10331040
(struct dmar_context_entry *)hpa2hva(context_table_addr);

hypervisor/include/arch/x86/mmu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ enum _page_table_level {
7171
#define PAGE_SIZE_2M MEM_2M
7272
#define PAGE_SIZE_1G MEM_1G
7373

74+
struct cpu_page {
75+
uint8_t contents[CPU_PAGE_SIZE];
76+
};
77+
7478
uint64_t get_paging_pml4(void);
7579
void *alloc_paging_struct(void);
7680
void free_paging_struct(void *ptr);

0 commit comments

Comments
 (0)