mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-28 08:16:54 +00:00
hv: vtd: defer dma remapping enabling until vm creation
In current code, DMA remapping is enabled at very early stage, when there is no device added. Devices are added to VT-d context table when creating VMs. There is potential risk that there may be device DMA transactions when DMA remapping is enabled, but the device is not added to the VT-d context table. (Eg. this could happen in UEFI enviroment when USB keyboard use in efi intenal shell.) This patch defers DMA remapping enabling until vm creation. Tracked-On: #1855 Signed-off-by: Binbin Wu <binbin.wu@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
parent
42e0e169c3
commit
c449002846
@ -119,6 +119,8 @@ int create_vm(struct vm_description *vm_desc, struct acrn_vm **rtn_vm)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enable_iommu();
|
||||||
|
|
||||||
INIT_LIST_HEAD(&vm->softirq_dev_entry_list);
|
INIT_LIST_HEAD(&vm->softirq_dev_entry_list);
|
||||||
spinlock_init(&vm->softirq_dev_lock);
|
spinlock_init(&vm->softirq_dev_lock);
|
||||||
vm->intr_inject_delay_delta = 0UL;
|
vm->intr_inject_delay_delta = 0UL;
|
||||||
|
@ -152,7 +152,7 @@ bool iommu_snoop_supported(struct acrn_vm *vm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct dmar_drhd_rt dmar_drhd_units[CONFIG_MAX_IOMMU_NUM];
|
static struct dmar_drhd_rt dmar_drhd_units[CONFIG_MAX_IOMMU_NUM];
|
||||||
|
static bool iommu_page_walk_coherent = true;
|
||||||
static struct iommu_domain *vm0_domain;
|
static struct iommu_domain *vm0_domain;
|
||||||
|
|
||||||
/* Domain id 0 is reserved in some cases per VT-d */
|
/* Domain id 0 is reserved in some cases per VT-d */
|
||||||
@ -424,6 +424,10 @@ static int dmar_register_hrhd(struct dmar_drhd_rt *dmar_unit)
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((iommu_ecap_c(dmar_unit->ecap) == 0U) && (dmar_unit->drhd->ignore != 0U)) {
|
||||||
|
iommu_page_walk_coherent = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* when the hardware support snoop control,
|
/* when the hardware support snoop control,
|
||||||
* to make sure snoop control is always enabled,
|
* to make sure snoop control is always enabled,
|
||||||
* the SNP filed in the leaf PTE should be set.
|
* the SNP filed in the leaf PTE should be set.
|
||||||
@ -771,12 +775,17 @@ static int dmar_setup_interrupt(struct dmar_drhd_rt *dmar_unit)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dmar_enable(struct dmar_drhd_rt *dmar_unit)
|
static void dmar_prepare(struct dmar_drhd_rt *dmar_unit)
|
||||||
{
|
{
|
||||||
dev_dbg(ACRN_DBG_IOMMU, "enable dmar uint [0x%x]", dmar_unit->drhd->reg_base_addr);
|
dev_dbg(ACRN_DBG_IOMMU, "enable dmar uint [0x%x]", dmar_unit->drhd->reg_base_addr);
|
||||||
dmar_setup_interrupt(dmar_unit);
|
dmar_setup_interrupt(dmar_unit);
|
||||||
dmar_write_buffer_flush(dmar_unit);
|
|
||||||
dmar_set_root_table(dmar_unit);
|
dmar_set_root_table(dmar_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dmar_enable(struct dmar_drhd_rt *dmar_unit)
|
||||||
|
{
|
||||||
|
dev_dbg(ACRN_DBG_IOMMU, "enable dmar uint [0x%x]", dmar_unit->drhd->reg_base_addr);
|
||||||
|
dmar_write_buffer_flush(dmar_unit);
|
||||||
dmar_invalid_context_cache_global(dmar_unit);
|
dmar_invalid_context_cache_global(dmar_unit);
|
||||||
dmar_invalid_iotlb_global(dmar_unit);
|
dmar_invalid_iotlb_global(dmar_unit);
|
||||||
dmar_enable_translation(dmar_unit);
|
dmar_enable_translation(dmar_unit);
|
||||||
@ -813,6 +822,7 @@ static void dmar_resume(struct dmar_drhd_rt *dmar_unit)
|
|||||||
for (i = 0U; i < IOMMU_FAULT_REGISTER_STATE_NUM; i++) {
|
for (i = 0U; i < IOMMU_FAULT_REGISTER_STATE_NUM; i++) {
|
||||||
iommu_write32(dmar_unit, DMAR_FECTL_REG + (i * IOMMU_FAULT_REGISTER_SIZE), dmar_unit->fault_state[i]);
|
iommu_write32(dmar_unit, DMAR_FECTL_REG + (i * IOMMU_FAULT_REGISTER_SIZE), dmar_unit->fault_state[i]);
|
||||||
}
|
}
|
||||||
|
dmar_prepare(dmar_unit);
|
||||||
dmar_enable(dmar_unit);
|
dmar_enable(dmar_unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,6 +1070,9 @@ int unassign_iommu_device(const struct iommu_domain *domain, uint8_t bus, uint8_
|
|||||||
|
|
||||||
void enable_iommu(void)
|
void enable_iommu(void)
|
||||||
{
|
{
|
||||||
|
if (!iommu_page_walk_coherent) {
|
||||||
|
cache_flush_invalidate_all();
|
||||||
|
}
|
||||||
do_action_for_iommus(dmar_enable);
|
do_action_for_iommus(dmar_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1087,9 +1100,7 @@ int init_iommu(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_iommu();
|
do_action_for_iommus(dmar_prepare);
|
||||||
|
|
||||||
cache_flush_invalidate_all();
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1108,5 +1119,4 @@ void init_iommu_vm0_domain(struct acrn_vm *vm0)
|
|||||||
add_iommu_device(vm0_domain, 0U, (uint8_t)bus, (uint8_t)devfun);
|
add_iommu_device(vm0_domain, 0U, (uint8_t)bus, (uint8_t)devfun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache_flush_invalidate_all();
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user