vtd: fix memory coherency issue of vtd table

Signed-off-by: Binbin Wu <binbin.wu@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
Binbin Wu 2018-04-11 17:19:41 +08:00 committed by lijinxia
parent 2943e43955
commit 46c32eb000

View File

@ -252,6 +252,20 @@ static void iommu_write64(struct dmar_drhd_rt *dmar_uint, uint32_t offset,
mmio_write_long(temp, dmar_uint->drhd->reg_base_addr + offset + 4);
}
/* flush cache when root table, context table updated */
static void iommu_flush_cache(struct dmar_drhd_rt *dmar_uint,
void *p, uint32_t size)
{
uint32_t i;
/* if vtd support page-walk coherency, no need to flush cacheline */
if (iommu_ecap_c(dmar_uint->ecap))
return;
for (i = 0; i < size; i += CACHE_LINE_SIZE)
clflush((char *)p + i);
}
#if DBG_IOMMU
static void dmar_uint_show_capability(struct dmar_drhd_rt *dmar_uint)
{
@ -975,6 +989,8 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
root_entry->upper = 0;
root_entry->lower = lower;
iommu_flush_cache(dmar_uint, root_entry,
sizeof(struct dmar_root_entry));
} else {
context_table_addr = DMAR_GET_BITSLICE(root_entry->lower,
ROOT_ENTRY_LOWER_CTP);
@ -1028,6 +1044,8 @@ static int add_iommu_device(struct iommu_domain *domain, uint16_t segment,
context_entry->upper = upper;
context_entry->lower = lower;
iommu_flush_cache(dmar_uint, context_entry,
sizeof(struct dmar_context_entry));
return 0;
}
@ -1072,6 +1090,8 @@ remove_iommu_device(struct iommu_domain *domain, uint16_t segment,
/* clear the present bit first */
context_entry->lower = 0;
context_entry->upper = 0;
iommu_flush_cache(dmar_uint, context_entry,
sizeof(struct dmar_context_entry));
/* if caching mode is present, need to invalidate translation cache */
/* if(cap_caching_mode(dmar_uint->cap)) { */